Mercurial > hg > index.cgi
comparison lwbasic/parser.c @ 36:5325b640424d
First pass expression parsing
author | Lost Wizard (lost@starbug3) |
---|---|
date | Tue, 08 Feb 2011 22:42:12 -0700 |
parents | cdb0175e1063 |
children |
comparison
equal
deleted
inserted
replaced
35:cdb0175e1063 | 36:5325b640424d |
---|---|
64 lexer(state); | 64 lexer(state); |
65 /* look for "unsigned" modifier for integer types */ | 65 /* look for "unsigned" modifier for integer types */ |
66 return pt; | 66 return pt; |
67 } | 67 } |
68 | 68 |
69 static void parse_expr(cstate *state, int prec); | |
70 static void parse_term(cstate *state); | |
69 static int parse_expression(cstate *state) | 71 static int parse_expression(cstate *state) |
70 { | 72 { |
71 state -> expression = 1; | 73 state -> expression = 1; |
74 | |
75 parse_expr(state, 0); | |
72 | 76 |
73 state -> expression = 0; | 77 state -> expression = 0; |
74 return 1; | 78 return 1; |
75 } | 79 } |
76 | 80 |
353 default: | 357 default: |
354 lwb_error("Invalid token '%s' in global state\n", lexer_return_token(state)); | 358 lwb_error("Invalid token '%s' in global state\n", lexer_return_token(state)); |
355 } | 359 } |
356 } | 360 } |
357 } | 361 } |
362 | |
363 static void parse_expr(cstate *state, int prec) | |
364 { | |
365 static const struct operinfo { | |
366 int opernum; | |
367 int operprec; | |
368 } operators[] = | |
369 { | |
370 { token_op_plus, 100 }, | |
371 { token_op_minus, 100 }, | |
372 { token_op_times, 150 }, | |
373 { token_op_divide, 150 }, | |
374 { token_op_modulus, 150 }, | |
375 { token_op_and, 25 }, | |
376 { token_op_or, 20 }, | |
377 { token_op_xor, 20 }, | |
378 { token_op_band, 50 }, | |
379 { token_op_bor, 45 }, | |
380 { token_op_bxor, 45 }, | |
381 { -1, -1 } | |
382 }; | |
383 int opern; | |
384 | |
385 parse_term(state); | |
386 | |
387 eval_next: | |
388 for (opern = 0; operators[opern].opernum != -1; opern++) | |
389 { | |
390 if (operators[opern].opernum == state -> lexer_token) | |
391 break; | |
392 } | |
393 if (operators[opern].opernum == -1) | |
394 return; | |
395 | |
396 if (operators[opern].operprec <= prec) | |
397 return; | |
398 | |
399 lexer(state); | |
400 | |
401 parse_expr(state, operators[opern].operprec); | |
402 | |
403 /* push operator */ | |
404 | |
405 goto eval_next; | |
406 } | |
407 | |
408 static void parse_term(cstate *state) | |
409 { | |
410 eval_next: | |
411 /* parens */ | |
412 if (state -> lexer_token == token_op_oparen) | |
413 { | |
414 lexer(state); | |
415 parse_expr(state, 0); | |
416 expect(state, token_op_cparen); | |
417 return; | |
418 } | |
419 | |
420 /* unary plus; ignore it */ | |
421 if (state -> lexer_token == token_op_plus) | |
422 { | |
423 lexer(state); | |
424 goto eval_next; | |
425 } | |
426 | |
427 /* unary minus, precision 200 */ | |
428 if (state -> lexer_token == token_op_minus) | |
429 { | |
430 lexer(state); | |
431 parse_expr(state, 200); | |
432 | |
433 /* push unary negation */ | |
434 } | |
435 | |
436 /* BNOT, NOT */ | |
437 if (state -> lexer_token == token_op_not || state -> lexer_token == token_op_bnot) | |
438 { | |
439 lexer(state); | |
440 parse_expr(state, 200); | |
441 | |
442 /* push unary operator */ | |
443 } | |
444 | |
445 /* integer */ | |
446 if (state -> lexer_token == token_int) | |
447 { | |
448 } | |
449 | |
450 /* unsigned integer */ | |
451 if (state -> lexer_token == token_uint) | |
452 { | |
453 } | |
454 | |
455 /* variable or function call */ | |
456 if (state -> lexer_token == token_identifier) | |
457 { | |
458 lexer(state); | |
459 if (state -> lexer_token == token_op_oparen) | |
460 { | |
461 /* function call */ | |
462 return; | |
463 } | |
464 /* variable */ | |
465 return; | |
466 } | |
467 | |
468 lwb_error("Invalid input in expression; got %s\n", lexer_return_token(state)); | |
469 } |