/* Copyright (c) 2024 Freya Murphy */ #ifndef __PARSE_H__ #define __PARSE_H__ #include "lex.h" #include #include /// 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, }; /// 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]; // e.g. .ascii "hello world!" struct string string; // e.g. .globl main struct string label; // e.g. .text struct string section; }; }; /// 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, // e.g. main EXPR_INS_ARG_LABEL, // e.g. 4($sp) EXPR_INS_ARG_OFFSET, }; /// 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; }; }; /// holds a instruction struct expr_ins { /// pesudo instructions can return /// more than one instruction struct string name; // 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 expr_directive directive; // constant struct expr_const constant; // instruction struct expr_ins instruction; // label struct string label; }; }; void expr_free(struct expr *expr); struct parser { // the lexer // *weak* ponter, we do not own this struct lexer lexer; // the last token peeked struct token peek; }; /* get the next expression in the parser */ int parser_next(struct parser *parser, struct expr *expr); /* initalize the base parser */ int parser_init(const char *file, struct parser *parser); /* free the base parser */ void parser_free(struct parser *parser); #endif /* __PARSE_H__ */