Skip to content

Commit 5143f97

Browse files
easier maintained keyword list
1 parent ce26ebc commit 5143f97

6 files changed

Lines changed: 191 additions & 305 deletions

File tree

include/basic/console.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ void print_statement(struct basic_ctx* ctx);
165165
* @param ctx The BASIC context.
166166
* @param tok The token for the colour.
167167
*/
168-
void colour_statement(struct basic_ctx* ctx, enum token_t tok);
168+
void colour_statement(struct basic_ctx* ctx);
169169

170170
/**
171171
* @brief Set the text background colour.

include/basic/tokenizer.h

Lines changed: 137 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,14 @@
4444
#define NONSTMT NONSTMT
4545

4646
/* Conditional emit: only statement keywords produce a const in .kw.<name> */
47-
#define EMIT_STMT(name) \
47+
#define EMIT_STMT(name, dispatcher) \
4848
static const int kw_##name __attribute__((section(".kw." #name), used)) = name;
49-
#define EMIT_NONSTMT(name) /* nothing */
49+
#define EMIT_NONSTMT(name, dispatcher) /* nothing */
5050

51-
#define EMIT_FROM_FLAG(name, flag) EMIT_##flag(name)
51+
#define EMIT_FROM_FLAG(name, flag, dispatcher) EMIT_##flag(name, dispatcher)
52+
53+
/* Handler function type */
54+
typedef void (*keyword_handler_t)(struct basic_ctx*);
5255

