105 lines
1.9 KiB
C
105 lines
1.9 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>
|
|
|
|
/* mips directive types */
|
|
enum mips_directive_type {
|
|
MIPS_DIRECTIVE_ALIGN,
|
|
MIPS_DIRECTIVE_SPACE,
|
|
MIPS_DIRECTIVE_WORD,
|
|
MIPS_DIRECTIVE_HALF,
|
|
MIPS_DIRECTIVE_BYTE,
|
|
MIPS_DIRECTIVE_SECTION,
|
|
MIPS_DIRECTIVE_EXTERN,
|
|
MIPS_DIRECTIVE_GLOBL,
|
|
MIPS_DIRECTIVE_ASCII,
|
|
MIPS_DIRECTIVE_ASCIIZ,
|
|
};
|
|
|
|
/* mip32 directive */
|
|
struct mips_directive {
|
|
enum mips_directive_type type;
|
|
uint32_t len; // used for words, halfs, bytes
|
|
union {
|
|
uint16_t align;
|
|
uint16_t space;
|
|
uint32_t words[MAX_ARG_LENGTH];
|
|
uint16_t halfs[MAX_ARG_LENGTH];
|
|
uint8_t bytes[MAX_ARG_LENGTH];
|
|
char name[MAX_ARG_LENGTH];
|
|
};
|
|
};
|
|
|
|
struct reference {
|
|
// ELF relocate type
|
|
unsigned char type;
|
|
|
|
/// symbol name
|
|
char name[MAX_LEX_LENGTH];
|
|
|
|
/// integer addend
|
|
int64_t addend;
|
|
};
|
|
|
|
struct const_expr {
|
|
char name[MAX_LEX_LENGTH];
|
|
uint32_t value;
|
|
};
|
|
|
|
struct ins_expr {
|
|
/// pesudo instructions can return
|
|
/// more than one instruction
|
|
size_t ins_len;
|
|
struct mips_instruction ins[2];
|
|
|
|
/// instructions can reference symbols.
|
|
/// instruction `n` will be paried with reference `n`
|
|
struct reference ref[2];
|
|
};
|
|
|
|
enum expr_type {
|
|
EXPR_DIRECTIVE,
|
|
EXPR_CONSTANT,
|
|
EXPR_INS,
|
|
EXPR_LABEL,
|
|
};
|
|
|
|
struct expr {
|
|
enum expr_type type;
|
|
union {
|
|
// directive
|
|
struct mips_directive directive;
|
|
// constant
|
|
struct const_expr constant;
|
|
// instruction
|
|
struct ins_expr ins;
|
|
// label
|
|
char label[MAX_LEX_LENGTH];
|
|
};
|
|
};
|
|
|
|
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(struct lexer *lexer, struct parser *parser);
|
|
|
|
/* free the base parser */
|
|
void parser_free(struct parser *parser);
|
|
|
|
#endif /* __PARSE_H__ */
|