diff options
author | Freya Murphy <freya@freyacat.org> | 2024-09-09 12:41:49 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-09-09 12:41:49 -0400 |
commit | 2ed275821676a0d5baea6c7fd843d71c72c2342c (patch) | |
tree | 480297f28e5c42d02a47b3b94027a7abe507d010 /masm/parse.h | |
download | mips-2ed275821676a0d5baea6c7fd843d71c72c2342c.tar.gz mips-2ed275821676a0d5baea6c7fd843d71c72c2342c.tar.bz2 mips-2ed275821676a0d5baea6c7fd843d71c72c2342c.zip |
initial mips32 (r2000ish mips32r6) assembler
Diffstat (limited to 'masm/parse.h')
-rw-r--r-- | masm/parse.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/masm/parse.h b/masm/parse.h new file mode 100644 index 0000000..2aea0be --- /dev/null +++ b/masm/parse.h @@ -0,0 +1,156 @@ +/* Copyright (c) 2024 Freya Murphy */ + +#ifndef __PARSE_H__ +#define __PARSE_H__ + +#include "lex.h" + +#include <mlimits.h> +#include <mips.h> +#include <stdint.h> + +struct const_expr { + char name[MAX_LEX_LENGTH]; + uint32_t value; +}; + +enum expr_type { + EXPR_INS, + EXPR_DIRECTIVE, + EXPR_CONSTANT, + EXPR_SEGMENT, + 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 symbol_flag { + SYM_LOCAL, + SYM_GLOBAL, + SYM_EXTERNAL, +}; + +struct symbol { + char name[MAX_LEX_LENGTH]; + uint32_t position; + enum symbol_flag flag; + +}; + +struct symbol_table { + uint32_t count; + uint32_t len; + struct symbol *symbols; +}; + +int symtbl_init(struct symbol_table *sym_tbl); +void symtbl_free(struct symbol_table *sym_tbl); + +int symtbl_push(struct symbol_table *sym_tbl, struct symbol sym); +int symtbl_find(struct symbol_table *sym_tbl, struct symbol **sym, + const char name[MAX_LEX_LENGTH]); + +struct section { + uint32_t count; + uint32_t len; + uint32_t start; + uint32_t alignment; + union mips_instruction *ins; + char name[MAX_LEX_LENGTH]; +}; + +struct section_table { + uint32_t count; + uint32_t len; + struct section *sections; + struct section *current; + char name[MAX_LEX_LENGTH]; + uint32_t total_ins; +}; + +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_push(struct section_table *sec_tbl, struct section *section, + union mips_instruction ins); +int sectbl_get(struct section_table *sec_tbl, struct section **sec, + const char name[MAX_LEX_LENGTH]); + +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; + + // symbols + struct symbol_table sym_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__ */ |