Current work on preprocessor implementation
Lots to refactor and test
This commit is contained in:
11
asm/lexer.c
11
asm/lexer.c
@@ -24,6 +24,10 @@ const char *token_type_as_cstr(token_type_t type)
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
case TOKEN_PP_CONST:
|
||||||
|
return "PP_CONST";
|
||||||
|
case TOKEN_PP_END:
|
||||||
|
return "PP_END";
|
||||||
case TOKEN_GLOBAL:
|
case TOKEN_GLOBAL:
|
||||||
return "GLOBAL";
|
return "GLOBAL";
|
||||||
case TOKEN_STAR:
|
case TOKEN_STAR:
|
||||||
@@ -164,7 +168,12 @@ token_t tokenise_symbol(buffer_t *buffer, size_t *column)
|
|||||||
token_type_t type = 0;
|
token_type_t type = 0;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
if (sym_size == 4 && strncmp(opcode, "NOOP", 4) == 0)
|
if (sym_size > 1 && strncmp(opcode, "%", 1) == 0)
|
||||||
|
{
|
||||||
|
// Some kind of preprocessing directive
|
||||||
|
// TODO: Implement tokeniser for preprocessing directive
|
||||||
|
}
|
||||||
|
else if (sym_size == 4 && strncmp(opcode, "NOOP", 4) == 0)
|
||||||
{
|
{
|
||||||
offset = 4;
|
offset = 4;
|
||||||
type = TOKEN_NOOP;
|
type = TOKEN_NOOP;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
typedef enum TokenType
|
typedef enum TokenType
|
||||||
{
|
{
|
||||||
|
TOKEN_PP_CONST,
|
||||||
|
TOKEN_PP_END,
|
||||||
TOKEN_GLOBAL,
|
TOKEN_GLOBAL,
|
||||||
TOKEN_STAR,
|
TOKEN_STAR,
|
||||||
TOKEN_LITERAL_NUMBER,
|
TOKEN_LITERAL_NUMBER,
|
||||||
|
|||||||
169
asm/parser.c
169
asm/parser.c
@@ -50,6 +50,23 @@ const char *perr_as_cstr(perr_t perr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void presult_free(presult_t res)
|
||||||
|
{
|
||||||
|
switch (res.type)
|
||||||
|
{
|
||||||
|
case PRES_GLOBAL_LABEL:
|
||||||
|
case PRES_LABEL:
|
||||||
|
free(res.label.name);
|
||||||
|
break;
|
||||||
|
case PRES_PP_CONST:
|
||||||
|
case PRES_LABEL_ADDRESS:
|
||||||
|
case PRES_RELATIVE_ADDRESS:
|
||||||
|
case PRES_COMPLETE_RESULT:
|
||||||
|
free(res.instructions.data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
perr_t parse_word(token_t token, word *ret)
|
perr_t parse_word(token_t token, word *ret)
|
||||||
{
|
{
|
||||||
if (token.type == TOKEN_LITERAL_NUMBER)
|
if (token.type == TOKEN_LITERAL_NUMBER)
|
||||||
@@ -124,17 +141,19 @@ perr_t parse_word_label_or_relative(token_stream_t *stream, presult_t *res)
|
|||||||
token_t token = TOKEN_STREAM_AT(stream->data, stream->used);
|
token_t token = TOKEN_STREAM_AT(stream->data, stream->used);
|
||||||
if (token.type == TOKEN_SYMBOL)
|
if (token.type == TOKEN_SYMBOL)
|
||||||
{
|
{
|
||||||
res->type = PRES_LABEL_ADDRESS;
|
res->type = PRES_LABEL_ADDRESS;
|
||||||
res->label = calloc(token.str_size + 1, 1);
|
res->label.size = token.str_size;
|
||||||
memcpy(res->label, token.str, token.str_size);
|
res->label.name = calloc(res->label.size + 1, 1);
|
||||||
res->label[token.str_size] = '\0';
|
memcpy(res->label.name, token.str, res->label.size + 1);
|
||||||
return PERR_OK;
|
return PERR_OK;
|
||||||
}
|
}
|
||||||
else if (token.type == TOKEN_LITERAL_CHAR ||
|
else if (token.type == TOKEN_LITERAL_CHAR ||
|
||||||
token.type == TOKEN_LITERAL_NUMBER)
|
token.type == TOKEN_LITERAL_NUMBER)
|
||||||
{
|
{
|
||||||
res->type = PRES_COMPLETE_RESULT;
|
res->type = PRES_COMPLETE_RESULT;
|
||||||
return parse_word(token, &res->instruction.operand.as_word);
|
darr_init(&res->instructions, sizeof(inst_t));
|
||||||
|
return parse_word(
|
||||||
|
token, &DARR_AT(inst_t, res->instructions.data, 0).operand.as_word);
|
||||||
}
|
}
|
||||||
else if (token.type == TOKEN_STAR)
|
else if (token.type == TOKEN_STAR)
|
||||||
{
|
{
|
||||||
@@ -241,7 +260,9 @@ perr_t parse_utype_inst_with_operand(token_stream_t *stream, inst_t *ret)
|
|||||||
|
|
||||||
perr_t parse_jump_inst_operand(token_stream_t *stream, presult_t *res)
|
perr_t parse_jump_inst_operand(token_stream_t *stream, presult_t *res)
|
||||||
{
|
{
|
||||||
perr_t inst_err = parse_utype_inst(stream, &res->instruction);
|
perr_t inst_err = parse_utype_inst(
|
||||||
|
stream, &DARR_AT(inst_t, res->instructions.data,
|
||||||
|
res->instructions.used / sizeof(inst_t)));
|
||||||
if (inst_err)
|
if (inst_err)
|
||||||
return inst_err;
|
return inst_err;
|
||||||
++stream->used;
|
++stream->used;
|
||||||
@@ -266,10 +287,13 @@ perr_t parse_type_inst_with_operand(token_stream_t *stream, inst_t *ret)
|
|||||||
|
|
||||||
perr_t parse_next(token_stream_t *stream, presult_t *ret)
|
perr_t parse_next(token_stream_t *stream, presult_t *ret)
|
||||||
{
|
{
|
||||||
const token_t token = TOKEN_STREAM_AT(stream->data, stream->used);
|
token_t token = TOKEN_STREAM_AT(stream->data, stream->used);
|
||||||
perr_t perr = PERR_OK;
|
perr_t perr = PERR_OK;
|
||||||
switch (token.type)
|
switch (token.type)
|
||||||
{
|
{
|
||||||
|
case TOKEN_PP_CONST:
|
||||||
|
|
||||||
|
break;
|
||||||
case TOKEN_LITERAL_NUMBER:
|
case TOKEN_LITERAL_NUMBER:
|
||||||
case TOKEN_LITERAL_CHAR:
|
case TOKEN_LITERAL_CHAR:
|
||||||
return PERR_EXPECTED_SYMBOL;
|
return PERR_EXPECTED_SYMBOL;
|
||||||
@@ -279,180 +303,155 @@ perr_t parse_next(token_stream_t *stream, presult_t *ret)
|
|||||||
return PERR_EXPECTED_LABEL;
|
return PERR_EXPECTED_LABEL;
|
||||||
++stream->used;
|
++stream->used;
|
||||||
token_t label = TOKEN_STREAM_AT(stream->data, stream->used);
|
token_t label = TOKEN_STREAM_AT(stream->data, stream->used);
|
||||||
*ret = (presult_t){.type = PRES_GLOBAL_LABEL,
|
*ret =
|
||||||
.label = malloc(label.str_size + 1)};
|
(presult_t){.type = PRES_GLOBAL_LABEL,
|
||||||
memcpy(ret->label, label.str, label.str_size);
|
.label = (struct PLabel){.name = malloc(label.str_size + 1),
|
||||||
ret->label[label.str_size] = '\0';
|
.size = label.str_size}};
|
||||||
|
memcpy(ret->label.name, label.str, label.str_size + 1);
|
||||||
return PERR_OK;
|
return PERR_OK;
|
||||||
}
|
}
|
||||||
case TOKEN_NOOP:
|
case TOKEN_NOOP:
|
||||||
*ret = (presult_t){.instruction = INST_NOOP, .type = PRES_COMPLETE_RESULT};
|
*ret = presult_instruction(INST_NOOP);
|
||||||
|
ret->type = PRES_COMPLETE_RESULT;
|
||||||
break;
|
break;
|
||||||
case TOKEN_HALT:
|
case TOKEN_HALT:
|
||||||
*ret = (presult_t){.instruction = INST_HALT, .type = PRES_COMPLETE_RESULT};
|
*ret = presult_instruction(INST_HALT);
|
||||||
|
ret->type = PRES_COMPLETE_RESULT;
|
||||||
break;
|
break;
|
||||||
case TOKEN_PUSH:
|
case TOKEN_PUSH:
|
||||||
*ret = (presult_t){.instruction = INST_PUSH(BYTE, 0),
|
*ret = presult_instruction(INST_PUSH(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_POP:
|
case TOKEN_POP:
|
||||||
*ret = (presult_t){.instruction = INST_POP(BYTE),
|
*ret = presult_instruction(INST_POP(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_PUSH_REG:
|
case TOKEN_PUSH_REG:
|
||||||
*ret = (presult_t){.instruction = INST_PUSH_REG(BYTE, 0),
|
*ret = presult_instruction(INST_PUSH_REG(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MOV:
|
case TOKEN_MOV:
|
||||||
*ret = (presult_t){.instruction = INST_MOV(BYTE, 0),
|
*ret = presult_instruction(INST_PUSH_REG(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_DUP:
|
case TOKEN_DUP:
|
||||||
*ret = (presult_t){.instruction = INST_DUP(BYTE, 0),
|
*ret = presult_instruction(INST_DUP(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MALLOC:
|
case TOKEN_MALLOC:
|
||||||
*ret = (presult_t){.instruction = INST_MALLOC(BYTE, 0),
|
*ret = presult_instruction(INST_MALLOC(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MSET:
|
case TOKEN_MSET:
|
||||||
*ret = (presult_t){.instruction = INST_MSET(BYTE, 0),
|
*ret = presult_instruction(INST_MSET(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MGET:
|
case TOKEN_MGET:
|
||||||
*ret = (presult_t){.instruction = INST_MGET(BYTE, 0),
|
*ret = presult_instruction(INST_MGET(BYTE, 0));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
perr = parse_utype_inst_with_operand(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MALLOC_STACK:
|
case TOKEN_MALLOC_STACK:
|
||||||
*ret = (presult_t){.instruction = INST_MALLOC_STACK(BYTE),
|
*ret = presult_instruction(INST_MALLOC_STACK(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MSET_STACK:
|
case TOKEN_MSET_STACK:
|
||||||
*ret = (presult_t){.instruction = INST_MSET_STACK(BYTE),
|
*ret = presult_instruction(INST_MSET_STACK(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MGET_STACK:
|
case TOKEN_MGET_STACK:
|
||||||
*ret = (presult_t){.instruction = INST_MGET_STACK(BYTE),
|
*ret = presult_instruction(INST_MGET_STACK(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MDELETE:
|
case TOKEN_MDELETE:
|
||||||
*ret =
|
*ret = presult_instruction(INST_MDELETE);
|
||||||
(presult_t){.instruction = INST_MDELETE, .type = PRES_COMPLETE_RESULT};
|
|
||||||
break;
|
break;
|
||||||
case TOKEN_MSIZE:
|
case TOKEN_MSIZE:
|
||||||
*ret = (presult_t){.instruction = INST_MSIZE, .type = PRES_COMPLETE_RESULT};
|
*ret = presult_instruction(INST_MSIZE);
|
||||||
break;
|
break;
|
||||||
case TOKEN_NOT:
|
case TOKEN_NOT:
|
||||||
*ret = (presult_t){.instruction = INST_NOT(BYTE),
|
*ret = presult_instruction(INST_NOT(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_OR:
|
case TOKEN_OR:
|
||||||
*ret =
|
*ret = presult_instruction(INST_OR(BYTE));
|
||||||
(presult_t){.instruction = INST_OR(BYTE), .type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_AND:
|
case TOKEN_AND:
|
||||||
*ret = (presult_t){.instruction = INST_AND(BYTE),
|
*ret = presult_instruction(INST_AND(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_XOR:
|
case TOKEN_XOR:
|
||||||
*ret = (presult_t){.instruction = INST_XOR(BYTE),
|
*ret = presult_instruction(INST_XOR(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_EQ:
|
case TOKEN_EQ:
|
||||||
*ret =
|
*ret = presult_instruction(INST_EQ(BYTE));
|
||||||
(presult_t){.instruction = INST_EQ(BYTE), .type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_LT:
|
case TOKEN_LT:
|
||||||
*ret =
|
*ret = presult_instruction(INST_LT(BYTE));
|
||||||
(presult_t){.instruction = INST_LT(BYTE), .type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_type_inst(stream, &ret->instruction);
|
perr = parse_type_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_LTE:
|
case TOKEN_LTE:
|
||||||
*ret = (presult_t){.instruction = INST_LTE(BYTE),
|
*ret = presult_instruction(INST_LTE(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_type_inst(stream, &ret->instruction);
|
perr = parse_type_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_GT:
|
case TOKEN_GT:
|
||||||
*ret =
|
*ret = presult_instruction(INST_GT(BYTE));
|
||||||
(presult_t){.instruction = INST_GT(BYTE), .type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_type_inst(stream, &ret->instruction);
|
perr = parse_type_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_GTE:
|
case TOKEN_GTE:
|
||||||
*ret = (presult_t){.instruction = INST_GTE(BYTE),
|
*ret = presult_instruction(INST_GTE(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_type_inst(stream, &ret->instruction);
|
perr = parse_type_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_PLUS:
|
case TOKEN_PLUS:
|
||||||
*ret = (presult_t){.instruction = INST_PLUS(BYTE),
|
*ret = presult_instruction(INST_PLUS(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_SUB:
|
case TOKEN_SUB:
|
||||||
*ret = (presult_t){.instruction = INST_SUB(BYTE),
|
*ret = presult_instruction(INST_SUB(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_MULT:
|
case TOKEN_MULT:
|
||||||
*ret = (presult_t){.instruction = INST_MULT(BYTE),
|
*ret = presult_instruction(INST_MULT(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_utype_inst(stream, &ret->instruction);
|
perr = parse_utype_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_PRINT:
|
case TOKEN_PRINT:
|
||||||
*ret = (presult_t){.instruction = INST_PRINT(BYTE),
|
*ret = presult_instruction(INST_PRINT(BYTE));
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
perr = parse_type_inst(stream, &ret->instruction);
|
perr = parse_type_inst(stream, &ret->instruction);
|
||||||
break;
|
break;
|
||||||
case TOKEN_JUMP_ABS:
|
case TOKEN_JUMP_ABS:
|
||||||
*ret = (presult_t){.instruction = INST_JUMP_ABS(0)};
|
*ret = presult_instruction(INST_JUMP_ABS(0));
|
||||||
++stream->used;
|
++stream->used;
|
||||||
if (stream->used >= stream->available)
|
if (stream->used >= stream->available)
|
||||||
return PERR_EXPECTED_OPERAND;
|
return PERR_EXPECTED_OPERAND;
|
||||||
return parse_word_label_or_relative(stream, ret);
|
return parse_word_label_or_relative(stream, ret);
|
||||||
case TOKEN_JUMP_STACK:
|
case TOKEN_JUMP_STACK:
|
||||||
*ret = (presult_t){.instruction = INST_JUMP_STACK,
|
*ret = presult_instruction(INST_JUMP_STACK);
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
break;
|
break;
|
||||||
case TOKEN_JUMP_IF: {
|
case TOKEN_JUMP_IF: {
|
||||||
*ret = (presult_t){.instruction = INST_JUMP_IF(BYTE, 0)};
|
*ret = presult_instruction(INST_JUMP_IF(BYTE, 0));
|
||||||
return parse_jump_inst_operand(stream, ret);
|
return parse_jump_inst_operand(stream, ret);
|
||||||
}
|
}
|
||||||
case TOKEN_CALL:
|
case TOKEN_CALL:
|
||||||
*ret = (presult_t){.instruction = INST_CALL(0)};
|
*ret = presult_instruction(INST_CALL(0));
|
||||||
++stream->used;
|
++stream->used;
|
||||||
if (stream->used >= stream->available)
|
if (stream->used >= stream->available)
|
||||||
return PERR_EXPECTED_OPERAND;
|
return PERR_EXPECTED_OPERAND;
|
||||||
return parse_word_label_or_relative(stream, ret);
|
return parse_word_label_or_relative(stream, ret);
|
||||||
case TOKEN_CALL_STACK:
|
case TOKEN_CALL_STACK:
|
||||||
*ret = (presult_t){.instruction = INST_CALL_STACK,
|
*ret = presult_instruction(INST_CALL_STACK);
|
||||||
.type = PRES_COMPLETE_RESULT};
|
|
||||||
break;
|
break;
|
||||||
case TOKEN_RET:
|
case TOKEN_RET:
|
||||||
*ret = (presult_t){.instruction = INST_RET, .type = PRES_COMPLETE_RESULT};
|
*ret = presult_instruction(INST_RET);
|
||||||
break;
|
break;
|
||||||
case TOKEN_SYMBOL: {
|
case TOKEN_SYMBOL: {
|
||||||
size_t label_size = strcspn(token.str, ":");
|
size_t label_size = strcspn(token.str, ":");
|
||||||
if (label_size == strlen(token.str))
|
if (label_size == token.str_size)
|
||||||
return PERR_UNKNOWN_OPERATOR;
|
return PERR_UNKNOWN_OPERATOR;
|
||||||
*ret = (presult_t){.type = PRES_LABEL};
|
else if (label_size != token.str_size - 1)
|
||||||
ret->label = calloc(label_size + 1, 1);
|
return PERR_EXPECTED_LABEL;
|
||||||
memcpy(ret->label, token.str, label_size);
|
*ret = presult_label(token.str, label_size, 0);
|
||||||
ret->label[label_size] = '\0';
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_STAR:
|
case TOKEN_STAR:
|
||||||
@@ -510,8 +509,7 @@ perr_t process_presults(presult_t *results, size_t res_count,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
bool global_start_defined = false;
|
label_t start_label = {0};
|
||||||
char *start_label = NULL;
|
|
||||||
|
|
||||||
darr_t label_registry = {0};
|
darr_t label_registry = {0};
|
||||||
darr_init(&label_registry, sizeof(label_t));
|
darr_init(&label_registry, sizeof(label_t));
|
||||||
@@ -522,8 +520,8 @@ perr_t process_presults(presult_t *results, size_t res_count,
|
|||||||
switch (res.type)
|
switch (res.type)
|
||||||
{
|
{
|
||||||
case PRES_LABEL: {
|
case PRES_LABEL: {
|
||||||
label_t label = {.name = res.label,
|
label_t label = {.name = res.label.name,
|
||||||
.name_size = strlen(res.label),
|
.name_size = res.label.size,
|
||||||
.addr = inst_count};
|
.addr = inst_count};
|
||||||
darr_append_bytes(&label_registry, (byte *)&label, sizeof(label));
|
darr_append_bytes(&label_registry, (byte *)&label, sizeof(label));
|
||||||
break;
|
break;
|
||||||
@@ -540,8 +538,9 @@ perr_t process_presults(presult_t *results, size_t res_count,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRES_GLOBAL_LABEL: {
|
case PRES_GLOBAL_LABEL: {
|
||||||
global_start_defined = true;
|
start_label = (label_t){.name = res.label.name,
|
||||||
start_label = res.label;
|
.name_size = res.label.size,
|
||||||
|
.addr = (word)inst_count};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRES_LABEL_ADDRESS:
|
case PRES_LABEL_ADDRESS:
|
||||||
@@ -556,7 +555,7 @@ perr_t process_presults(presult_t *results, size_t res_count,
|
|||||||
darr_init(&instr_darr, sizeof(inst_t));
|
darr_init(&instr_darr, sizeof(inst_t));
|
||||||
|
|
||||||
prog_header_t header = {0};
|
prog_header_t header = {0};
|
||||||
if (global_start_defined)
|
if (start_label.name_size > 0)
|
||||||
{
|
{
|
||||||
label_t label =
|
label_t label =
|
||||||
search_labels((label_t *)label_registry.data,
|
search_labels((label_t *)label_registry.data,
|
||||||
|
|||||||
18
asm/parser.h
18
asm/parser.h
@@ -34,10 +34,16 @@ typedef enum
|
|||||||
|
|
||||||
const char *perr_as_cstr(perr_t);
|
const char *perr_as_cstr(perr_t);
|
||||||
|
|
||||||
|
// TODO: Refactor parser.c
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
inst_t instruction;
|
inst_t instruction;
|
||||||
char *label;
|
darr_t instructions;
|
||||||
|
struct PLabel
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
size_t size;
|
||||||
|
} label;
|
||||||
s_word address;
|
s_word address;
|
||||||
enum PResult_Type
|
enum PResult_Type
|
||||||
{
|
{
|
||||||
@@ -45,10 +51,20 @@ typedef struct
|
|||||||
PRES_LABEL_ADDRESS,
|
PRES_LABEL_ADDRESS,
|
||||||
PRES_GLOBAL_LABEL,
|
PRES_GLOBAL_LABEL,
|
||||||
PRES_RELATIVE_ADDRESS,
|
PRES_RELATIVE_ADDRESS,
|
||||||
|
PRES_PP_CONST,
|
||||||
PRES_COMPLETE_RESULT,
|
PRES_COMPLETE_RESULT,
|
||||||
} type;
|
} type;
|
||||||
} presult_t;
|
} presult_t;
|
||||||
|
|
||||||
|
// TODO: Implement these
|
||||||
|
presult_t presult_label(const char *, size_t, s_word);
|
||||||
|
presult_t presult_instruction(inst_t);
|
||||||
|
presult_t presult_instructions(size_t);
|
||||||
|
presult_t presult_addr(s_word);
|
||||||
|
presult_t pres_pp_const(const char *, s_word, size_t);
|
||||||
|
// TODO: Refactor parser.c to use this instead
|
||||||
|
void presult_free(presult_t);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ typedef struct
|
|||||||
size_t used, available;
|
size_t used, available;
|
||||||
} darr_t;
|
} darr_t;
|
||||||
|
|
||||||
#define DARR_DEFAULT_SIZE 8
|
#define DARR_DEFAULT_SIZE 8
|
||||||
#define DARR_REALLOC_MULT 1.5
|
#define DARR_REALLOC_MULT 1.5
|
||||||
|
#define DARR_AT(TYPE, DARR_DATA, IND) ((TYPE *)(DARR_DATA))[(IND)]
|
||||||
|
|
||||||
void darr_init(darr_t *, size_t);
|
void darr_init(darr_t *, size_t);
|
||||||
void darr_ensure_capacity(darr_t *, size_t);
|
void darr_ensure_capacity(darr_t *, size_t);
|
||||||
|
|||||||
Reference in New Issue
Block a user