harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4db3a7129372f4a13421fb70c50fa244b3a1813e
parent 04988d5245f29f669d7f4909e00ecd07d8957ebc
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 26 Dec 2020 10:37:21 -0500

Initial riggings for eval

Diffstat:
Mconfigure | 1+
Minclude/check.h | 5+++++
Ainclude/eval.h | 25+++++++++++++++++++++++++
Minclude/expr.h | 1-
Minclude/type_store.h | 3+++
Msrc/check.c | 6+++---
Asrc/eval.c | 39+++++++++++++++++++++++++++++++++++++++
Msrc/gen.c | 1-
Msrc/type_store.c | 4+++-
9 files changed, 79 insertions(+), 6 deletions(-)

diff --git a/configure b/configure @@ -6,6 +6,7 @@ harec() { genrules harec \ src/check.c \ src/emit.c \ + src/eval.c \ src/gen.c \ src/identifier.c \ src/lex.c \ diff --git a/include/check.h b/include/check.h @@ -4,6 +4,7 @@ #include "identifier.h" #include "types.h" +struct context; struct expression; struct scope; @@ -47,8 +48,12 @@ struct unit { struct declarations *declarations; }; +struct ast_expression; struct ast_unit; void check(const struct ast_unit *aunit, struct unit *unit); +void check_expression(struct context *ctx, + const struct ast_expression *aexpr, struct expression *expr); + #endif diff --git a/include/eval.h b/include/eval.h @@ -0,0 +1,25 @@ +#ifndef HAREC_EVAL_H +#define HAREC_EVAL_H +#include <stdbool.h> + +struct expression; +struct context; + +enum eval_result { + // Evaluation succeeded. + EVAL_OK, + + // Insufficient context, such as references to unknown types or + // objects. Defer this expression until later and re-try when more of + // the type & object graph are populated. + EVAL_NEED_CONTEXT, + + // This expression cannot be evaluated at compile time (user error). + EVAL_INVALID, +}; + +// Evaluates an expression at compile time. +enum eval_result eval_expr(struct context *ctx, + struct expression *in, struct expression *out); + +#endif diff --git a/include/expr.h b/include/expr.h @@ -19,7 +19,6 @@ enum expr_type { EXPR_CONSTANT, EXPR_CONTINUE, EXPR_FOR, - EXPR_FREE, EXPR_IF, EXPR_LIST, EXPR_MATCH, diff --git a/include/type_store.h b/include/type_store.h @@ -10,8 +10,11 @@ struct type_bucket { struct type_bucket *next; }; +struct context; + struct type_store { struct type_bucket *buckets[TYPE_STORE_BUCKETS]; + struct context *check_context; }; bool type_is_assignable(struct type_store *store, diff --git a/src/check.c b/src/check.c @@ -33,7 +33,7 @@ expect(bool constraint, char *fmt, ...) } } -static void check_expression(struct context *ctx, +void check_expression(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr); static void @@ -425,7 +425,7 @@ check_expr_unarithm(struct context *ctx, trleave(TR_CHECK, NULL); } -static void +void check_expression(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr) @@ -459,7 +459,6 @@ check_expression(struct context *ctx, break; case EXPR_CONTINUE: case EXPR_FOR: - case EXPR_FREE: case EXPR_IF: assert(0); // TODO case EXPR_LIST: @@ -635,6 +634,7 @@ void check(const struct ast_unit *aunit, struct unit *unit) { struct context ctx = {0}; + ctx.store.check_context = &ctx; // Top-level scope management involves: // diff --git a/src/eval.c b/src/eval.c @@ -0,0 +1,39 @@ +#include <assert.h> +#include <stdbool.h> +#include "eval.h" +#include "expr.h" +#include "scope.h" +#include "type_store.h" +#include "types.h" + +enum eval_result +eval_expr(struct context *ctx, struct expression *in, struct expression *out) +{ + switch (in->type) { + case EXPR_ACCESS: + case EXPR_BINARITHM: + case EXPR_CAST: + case EXPR_CONSTANT: + case EXPR_CONTINUE: + case EXPR_FOR: + case EXPR_MEASURE: + case EXPR_SLICE: + case EXPR_STRUCT: + case EXPR_UNARITHM: + assert(0); // TODO + case EXPR_ASSERT: + case EXPR_ASSIGN: + case EXPR_BINDING: + case EXPR_BREAK: + case EXPR_CALL: + case EXPR_IF: + case EXPR_LIST: + case EXPR_MATCH: + case EXPR_RETURN: + case EXPR_SWITCH: + case EXPR_WHILE: + // Excluded from translation-compatible subset + return EVAL_INVALID; + } + assert(0); // Unreachable +} diff --git a/src/gen.c b/src/gen.c @@ -519,7 +519,6 @@ gen_expression(struct gen_context *ctx, break; case EXPR_CONTINUE: case EXPR_FOR: - case EXPR_FREE: case EXPR_IF: assert(0); // TODO case EXPR_LIST: diff --git a/src/type_store.c b/src/type_store.c @@ -1,8 +1,8 @@ #include <assert.h> #include <stdlib.h> +#include "check.h" #include "type_store.h" #include "util.h" -#include <stdio.h> bool type_is_assignable(struct type_store *store, @@ -177,6 +177,7 @@ atype_hash(struct type_store *store, const struct ast_type *type) break; // built-ins case TYPE_STORAGE_ALIAS: case TYPE_STORAGE_ARRAY: + assert(0); // TODO case TYPE_STORAGE_FUNCTION: hash = djb2(hash, atype_hash(store, type->func.result)); hash = djb2(hash, type->func.variadism); @@ -231,6 +232,7 @@ type_hash(struct type_store *store, const struct type *type) break; // built-ins case TYPE_STORAGE_ALIAS: case TYPE_STORAGE_ARRAY: + assert(0); // TODO case TYPE_STORAGE_FUNCTION: hash = djb2(hash, type_hash(store, type->func.result)); hash = djb2(hash, type->func.variadism);