summaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c319
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;
}