From 4946ca67cf04845737f0f7f70b5ed27bcfe9a18b Mon Sep 17 00:00:00 2001 From: 0x221E <0x221E@0xinfinity.dev> Date: Sun, 12 Apr 2026 16:24:06 +0200 Subject: Initial commit --- src/parser.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/parser.c (limited to 'src/parser.c') diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..5e5485d --- /dev/null +++ b/src/parser.c @@ -0,0 +1,170 @@ +#include "parser.h" + +#include + +#include +#include +#include + +#include "irm.h" +#include "lex.h" + +int parser_within_bounds(struct parser_config *pc) +{ + return pc->pos < pc->size && pc->tokens[pc->pos].type != T_EOF; +} + +int parser_within_obounds(struct parser_config *pc, size_t o) +{ + return (pc->pos + o) < pc->size && pc->tokens[pc->pos + o].type != T_EOF; +} + +struct token parser_peek(struct parser_config *pc, size_t o) +{ + assert(pc != NULL); + if(!parser_within_obounds(pc, o)) return pc->tokens[pc->pos]; + return pc->tokens[pc->pos + o]; +} + +void parser_throw(struct parser_config *pc, const char *err) +{ + pc->state = PARSER_PANIC; + DEBUG("%s", err); + irm_panic(&pc->irm); +} + +int parser_expect(struct parser_config *pc, uint64_t type, const char *err) +{ + assert(pc != NULL); + if(parser_peek(pc, 0).type == type) + return 0; + parser_throw(pc, err); + return 1; +} + +int parser_expect_condthrow(struct parser_config *pc, uint64_t type, const char *err) +{ + assert(pc != NULL); + if(parser_peek(pc, 0).type == type) + return 0; + if(err[0] != '\0') + parser_throw(pc, err); + return 1; +} + +struct token parser_advance(struct parser_config *pc) +{ + assert(pc != NULL); + if(!parser_within_bounds(pc)) return pc->tokens[pc->pos]; + pc->pos++; + return pc->tokens[pc->pos]; +} + +void parser_literal(struct parser_config *pc) +{ + assert(pc != NULL); + + struct token t = parser_peek(pc, 0); + + if(t.type == T_NUMBER) { + uint64_t a = atoi(t.me.buf); + irm_push_64v(&pc->irm, NUMBER64, a); + DEBUG("Pushed into the irm: %lld.\n", a); + parser_advance(pc); + return; + } + + parser_throw(pc, "Invalid expression\n"); +} + +uint64_t parser_type_to_irm_inst(struct parser_config *pc, uint64_t type) +{ + switch(type) { + case T_TYPE_G64: + return VAR_DECL_QWORD; + case T_TYPE_G32: + return VAR_DECL_DWORD; + case T_TYPE_G16: + return VAR_DECL_WORD; + case T_TYPE_G8: + return VAR_DECL_BYTE; + default: + parser_throw(pc, "An invalid type detected... defaulting storage to QWORD."); + return VAR_DECL_QWORD; + } +} + +void parser_assign_stmt(struct parser_config *pc) +{ + struct string_view symbol = parser_peek(pc, 0).me; + irm_push(&pc->irm, VAR_ASSIGN); + irm_push_lookup_sym(&pc->irm, SYM_VAR, symbol); + parser_advance(pc); + parser_expect(pc, T_EQUAL_SIGN, "Assignment operation requires an equal sign after the symbol."); + parser_advance(pc); + parser_literal(pc); +} + +void parser_decl_stmt(struct parser_config *pc) +{ + struct token t = parser_peek(pc, 0); + if(!(t.type & T_TYPE)) { + parser_throw(pc, "Declaration statement must begin with a type!"); + parser_advance(pc); + return; + } + + uint64_t type = parser_peek(pc, 0).type; + irm_push(&pc->irm, parser_type_to_irm_inst(pc, type)); + parser_advance(pc); + + parser_expect(pc, T_ID, "An identifier must follow a type in a declaration statement."); + struct string_view symbol_name = parser_peek(pc, 0).me; + irm_push_sym(&pc->irm, SYM_VAR, symbol_name); + parser_advance(pc); + + parser_expect(pc, T_EQUAL_SIGN, "Equal sign must be used to assign a value to a locator"); + parser_advance(pc); + parser_literal(pc); +} + +void parser_stmt(struct parser_config *pc) +{ + struct token t = parser_peek(pc, 0); + if(t.type & T_TYPE) { + parser_decl_stmt(pc); + } else if(t.type == T_ID) { + parser_assign_stmt(pc); + } else { + parser_throw(pc, + "Invalid statement, can only be declaration " + "or assignment."); + } + + irm_push(&pc->irm, STMT_DONE); // PUSH STATEMENT DONE SIGNAL + irm_stmt_done(&pc->irm); // TRIGGER SIGNAL + + parser_expect(pc, T_SEMICOL, "Statement must end with a semicolon.\n"); + parser_advance(pc); +} + +void parse_compound_stmt(struct parser_config *pc) +{ + assert(pc != NULL); + + irm_stmt_enter_scope(&pc->irm); + + irm_stmt_leave_scope(&pc->irm); +} + +void parser_parse(struct parser_config *pc) +{ + assert(pc != NULL); + pc->state = PARSER_GRACEFUL; + + irm_init(&pc->irm); + + while(parser_within_bounds(pc)) { + parser_stmt(pc); + } +} -- cgit v1.2.3