From dfc0f47d0847f4f862f46b64b025427f66cb648f Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Mon, 20 Nov 2023 08:27:32 +0100 Subject: [PATCH] Added more operators --- src/test.c | 16 ++++++++++++ src/ulas.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/test.c b/src/test.c index 46529ba..c17b9e8 100644 --- a/src/test.c +++ b/src/test.c @@ -243,11 +243,27 @@ void test_intexpr(void) { TESTBEGIN("intexpr"); ASSERT_INTEXPR(-1, -1, ""); + ASSERT_INTEXPR(1, 0, "1"); + ASSERT_INTEXPR(1, 0, "2 == 2"); ASSERT_INTEXPR(0, 0, "2 == 2 == 3"); ASSERT_INTEXPR(1, 0, "2 == 2 == 1"); + ASSERT_INTEXPR(1, 0, "2 < 3"); + ASSERT_INTEXPR(0, 0, "2 > 3"); + ASSERT_INTEXPR(1, 0, "3 <= 3"); + ASSERT_INTEXPR(1, 0, "3 >= 3"); + + ASSERT_INTEXPR(5, 0, "2 + 3"); + ASSERT_INTEXPR(-1, 0, "2 + 3 - 6"); + + ASSERT_INTEXPR(6, 0, "2 * 3"); + ASSERT_INTEXPR(2, 0, "8 / 4"); + ASSERT_INTEXPR(0, -1, "8 / 0"); + ASSERT_INTEXPR(0, -1, "8 % 0"); + ASSERT_INTEXPR(0, 0, "8 % 4"); + TESTEND("intexpr"); } diff --git a/src/ulas.c b/src/ulas.c index b4b9d2d..e910cfe 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -1045,7 +1045,8 @@ end: int ulas_parseprim(int *i) { struct ulas_tok *t = ulas_tokbufget(&ulas.toks, *i); - if (!t || (t->type != ULAS_INT && t->type != ULAS_STR && t->type != ULAS_SYMBOL)) { + if (!t || + (t->type != ULAS_INT && t->type != ULAS_STR && t->type != ULAS_SYMBOL)) { ULASERR("Primary expression expected\n"); return -1; } @@ -1061,17 +1062,58 @@ int ulas_parseun(int *i) { return ulas_parseprim(i); } int ulas_parsefact(int *i) { int expr = ulas_parseun(i); + struct ulas_tok *t = NULL; + + while ((t = ulas_tokbufget(&ulas.toks, *i)) && + (t->type == '*' || t->type == '/' || t->type == '%')) { + int op = *i; + *i += 1; + int right = ulas_parsecmp(i); + + struct ulas_expbin bin = {expr, right, op}; + union ulas_expval val = {.bin = bin}; + struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + expr = ulas_exprbufpush(&ulas.exprs, e); + } return expr; } int ulas_parseterm(int *i) { int expr = ulas_parsefact(i); + struct ulas_tok *t = NULL; + + while ((t = ulas_tokbufget(&ulas.toks, *i)) && + (t->type == '+' || t->type == '-')) { + int op = *i; + *i += 1; + int right = ulas_parsecmp(i); + + struct ulas_expbin bin = {expr, right, op}; + union ulas_expval val = {.bin = bin}; + struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + expr = ulas_exprbufpush(&ulas.exprs, e); + } + return expr; } int ulas_parsecmp(int *i) { int expr = ulas_parseterm(i); + struct ulas_tok *t = NULL; + + while ((t = ulas_tokbufget(&ulas.toks, *i)) && + (t->type == ULAS_LTEQ || t->type == ULAS_GTEQ || t->type == '>' || + t->type == '<')) { + int op = *i; + *i += 1; + int right = ulas_parsecmp(i); + + struct ulas_expbin bin = {expr, right, op}; + union ulas_expval val = {.bin = bin}; + struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + expr = ulas_exprbufpush(&ulas.exprs, e); + } return expr; } @@ -1135,7 +1177,37 @@ int ulas_intexpreval(int i, int *rc) { int right = ulas_intexpreval(e->val.bin.right, rc); switch (op->type) { case ULAS_EQ: - return left == right; + return left == right; + case ULAS_NEQ: + return left != right; + case '<': + return left < right; + case '>': + return left > right; + case ULAS_LTEQ: + return left <= right; + case ULAS_GTEQ: + return left >= right; + case '+': + return left + right; + case '-': + return left - right; + case '*': + return left * right; + case '/': + if (right == 0) { + ULASERR("integer division by 0\n"); + *rc = -1; + return 0; + } + return left / right; + case '%': + if (right == 0) { + ULASERR("integer division by 0\n"); + *rc = -1; + return 0; + } + return left % right; default: ULASPANIC("Unhandeled binary operator\n"); break; -- 2.30.2