From a986dfc17093ae5b7a33a8fffecd2cabf49deee3 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 1 Aug 2026 22:00:18 +0300 Subject: add builtin type checking + Rather terrible error messages, should be improved at some point, but seems to work for now --- src/fwdscript.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/src/fwdscript.c b/src/fwdscript.c index 215f782..6b47ca0 100644 --- a/src/fwdscript.c +++ b/src/fwdscript.c @@ -226,7 +226,40 @@ static int fwdscript_get(struct fwdscript *s, struct fwdvals *args) static int fwdscript_get_typecheck(struct fwdscript *s, struct fwdtypes *types) { - TODO(); + (void)s; + size_t l = fwdtypes_len(types); + if (l != 4) { + /** @todo better error messages? */ + fprintf(stderr, "expected 4 args, got %zu\n", l); + return -1; + } + + enum fwdtype table = *fwdtypes_at(types, 0); + /* index can be whatever but would look something like */ + //enum fwdtype index = fwdtypes_at(types, 1); + enum fwdtype err = *fwdtypes_at(types, 2); + enum fwdtype ok = *fwdtypes_at(types, 3); + + if (table != FWDSCRIPT_TBL) { + fprintf(stderr, "expected /tbl, got %s\n", + fwdtype_str(table)); + return -1; + } + + if (err != FWDSCRIPT_CNT) { + fprintf(stderr, "expected /cnt, got %s\n", + fwdtype_str(err)); + return -1; + } + + if (ok != FWDSCRIPT_CNT) { + fprintf(stderr, "expected /cnt, got %s\n", + fwdtype_str(ok)); + return -1; + } + + /* check cnt args at runtime */ + return 0; } static int fwdscript_abort(struct fwdscript *s, struct fwdvals *args) @@ -236,7 +269,24 @@ static int fwdscript_abort(struct fwdscript *s, struct fwdvals *args) static int fwdscript_abort_typecheck(struct fwdscript *s, struct fwdtypes *types) { - TODO(); + (void)s; + + /* I guess we could also accept anything that's convertible to string, + * so I guess number for now? */ + size_t l = fwdtypes_len(types); + if (l != 1) { + fprintf(stderr, "expected 1 arg, got %zu\n", l); + return -1; + } + + enum fwdtype msg = *fwdtypes_at(types, 0); + if (msg != FWDSCRIPT_STR) { + fprintf(stderr, "expected /str, got %s\n", + fwdtype_str(msg)); + return -1; + } + + return 0; } static int fwdscript_print(struct fwdscript *s, struct fwdvals *args) @@ -246,7 +296,17 @@ static int fwdscript_print(struct fwdscript *s, struct fwdvals *args) static int fwdscript_print_typecheck(struct fwdscript *s, struct fwdtypes *args) { - TODO(); + (void)s; + + /* we take any number of args as long as they're printable */ + foreach(fwdtypes, type, args) { + if (*type != FWDSCRIPT_STR && *type != FWDSCRIPT_NUM) { + fprintf(stderr, "arg not printable\n"); + return -1; + } + } + + return 0; } static int fwdscript_register_builtins(struct fwdscript *s) @@ -539,19 +599,13 @@ struct fwdast { }; - union { - /* node type and status */ - struct { - bool moved; - enum fwdtype t; - }; + /* node type and status */ + bool moved; + enum fwdtype t; - /* cmd args and cnt params */ - struct { - size_t argc; - struct fwdast *args; - }; - }; + /* cmd args and cnt params */ + size_t argc; + struct fwdast *args; size_t bodyc; struct fwdast *body; @@ -584,6 +638,7 @@ static void free_ast(struct fwdast *ast) break; case FWDAST_CMD: + free(ast->s); free_asts(&args); break; @@ -594,6 +649,7 @@ static void free_ast(struct fwdast *ast) break; case FWDAST_CNT: + free(ast->s); free_asts(&args); free_asts(&body); break; @@ -995,7 +1051,7 @@ static void fwdscript_debug_tokens(struct fwdtokens *tokens) break; case FWDTOKEN_NUM: - fprintf(stderr, "line %4zu: %s (%f)\n", + fprintf(stderr, "line %4zu: %s (%g)\n", tok->line, fwdtoken_kind_str(tok->kind), tok->d); @@ -1064,7 +1120,7 @@ static void fwdscript_debug_ast(struct fwdast *ast, int depth) break; case FWDAST_NUM: - fprintf(stderr, "%*s+ num (%f)\n", depth, "|", + fprintf(stderr, "%*s+ num (%g)\n", depth, "|", ast->d); break; @@ -1442,6 +1498,10 @@ static int fwdscript_parse(struct fwdscript *s, const char *buf) return -1; } + /** @todo this means that the global ctx in s will be illegal to + * reference after this point, which is presumably not ideal if we want + * to support modules. Will have to think of something better. */ + free_ast(&top); return 0; } @@ -1455,6 +1515,8 @@ static void fwdscript_destroy(struct fwdscript *s) foreach(fwdbuiltins, builtin, &s->builtins) { free(builtin.t->key); } + + fwdctx_destroy(&s->ctx); fwdinsns_destroy(&s->insns); fwdbuiltins_destroy(&s->builtins); } -- cgit v1.3