asm/asm.c
static usize type_args(
        struct Context *ctx,
        struct Token *tk,
        enum Arg *args,
        struct Token **arg_tokens,
        usize args_capacity
    ) {
    char symbol[256];
    usize n = 0;
    isize i = 0, num_address = -1;

    while (tk->kind != TK_EOL) {
        assert(n < args_capacity);

        switch (tk->kind) {
            case TK_LBRACKET:
                num_address = 0;
                break;
            case TK_RBRACKET:
                asmchk(num_address > 0, ctx, tk, "Empty address");
                asmchk(
                    args[n - 1] & A_IMM, ctx, tk,
                    "Illegal address (not imm)"
                );
                args[n - 1] |= A_ADDR;
                num_address = -1;
                break;
            case TK_NUMBER:
                asmchk(tk->value <= 0xFFFF, ctx, tk, "Value out of bounds");
                arg_tokens[n] = tk;
                args[n++] = tk->value <= 0xFF ? A_IMM8 : A_IMM16;

                if (num_address != -1) {
                    asmchk(
                        num_address == 0, ctx, tk,
                        "Illegal address (>1 elements)"
                    );
                    num_address++;
                }
                break;
            case TK_DOT:
                asmchk(tk->next->kind == TK_SYMBOL, ctx, tk, "Expected label");
                tk = tk->next;
            case TK_SYMBOL:
                arg_tokens[n] = tk;

                assert(token_data(tk, symbol, sizeof(symbol)));
                if (num_address != -1) {
                    asmdbg(
                        ctx, NULL,
                        "Assuming type of %s is address", symbol
                    );
                    num_address++;
                    args[n++] = A_ADDR | A_IMM16;
                    break;
                }

                asmchk(
                    (i = strcasetab(R_NAMES, R_COUNT, symbol)) != -1,
                    ctx, tk,
                    "Unknown register %s", symbol
                );

                args[n++] = A_REG;
                break;
            default:
                asmchk(false, ctx, tk, "Unexpected token");
        }

        tk = tk->next;
    }

    return n;
}
// emits types of arguments starting at Token tk to *types
// returns the number of argument types emitted.
// errors on un-typable things
emits types of arguments starting at Token tk to *types
returns the number of argument types emitted.
errors on un-typable things
emits types of arguments starting at Token tk to * types returns the number of argument types emitted . errors on un - typable things
static usize type_args(
        struct Context *ctx,
        struct Token *tk,
        enum Arg *args,
        struct Token **arg_tokens,
        usize args_capacity
    ) {
    char symbol[256];
    usize n = 0;
    isize i = 0, num_address = -1;
    while (tk->kind != TK_EOL) {
        assert(n < args_capacity);
        switch (tk->kind) {
            case TK_LBRACKET:
                num_address = 0;
                break;
            case TK_RBRACKET:
                asmchk(num_address > 0, ctx, tk, "Empty address");
                asmchk(
                    args[n - 1] & A_IMM, ctx, tk,
                    "Illegal address (not imm)"
                );
                args[n - 1] |= A_ADDR;
                num_address = -1;
                break;
            case TK_NUMBER:
                asmchk(tk->value <= 0xFFFF, ctx, tk, "Value out of bounds");
                arg_tokens[n] = tk;
                args[n++] = tk->value <= 0xFF ? A_IMM8 : A_IMM16;
                if (num_address != -1) {
                    asmchk(
                        num_address == 0, ctx, tk,
                        "Illegal address (>1 elements)"
                    );
                    num_address++;
                }
                break;
            case TK_DOT:
                asmchk(tk->next->kind == TK_SYMBOL, ctx, tk, "Expected label");
                tk = tk->next;
            case TK_SYMBOL:
                arg_tokens[n] = tk;
                assert(token_data(tk, symbol, sizeof(symbol)));
                if (num_address != -1) {
                    asmdbg(
                        ctx, NULL,
                        "Assuming type of %s is address", symbol
                    );
                    num_address++;
                    args[n++] = A_ADDR | A_IMM16;
                    break;
                }
                asmchk(
                    (i = strcasetab(R_NAMES, R_COUNT, symbol)) != -1,
                    ctx, tk,
                    "Unknown register %s", symbol
                );
                args[n++] = A_REG;
                break;
            default:
                asmchk(false, ctx, tk, "Unexpected token");
        }
        tk = tk->next;
    }
    return n;
}
static usize type_args ( struct Context * ctx , struct Token * tk , enum Arg * args , struct Token * * arg_tokens , usize args_capacity ) { char symbol [ 256 ] ; usize n = 0 ; isize i = 0 , num_address = -1 ; while ( tk -> kind != TK_EOL ) { assert ( n < args_capacity ) ; switch ( tk -> kind ) { case TK_LBRACKET : num_address = 0 ; break ; case TK_RBRACKET : asmchk ( num_address > 0 , ctx , tk , " " ) ; asmchk ( args [ n - 1 ] & A_IMM , ctx , tk , " " ) ; args [ n - 1 ] |= A_ADDR ; num_address = -1 ; break ; case TK_NUMBER : asmchk ( tk -> value <= 0xFFFF , ctx , tk , " " ) ; arg_tokens [ n ] = tk ; args [ n ++ ] = tk -> value <= 0xFF ? A_IMM8 : A_IMM16 ; if ( num_address != -1 ) { asmchk ( num_address == 0 , ctx , tk , " " ) ; num_address ++ ; } break ; case TK_DOT : asmchk ( tk -> next -> kind == TK_SYMBOL , ctx , tk , " " ) ; tk = tk -> next ; case TK_SYMBOL : arg_tokens [ n ] = tk ; assert ( token_data ( tk , symbol , sizeof ( symbol ) ) ) ; if ( num_address != -1 ) { asmdbg ( ctx , NULL , " " , symbol ) ; num_address ++ ; args [ n ++ ] = A_ADDR | A_IMM16 ; break ; } asmchk ( ( i = strcasetab ( R_NAMES , R_COUNT , symbol ) ) != -1 , ctx , tk , " " , symbol ) ; args [ n ++ ] = A_REG ; break ; default : asmchk ( false , ctx , tk , " " ) ; } tk = tk -> next ; } return n ; }
emits types of arguments starting at Token tk to *types
returns the number of argument types emitted.
emits types of arguments starting at Token tk to * types returns the number of argument types emitted .