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 }