5356
/**
5457
* @brief All tokens recognised by the interpreter. Note that built in function names are NOT
@@ -59,123 +62,140 @@
5962
* enum, which is built and used within basic.c for tokenization.
6063
*/
6164
#define TOKEN(T) \
62-
T(NO_TOKEN, NONSTMT) /* 0 */ \
63-
T(ERROR, STMT) /* 1 */ \
64-
T(ENDOFINPUT, NONSTMT) /* 2 */ \
65-
T(NUMBER, NONSTMT) /* 3 */ \
66-
T(HEXNUMBER, NONSTMT) /* 4 */ \
67-
T(STRING, NONSTMT) /* 5 */ \
68-
T(VARIABLE, NONSTMT) /* 6 */ \
69-
T(LET, STMT) /* 7 */ \
70-
T(PRINT, STMT) /* 8 */ \
71-
T(IF, STMT) /* 9 */ \
72-
T(THEN, STMT) /* 10 */ \
73-
T(ELSE, STMT) /* 11 */ \
74-
T(CHAIN, STMT) /* 12 */ \
75-
T(FOR, STMT) /* 13 */ \
76-
T(STEP, STMT) /* 14 */ \
77-
T(TO, STMT) /* 15 */ \
78-
T(NEXT, STMT) /* 16 */ \
79-
T(CURSOR, STMT) /* 17 */ \
80-
T(GOTO, STMT) /* 18 */ \
81-
T(GOSUB, STMT) /* 19 */ \
82-
T(RETURN, STMT) /* 20 */ \
83-
T(CALL, STMT) /* 21 */ \
84-
T(INPUT, STMT) /* 22 */ \
85-
T(COLOUR, STMT) /* 23 */ \
86-
T(COLOR, STMT) /* 24 */ \
87-
T(BACKGROUND, STMT) /* 25 */ \
88-
T(EVAL, STMT) /* 26 */ \
89-
T(CLOSE, STMT) /* 27 */ \
90-
T(DEF, STMT) /* 28 */ \
91-
T(PROC, STMT) /* 29 */ \
92-
T(ENDPROC, STMT) /* 30 */ \
93-
T(FN, NONSTMT) /* 31 */ \
94-
T(END, STMT) /* 32 */ \
95-
T(REM, STMT) /* 33 */ \
96-
T(COMMA, NONSTMT) /* 34 */ \
97-
T(SEMICOLON, NONSTMT) /* 35 */ \
98-
T(PLUS, NONSTMT) /* 36 */ \
99-
T(MINUS, NONSTMT) /* 37 */ \
100-
T(AND, STMT) /* 38 */ \
101-
T(OR, STMT) /* 39 */ \
102-
T(NOT, STMT) /* 40 */ \
103-
T(EOR, STMT) /* 41 */ \
104-
T(ASTERISK, NONSTMT) /* 42 */ \
105-
T(SLASH, NONSTMT) /* 43 */ \
106-
T(MOD, NONSTMT) /* 44 */ \
107-
T(OPENBRACKET, NONSTMT) /* 45 */ \
108-
T(CLOSEBRACKET, NONSTMT) /* 46 */ \
109-
T(LESSTHAN, NONSTMT) /* 47 */ \
110-
T(GREATERTHAN, NONSTMT) /* 48 */ \
111-
T(EQUALS, NONSTMT) /* 49 */ \
112-
T(NEWLINE, NONSTMT) /* 50 */ \
113-
T(AMPERSAND, NONSTMT) /* 51 */ \
114-
T(TILDE, NONSTMT) /* 52 */ \
115-
T(GLOBAL, STMT) /* 53 */ \
116-
T(SOCKREAD, STMT) /* 54 */ \
117-
T(SOCKWRITE, STMT) /* 55 */ \
118-
T(CONNECT, STMT) /* 56 */ \
119-
T(SOCKCLOSE, STMT) /* 57 */ \
120-
T(CLS, STMT) /* 58 */ \
121-
T(GCOL, STMT) /* 59 */ \
122-
T(LINE, STMT) /* 60 */ \
123-
T(TRIANGLE, STMT) /* 61 */ \
124-
T(RECTANGLE, STMT) /* 62 */ \
125-
T(CIRCLE, STMT) /* 63 */ \
126-
T(POINT, STMT) /* 64 */ \
127-
T(DATA, STMT) /* 65 */ \
128-
T(RESTORE, STMT) /* 66 */ \
129-
T(WRITE, STMT) /* 67 */ \
130-
T(MKDIR, STMT) /* 68 */ \
131-
T(RMDIR, STMT) /* 69 */ \
132-
T(DELETE, STMT) /* 70 */ \
133-
T(REPEAT, STMT) /* 71 */ \
134-
T(UNTIL, STMT) /* 72 */ \
135-
T(DIM, STMT) /* 73 */ \
136-
T(REDIM, STMT) /* 74 */ \
137-
T(PUSH, STMT) /* 75 */ \
138-
T(POKE, STMT) /* 76 */ \
139-
T(POKEW, STMT) /* 77 */ \
140-
T(POKED, STMT) /* 78 */ \
141-
T(POKEQ, STMT) /* 79 */ \
142-
T(POP, STMT) /* 80 */ \
143-
T(LOCAL, STMT) /* 81 */ \
144-
T(CHDIR, STMT) /* 82 */ \
145-
T(LIBRARY, STMT) /* 83 */ \
146-
T(YIELD, STMT) /* 84 */ \
147-
T(SETVARI, STMT) /* 85 */ \
148-
T(SETVARR, STMT) /* 86 */ \
149-
T(SETVARS, STMT) /* 87 */ \
150-
T(SPRITELOAD, STMT) /* 88 */ \
151-
T(SPRITEFREE, STMT) /* 89 */ \
152-
T(PLOT, STMT) /* 90 */ \
153-
T(AUTOFLIP, STMT) /* 91 */ \
154-
T(FLIP, STMT) /* 92 */ \
155-
T(KEYMAP, STMT) /* 93 */ \
156-
T(MOUNT, STMT) /* 94 */ \
157-
T(SETTIMEZONE, STMT) /* 95 */ \
158-
T(ENDIF, STMT) /* 96 */ \
159-
T(PLOTQUAD, STMT) /* 97 */ \
160-
T(ON, STMT) /* 98 */ \
161-
T(OFF, STMT) /* 99 */ \
162-
T(WHILE, STMT) /* 100 */ \
163-
T(ENDWHILE, STMT) /* 101 */ \
164-
T(SLEEP, STMT) /* 102 */ \
165-
T(CONTINUE, STMT) /* 103 */ \
166-
T(UDPBIND, STMT) /* 104 */ \
167-
T(UDPUNBIND, STMT) /* 105 */ \
168-
T(UDPWRITE, STMT) /* 106 */ \
169-
T(OUTPORT, STMT) /* 107 */ \
170-
T(OUTPORTW, STMT) /* 108 */ \
171-
T(OUTPORTD, STMT) /* 109 */ \
172-
T(KGET, STMT) /* 110 */ \
173-
T(MODLOAD, STMT) /* 111 */ \
174-
T(MODUNLOAD, STMT) /* 112 */ \
175-
T(SOCKFLUSH, STMT) /* 113 */ \
65+
T(NO_TOKEN, NONSTMT, NULL) /* 0 */ \
66+
T(ERROR, STMT, error_statement) /* 1 */ \
67+
T(ENDOFINPUT, NONSTMT, NULL) /* 2 */ \
68+
T(NUMBER, NONSTMT, NULL) /* 3 */ \
69+
T(HEXNUMBER, NONSTMT, NULL) /* 4 */ \
70+
T(STRING, NONSTMT, NULL) /* 5 */ \
71+
T(VARIABLE, NONSTMT, variable_statement) /* 6 */ \
72+
T(LET, STMT, let_statement) /* 7 */ \
73+
T(PRINT, STMT, print_statement) /* 8 */ \
74+
T(IF, STMT, if_statement) /* 9 */ \
75+
T(THEN, STMT, NULL) /* 10 */ \
76+
T(ELSE, STMT, else_statement) /* 11 */ \
77+
T(CHAIN, STMT, chain_statement) /* 12 */ \
78+
T(FOR, STMT, for_statement) /* 13 */ \
79+
T(STEP, STMT, NULL) /* 14 */ \
80+
T(TO, STMT, NULL) /* 15 */ \
81+
T(NEXT, STMT, next_statement) /* 16 */ \
82+
T(CURSOR, STMT, gotoxy_statement) /* 17 */ \
83+
T(GOTO, STMT, goto_statement) /* 18 */ \
84+
T(GOSUB, STMT, gosub_statement) /* 19 */ \
85+
T(RETURN, STMT, return_statement) /* 20 */ \
86+
T(CALL, STMT, NULL) /* 21 */ \
87+
T(INPUT, STMT, input_statement) /* 22 */ \
88+
T(COLOUR, STMT, colour_statement) /* 23 */ \
89+
T(COLOR, STMT, colour_statement) /* 24 */ \
90+
T(BACKGROUND, STMT, background_statement) /* 25 */ \
91+
T(EVAL, STMT, eval_statement) /* 26 */ \
92+
T(CLOSE, STMT, close_statement) /* 27 */ \
93+
T(DEF, STMT, def_statement) /* 28 */ \
94+
T(PROC, STMT, proc_statement) /* 29 */ \
95+
T(ENDPROC, STMT, endproc_statement) /* 30 */ \
96+
T(FN, NONSTMT, NULL) /* 31 */ \
97+
T(END, STMT, end_statement) /* 32 */ \
98+
T(REM, STMT, rem_statement) /* 33 */ \
99+
T(COMMA, NONSTMT, NULL) /* 34 */ \
100+
T(SEMICOLON, NONSTMT, NULL) /* 35 */ \
101+
T(PLUS, NONSTMT, NULL) /* 36 */ \
102+
T(MINUS, NONSTMT, NULL) /* 37 */ \
103+
T(AND, STMT, NULL) /* 38 */ \
104+
T(OR, STMT, NULL) /* 39 */ \
105+
T(NOT, STMT, NULL) /* 40 */ \
106+
T(EOR, STMT, NULL) /* 41 */ \
107+
T(ASTERISK, NONSTMT, NULL) /* 42 */ \
108+
T(SLASH, NONSTMT, NULL) /* 43 */ \
109+
T(MOD, NONSTMT, NULL) /* 44 */ \
110+
T(OPENBRACKET, NONSTMT, NULL) /* 45 */ \
111+
T(CLOSEBRACKET, NONSTMT, NULL) /* 46 */ \
112+
T(LESSTHAN, NONSTMT, NULL) /* 47 */ \
113+
T(GREATERTHAN, NONSTMT, NULL) /* 48 */ \
114+
T(EQUALS, NONSTMT, eq_statement) /* 49 */ \
115+
T(NEWLINE, NONSTMT, newline_statement) /* 50 */ \
116+
T(AMPERSAND, NONSTMT, NULL) /* 51 */ \
117+
T(TILDE, NONSTMT, NULL) /* 52 */ \
118+
T(GLOBAL, STMT, global_statement) /* 53 */ \
119+
T(SOCKREAD, STMT, sockread_statement) /* 54 */ \
120+
T(SOCKWRITE, STMT, sockwrite_statement) /* 55 */ \
121+
T(CONNECT, STMT, connect_statement) /* 56 */ \
122+
T(SOCKCLOSE, STMT, sockclose_statement) /* 57 */ \
123+
T(CLS, STMT, cls_statement) /* 58 */ \
124+
T(GCOL, STMT, gcol_statement) /* 59 */ \
125+
T(LINE, STMT, draw_line_statement) /* 60 */ \
126+
T(TRIANGLE, STMT, triangle_statement) /* 61 */ \
127+
T(RECTANGLE, STMT, rectangle_statement) /* 62 */ \
128+
T(CIRCLE, STMT, circle_statement) /* 63 */ \
129+
T(POINT, STMT, point_statement) /* 64 */ \
130+
T(DATA, STMT, data_statement) /* 65 */ \
131+
T(RESTORE, STMT, restore_statement) /* 66 */ \
132+
T(WRITE, STMT, write_statement) /* 67 */ \
133+
T(MKDIR, STMT, mkdir_statement) /* 68 */ \
134+
T(RMDIR, STMT, rmdir_statement) /* 69 */ \
135+
T(DELETE, STMT, delete_statement) /* 70 */ \
136+
T(REPEAT, STMT, repeat_statement) /* 71 */ \
137+
T(UNTIL, STMT, until_statement) /* 72 */ \
138+
T(DIM, STMT, dim_statement) /* 73 */ \
139+
T(REDIM, STMT, redim_statement) /* 74 */ \
140+
T(PUSH, STMT, push_statement) /* 75 */ \
141+
T(POKE, STMT, poke_statement) /* 76 */ \
142+
T(POKEW, STMT, pokew_statement) /* 77 */ \
143+
T(POKED, STMT, poked_statement) /* 78 */ \
144+
T(POKEQ, STMT, pokeq_statement) /* 79 */ \
145+
T(POP, STMT, pop_statement) /* 80 */ \
146+
T(LOCAL, STMT, local_statement) /* 81 */ \
147+
T(CHDIR, STMT, chdir_statement) /* 82 */ \
148+
T(LIBRARY, STMT, library_statement) /* 83 */ \
149+
T(YIELD, STMT, yield_statement) /* 84 */ \
150+
T(SETVARI, STMT, setvari_statement) /* 85 */ \
151+
T(SETVARR, STMT, setvarr_statement) /* 86 */ \
152+
T(SETVARS, STMT, setvars_statement) /* 87 */ \
153+
T(SPRITELOAD, STMT, loadsprite_statement) /* 88 */ \
154+
T(SPRITEFREE, STMT, freesprite_statement) /* 89 */ \
155+
T(PLOT, STMT, plot_statement) /* 90 */ \
156+
T(AUTOFLIP, STMT, autoflip_statement) /* 91 */ \
157+
T(FLIP, STMT, flip_statement) /* 92 */ \
158+
T(KEYMAP, STMT, keymap_statement) /* 93 */ \
159+
T(MOUNT, STMT, mount_statement) /* 94 */ \
160+
T(SETTIMEZONE, STMT, settimezone_statement) /* 95 */ \
161+
T(ENDIF, STMT, endif_statement) /* 96 */ \
162+
T(PLOTQUAD, STMT, plotquad_statement) /* 97 */ \
163+
T(ON, STMT, on_statement) /* 98 */ \
164+
T(OFF, STMT, off_statement) /* 99 */ \
165+
T(WHILE, STMT, while_statement) /* 100 */ \
166+
T(ENDWHILE, STMT, endwhile_statement) /* 101 */ \
167+
T(SLEEP, STMT, sleep_statement) /* 102 */ \
168+
T(CONTINUE, STMT, continue_statement) /* 103 */ \
169+
T(UDPBIND, STMT, udpbind_statement) /* 104 */ \
170+
T(UDPUNBIND, STMT, udpunbind_statement) /* 105 */ \
171+
T(UDPWRITE, STMT, udpwrite_statement) /* 106 */ \
172+
T(OUTPORT, STMT, outport_statement) /* 107 */ \
173+
T(OUTPORTW, STMT, outportw_statement) /* 108 */ \
174+
T(OUTPORTD, STMT, outportd_statement) /* 109 */ \
175+
T(KGET, STMT, kget_statement) /* 110 */ \
176+
T(MODLOAD, STMT, modload_statement) /* 111 */ \
177+
T(MODUNLOAD, STMT, modunload_statement) /* 112 */ \
178+
T(SOCKFLUSH, STMT, sockflush_statement) /* 113 */ \
176179

