| 227 | |
| 228 | |
| 229 | void next_token(state *s) { |
| 230 | s->type = TOK_NULL; |
| 231 | |
| 232 | do { |
| 233 | |
| 234 | if (!*s->next){ |
| 235 | s->type = TOK_END; |
| 236 | return; |
| 237 | } |
| 238 | |
| 239 | /* Try reading a number. */ |
| 240 | if ((s->next[0] >= '0' && s->next[0] <= '9') || s->next[0] == '.') { |
| 241 | s->value = strtod(s->next, (char**)&s->next); |
| 242 | s->type = TOK_NUMBER; |
| 243 | } else { |
| 244 | /* Look for a variable or builtin function call. */ |
| 245 | if (s->next[0] >= 'a' && s->next[0] <= 'z') { |
| 246 | const char *start; |
| 247 | start = s->next; |
| 248 | while ((s->next[0] >= 'a' && s->next[0] <= 'z') || (s->next[0] >= '0' && s->next[0] <= '9') || (s->next[0] == '_')) s->next++; |
| 249 | |
| 250 | const te_variable *var = find_lookup(s, start, s->next - start); |
| 251 | if (!var) var = find_builtin(start, s->next - start); |
| 252 | |
| 253 | if (!var) { |
| 254 | s->type = TOK_ERROR; |
| 255 | } else { |
| 256 | switch(TYPE_MASK(var->type)) |
| 257 | { |
| 258 | case TE_VARIABLE: |
| 259 | s->type = TOK_VARIABLE; |
| 260 | s->bound = var->address; |
| 261 | break; |
| 262 | |
| 263 | case TE_CLOSURE0: case TE_CLOSURE1: case TE_CLOSURE2: case TE_CLOSURE3: /* Falls through. */ |
| 264 | case TE_CLOSURE4: case TE_CLOSURE5: case TE_CLOSURE6: case TE_CLOSURE7: /* Falls through. */ |
| 265 | s->context = var->context; /* Falls through. */ |
| 266 | |
| 267 | case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: /* Falls through. */ |
| 268 | case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: /* Falls through. */ |
| 269 | s->type = var->type; |
| 270 | s->function = var->address; |
| 271 | break; |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | } else { |
| 276 | /* Look for an operator or special character. */ |
| 277 | switch (s->next++[0]) { |
| 278 | case '+': s->type = TOK_INFIX; s->function = add; break; |
| 279 | case '-': s->type = TOK_INFIX; s->function = sub; break; |
| 280 | case '*': s->type = TOK_INFIX; s->function = mul; break; |
| 281 | case '/': s->type = TOK_INFIX; s->function = divide; break; |
| 282 | case '^': s->type = TOK_INFIX; s->function = pow; break; |
| 283 | case '%': s->type = TOK_INFIX; s->function = fmod; break; |
| 284 | case '(': s->type = TOK_OPEN; break; |
| 285 | case ')': s->type = TOK_CLOSE; break; |
| 286 | case ',': s->type = TOK_SEP; break; |