asm: implement an asm parser and emitter

This commit is contained in:
2024-12-13 12:26:01 +00:00
parent 0a8d913fdd
commit 5fe1a21978
19 changed files with 1106 additions and 49 deletions

View File

@@ -21,14 +21,13 @@
}
static struct lex_token_def keywords[] = {
LEX_TOKEN_DEF(IVY_ASM_KW_USE, "@use"),
LEX_TOKEN_DEF(IVY_ASM_KW_IMPORT, "@import"),
LEX_TOKEN_DEF(IVY_ASM_KW_IDENT, "@ident"),
LEX_TOKEN_DEF(IVY_ASM_KW_SELECTOR, "@selector"),
LEX_TOKEN_DEF(IVY_ASM_KW_ATOM, "@atom"),
LEX_TOKEN_DEF(IVY_ASM_KW_LAMBDA, "@lambda"),
LEX_TOKEN_DEF(IVY_ASM_KW_CONSTPOOL, "@constpool"),
LEX_TOKEN_DEF(IVY_ASM_KW_CLASS, "@class"),
LEX_TOKEN_DEF(IVY_ASM_KW_MSGH, "@msgh"),
LEX_TOKEN_DEF(IVY_ASM_KW_BLOCK, "@block"),
LEX_TOKEN_DEF(IVY_ASM_KW_END, "@end"),
};
static const size_t nr_keywords = sizeof keywords / sizeof keywords[0];
@@ -249,10 +248,14 @@ enum ivy_status ivy_asm_lexer_create(struct ivy_asm_lexer **lexp)
void ivy_asm_lexer_destroy(struct ivy_asm_lexer *lex)
{
while (lex->lex_queue) {
struct ivy_asm_token *next = lex->lex_queue->t_next;
ivy_asm_token_destroy(lex->lex_queue);
lex->lex_queue = next;
b_queue_iterator it = {0};
b_queue_iterator_begin(&lex->lex_queue, &it);
while (b_queue_iterator_is_valid(&it)) {
struct ivy_asm_token *tok
= b_unbox(struct ivy_asm_token, it.entry, t_entry);
b_queue_iterator_erase(&it);
ivy_asm_token_destroy(tok);
}
if (lex->lex_linebuf) {
@@ -399,13 +402,7 @@ static struct ivy_asm_token *create_token(enum ivy_asm_token_type type)
static enum ivy_status push_token(
struct ivy_asm_lexer *lex, struct ivy_asm_token *tok)
{
struct ivy_asm_token **slot = &lex->lex_queue;
while (*slot) {
slot = &(*slot)->t_next;
}
*slot = tok;
b_queue_push_back(&lex->lex_queue, &tok->t_entry);
lex->lex_prev_token = tok->t_type;
return IVY_OK;
}
@@ -953,7 +950,7 @@ struct ivy_asm_token *ivy_asm_lexer_peek(struct ivy_asm_lexer *lex)
{
enum ivy_status status = IVY_OK;
while (!lex->lex_queue) {
while (b_queue_empty(&lex->lex_queue)) {
status = pump_tokens(lex);
if (status != IVY_OK) {
@@ -963,7 +960,8 @@ struct ivy_asm_token *ivy_asm_lexer_peek(struct ivy_asm_lexer *lex)
}
lex->lex_status = status;
struct ivy_asm_token *tok = lex->lex_queue;
b_queue_entry *entry = b_queue_first(&lex->lex_queue);
struct ivy_asm_token *tok = b_unbox(struct ivy_asm_token, entry, t_entry);
return tok;
}
@@ -971,7 +969,7 @@ struct ivy_asm_token *ivy_asm_lexer_read(struct ivy_asm_lexer *lex)
{
enum ivy_status status = IVY_OK;
while (!lex->lex_queue) {
while (b_queue_empty(&lex->lex_queue)) {
status = pump_tokens(lex);
if (status != IVY_OK) {
@@ -980,11 +978,8 @@ struct ivy_asm_token *ivy_asm_lexer_read(struct ivy_asm_lexer *lex)
}
}
struct ivy_asm_token *tok = lex->lex_queue;
if (tok) {
lex->lex_queue = tok->t_next;
}
b_queue_entry *entry = b_queue_pop_front(&lex->lex_queue);
struct ivy_asm_token *tok = b_unbox(struct ivy_asm_token, entry, t_entry);
return tok;
}
@@ -1028,14 +1023,13 @@ const char *ivy_asm_keyword_to_string(enum ivy_asm_keyword keyword)
{
switch (keyword) {
ENUM_STR(IVY_ASM_KW_NONE);
ENUM_STR(IVY_ASM_KW_USE);
ENUM_STR(IVY_ASM_KW_IDENT);
ENUM_STR(IVY_ASM_KW_SELECTOR);
ENUM_STR(IVY_ASM_KW_ATOM);
ENUM_STR(IVY_ASM_KW_LAMBDA);
ENUM_STR(IVY_ASM_KW_CONSTPOOL);
ENUM_STR(IVY_ASM_KW_CLASS);
ENUM_STR(IVY_ASM_KW_MSGH);
ENUM_STR(IVY_ASM_KW_BLOCK);
ENUM_STR(IVY_ASM_KW_IMPORT);
ENUM_STR(IVY_ASM_KW_END);
default:
return "";