summaryrefslogtreecommitdiff
path: root/expr.y
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-04-17 15:38:51 -0400
committerJakob Kaivo <jkk@ung.org>2022-04-17 15:38:51 -0400
commitde4091fec9cd5716445ae40f95789188e018d476 (patch)
tree513fe59372560501da1673af1c2ffbacb0d1695b /expr.y
parent785f598db1da0406416cd6f184d929112bdd0e80 (diff)
now comparisons
Diffstat (limited to 'expr.y')
-rw-r--r--expr.y53
1 files changed, 53 insertions, 0 deletions
diff --git a/expr.y b/expr.y
index 785b004..b2f2061 100644
--- a/expr.y
+++ b/expr.y
@@ -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 {