nooc

nooc programming language compiler
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit f7ab34cdcb02decea9fd1ce473506b001386af5d
parent 2927ef3df25f495a4c4c30c6764c02c10fc98780
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Thu, 30 Dec 2021 19:56:04 -0600

move typecheck into type.c

Diffstat:
Mmain.c | 68--------------------------------------------------------------------
Mtype.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtype.h | 1+
3 files changed, 72 insertions(+), 68 deletions(-)

diff --git a/main.c b/main.c @@ -264,74 +264,6 @@ place_move(char *buf, struct place *dest, struct place *src) return total; } -void -typecheck(struct block *block) -{ - for (size_t i = 0; i < block->len; i++) { - struct item *item = &block->data[i]; - struct expr *expr; - struct decl *decl; - struct type *type; - struct assgn *assgn; - size_t line, col; - switch (block->data[i].kind) { - case ITEM_ASSGN: - assgn = &assgns.data[item->idx]; - decl = finddecl(assgn->s); - if (decl == NULL) - error(assgn->start->line, assgn->start->col, "typecheck: unknown name '%.*s'", assgn->s.len, assgn->s.data); - - type = &types.data[decl->type]; - expr = &exprs.data[assgn->val]; - line = assgn->start->line; - col = assgn->start->col; - goto check; - case ITEM_DECL: - // FIXME: typecheck procedure parameters - decl = &block->decls.data[item->idx]; - type = &types.data[decl->type]; - expr = &exprs.data[decl->val]; - line = decl->start->line; - col = decl->start->col; -check: - switch (type->class) { - case TYPE_INT: - if (expr->class != C_INT) - error(line, col, "expected integer expression for integer declaration"); - break; - case TYPE_ARRAY: - if (expr->class != C_STR) - error(line, col, "expected string expression for array declaration"); - break; - case TYPE_REF: - if (expr->class != C_REF) - error(line, col, "expected reference expression for reference declaration"); - break; - case TYPE_PROC: - if (expr->class != C_PROC) - error(line, col, "expected proc expression for proc declaration"); - - if (expr->d.proc.in.len != type->d.params.in.len) - error(line, col, "procedure expression takes %u parameters, but declaration has type which takes %u", expr->d.proc.in.len, type->d.params.in.len); - - for (size_t j = 0; j < expr->d.proc.in.len; j++) { - if (expr->d.proc.in.data[j].type != type->d.params.in.data[j]) - error(line, col, "unexpected type for parameter %u in procedure declaration", j); - } - break; - default: - error(line, col, "unknown decl type"); - } - break; - case ITEM_EXPR: - case ITEM_RETURN: - break; - default: - error(item->start->line, item->start->col, "unknown item type"); - } - } -} - size_t genexpr(char *buf, size_t idx, struct place *place); size_t genproc(char *buf, struct proc *proc); size_t genblock(char *buf, struct block *block, bool toplevel); diff --git a/type.c b/type.c @@ -4,6 +4,7 @@ #include <string.h> #include "nooc.h" +#include "parse.h" #include "util.h" #include "type.h" #include "map.h" @@ -14,6 +15,8 @@ struct types types; extern struct map *typesmap; +extern struct assgns assgns; +extern struct exprs exprs; static struct typetable { size_t cap, count; @@ -159,3 +162,71 @@ type_put(struct type *type) return table.vals[i]; } + +void +typecheck(struct block *block) +{ + for (size_t i = 0; i < block->len; i++) { + struct item *item = &block->data[i]; + struct expr *expr; + struct decl *decl; + struct type *type; + struct assgn *assgn; + size_t line, col; + switch (block->data[i].kind) { + case ITEM_ASSGN: + assgn = &assgns.data[item->idx]; + decl = finddecl(assgn->s); + if (decl == NULL) + error(assgn->start->line, assgn->start->col, "typecheck: unknown name '%.*s'", assgn->s.len, assgn->s.data); + + type = &types.data[decl->type]; + expr = &exprs.data[assgn->val]; + line = assgn->start->line; + col = assgn->start->col; + goto check; + case ITEM_DECL: + // FIXME: typecheck procedure parameters + decl = &block->decls.data[item->idx]; + type = &types.data[decl->type]; + expr = &exprs.data[decl->val]; + line = decl->start->line; + col = decl->start->col; +check: + switch (type->class) { + case TYPE_INT: + if (expr->class != C_INT) + error(line, col, "expected integer expression for integer declaration"); + break; + case TYPE_ARRAY: + if (expr->class != C_STR) + error(line, col, "expected string expression for array declaration"); + break; + case TYPE_REF: + if (expr->class != C_REF) + error(line, col, "expected reference expression for reference declaration"); + break; + case TYPE_PROC: + if (expr->class != C_PROC) + error(line, col, "expected proc expression for proc declaration"); + + if (expr->d.proc.in.len != type->d.params.in.len) + error(line, col, "procedure expression takes %u parameters, but declaration has type which takes %u", expr->d.proc.in.len, type->d.params.in.len); + + for (size_t j = 0; j < expr->d.proc.in.len; j++) { + if (expr->d.proc.in.data[j].type != type->d.params.in.data[j]) + error(line, col, "unexpected type for parameter %u in procedure declaration", j); + } + break; + default: + error(line, col, "unknown decl type"); + } + break; + case ITEM_EXPR: + case ITEM_RETURN: + break; + default: + error(item->start->line, item->start->col, "unknown item type"); + } + } +} diff --git a/type.h b/type.h @@ -1,3 +1,4 @@ size_t type_get(uint8_t hash[16]); size_t type_put(struct type *type); void inittypes(); +void typecheck(struct block *block);