|
44 | 44 | #define NONSTMT NONSTMT |
45 | 45 |
|
46 | 46 | /* Conditional emit: only statement keywords produce a const in .kw.<name> */ |
47 | | -#define EMIT_STMT(name) \ |
| 47 | +#define EMIT_STMT(name, dispatcher) \ |
48 | 48 | static const int kw_##name __attribute__((section(".kw." #name), used)) = name; |
49 | | -#define EMIT_NONSTMT(name) /* nothing */ |
| 49 | +#define EMIT_NONSTMT(name, dispatcher) /* nothing */ |
50 | 50 |
|
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*); |
52 | 55 |
|
53 | 56 | /** |
54 | 57 | * @brief All tokens recognised by the interpreter. Note that built in function names are NOT |
|
59 | 62 | * enum, which is built and used within basic.c for tokenization. |
60 | 63 | */ |
61 | 64 | #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 */ \ |
176 | 179 |
|
177 | 180 | GENERATE_ENUM_LIST(TOKEN, token_t) |
178 | 181 |
|
| 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 | + |
179 | 199 | /** |
180 | 200 | * @brief Initialise tokenizer |
181 | 201 | * |
|
0 commit comments