Skip to content

Commit

Permalink
0.5.2: Allow trailing comma in calls and parameter declarations #1092.…
Browse files Browse the repository at this point in the history
… Fixes issue where single character filenames like 'a.c3' would be rejected. Improve error messages for incorrect user defined foreach. Fix bug with generics in generics.
  • Loading branch information
lerno committed Dec 18, 2023
1 parent 7de5674 commit b41ceb2
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 7 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Fixes issue where single character filenames like 'a.c3' would be rejected.
- Better errors when index type doesn't match len() when doing user defined foreach.
- Fixes to `to_int` for hexadecimal strings.
- Fixed issue when using a generic type from a generic type.

### Stdlib changes
- Allow `to_int` family functions take a base, parsing base 2-10 and 16.
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ Decl *decl_new_with_type(const char *name, SourceSpan loc, DeclKind decl_type)
return decl;
}

const char *decl_safe_name(Decl *decl)
{
if (!decl) return "<no decl>";
if (decl->name) return decl->name;
return decl_to_name(decl);
}
const char *decl_to_name(Decl *decl)
{
const char *name = decl_to_a_name(decl);
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,7 @@ typedef struct Module_
bool is_c_library : 1;
bool is_exported : 1;
bool is_generic : 1;
bool is_from_generic : 1;
bool no_extprefix : 1;
AnalysisStage stage : 6;

Expand Down Expand Up @@ -2163,6 +2164,7 @@ Decl *decl_new_with_type(const char *name, SourceSpan span, DeclKind decl_type);
Decl *decl_new_var(const char *name, SourceSpan span, TypeInfo *type, VarDeclKind kind);
Decl *decl_new_generated_var(Type *type, VarDeclKind kind, SourceSpan span);
void decl_set_external_name(Decl *decl);
const char *decl_safe_name(Decl *decl);
const char *decl_to_name(Decl *decl);
const char *decl_to_a_name(Decl *decl);
int decl_count_elements(Decl *structlike);
Expand Down
24 changes: 18 additions & 6 deletions src/compiler/sema_decls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2789,7 +2789,7 @@ static inline bool sema_analyse_func_macro(SemaContext *context, Decl *decl, Att

static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *erase_decl)
{
DEBUG_LOG("----Analysing function %s", decl->name);
DEBUG_LOG(">>> Analyse function [%s] in %s", decl_safe_name(decl), context->unit->file->full_path);

bool is_interface_method = decl->func_decl.attr_interface_method;
if (!sema_analyse_func_macro(context, decl, is_interface_method ? ATTR_INTERFACE_METHOD : ATTR_FUNC, erase_decl)) return false;
Expand Down Expand Up @@ -2892,7 +2892,7 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *era
if (!sema_analyse_doc_header(decl->func_decl.docs, decl->func_decl.signature.params, NULL, &pure)) return decl_poison(decl);
decl->func_decl.signature.attrs.is_pure = pure;
if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false;
DEBUG_LOG("Function analysis done.");
DEBUG_LOG("<<< Function analysis of [%s] successful.", decl_safe_name(decl));
return true;
}

Expand Down Expand Up @@ -3396,19 +3396,20 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module,
SEMA_ERROR(param, "Expected a value, not a type.");
return NULL;
}
TypeInfo *type_info = param->type_expr;
if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false;
Decl *decl = decl_new_with_type(param_name, params[i]->span, DECL_TYPEDEF);
decl->resolve_status = RESOLVE_DONE;
TypeInfo *type_info = param->type_expr;
assert(type_info->resolve_status == RESOLVE_DONE);
decl->typedef_decl.type_info = type_info;
decl->type->name = decl->name;
decl->type->canonical = type_info->type->canonical;
params_decls[decls++] = decl;
}


Module *new_module = compiler_find_or_create_module(path, NULL);
new_module->is_generic = false;
new_module->is_from_generic = true;
CompilationUnit **units = module->units;
VECEACH(units, i)
{
Expand Down Expand Up @@ -3633,7 +3634,14 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
if (!sema_append_generate_parameterized_name(c, module, params, false)) return poisoned_decl;
if (!instantiated_module) return poisoned_decl;
instantiated_module->generic_suffix = scratch_buffer_copy();
sema_analyze_stage(instantiated_module, c->unit->module->stage - 1);
if (c->unit->module->is_from_generic)
{
sema_analyze_stage(instantiated_module, c->unit->module->stage);
}
else
{
sema_analyze_stage(instantiated_module, c->unit->module->stage - 1);
}
}
if (global_context.errors_found) return poisoned_decl;
Decl *symbol = module_find_symbol(instantiated_module, name);
Expand Down Expand Up @@ -3770,10 +3778,11 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
{
if (decl->resolve_status == RESOLVE_DONE) return decl_ok(decl);

DEBUG_LOG(">>> Analyse declaration [%s] in %s.", decl_safe_name(decl), context_filename(context));

SemaContext temp_context;
context = context_transform_for_eval(context, &temp_context, decl->unit);

DEBUG_LOG(">>> Analysing %s.", decl->name ? decl->name : ".anon");
if (decl->resolve_status == RESOLVE_RUNNING)
{
SEMA_ERROR(decl, decl->name
Expand Down Expand Up @@ -3859,9 +3868,12 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
decl->resolve_status = RESOLVE_DONE;
sema_context_destroy(&temp_context);

DEBUG_LOG("<<< Analysis of [%s] successful.", decl_safe_name(decl));

return true;
FAILED:
sema_context_destroy(&temp_context);
DEBUG_LOG("<<< Analysis of [%s] failed.", decl_safe_name(decl));
return decl_poison(decl);
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2547,7 +2547,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
Type *underlying_type = type_flatten(subscripted->type);

Type *current_type = underlying_type;

assert(current_type == current_type->canonical);
int64_t index_value = -1;
bool start_from_end = expr->subscript_expr.range.start_from_end;
if (start_from_end && (underlying_type->type_kind == TYPE_POINTER || underlying_type->type_kind == TYPE_FLEXIBLE_ARRAY))
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/sema_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ extern const char *ct_eval_error;
Decl **global_context_acquire_locals_list(void);
void generic_context_release_locals_list(Decl **);

const char *context_filename(SemaContext *context);

AstId context_get_defers(SemaContext *context, AstId defer_top, AstId defer_bottom, bool is_success);
void context_pop_defers(SemaContext *context, AstId *next);
void context_pop_defers_and_replace_ast(SemaContext *context, Ast *ast);
Expand Down
9 changes: 9 additions & 0 deletions src/compiler/semantic_analyser.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags)
}
}

const char *context_filename(SemaContext *context)
{
CompilationUnit *unit = context->unit;
if (!unit) return "<unknown unit>";
File *file = unit->file;
if (!file || !file->full_path) return "<unknown file>";
return file->full_path;
}

void context_change_scope_for_label(SemaContext *context, DeclId label_id)
{
context_change_scope_with_flags(context, SCOPE_NONE);
Expand Down

0 comments on commit b41ceb2

Please sign in to comment.