summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-06-25 15:31:25 +0300
committerOxore <oxore@protonmail.com>2023-06-25 15:31:25 +0300
commit66bfe8a24d9b1ca83d45396a9f9c962379d1895e (patch)
treec70312c5f878778349fff4a6e3a0765f8e2218ce
parent5ccc7b6c240bd927305bbacf4fb0a102de8f1147 (diff)
Fix parsing size specifier
-rw-r--r--main.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/main.c b/main.c
index dee5171..77df6cb 100644
--- a/main.c
+++ b/main.c
@@ -1344,21 +1344,22 @@ static size_t find_line_length(const char *const str)
}
static int pars_yield_error_str(
- struct pars *const self, const struct line_pos_info l, char *const str)
+ struct pars *const self,
+ const struct line_pos_info l,
+ const char *const found,
+ const size_t found_length)
{
fprintf(
stderr,
- "<stdin>:%lu:%lu: parsing error: expected %s, found '%s'\n",
+ "<stdin>:%lu:%lu: parsing error: expected %s, found '%.*s'\n",
l.line_num + 1,
l.column_num + 1,
- "<TODO>",
- str);
- free(str);
- const size_t line_length = find_line_length(self->lex->input + l.line_offset);
- char *const line = calloc(1, line_length + 1);
- memcpy(line, self->lex->input + l.line_offset, line_length);
- fprintf(stderr, "%5lu | %s\n", l.line_num + 1, line);
- free(line);
+ "<_unspecified_token_list>",
+ (int)found_length,
+ found);
+ const char *const line = self->lex->input + l.line_offset;
+ const size_t line_length = find_line_length(line);
+ fprintf( stderr, "%5lu | %.*s\n", l.line_num, (int)line_length, line);
fputs(" | ", stderr);
for (size_t i = 0; i < l.column_num; i++) {
if (self->lex->input[l.line_offset + i] == '\t') {
@@ -1376,9 +1377,8 @@ static int pars_yield_error(struct pars *const self, const size_t token_id)
const struct token token = self->lex->tokbuf[token_id];
const struct line_pos_info l =
lex_get_line_pos_info(self->lex, token.offset);
- char *const found = calloc(1, token.length + 10);
- snprintf(found, token.length + 1, "%s", self->lex->input + token.offset);
- return pars_yield_error_str(self, l, found);
+ const char *const found = self->lex->input + token.offset;
+ return pars_yield_error_str(self, l, found, token.length);
}
static int pars_yield_error_nesting(
@@ -1451,19 +1451,27 @@ static int pars_parse_arg(
(sizeof *self->lex->tokbuf);
const size_t first_token_id = self->cur_tok_id;
int nesting = 0;
+ int commas = 0;
enum arg_type arg_type = ARG_EXPR;
while (self->cur_tok_id < tokens_count) {
const size_t token_id = self->cur_tok_id; // Peek
const struct token token = self->lex->tokbuf[token_id];
- if (token.type == TT_LPAREN) {
+ if (nesting == 1 && token.type == TT_COMMA) {
+ if (commas >= 2) {
+ return pars_yield_error(self, self->cur_tok_id);
+ } else {
+ commas++;
+ }
+ } else if (token.type == TT_LPAREN) {
nesting++;
} else if (token.type == TT_RPAREN) {
nesting--;
} else if (is_expression_token(token.type)) {
// TODO parse expression
- } else if (nesting > 0 && token.type == TT_COMMA) {
- // Comma inside parentheses is allowed
} else {
+ if (nesting > 0) {
+ return pars_yield_error(self, self->cur_tok_id);
+ }
break;
}
self->cur_tok_id++; // Commit
@@ -1644,30 +1652,19 @@ static int pars_parse_instruction(
if (pars_is_eof_reached(self)) {
return pars_yield_error_eof(self);
}
- const size_t token2_id = self->cur_tok_id; // Peek
- const struct token token2 = self->lex->tokbuf[token2_id];
- if (token2.type == TT_DOT) {
+ const size_t size_spec_id = self->cur_tok_id; // Peek
+ const struct token size_spec = self->lex->tokbuf[size_spec_id];
+ if (size_spec.type == TT_DOT_ID) {
self->cur_tok_id++; // Commit
- if (pars_is_eof_reached(self)) {
- return pars_yield_error_eof(self);
- }
- const size_t size_spec_id = self->cur_tok_id++;
- const struct token size_spec = self->lex->tokbuf[size_spec_id];
- if (size_spec.type != TT_ID) {
- return pars_yield_error(self, size_spec_id);
- }
// Size specifier
- if (size_spec.length != 1) {
+ if (size_spec.length != 2) {
return pars_yield_error(self, size_spec_id);
}
const size_t opsize =
- get_opsize_from_specifier(self->lex->input[size_spec.offset]);
+ get_opsize_from_specifier(self->lex->input[size_spec.offset + 1]);
if (opsize == OPSIZE_NONE) {
return pars_yield_error(self, size_spec_id);
}
- if (pars_is_eof_reached(self)) {
- return pars_yield_error_eof(self);
- }
return pars_parse_instruction_args(self, label_id, mnemonic_id, opsize);
}
return pars_parse_instruction_args(