diff options
| author | Johnny Richard <johnny@johnnyrichard.com> | 2025-04-14 23:22:57 +0200 |
|---|---|---|
| committer | Johnny Richard <johnny@johnnyrichard.com> | 2025-04-14 23:22:57 +0200 |
| commit | b3bd068f614a46580ee3e5688dd9cfd40694d75b (patch) | |
| tree | 45183f99a8373527caa03ff473c4e40fe07cd459 /src/parser.c | |
| parent | 63104d34e1c1772131f6366f825e67f38d027dba (diff) | |
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 319 |
1 files changed, 165 insertions, 154 deletions
diff --git a/src/parser.c b/src/parser.c index 0eef4b7..673ad1d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -20,170 +20,181 @@ #include <string.h> #include "array.h" -#include "parser.h" #include "lexer.h" +#include "parser.h" #include "string_view.h" void -parser_init(parser_t *parser, char *file_name) +parser_init(parser_t* parser, char* file_name) { - assert(parser && file_name); + assert(parser && file_name); lexer_init(&parser->lexer, file_name); } void -parser_next_expected_token(parser_t *parser, token_t *token, token_kind_t kind) +parser_next_expected_token(parser_t* parser, token_t* token, token_kind_t kind) { - lexer_next_token(&parser->lexer, token); - if (token->kind != kind) { - fprintf( - stderr, - "%s:%zu:%zu: parser error: expected token <%s> but got <%s>.\n", - parser->lexer.file_name, - token->loc.lineno + 1, - token->loc.offset - token->loc.lineoffset + 1, - token_to_cstr(kind), - token_to_cstr(token->kind)); - exit(EXIT_FAILURE); - } + lexer_next_token(&parser->lexer, token); + if (token->kind != kind) { + fprintf(stderr, + "%s:%zu:%zu: parser error: expected token <%s> but got <%s>.\n", + parser->lexer.file_name, + token->loc.lineno + 1, + token->loc.offset - token->loc.lineoffset + 1, + token_to_cstr(kind), + token_to_cstr(token->kind)); + exit(EXIT_FAILURE); + } } -inst_t * -parser_parse(parser_t *parser) { - inst_t *insts = array(inst_t); - - token_t token = { 0 }; - int label_count = 0; - - lexer_next_token(&parser->lexer, &token); - while (token.kind != TOKEN_EOF) { - switch (token.kind) { - case TOKEN_KW_PUSH: { - parser_next_expected_token(parser, &token, TOKEN_NUMBER); - - char value[token.value.size + 1]; - value[token.value.size] = '\0'; - memcpy(value, token.value.chars, token.value.size); - - array_append(insts, ((inst_t) { .type = INST_PUSH, .operand = atoi(value) })); - - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_ADD: { - array_append(insts, ((inst_t) { .type = INST_ADD })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_DUP: { - array_append(insts, ((inst_t) { .type = INST_DUP })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_SWAP: { - array_append(insts, ((inst_t) { .type = INST_SWAP })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_SUB: { - array_append(insts, ((inst_t) { .type = INST_SUB })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_MUL: { - array_append(insts, ((inst_t) { .type = INST_MUL })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_STORE: { - array_append(insts, ((inst_t) { .type = INST_STORE })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_LOAD: { - array_append(insts, ((inst_t) { .type = INST_LOAD })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_RET: { - array_append(insts, ((inst_t) { .type = INST_RET })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_IDENT: { - array_append(insts, ((inst_t) { .type = INST_LABEL, .operand = label_count++ })); - parser_next_expected_token(parser, &token, TOKEN_COLON); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_JMP: { - parser_next_expected_token(parser, &token, TOKEN_NUMBER); - - char value[token.value.size + 1]; - value[token.value.size] = '\0'; - memcpy(value, token.value.chars, token.value.size); - - array_append(insts, ((inst_t) { .type = INST_JMP, .operand = atoi(value) })); - - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_JMPZ: { - parser_next_expected_token(parser, &token, TOKEN_NUMBER); - - char value[token.value.size + 1]; - value[token.value.size] = '\0'; - memcpy(value, token.value.chars, token.value.size); - - array_append(insts, ((inst_t) { .type = INST_JMPZ, .operand = atoi(value) })); - - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_CALL: { - parser_next_expected_token(parser, &token, TOKEN_NUMBER); - - char value[token.value.size + 1]; - value[token.value.size] = '\0'; - memcpy(value, token.value.chars, token.value.size); - - array_append(insts, ((inst_t) { .type = INST_CALL, .operand = atoi(value) })); - - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_READI: { - array_append(insts, ((inst_t) { .type = INST_READI })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_READC: { - array_append(insts, ((inst_t) { .type = INST_READC })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_PRINTI: { - array_append(insts, ((inst_t) { .type = INST_PRINTI })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_PRINTC: { - array_append(insts, ((inst_t) { .type = INST_PRINTC })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_KW_END: { - array_append(insts, ((inst_t) { .type = INST_END })); - parser_next_expected_token(parser, &token, TOKEN_EOS); - break; - } - case TOKEN_EOS: { - break; - } - default: break; - } - lexer_next_token(&parser->lexer, &token); - } - - return insts; +inst_t* +parser_parse(parser_t* parser) +{ + inst_t* insts = array(inst_t); + + token_t token = { 0 }; + int label_count = 0; + + lexer_next_token(&parser->lexer, &token); + while (token.kind != TOKEN_EOF) { + switch (token.kind) { + case TOKEN_KW_PUSH: { + parser_next_expected_token(parser, &token, TOKEN_NUMBER); + + char value[token.value.size + 1]; + value[token.value.size] = '\0'; + memcpy(value, token.value.chars, token.value.size); + + array_append( + insts, + ((inst_t){ .type = INST_PUSH, .operand = atoi(value) })); + + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_ADD: { + array_append(insts, ((inst_t){ .type = INST_ADD })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_DUP: { + array_append(insts, ((inst_t){ .type = INST_DUP })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_SWAP: { + array_append(insts, ((inst_t){ .type = INST_SWAP })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_SUB: { + array_append(insts, ((inst_t){ .type = INST_SUB })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_MUL: { + array_append(insts, ((inst_t){ .type = INST_MUL })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_STORE: { + array_append(insts, ((inst_t){ .type = INST_STORE })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_LOAD: { + array_append(insts, ((inst_t){ .type = INST_LOAD })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_RET: { + array_append(insts, ((inst_t){ .type = INST_RET })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_IDENT: { + array_append( + insts, + ((inst_t){ .type = INST_LABEL, .operand = label_count++ })); + parser_next_expected_token(parser, &token, TOKEN_COLON); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_JMP: { + parser_next_expected_token(parser, &token, TOKEN_NUMBER); + + char value[token.value.size + 1]; + value[token.value.size] = '\0'; + memcpy(value, token.value.chars, token.value.size); + + array_append( + insts, + ((inst_t){ .type = INST_JMP, .operand = atoi(value) })); + + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_JMPZ: { + parser_next_expected_token(parser, &token, TOKEN_NUMBER); + + char value[token.value.size + 1]; + value[token.value.size] = '\0'; + memcpy(value, token.value.chars, token.value.size); + + array_append( + insts, + ((inst_t){ .type = INST_JMPZ, .operand = atoi(value) })); + + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_CALL: { + parser_next_expected_token(parser, &token, TOKEN_NUMBER); + + char value[token.value.size + 1]; + value[token.value.size] = '\0'; + memcpy(value, token.value.chars, token.value.size); + + array_append( + insts, + ((inst_t){ .type = INST_CALL, .operand = atoi(value) })); + + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_READI: { + array_append(insts, ((inst_t){ .type = INST_READI })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_READC: { + array_append(insts, ((inst_t){ .type = INST_READC })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_PRINTI: { + array_append(insts, ((inst_t){ .type = INST_PRINTI })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_PRINTC: { + array_append(insts, ((inst_t){ .type = INST_PRINTC })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_KW_END: { + array_append(insts, ((inst_t){ .type = INST_END })); + parser_next_expected_token(parser, &token, TOKEN_EOS); + break; + } + case TOKEN_EOS: { + break; + } + default: + break; + } + lexer_next_token(&parser->lexer, &token); + } + + return insts; } |
