harec

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

commit b7c6dd96f53181bfca00d127c148f859a6c169c9
parent c7f7d297f83c885d47d0e0cad1b4579b7933a732
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 21 Dec 2020 14:42:37 -0500

check: access expressions

Diffstat:
Minclude/expr.h | 6++++++
Minclude/identifier.h | 6++++--
Msrc/check.c | 21+++++++++++++++++++++
Msrc/identifier.c | 14++++++++++++++
Msrc/scope.c | 12+++++++++++-
5 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/include/expr.h b/include/expr.h @@ -5,6 +5,7 @@ #include "types.h" struct scope; +struct scope_object; enum expr_type { EXPR_ACCESS, @@ -32,6 +33,10 @@ enum expr_type { EXPR_WHILE, }; +struct expression_access { + const struct scope_object *object; +}; + // TODO: Stretchy constants union expression_constant { bool bval; @@ -65,6 +70,7 @@ struct expression { enum expr_type type; bool terminates; union { + struct expression_access access; union expression_constant constant; struct expression_list list; struct expression_return _return; diff --git a/include/identifier.h b/include/identifier.h @@ -1,6 +1,7 @@ #ifndef HARE_IDENTIFIER_H #define HARE_IDENTIFIER_H #include <stddef.h> +#include <stdbool.h> struct identifier { char *name; @@ -8,8 +9,9 @@ struct identifier { }; char *identifier_unparse(const struct identifier *ident); -int identifier_unparse_static(const struct identifier *ident, - char *buf, size_t len); +int identifier_unparse_static( + const struct identifier *ident, char *buf, size_t len); void identifier_dup(struct identifier *new, const struct identifier *ident); +bool identifier_eq(const struct identifier *a, const struct identifier *b); #endif diff --git a/src/check.c b/src/check.c @@ -27,6 +27,7 @@ expect(bool constraint, char *fmt, ...) fprintf(stderr, "Error: "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); + abort(); } } @@ -34,6 +35,24 @@ static void check_expression(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr); static void +check_expr_access(struct context *ctx, + const struct ast_expression *aexpr, + struct expression *expr) +{ + trace(TR_CHECK, "access"); + expr->type = EXPR_ACCESS; + + const struct scope_object *obj = scope_lookup( + ctx->scope, &aexpr->access.ident); + char buf[1024]; + identifier_unparse_static(&aexpr->access.ident, buf, sizeof(buf)); + expect(obj, "Unknown object %s", buf); + + expr->result = obj->type; + expr->access.object = obj; +} + +static void check_expr_constant(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr) @@ -140,6 +159,8 @@ check_expression(struct context *ctx, switch (aexpr->type) { case EXPR_ACCESS: + check_expr_access(ctx, aexpr, expr); + break; case EXPR_ASSERT: case EXPR_ASSIGN: case EXPR_BINARITHM: diff --git a/src/identifier.c b/src/identifier.c @@ -73,3 +73,17 @@ identifier_dup(struct identifier *new, const struct identifier *ident) identifier_dup(new->ns, ident->ns); } } + +bool +identifier_eq(const struct identifier *a, const struct identifier *b) +{ + if (!a && !b) { + return true; + } else if ((!a && b) || (a && !b)) { + return false; + } + if (strcmp(a->name, b->name) != 0) { + return false; + } + return identifier_eq(a->ns, b->ns); +} diff --git a/src/scope.c b/src/scope.c @@ -74,5 +74,15 @@ scope_insert(struct scope *scope, const struct scope_object * scope_lookup(struct scope *scope, const struct identifier *ident) { - assert(0); // TODO + struct scope_object *o = scope->objects; + while (o) { + if (identifier_eq(&o->ident, ident)) { + return o; + } + o = o->next; + } + if (scope->parent) { + return scope_lookup(scope->parent, ident); + } + return NULL; }