163 lines
2.8 KiB
C
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__ */
|