Explicitly forbid nested optional types

This commit is contained in:
Bruce Hill 2024-11-30 14:59:28 -05:00
parent 18c1ce7fd1
commit e38ecde989
3 changed files with 13 additions and 8 deletions

View File

@ -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;

14
parse.c
View File

@ -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) {

View File

@ -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");