mips/masm/parse.h

157 lines
3.3 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_SEGMENT,
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 position;
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]);
struct section {
uint32_t count;
uint32_t len;
uint32_t start;
uint32_t alignment;
union mips_instruction *ins;
char name[MAX_LEX_LENGTH];
};
struct section_table {
uint32_t count;
uint32_t len;
struct section *sections;
struct section *current;
char name[MAX_LEX_LENGTH];
uint32_t total_ins;
};
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_push(struct section_table *sec_tbl, struct section *section,
union mips_instruction ins);
int sectbl_get(struct section_table *sec_tbl, struct section **sec,
const char name[MAX_LEX_LENGTH]);
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__ */