mips/masm/parse.h

163 lines
2.8 KiB
C

/* Copyright (c) 2024 Freya Murphy */
#ifndef __PARSE_H__
#define __PARSE_H__
#include "lex.h"
#include <mlimits.h>
#include <stdint.h>
/// 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__ */