summaryrefslogtreecommitdiff
path: root/masm/parse.h
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-09 12:41:49 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-09 12:41:49 -0400
commit2ed275821676a0d5baea6c7fd843d71c72c2342c (patch)
tree480297f28e5c42d02a47b3b94027a7abe507d010 /masm/parse.h
downloadmips-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.h156
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__ */