mips/masm/parse.h

181 lines
3.7 KiB
C

/* Copyright (c) 2024 Freya Murphy */
#ifndef __PARSE_H__
#define __PARSE_H__
#include "lex.h"
#include <mlimits.h>
#include <mips.h>
#include <stdint.h>
struct const_expr {
char name[MAX_LEX_LENGTH];
uint32_t value;
};
enum expr_type {
EXPR_INS,
EXPR_DIRECTIVE,
EXPR_CONSTANT,
EXPR_LABEL,
};
struct expr {
enum expr_type type;
union {
// instruction
union mips_instruction ins;
// directive
union mips_directive directive;
// constant
struct const_expr constant;
// segment or label
char text[MAX_LEX_LENGTH];
};
};
enum symbol_flag {
SYM_LOCAL,
SYM_GLOBAL,
SYM_EXTERNAL,
};
struct symbol {
char name[MAX_LEX_LENGTH];
uint32_t index;
struct section *sec;
enum symbol_flag flag;
};
struct symbol_table {
uint32_t count;
uint32_t len;
struct symbol *symbols;
};
int symtbl_init(struct symbol_table *sym_tbl);
void symtbl_free(struct symbol_table *sym_tbl);
int symtbl_push(struct symbol_table *sym_tbl, struct symbol sym);
int symtbl_find(struct symbol_table *sym_tbl, struct symbol **sym,
const char name[MAX_LEX_LENGTH]);
enum section_entry_type {
ENT_INS,
ENT_WORD,
ENT_HALF,
ENT_BYTE,
ENT_NO_DATA,
};
struct section_entry {
enum section_entry_type type;
size_t size;
union {
char data; // to get memory address
union mips_instruction ins;
int32_t word;
int16_t half;
int8_t byte;
};
};
struct section {
uint32_t count;
uint32_t len;
uint32_t alignment;
uint32_t index; // what index is my section
char name[MAX_LEX_LENGTH];
bool read;
bool write;
bool execute;
struct section_entry *entries;
};
struct section_table {
uint32_t count;
uint32_t len;
struct section *sections;
struct section *current;
char name[MAX_LEX_LENGTH];
};
int sectbl_init(struct section_table *sec_tbl);
void sectbl_free(struct section_table *sec_tbl);
int sectbl_alloc(struct section_table *sec_tbl, struct section **sec,
const char name[MAX_LEX_LENGTH]);
int sectbl_get(struct section_table *sec_tbl, struct section **sec,
const char name[MAX_LEX_LENGTH]);
int sec_push(struct section *section, struct section_entry entry);
size_t sec_size(struct section *section);
size_t sec_index(struct section *section, uint32_t index);
enum reference_type {
REF_OFFESET,
REF_TARGET,
};
struct reference {
enum reference_type type;
struct section *section;
uint32_t index;
char name[MAX_LEX_LENGTH];
};
struct reference_table {
uint32_t count;
uint32_t len;
struct reference *references;
};
int reftbl_init(struct reference_table *ref_tbl);
void reftbl_free(struct reference_table *ref_tbl);
int reftbl_push(struct reference_table *ref_tbl, struct reference reference);
struct parser {
struct lexer *lexer;
struct token peek;
// sections
struct section_table sec_tbl;
// symbols
struct symbol_table sym_tbl;
// references
struct reference_table ref_tbl;
int (*parse_instruction)(struct parser *, union mips_instruction *,
struct token);
int (*parse_directive)(struct parser *, union mips_directive *);
int (*is_instruction)(const char *ident);
};
/* get the next token in the parser */
int next_token(struct parser *parser, struct token *tok);
/* peek the next token in the parser */
int peek_token(struct parser *parser, struct token *tok);
/* assert the next token is a specific type */
int assert_token(struct parser *parser, enum token_type type,
struct token *tok);
/* assert the next token is EOF or NL */
int assert_eol(struct parser *parser);
/* get the next expression in the parser */
int parser_next(struct parser *parser, struct expr *expr);
/* initalize the base parser */
int parser_init(struct lexer *lexer, struct parser *parser);
/* free the base parser */
void parser_free(struct parser *parser);
#endif /* __PARSE_H__ */