summaryrefslogtreecommitdiff
path: root/masm/parse.h
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-10-04 19:41:10 -0400
committerFreya Murphy <freya@freyacat.org>2024-10-04 19:41:10 -0400
commit1c11a13ff33873bcc79d4597d31cd252d5c6c1ae (patch)
treea4321b97f5ad69d1a9b9d06dd629a4dc532758b0 /masm/parse.h
parentupdate msim usage (diff)
downloadmips-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.h140
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);