From 707f45f4b850364c95aae6f04410dd5d0263f59a Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Mon, 20 Nov 2023 13:10:49 +0100 Subject: [PATCH] Added group expressions --- include/ulas.h | 7 +------ src/test.c | 4 ++++ src/ulas.c | 52 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/include/ulas.h b/include/ulas.h index 32f8f6e..98bf219 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -241,9 +241,7 @@ struct ulas_expprim { struct ulas_expgrp { // points to the first expression // in this group - long expr; - // how many expressions belong to the group - long len; + long head; }; union ulas_expval { @@ -256,9 +254,6 @@ union ulas_expval { struct ulas_expr { enum ulas_exprs type; union ulas_expval val; - // link to the next expression, -1 indicates - // there is no next expression - long next; }; /** diff --git a/src/test.c b/src/test.c index ecdd3c2..dd76cd5 100644 --- a/src/test.c +++ b/src/test.c @@ -268,6 +268,10 @@ void test_intexpr(void) { ASSERT_INTEXPR(-1, 0, "-1"); ASSERT_INTEXPR(1, 0, "--1"); ASSERT_INTEXPR(2, 0, "1 - -1"); + ASSERT_INTEXPR(17, 0, "2 + 3 * 5"); + + ASSERT_INTEXPR(-1, -1, "((2 + 3) * 5"); + ASSERT_INTEXPR(25, 0, "(2 + 3) * 5"); TESTEND("intexpr"); } diff --git a/src/ulas.c b/src/ulas.c index 1a1cc3a..a5bb969 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -1044,19 +1044,38 @@ end: * we error out because of trailing tokens! */ +int ulas_parseexprat(int *i); + 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 && t->type != '(' && t->type != ')')) { ULASERR("Primary expression expected\n"); return -1; } - struct ulas_expprim prim = {*i}; - union ulas_expval val = {.prim = prim}; - struct ulas_expr e = {ULAS_EXPPRIM, val, -1}; - *i += 1; - return ulas_exprbufpush(&ulas.exprs, e); + if (t->type == '(') { + *i += 1; + int head = ulas_parseexprat(i); + + struct ulas_expgrp grp = {head}; + union ulas_expval val = {.grp = grp}; + struct ulas_expr e = {ULAS_EXPGRP, val}; + + struct ulas_tok *closing = ulas_tokbufget(&ulas.toks, *i); + if (!closing || closing->type != ')') { + ULASERR("Unterminated group expression\n"); + return -1; + } + *i += 1; + return ulas_exprbufpush(&ulas.exprs, e); + } else { + struct ulas_expprim prim = {*i}; + union ulas_expval val = {.prim = prim}; + struct ulas_expr e = {ULAS_EXPPRIM, val}; + *i += 1; + return ulas_exprbufpush(&ulas.exprs, e); + } } int ulas_parsecmp(int *i); @@ -1071,7 +1090,7 @@ int ulas_parseun(int *i) { struct ulas_expun un = {right, op}; union ulas_expval val = {.un = un}; - struct ulas_expr e = {ULAS_EXPUN, val, -1}; + struct ulas_expr e = {ULAS_EXPUN, val}; return ulas_exprbufpush(&ulas.exprs, e); } @@ -1090,7 +1109,7 @@ int ulas_parsefact(int *i) { struct ulas_expbin bin = {expr, right, op}; union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1109,7 +1128,7 @@ int ulas_parseterm(int *i) { struct ulas_expbin bin = {expr, right, op}; union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1129,7 +1148,7 @@ int ulas_parsecmp(int *i) { struct ulas_expbin bin = {expr, right, op}; union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1147,13 +1166,15 @@ int ulas_parseeq(int *i) { struct ulas_expbin bin = {expr, right, op}; union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val, -1}; + struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } return expr; } +int ulas_parseexprat(int *i) { return ulas_parseeq(i); } + // parses tokens to expression tree // returns head expression index int ulas_parseexpr(void) { @@ -1166,7 +1187,7 @@ int ulas_parseexpr(void) { } int i = 0; - int rc = ulas_parseeq(&i); + int rc = ulas_parseexprat(&i); if (i < toks->len) { ULASERR("Trailing token at index %d\n", i); @@ -1248,8 +1269,9 @@ int ulas_intexpreval(int i, int *rc) { } break; } - case ULAS_EXPGRP: - break; + case ULAS_EXPGRP: { + return ulas_intexpreval(e->val.grp.head, rc); + } case ULAS_EXPPRIM: { struct ulas_tok *t = ulas_tokbufget(&ulas.toks, e->val.prim.tok); return ulas_valint(t, rc); -- 2.30.2