diff options
| author | hachem <im@hachem.wtf> | 2026-09-19 11:52:25 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-19 11:52:25 +0200 |
| commit | b20c46c555986a99be70de61d91bc225e53f31d2 (patch) | |
| tree | 7c3b94ca7cd894e0597bcef65f5f19ea9f1e7ecd | |
| parent | dd52ccd9319aa847cddc486519075b806c9e9092 (diff) | |
eval: sum product and quotient
| -rw-r--r-- | ast.h | 3 | ||||
| -rw-r--r-- | eval.c | 46 | ||||
| -rw-r--r-- | eval.h | 4 | ||||
| -rw-r--r-- | examples/sums.sfinae | 3 | ||||
| -rw-r--r-- | sfinae.l | 3 | ||||
| -rw-r--r-- | sfinae.y | 9 |
6 files changed, 64 insertions, 4 deletions
@@ -5,6 +5,9 @@ enum NodeKind NODE_CHAR, TYPE_DECLTYPE, VALUE_DIFFERENCE, + VALUE_SUM, + VALUE_PRODUCT, + VALUE_QUOTIENT, STMT_EMIT }; @@ -1,14 +1,54 @@ #include <assert.h> +#include <inttypes.h> #include <stdio.h> #include "eval.h" -static int evaluate_value(const struct Node* node, long* out) +static int evaluate_value(const struct Node* node, int64_t* out); + +static int complain(const struct Node* node, const char* message) +{ + (void)fprintf(stderr, "line %d: %s\n", node->line, message); + return 1; +} + +static int evaluate_operands(const struct Node* node, int64_t* left, int64_t* right) { + if (evaluate_value(node->first, left)) + return 1; + + return evaluate_value(node->second, right); +} + +static int evaluate_value(const struct Node* node, int64_t* out) +{ + int64_t left = 0; + int64_t right = 0; switch (node->kind) { case VALUE_DIFFERENCE: - *out = (long)node->first->character - (long)node->second->character; + *out = (int64_t)node->first->character - (int64_t)node->second->character; + return 0; + case VALUE_SUM: + if (evaluate_operands(node, &left, &right)) + return 1; + + *out = left + right; + return 0; + case VALUE_PRODUCT: + if (evaluate_operands(node, &left, &right)) + return 1; + + *out = left * right; + return 0; + case VALUE_QUOTIENT: + if (evaluate_operands(node, &left, &right)) + return 1; + + if (right == 0) + return complain(node, "division by zero"); + + *out = left / right; return 0; default: break; } @@ -42,7 +82,7 @@ static enum RunStatus emit(const struct Node* node) return RUN_FAILED; if (type.kind == KIND_VALUE) - (void)printf("%ld\n", type.number); + (void)printf("%" PRId64 "\n", type.number); return RUN_DONE; } @@ -2,6 +2,8 @@ #include "ast.h" +#include <stdint.h> + enum TypeKind { KIND_VOID, @@ -11,7 +13,7 @@ enum TypeKind struct Type { enum TypeKind kind; - long number; + int64_t number; }; enum RunStatus diff --git a/examples/sums.sfinae b/examples/sums.sfinae new file mode 100644 index 0000000..b5ffb62 --- /dev/null +++ b/examples/sums.sfinae @@ -0,0 +1,3 @@ +::emit<::decltype(::sum<::difference<'F', 'A'>, ::difference<'C', 'A'>>)>::commit; +::emit<::decltype(::product<::difference<'D', 'A'>, ::difference<'E', 'A'>>)>::commit; +::emit<::decltype(::quotient<::difference<'H', 'A'>, ::difference<'C', 'A'>>)>::commit; @@ -36,6 +36,9 @@ static int fail(const char* message) "commit" return TOK_COMMIT; "decltype" return TOK_DECLTYPE; "difference" return TOK_DIFFERENCE; +"sum" return TOK_SUM; +"product" return TOK_PRODUCT; +"quotient" return TOK_QUOTIENT; [<>(),;] return yytext[0]; '\\.' yylval.character = unescape(yytext[2]); return TOK_CHAR; '.' yylval.character = yytext[1]; return TOK_CHAR; @@ -20,6 +20,9 @@ void yyerror(const char* message); %token TOK_COMMIT %token TOK_DECLTYPE %token TOK_DIFFERENCE +%token TOK_SUM +%token TOK_PRODUCT +%token TOK_QUOTIENT %token <character> TOK_CHAR %type <node> statements statement type value @@ -51,6 +54,12 @@ type value : TOK_COLONCOLON TOK_DIFFERENCE '<' TOK_CHAR ',' TOK_CHAR '>' { $$ = node_binary(VALUE_DIFFERENCE, node_char($4), node_char($6)); } + | TOK_COLONCOLON TOK_SUM '<' value ',' value '>' + { $$ = node_binary(VALUE_SUM, $4, $6); } + | TOK_COLONCOLON TOK_PRODUCT '<' value ',' value '>' + { $$ = node_binary(VALUE_PRODUCT, $4, $6); } + | TOK_COLONCOLON TOK_QUOTIENT '<' value ',' value '>' + { $$ = node_binary(VALUE_QUOTIENT, $4, $6); } ; %% |
