From e38ecde989fe378c49a61d6975784ccfb703cfee Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 30 Nov 2024 14:59:28 -0500 Subject: Explicitly forbid nested optional types --- compile.c | 3 +++ parse.c | 14 ++++++-------- typecheck.c | 4 ++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compile.c b/compile.c index bc035343..674bded3 100644 --- a/compile.c +++ b/compile.c @@ -2520,6 +2520,9 @@ CORD compile(env_t *env, ast_t *ast) type_t *key_t = Match(table_type, TableType)->key_type; type_t *value_t = Match(table_type, TableType)->value_type; + if (value_t->tag == OptionalType) + code_err(ast, "Tables whose values are optional (%T) are not currently supported.", value_t); + for (ast_list_t *entry = table->entries; entry; entry = entry->next) { if (entry->ast->tag == Comprehension) goto table_comprehension; diff --git a/parse.c b/parse.c index eb77c181..37956055 100644 --- a/parse.c +++ b/parse.c @@ -632,10 +632,9 @@ type_ast_t *parse_pointer_type(parse_ctx_t *ctx, const char *pos) { "I couldn't parse a pointer type after this point"); type_ast_t *ptr_type = NewTypeAST(ctx->file, start, pos, PointerTypeAST, .pointed=type, .is_view=is_view); spaces(&pos); - if (match(&pos, "?")) - return NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type=ptr_type); - else - return ptr_type; + while (match(&pos, "?")) + ptr_type = NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type=ptr_type); + return ptr_type; } type_ast_t *parse_type_name(parse_ctx_t *ctx, const char *pos) { @@ -685,10 +684,9 @@ type_ast_t *parse_type(parse_ctx_t *ctx, const char *pos) { if (!type) return NULL; pos = type->end; spaces(&pos); - if (match(&pos, "?")) - return NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type=type); - else - return type; + while (match(&pos, "?")) + type = NewTypeAST(ctx->file, start, pos, OptionalTypeAST, .type=type); + return type; } PARSER(parse_num) { diff --git a/typecheck.c b/typecheck.c index e602c774..82c1f84a 100644 --- a/typecheck.c +++ b/typecheck.c @@ -93,6 +93,8 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) if (!val_type) code_err(val_type_ast, "I can't figure out what type this is."); if (has_view_memory(val_type)) code_err(val_type_ast, "Tables can't have stack references because the array may outlive the stack frame."); + else if (val_type->tag == OptionalType) + code_err(ast, "Tables with optional-typed values are not currently supported"); return Type(TableType, .key_type=key_type, .value_type=val_type); } case FunctionTypeAST: { @@ -118,6 +120,8 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) type_t *t = parse_type_ast(env, opt->type); if (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType) code_err(ast, "Optional %T types are not supported.", t); + else if (t->tag == OptionalType) + code_err(ast, "Nested optional types are not currently supported"); return Type(OptionalType, .type=t); } case UnknownTypeAST: code_err(ast, "I don't know how to get this type"); -- cgit v1.2.3