diff --git a/asm/include/ivy/asm/lex.h b/asm/include/ivy/asm/lex.h index 4c347c1..5e55891 100644 --- a/asm/include/ivy/asm/lex.h +++ b/asm/include/ivy/asm/lex.h @@ -15,6 +15,7 @@ enum ivy_asm_token_type { IVY_ASM_TOK_INT, IVY_ASM_TOK_DOUBLE, IVY_ASM_TOK_LABEL, + IVY_ASM_TOK_LABEL_REF, IVY_ASM_TOK_IDENT, IVY_ASM_TOK_STRING, IVY_ASM_TOK_LINEFEED, @@ -52,7 +53,6 @@ enum ivy_asm_symbol { IVY_ASM_SYM_RIGHT_BRACE, IVY_ASM_SYM_COLON, IVY_ASM_SYM_SEMICOLON, - IVY_ASM_SYM_DOLLAR, IVY_ASM_SYM_HYPHEN, IVY_ASM_SYM_PLUS, IVY_ASM_SYM_SQUOTE, diff --git a/asm/lex.c b/asm/lex.c index ca08f48..0fcdc76 100644 --- a/asm/lex.c +++ b/asm/lex.c @@ -47,7 +47,6 @@ static struct lex_token_def symbols[] = { LEX_TOKEN_DEF(IVY_ASM_SYM_RIGHT_BRACE, "}"), LEX_TOKEN_DEF(IVY_ASM_SYM_COLON, ":"), LEX_TOKEN_DEF(IVY_ASM_SYM_SEMICOLON, ";"), - LEX_TOKEN_DEF(IVY_ASM_SYM_DOLLAR, "$"), LEX_TOKEN_DEF(IVY_ASM_SYM_HYPHEN, "-"), LEX_TOKEN_DEF(IVY_ASM_SYM_SQUOTE, "'"), LEX_TOKEN_DEF(IVY_ASM_SYM_DQUOTE, "\""), @@ -853,6 +852,43 @@ static enum ivy_status read_keyword(struct ivy_asm_lexer *lex) return push_keyword(lex, keyword); } +static enum ivy_status read_label_ref(struct ivy_asm_lexer *lex) +{ + advance(lex); + + b_string *str = get_temp_string(lex); + bool label = false; + + while (true) { + int c = peek(lex); + + if (c < 0) { + break; + } + + if (c == ':' && peek_next(lex) != ':') { + advance(lex); + label = true; + break; + } + + if (!isalnum(c) && c != '_') { + break; + } + + char s[2] = {c, 0}; + b_string_append_cstr(str, s); + advance(lex); + } + + const char *s = b_string_ptr(str); + + struct ivy_asm_token *tok = create_token(IVY_ASM_TOK_LABEL_REF); + tok->t_str = b_string_steal(str); + + return push_token(lex, tok); +} + static enum ivy_status read_ident(struct ivy_asm_lexer *lex) { b_string *str = get_temp_string(lex); @@ -942,6 +978,10 @@ static enum ivy_status pump_tokens(struct ivy_asm_lexer *lex) return read_symbol(lex); } + if (c == '$') { + return read_label_ref(lex); + } + if (c == '@') { return read_keyword(lex); } @@ -1018,6 +1058,7 @@ const char *ivy_asm_token_type_to_string(enum ivy_asm_token_type type) ENUM_STR(IVY_ASM_TOK_INT); ENUM_STR(IVY_ASM_TOK_DOUBLE); ENUM_STR(IVY_ASM_TOK_LABEL); + ENUM_STR(IVY_ASM_TOK_LABEL_REF); ENUM_STR(IVY_ASM_TOK_IDENT); ENUM_STR(IVY_ASM_TOK_STRING); ENUM_STR(IVY_ASM_TOK_LINEFEED); @@ -1064,7 +1105,6 @@ const char *ivy_asm_symbol_to_string(enum ivy_asm_symbol sym) ENUM_STR(IVY_ASM_SYM_HYPHEN); ENUM_STR(IVY_ASM_SYM_COMMA); ENUM_STR(IVY_ASM_SYM_SEMICOLON); - ENUM_STR(IVY_ASM_SYM_DOLLAR); ENUM_STR(IVY_ASM_SYM_FORWARD_SLASH_ASTERISK); default: return ""; diff --git a/asm/parse/block.c b/asm/parse/block.c index 9a6e8cd..0d4bf7a 100644 --- a/asm/parse/block.c +++ b/asm/parse/block.c @@ -487,7 +487,7 @@ static enum ivy_status parse_ident( state->s_prev_component = INSTR_OPERAND; if (x == REG_INDEX_INVALID) { - return push_label_arg(state, tok, x); + return IVY_ERR_BAD_SYNTAX; } else { return push_reg_arg(state, tok, x); } @@ -510,6 +510,28 @@ static enum ivy_status parse_ident( return IVY_ERR_BAD_SYNTAX; } +static enum ivy_status parse_label_ref( + struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) +{ + struct block_parser_state *state + = (struct block_parser_state *)asm_parser_get_state(ctx); + + unsigned long long x = 0; + + switch (state->s_prev_component) { + case INSTR_OPCODE: + case INSTR_OPERAND_SEPARATOR: + state->s_prev_component = INSTR_OPERAND; + + return push_label_arg(state, tok, x); + default: + return IVY_ERR_BAD_SYNTAX; + } + + /* not sure what this is but we aren't expecting it. */ + return IVY_ERR_BAD_SYNTAX; +} + static enum ivy_status parse_dot( struct ivy_asm_parser *ctx, struct ivy_asm_token *tok) { @@ -633,6 +655,7 @@ struct parser_state_type block_parser_state_type = { .n_token_parsers = { TOK_PARSER(IDENT, parse_ident), TOK_PARSER(LABEL, parse_label), + TOK_PARSER(LABEL_REF, parse_label_ref), TOK_PARSER(INT, parse_int), TOK_PARSER(LINEFEED, parse_linefeed), },