2024-09-09 16:41:49 +00:00
|
|
|
/* 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];
|
2024-09-10 00:48:08 +00:00
|
|
|
uint32_t index;
|
|
|
|
struct section *sec;
|
2024-09-09 16:41:49 +00:00
|
|
|
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]);
|
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-09-09 16:41:49 +00:00
|
|
|
struct section {
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t len;
|
|
|
|
uint32_t alignment;
|
2024-09-10 00:48:08 +00:00
|
|
|
uint32_t index; // what index is my section
|
2024-09-09 16:41:49 +00:00
|
|
|
char name[MAX_LEX_LENGTH];
|
2024-09-10 00:48:08 +00:00
|
|
|
bool read;
|
|
|
|
bool write;
|
|
|
|
bool execute;
|
|
|
|
struct section_entry *entries;
|
2024-09-09 16:41:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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]);
|
2024-09-10 00:48:08 +00:00
|
|
|
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);
|
2024-09-09 16:41:49 +00:00
|
|
|
|
|
|
|
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__ */
|