157 lines
3.3 KiB
C
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__ */
|