diff options
author | Himbeer <himbeer@disroot.org> | 2024-09-23 15:52:09 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-09-23 15:52:09 +0200 |
commit | c9a22c04a32f3db2b0c2a70febfafcefa26f6f2a (patch) | |
tree | b71b44f1aeb3e72a12a5ecfffb7c5e3d67468200 | |
parent | f7969e4a66b8a2b81405923a2a4fe19ba6095cb7 (diff) |
Implement expressions
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | include/expr.h | 197 | ||||
-rw-r--r-- | include/parse.h | 14 | ||||
-rw-r--r-- | src/parse.c | 18 |
4 files changed, 213 insertions, 17 deletions
@@ -2,6 +2,7 @@ BINOUT = .bin HDR = \ + include/expr.h \ include/lex.h \ include/parse.h \ include/type.h \ diff --git a/include/expr.h b/include/expr.h new file mode 100644 index 0000000..93b9204 --- /dev/null +++ b/include/expr.h @@ -0,0 +1,197 @@ +#ifndef CERC_EXPR_H +#define CERC_EXPR_H +#include <stdbool.h> +#include "lex.h" +#include "type.h" + +struct grouping_e { + struct disjunction_e *inner; +}; + +struct number_e { + struct number value; + struct type type; +}; + +struct array_e { + struct cer_array meta; + struct disjunction_e *elems; + int elemsz, elemlen; +}; + +enum literal { + LIT_BOOL, + LIT_STRING, + LIT_NUMBER, + LIT_ARRAY, +}; + +struct literal_e { + enum literal kind; + union { + bool b; + const char *str; + struct number_e num; + struct array_e arr; + } lit; +}; + +struct path { + const char **segments; + int segsz, seglen; +}; + +struct call_e { + struct path path; + struct disjunction_e *args; + int argsz, arglen; +}; + +enum primary { + PRM_GROUPING, + PRM_LITERAL, + PRM_CALL, + PRM_PATH, +}; + +struct primary_e { + enum primary kind; + union { + struct grouping_e grp; + struct literal_e lit; + struct call_e call; + struct path path; + } prim; +}; + +enum unary_postfix { + UPS_DEREF, + UPS_TRY, + UPS_ASSERT, +}; + +struct unarypost_e { + enum unary_postfix op; + struct primary_e prim; +}; + +enum unary_prefix { + UPR_NUMNEG, + UPR_BOOLNEG, + UPR_BITNEG, +}; + +struct unarypre_e { + enum unary_prefix op; + struct unarypost_e post; +}; + +struct bitfactor_e { + struct unarypre_e lhs, *rhs; + int rhssz, rhslen; +}; + +struct bitsummand_e { + struct bitfactor_e lhs, *rhs; + int rhssz, rhslen; +}; + +struct bin_e { + struct bitsummand_e lhs, *rhs; + int rhssz, rhslen; +}; + +enum factor { + FCT_MUL, + FCT_DIV, + FCT_REM, +}; + +struct factor_rhs { + enum factor factor; + struct bin_e bin; +}; + +struct factor_e { + struct bin_e lhs; + struct factor_rhs *rhs; + int rhssz, rhslen; +}; + +enum numeral { + NUM_ADD, + NUM_SUB, +}; + +struct num_rhs { + enum numeral num; + struct factor_e factor; +}; + +struct num_e { + struct factor_e lhs; + struct num_rhs *rhs; + int rhssz, rhslen; +}; + +enum term { + TRM_NUM, + TRM_SHL, + TRM_SHR, +}; + +struct term_e { + enum term term; + struct num_e lhs, rhs; +}; + +enum comparison { + CMP_LT, + CMP_LE, + CMP_GT, + CMP_GE, +}; + +struct cmp_rhs { + enum comparison cmp; + struct term_e term; +}; + +struct cmp_e { + struct term_e lhs; + struct cmp_rhs *rhs; + int rhssz, rhslen; +}; + +struct eq_e { + bool invert; + struct cmp_e lhs, rhs; +}; + +enum boolean { + B_EQ, + B_CMP, +}; + +struct bool_e { + enum boolean kind; + union { + struct eq_e eq; + struct cmp_e cmp; + } cond; +}; + +struct conjunction_e { + // At least one required + struct bool_e *bools; + int boolsz, boollen; +}; + +// Entry point +struct disjunction_e { + // At least one required + struct conjunction_e *cons; + int consz, conlen; +}; + +#endif diff --git a/include/parse.h b/include/parse.h index 8cc4985..de30f39 100644 --- a/include/parse.h +++ b/include/parse.h @@ -1,7 +1,10 @@ #ifndef CERC_PARSE_H #define CERC_PARSE_H -#include "lex.h" -#include "type.h" +#include "expr.h" + +struct ast_expr { + struct disjunction_e dis; +}; struct ast_externfunc { const char *name; @@ -47,13 +50,8 @@ struct ast_const_global { } value; }; -struct ast_path { - const char **segments; - int len, cap; -}; - struct ast_import { - struct ast_path path; + struct path path; const char *name; }; diff --git a/src/parse.c b/src/parse.c index 2fa3ee4..ef4f4dc 100644 --- a/src/parse.c +++ b/src/parse.c @@ -19,19 +19,19 @@ error(struct location loc, const char *fmt, ...) } static void -append(struct ast_path *path, const char *name) +append(struct path *path, const char *name) { - if (path->len >= path->cap) { - path->cap *= 2; - size_t sz = sizeof(const char *) * path->cap; + if (path->seglen >= path->segsz) { + path->segsz *= 2; + size_t sz = sizeof(const char *) * path->segsz; path->segments = must_realloc(path->segments, sz); } - path->segments[path->len++] = name; + path->segments[path->seglen++] = name; } static bool -parse_path(struct lexer *lexer, struct ast_path *out) +parse_path(struct lexer *lexer, struct path *out) { struct token name; @@ -41,8 +41,8 @@ parse_path(struct lexer *lexer, struct ast_path *out) out->segments = must_calloc(1, sizeof(const char *)); out->segments[0] = name.info.str; - out->len = 1; - out->cap = 1; + out->seglen = 1; + out->segsz = 1; while (match(lexer, T_MODDELIM)) { if (lex(lexer, &name) != T_NAME) { @@ -70,7 +70,7 @@ parse_import(struct lexer *lexer, struct ast_import *out) out->name = token.info.str; } else { unlex(lexer, &token); - out->name = out->path.segments[out->path.len - 1]; + out->name = out->path.segments[out->path.seglen - 1]; } if (!match(lexer, T_SEMICOLON)) { |