diff options
author | Freya Murphy <freya@freyacat.org> | 2024-10-04 19:41:10 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-10-04 19:41:10 -0400 |
commit | 1c11a13ff33873bcc79d4597d31cd252d5c6c1ae (patch) | |
tree | a4321b97f5ad69d1a9b9d06dd629a4dc532758b0 /masm/parse.h | |
parent | update msim usage (diff) | |
download | mips-1c11a13ff33873bcc79d4597d31cd252d5c6c1ae.tar.gz mips-1c11a13ff33873bcc79d4597d31cd252d5c6c1ae.tar.bz2 mips-1c11a13ff33873bcc79d4597d31cd252d5c6c1ae.zip |
refactor masm to add codegen step
Diffstat (limited to 'masm/parse.h')
-rw-r--r-- | masm/parse.h | 140 |
1 files changed, 99 insertions, 41 deletions
diff --git a/masm/parse.h b/masm/parse.h index 9e0e928..61036cd 100644 --- a/masm/parse.h +++ b/masm/parse.h @@ -6,89 +6,147 @@ #include "lex.h" #include <mlimits.h> -#include <mips.h> #include <stdint.h> -/* mips directive types */ -enum mips_directive_type { - MIPS_DIRECTIVE_ALIGN, - MIPS_DIRECTIVE_SPACE, - MIPS_DIRECTIVE_WORD, - MIPS_DIRECTIVE_HALF, - MIPS_DIRECTIVE_BYTE, - MIPS_DIRECTIVE_SECTION, - MIPS_DIRECTIVE_EXTERN, - MIPS_DIRECTIVE_GLOBL, - MIPS_DIRECTIVE_ASCII, - MIPS_DIRECTIVE_ASCIIZ, +/// the type to a direcive +enum expr_directive_type { + EXPR_DIRECTIVE_ALIGN, + EXPR_DIRECTIVE_SPACE, + EXPR_DIRECTIVE_WORD, + EXPR_DIRECTIVE_HALF, + EXPR_DIRECTIVE_BYTE, + EXPR_DIRECTIVE_SECTION, + EXPR_DIRECTIVE_EXTERN, + EXPR_DIRECTIVE_GLOBL, + EXPR_DIRECTIVE_ASCII, + EXPR_DIRECTIVE_ASCIIZ, }; -/* mip32 directive */ -struct mips_directive { - enum mips_directive_type type; - uint32_t len; // used for words, halfs, bytes +/// holds a directive +struct expr_directive { + // the type of the directive + enum expr_directive_type type; + + // lengh of .word, .half, or .byte directive + uint32_t len; + + // directive data union { + // e.g. align 2 uint16_t align; + // e.g. space 4096 uint16_t space; + // e.g. .word 0x1 0x2 uint32_t words[MAX_ARG_LENGTH]; uint16_t halfs[MAX_ARG_LENGTH]; - uint8_t bytes[MAX_ARG_LENGTH]; - char name[MAX_ARG_LENGTH]; + uint8_t bytes[MAX_ARG_LENGTH]; + // e.g. .ascii "hello world!" + struct string string; + // e.g. .globl main + struct string label; + // e.g. .text + struct string section; }; }; -struct reference { - // ELF relocate type - unsigned char type; +/// holds a constant expression +struct expr_const { + // the name of the constant + struct string name; + + // the value of the constant + uint32_t num; +}; + +/// the type to a right +/// hand side argument to an +/// instruction +enum expr_ins_arg_type { + // e.g. $ra + EXPR_INS_ARG_REGISTER, + + // e.g. 0x80 + EXPR_INS_ARG_IMMEDIATE, - /// symbol name - char name[MAX_LEX_LENGTH]; + // e.g. main + EXPR_INS_ARG_LABEL, - /// integer addend - int64_t addend; + // e.g. 4($sp) + EXPR_INS_ARG_OFFSET, }; -struct const_expr { - char name[MAX_LEX_LENGTH]; - uint32_t value; +/// a right hand argument +/// to an instruction +struct expr_ins_arg { + enum expr_ins_arg_type type; + + union { + // register + struct string reg; + + // immediate + uint64_t immd; + + // label + struct string label; + + // offset + struct expr_ins_offset { + // immediate + uint64_t immd; + // register + struct string reg; + } offset; + }; }; -struct ins_expr { +/// holds a instruction +struct expr_ins { /// pesudo instructions can return /// more than one instruction - size_t ins_len; - struct mips_instruction ins[2]; + struct string name; - /// instructions can reference symbols. - /// instruction `n` will be paried with reference `n` - struct reference ref[2]; + // the arguments of the instruction + uint32_t args_len; + struct expr_ins_arg args[MAX_ARG_LENGTH]; }; enum expr_type { + // e.g. .align 2 EXPR_DIRECTIVE, + // e.g. SIZE = 8 EXPR_CONSTANT, + // e.g. li $t0, 17 EXPR_INS, + // e.g. _start: EXPR_LABEL, }; struct expr { enum expr_type type; + + uint32_t line_no; + uint32_t byte_start; + uint32_t byte_end; + union { // directive - struct mips_directive directive; + struct expr_directive directive; // constant - struct const_expr constant; + struct expr_const constant; // instruction - struct ins_expr ins; + struct expr_ins instruction; // label - char label[MAX_LEX_LENGTH]; + struct string label; }; }; +void expr_free(struct expr *expr); + struct parser { // the lexer // *weak* ponter, we do not own this - struct lexer *lexer; + struct lexer lexer; // the last token peeked struct token peek; }; @@ -97,7 +155,7 @@ struct parser { int parser_next(struct parser *parser, struct expr *expr); /* initalize the base parser */ -int parser_init(struct lexer *lexer, struct parser *parser); +int parser_init(const char *file, struct parser *parser); /* free the base parser */ void parser_free(struct parser *parser); |