diff options
author | Jakob Kaivo <jkk@ung.org> | 2022-04-17 15:38:51 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2022-04-17 15:38:51 -0400 |
commit | de4091fec9cd5716445ae40f95789188e018d476 (patch) | |
tree | 513fe59372560501da1673af1c2ffbacb0d1695b /expr.y | |
parent | 785f598db1da0406416cd6f184d929112bdd0e80 (diff) |
now comparisons
Diffstat (limited to 'expr.y')
-rw-r--r-- | expr.y | 53 |
1 files changed, 53 insertions, 0 deletions
@@ -1,12 +1,48 @@ %{ #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "expr.h" +#include "y.tab.h" extern int yylex(void); extern int yyerror(const char *s); static void breakpoint(void) { } + +static void expr_only_integers(YYSTYPE *y1, YYSTYPE *y2) +{ + if (y1->type == STRING) { + fprintf(stderr, "expr: %s is not an integer\n", y1->u.s); + exit(1); + } + if (y2->type == STRING) { + fprintf(stderr, "expr: %s is not an integer\n", y2->u.s); + exit(1); + } +} + +static int expr_compare(YYSTYPE *y1, YYSTYPE *y2) +{ + if (y1->type == INTEGER && y2->type == INTEGER) { + return y1->u.i - y2->u.i; + } + + char buf[64]; + char *s1 = y1->u.s; + char *s2 = y2->u.s; + + if (y1->type == INTEGER) { + snprintf(buf, sizeof(buf), "%d", y1->u.i); + s1 = buf; + } else if (y2->type == INTEGER) { + snprintf(buf, sizeof(buf), "%d", y2->u.i); + s2 = buf; + } + + return strcmp(s1, s2); +} %} %token INTEGER @@ -37,46 +73,63 @@ expr : STRING { } | expr '*' expr { + expr_only_integers(&$1, &$3); $$.u.i = $1.u.i * $3.u.i; printf("%d\n", $$.u.i); } | expr '/' expr { + expr_only_integers(&$1, &$3); $$.u.i = $1.u.i / $3.u.i; printf("%d\n", $$.u.i); } | expr '%' expr { + expr_only_integers(&$1, &$3); $$.u.i = $1.u.i % $3.u.i; printf("%d\n", $$.u.i); } | expr '+' expr { + expr_only_integers(&$1, &$3); $$.u.i = $1.u.i + $3.u.i; printf("%d\n", $$.u.i); } | expr '-' expr { + expr_only_integers(&$1, &$3); $$.u.i = $1.u.i - $3.u.i; printf("%d\n", $$.u.i); } | expr '=' expr { + int r = expr_compare(&$1, &$3) == 0; + printf("%d\n", r); } | expr NE expr { + int r = expr_compare(&$1, &$3) != 0; + printf("%d\n", r); } | expr '<' expr { + int r = expr_compare(&$1, &$3) < 0; + printf("%d\n", r); } | expr LE expr { + int r = expr_compare(&$1, &$3) <= 0; + printf("%d\n", r); } | expr '>' expr { + int r = expr_compare(&$1, &$3) > 0; + printf("%d\n", r); } | expr GE expr { + int r = expr_compare(&$1, &$3) >= 0; + printf("%d\n", r); } | expr '&' expr { |