177180
GENERATE_ENUM_LIST(TOKEN, token_t)
178181

182+
/* Pair of token id and its dispatcher (can be NULL) */
183+
struct keyword_dispatch_t {
184+
enum token_t token;
185+
keyword_handler_t handler;
186+
};
187+
188+
/* Expand one TOKEN() entry into a { token, handler } initializer */
189+
#define GENERATE_DISPATCH_ENTRY(NAME, FLAG, DISPATCHER) { NAME, (keyword_handler_t)(DISPATCHER) },
190+
191+
/* Emit a const array named ARRAY_NAME with one element per TOKEN() entry */
192+
#define GENERATE_DISPATCH_TABLE(ARRAY_NAME) \
193+
const struct keyword_dispatch_t ARRAY_NAME[] = { \
194+
TOKEN(GENERATE_DISPATCH_ENTRY) \
195+
};
196+
197+
#define DISPATCH_TABLE_COUNT(ARRAY_NAME) (sizeof(ARRAY_NAME) / sizeof((ARRAY_NAME)[0]))
198+
179199
/**
180200
* @brief Initialise tokenizer
181201
*

include/basic/variable.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ ub_return_type basic_get_numeric_variable(const char* var, struct basic_ctx* ctx
101101
int64_t basic_get_numeric_int_variable(const char* var, struct basic_ctx* ctx);
102102

103103
/**
104-
* @brief Handle the LET statement.
104+
* @brief Handle variable assignment
105105
*
106106
* This function processes the LET statement, setting the value of a variable.
107107
*
108108
* @param ctx The current BASIC context.
109109
* @param global Boolean indicating whether the variable is global.
110110
* @param local Boolean indicating whether the variable is local.
111111
*/
112-
void let_statement(struct basic_ctx* ctx, bool global, bool local);
112+
void assignment_statement(struct basic_ctx* ctx, bool global, bool local);
113113

