Skip to content

Commit

Permalink
refactor: assembler.h
Browse files Browse the repository at this point in the history
  • Loading branch information
MeerkatBoss committed Oct 13, 2022
1 parent 9eed3d0 commit 74d1fb8
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 40 deletions.
27 changes: 27 additions & 0 deletions lib/asm/asm_cmd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef ASM_CMD
#error "macro ASM_CMD was not defined"
#endif

#define _ ,

ASM_CMD(NOP, 0x00, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(ADD, 0x01, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(INC, 0x02, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(SUB, 0x03, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(DEC, 0x04, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(MUL, 0x05, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(DIV, 0x06, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(PUSH,0x07, {.arg_count = 1 _ .arg_list = {{.perms = ARG_RD}}})

ASM_CMD(POP, 0x08, {.arg_count = 0 _ .arg_list = {}})

ASM_CMD(HALT,0x09, {.arg_count = 0 _ .arg_list = {}})

#undef _
75 changes: 53 additions & 22 deletions lib/asm/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,83 @@

#include <stddef.h>

#define ASM_CMD(name, num, ...) CMD_##name=num,

/**
* @brief
* Byte-codes of virtual CPU instructions
*/
enum asm_command
enum cpu_command : char
{
CMD_NOP = 0x00,
CMD_ADD = 0x01,
CMD_INC = 0x02,
CMD_SUB = 0x03,
CMD_DEC = 0x04,
CMD_MUL = 0x05,
CMD_DIV = 0x06,
CMD_PUSH = 0x07,
CMD_POP = 0x08,
CMD_HALT = 0x09
#include "asm_cmd.h"
};

#undef ASM_CMD

const size_t ARG_MAX = 1;

/**
* @brief
* Permissions required for CPU command's formal argument
*/
enum arg_perms
{
ARG_RD = 01,
ARG_WR = 02,
ARG_RDWR = ARG_RD | ARG_WR
};

/**
* @brief
* Description of CPU command formal argument
*/
struct asm_arg
{
int* val_ptr;
arg_perms perms;
};

/**
* @brief
* Inforamtion about specific command's formal
* arguments
*/
struct cmd_args
{
size_t arg_count;
asm_arg arg_list[ARG_MAX];
};

/**
* @brief Wrapper for struct initializers
*
* @param args `cmd_args` initializet
* @return args
*/
inline cmd_args get_arg(cmd_args args) { return args; }

/**
* @brief
* Description for virtual CPU command
*/
struct command_description
{
asm_command command;
cpu_command command;
const char* name;
size_t arg_count;
};

#define ASM_CMD(cmd_name, num, args, ...)\
{ .command = (cpu_command) num, .name = #cmd_name, .arg_count = get_arg(args).arg_count },
/**
* @brief
* All commands array
*/
const command_description COMMANDS[] =
{
{.command = CMD_NOP, .name = "nop", .arg_count = 0},
{.command = CMD_ADD, .name = "add", .arg_count = 0},
{.command = CMD_INC, .name = "inc", .arg_count = 0},
{.command = CMD_SUB, .name = "sub", .arg_count = 0},
{.command = CMD_DEC, .name = "dec", .arg_count = 0},
{.command = CMD_MUL, .name = "mul", .arg_count = 0},
{.command = CMD_DIV, .name = "div", .arg_count = 0},
{.command = CMD_PUSH, .name = "push", .arg_count = 1},
{.command = CMD_POP, .name = "pop", .arg_count = 0},
{.command = CMD_HALT, .name = "halt", .arg_count = 0}
#include "asm_cmd.h"
};
#undef ASM_CMD

/**
* @brief
Expand Down
2 changes: 1 addition & 1 deletion lib/stack
Submodule stack updated 1 files
+1 −1 stack.h
18 changes: 9 additions & 9 deletions output/listing.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
1: push 50 7 50
2: push 30 7 30
3: sub 3
4: push 5 7 5
5: push 3 7 3
6: sub 3
7: div 6
8: pop 8
9: halt 9
[000000] 0x0007 0x0032 | push 50
[0x0002] 0x0007 0x001e | push 30
[0x0004] 0x0003 | sub
[0x0005] 0x0007 0x0005 | push 5
[0x0007] 0x0007 0x0003 | push 3
[0x0009] 0x0003 | sub
[0x000a] 0x0006 | div
[0x000b] 0x0008 | pop
[0x000c] 0x0009 | halt
14 changes: 8 additions & 6 deletions src/asm/asm_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,17 @@ void try_print_listing(const TextLines text_lines, const void* cmd_array)
LOG_ASSERT_ERROR(listing != NULL, return,
"Could not open listing file \'%s\'", listing_file);

const int *int_cmd = (const int*)cmd_array;
const unsigned int *int_cmd = (const unsigned int*)cmd_array;
size_t ip = 0;

for (size_t i = 0; i < text_lines.line_count; i++)
{
fprintf(listing, "%zu:\t%24s|\t%04x", i + 1, text_lines.lines[i].line, *int_cmd);
size_t arg_count = COMMANDS[*int_cmd].arg_count;
int_cmd++;
fprintf(listing, "[%#06zx] %#06x", ip, int_cmd[ip]);
size_t arg_count = COMMANDS[int_cmd[ip]].arg_count;
ip++;
for (size_t j = 0; j < arg_count; j++)
fprintf(listing, " %04x", *(int_cmd++));
fputc('\n', listing);
fprintf(listing, " %#06x", int_cmd[ip++]);
fprintf(listing, "%*s %s\n", (ARG_MAX - arg_count + 1) * 7 + 4,
"|", text_lines.lines[i].line);
}
}
48 changes: 46 additions & 2 deletions src/asm/asm_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,56 @@ const arg_tag TAGS[] =
*/
const size_t TAG_COUNT = sizeof(TAGS)/sizeof(*TAGS);

enum assembly_result
{
ASM_SUCCESS = 0,
ASM_SYNTAX = -1,
ASM_LABEL_OVF = -2,
ASM_DEFS_OVF = -3,
ASM_FIXUP_OVF = -4
};

const size_t MAX_LABEL_LEN = 32;
struct asm_label
{
char name[32];
ssize_t addr;
};

struct fixup
{
size_t label_number;
size_t addr;
};

struct asm_def
{
char name[MAX_LABEL_LEN];
int value;
};

const size_t MAX_LABELS = 64;
const size_t MAX_FIXUPS = MAX_LABELS * 4;

struct assembly_state
{
padded_header header;
size_t ip;
int* cmd;
asm_label labels[MAX_LABELS];
asm_def definitions[MAX_LABELS];
fixup fixups[MAX_FIXUPS];
assembly_result result;
};

int assemble(TextLines* text_lines, assembly_state* state);

/**
* @brief Get the command by name
*
* @param[in] str Command name
* @param[out] n_read Number of charachters read from `str`
* @return pointer to mathcing `command_description` upon success,
* @param[out] n_read Number of characters read from `str`
* @return pointer to matching `command_description` upon success,
* `NULL` otheriwse
*/
const command_description* get_description(const char* str, int* n_read);
Expand Down

0 comments on commit 74d1fb8

Please sign in to comment.