/* Copyright (c) 2024 Freya Murphy */ #ifndef __PARSE_H__ #define __PARSE_H__ #include "lex.h" #include #include #include struct const_expr { char name[MAX_LEX_LENGTH]; uint32_t value; }; enum expr_type { EXPR_INS, EXPR_DIRECTIVE, EXPR_CONSTANT, EXPR_LABEL, }; struct expr { enum expr_type type; union { // instruction union mips_instruction ins; // directive union mips_directive directive; // constant struct const_expr constant; // segment or label char text[MAX_LEX_LENGTH]; }; }; enum section_entry_type { ENT_INS, ENT_WORD, ENT_HALF, ENT_BYTE, ENT_NO_DATA, }; struct section_entry { enum section_entry_type type; size_t size; union { char data; // to get memory address union mips_instruction ins; int32_t word; int16_t half; int8_t byte; }; }; struct section { uint32_t count; uint32_t len; uint32_t alignment; uint32_t index; // what index is my section char name[MAX_LEX_LENGTH]; bool read; bool write; bool execute; struct section_entry *entries; }; struct section_table { uint32_t count; uint32_t len; struct section *sections; struct section *current; char name[MAX_LEX_LENGTH]; }; int sectbl_init(struct section_table *sec_tbl); void sectbl_free(struct section_table *sec_tbl); int sectbl_alloc(struct section_table *sec_tbl, struct section **sec, const char name[MAX_LEX_LENGTH]); int sectbl_get(struct section_table *sec_tbl, struct section **sec, const char name[MAX_LEX_LENGTH]); int sec_push(struct section *section, struct section_entry entry); size_t sec_size(struct section *section); size_t sec_index(struct section *section, uint32_t index); enum reference_type { REF_OFFESET, REF_TARGET, }; struct reference { enum reference_type type; struct section *section; uint32_t index; char name[MAX_LEX_LENGTH]; }; struct reference_table { uint32_t count; uint32_t len; struct reference *references; }; int reftbl_init(struct reference_table *ref_tbl); void reftbl_free(struct reference_table *ref_tbl); int reftbl_push(struct reference_table *ref_tbl, struct reference reference); struct parser { struct lexer *lexer; struct token peek; // sections struct section_table sec_tbl; // references struct reference_table ref_tbl; int (*parse_instruction)(struct parser *, union mips_instruction *, struct token); int (*parse_directive)(struct parser *, union mips_directive *); int (*is_instruction)(const char *ident); }; /* get the next token in the parser */ int next_token(struct parser *parser, struct token *tok); /* peek the next token in the parser */ int peek_token(struct parser *parser, struct token *tok); /* assert the next token is a specific type */ int assert_token(struct parser *parser, enum token_type type, struct token *tok); /* assert the next token is EOF or NL */ int assert_eol(struct parser *parser); /* get the next expression in the parser */ int parser_next(struct parser *parser, struct expr *expr); /* initalize the base parser */ int parser_init(struct lexer *lexer, struct parser *parser); /* free the base parser */ void parser_free(struct parser *parser); #endif /* __PARSE_H__ */