114114
/**
115115
* @brief Check if an integer variable exists.
@@ -143,3 +143,13 @@ bool basic_string_variable_exists(const char* var, struct basic_ctx* ctx);
143143
* @return True if the double variable exists, false otherwise.
144144
*/
145145
bool basic_double_variable_exists(const char* var, struct basic_ctx* ctx);
146+
147+
void let_statement(struct basic_ctx* ctx);
148+
149+
void variable_statement(struct basic_ctx* ctx);
150+
151+
void global_statement(struct basic_ctx* ctx);
152+
153+
void local_statement(struct basic_ctx* ctx);
154+
155+
void newline_statement(struct basic_ctx* ctx);

src/basic/console.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,13 @@ void print_statement(struct basic_ctx* ctx)
172172
}
173173
}
174174

175-
void colour_statement(struct basic_ctx* ctx, enum token_t tok)
175+
void colour_statement(struct basic_ctx* ctx)
176176
{
177-
accept_or_return(tok, ctx);
177+
if (tokenizer_token(ctx) != COLOR && tokenizer_token(ctx) != COLOUR) {
178+
tokenizer_error_print(ctx, "COLOUR expected");
179+
return;
180+
}
181+
tokenizer_next(ctx);
178182
setforeground(expr(ctx));
179183
accept_or_return(NEWLINE, ctx);
180184
}

0 commit comments

Comments
 (0)