@@ -335,6 +335,7 @@ struct FastcEnumInfo {
335335struct FastcTypeDeclarations {
336336 declarations string
337337 enum_string_helpers string
338+ alias_base_types map [string ]string
338339}
339340
340341struct FastcLoopBlockResult {
@@ -349,6 +350,7 @@ struct Parser {
349350 imports map [string ]string
350351 declared_types map [string ]bool
351352 declared_kinds map [string ]FastcDeclaredTypeKind
353+ alias_base_types map [string ]string
352354 struct_fields map [string ]map [string ]string
353355 struct_field_info map [string ][]FastcStructField
354356 constants map [string ]string
381383 current_receiver string
382384 expected_expression_type string
383385 capturing_defer bool
386+ defer_depth int
384387 captured_defer_lines []string
385388 deferred_lines []string
386389 deferred_block_starts []int
@@ -465,15 +468,15 @@ fn generate_source_files(sources []FastcSourceFile, prefs &pref.Preferences) !st
465468 type_declarations := type_output.declarations
466469 mut constant_types := map [string ]string {}
467470 mut global_types := map [string ]string {}
468- fastc_render_struct_field_defaults (prefs, declared_types, declared_kinds, struct_fields, mut
469- struct_field_info, functions, constants, public_constants, constant_types, globals ,
470- public_globals, global_types)!
471+ fastc_render_struct_field_defaults (prefs, declared_types, declared_kinds,
472+ type_output.alias_base_types, struct_fields, mut struct_field_info, functions, constants ,
473+ public_constants, constant_types, globals, public_globals, global_types)!
471474 constant_output := fastc_generate_constant_declarations (sources, prefs, declared_types,
472- declared_kinds, struct_fields, struct_field_info, functions, constants, public_constants ,
473- globals, public_globals, mut constant_types)!
475+ declared_kinds, type_output.alias_base_types, struct_fields, struct_field_info, functions,
476+ constants, public_constants, globals, public_globals, mut constant_types)!
474477 global_output := fastc_generate_global_declarations (sources, prefs, declared_types,
475- declared_kinds, struct_fields, struct_field_info, functions, constants, public_constants ,
476- constant_types, globals, public_globals, mut global_types)!
478+ declared_kinds, type_output.alias_base_types, struct_fields, struct_field_info, functions,
479+ constants, public_constants, constant_types, globals, public_globals, mut global_types)!
477480 for constant_type in constant_types.values () {
478481 fastc_register_composite_type (constant_type, mut composite_types)
479482 }
@@ -496,6 +499,7 @@ fn generate_source_files(sources []FastcSourceFile, prefs &pref.Preferences) !st
496499 imports: source_file.header.imports
497500 declared_types: declared_types
498501 declared_kinds: declared_kinds
502+ alias_base_types: type_output.alias_base_types
499503 struct_fields: struct_fields
500504 struct_field_info: struct_field_info
501505 constants: constants
@@ -1264,7 +1268,7 @@ fn fastc_register_global(header FastcSourceHeader, name string, is_public bool,
12641268 }
12651269}
12661270
1267- fn fastc_generate_global_declarations (sources []FastcSourceFile, prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, struct_fields map [string ]map [string ]string , struct_field_info map [string ][]FastcStructField, functions map [string ]FastcFunctionSignature, constants map [string ]string , public_constants map [string ]bool , constant_types map [string ]string , globals map [string ]string , public_globals map [string ]bool , mut global_types map [string ]string ) ! FastcGlobalDeclarations {
1271+ fn fastc_generate_global_declarations (sources []FastcSourceFile, prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, alias_base_types map [ string ] string , struct_fields map [string ]map [string ]string , struct_field_info map [string ][]FastcStructField, functions map [string ]FastcFunctionSignature, constants map [string ]string , public_constants map [string ]bool , constant_types map [string ]string , globals map [string ]string , public_globals map [string ]bool , mut global_types map [string ]string ) ! FastcGlobalDeclarations {
12681272 mut out := strings.new_builder (1024 )
12691273 mut module_initializers := map [string ]string {}
12701274 ordered_sources := fastc_sources_in_dependency_order (sources)!
@@ -1280,6 +1284,7 @@ fn fastc_generate_global_declarations(sources []FastcSourceFile, prefs &pref.Pre
12801284 imports: source_file.header.imports
12811285 declared_types: declared_types
12821286 declared_kinds: declared_kinds
1287+ alias_base_types: alias_base_types
12831288 struct_fields: struct_fields
12841289 struct_field_info: struct_field_info
12851290 constants: constants
@@ -1385,7 +1390,7 @@ fn (mut g Parser) parse_global_declaration(mut out strings.Builder, mut initiali
13851390 g.skip_semicolons ()
13861391}
13871392
1388- fn fastc_render_struct_field_defaults (prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, struct_fields map [string ]map [string ]string , mut struct_field_info map [string ][]FastcStructField, functions map [string ]FastcFunctionSignature, constants map [string ]string , public_constants map [string ]bool , constant_types map [string ]string , globals map [string ]string , public_globals map [string ]bool , global_types map [string ]string ) ! {
1393+ fn fastc_render_struct_field_defaults (prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, alias_base_types map [ string ] string , struct_fields map [string ]map [string ]string , mut struct_field_info map [string ][]FastcStructField, functions map [string ]FastcFunctionSignature, constants map [string ]string , public_constants map [string ]bool , constant_types map [string ]string , globals map [string ]string , public_globals map [string ]bool , global_types map [string ]string ) ! {
13891394 mut type_names := struct_field_info.keys ()
13901395 type_names.sort ()
13911396 for type_name in type_names {
@@ -1405,6 +1410,7 @@ fn fastc_render_struct_field_defaults(prefs &pref.Preferences, declared_types ma
14051410 imports: field.imports
14061411 declared_types: declared_types
14071412 declared_kinds: declared_kinds
1413+ alias_base_types: alias_base_types
14081414 struct_fields: struct_fields
14091415 struct_field_info: struct_field_info
14101416 constants: constants
@@ -1445,7 +1451,7 @@ fn fastc_render_struct_field_defaults(prefs &pref.Preferences, declared_types ma
14451451 }
14461452}
14471453
1448- fn fastc_generate_constant_declarations (sources []FastcSourceFile, prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, struct_fields map [string ]map [string ]string , struct_field_info map [string ][]FastcStructField, functions map [string ]FastcFunctionSignature, constants map [string ]string , public_constants map [string ]bool , globals map [string ]string , public_globals map [string ]bool , mut constant_types map [string ]string ) ! FastcConstantDeclarations {
1454+ fn fastc_generate_constant_declarations (sources []FastcSourceFile, prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, alias_base_types map [ string ] string , struct_fields map [string ]map [string ]string , struct_field_info map [string ][]FastcStructField, functions map [string ]FastcFunctionSignature, constants map [string ]string , public_constants map [string ]bool , globals map [string ]string , public_globals map [string ]bool , mut constant_types map [string ]string ) ! FastcConstantDeclarations {
14491455 mut values := []FastcConstantValue{}
14501456 ordered_sources := fastc_sources_in_dependency_order (sources)!
14511457 for source_file in ordered_sources {
@@ -1459,6 +1465,7 @@ fn fastc_generate_constant_declarations(sources []FastcSourceFile, prefs &pref.P
14591465 imports: source_file.header.imports
14601466 declared_types: declared_types
14611467 declared_kinds: declared_kinds
1468+ alias_base_types: alias_base_types
14621469 struct_fields: struct_fields
14631470 struct_field_info: struct_field_info
14641471 constants: constants
@@ -1689,6 +1696,7 @@ fn fastc_generate_type_declarations(sources []FastcSourceFile, prefs &pref.Prefe
16891696 mut out := strings.new_builder (4096 )
16901697 mut bodies := strings.new_builder (4096 )
16911698 mut enum_infos := []FastcEnumInfo{}
1699+ mut alias_base_types := map [string ]string {}
16921700 mut keys := declared_kinds.keys ()
16931701 keys.sort ()
16941702 for type_id, key in keys {
@@ -1705,7 +1713,7 @@ fn fastc_generate_type_declarations(sources []FastcSourceFile, prefs &pref.Prefe
17051713 for source_file in sources {
17061714 fastc_emit_source_type_declarations (source_file, prefs, declared_types, declared_kinds,
17071715 constants, public_constants, mut struct_fields, mut struct_field_info, mut
1708- composite_types, mut enum_infos, mut bodies)!
1716+ composite_types, mut alias_base_types, mut enum_infos, mut bodies)!
17091717 }
17101718 mut composite_names := composite_types.keys ()
17111719 composite_names.sort ()
@@ -1727,6 +1735,7 @@ fn fastc_generate_type_declarations(sources []FastcSourceFile, prefs &pref.Prefe
17271735 } else {
17281736 ''
17291737 }
1738+ alias_base_types: alias_base_types
17301739 }
17311740}
17321741
@@ -1808,7 +1817,7 @@ fn fastc_c_composite_definition_end(source string, start int) ?int {
18081817 return none
18091818}
18101819
1811- fn fastc_emit_source_type_declarations (source_file FastcSourceFile, prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, constants map [string ]string , public_constants map [string ]bool , mut struct_fields map [string ]map [string ]string , mut struct_field_info map [string ][]FastcStructField, mut composite_types map [string ]bool , mut enum_infos []FastcEnumInfo, mut out strings.Builder) ! {
1820+ fn fastc_emit_source_type_declarations (source_file FastcSourceFile, prefs & pref.Preferences, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, constants map [string ]string , public_constants map [string ]bool , mut struct_fields map [string ]map [string ]string , mut struct_field_info map [string ][]FastcStructField, mut composite_types map [string ]bool , mut alias_base_types map [ string ] string , mut enum_infos []FastcEnumInfo, mut out strings.Builder) ! {
18121821 mut file_set := token.FileSet.new ()
18131822 mut file := file_set.add_file (source_file.path, source_file.source.len)
18141823 file.index_lines (source_file.source)
@@ -1831,7 +1840,8 @@ fn fastc_emit_source_type_declarations(source_file FastcSourceFile, prefs &pref.
18311840 }
18321841 fastc_emit_source_type_declarations (selected_source, prefs, declared_types,
18331842 declared_kinds, constants, public_constants, mut struct_fields, mut
1834- struct_field_info, mut composite_types, mut enum_infos, mut out)!
1843+ struct_field_info, mut composite_types, mut alias_base_types, mut
1844+ enum_infos, mut out)!
18351845 }
18361846 tok = selected.tok
18371847 next_enum_is_flag = false
@@ -1860,7 +1870,8 @@ fn fastc_emit_source_type_declarations(source_file FastcSourceFile, prefs &pref.
18601870 }
18611871 if depth == 0 && tok == .key_type {
18621872 tok = fastc_emit_alias_declaration (mut scan, source_file, declared_types,
1863- declared_kinds, prefs.building_v, mut struct_fields, mut struct_field_info, mut out)!
1873+ declared_kinds, prefs.building_v, mut struct_fields, mut struct_field_info, mut
1874+ alias_base_types, mut out)!
18641875 continue
18651876 }
18661877 if tok == .lcbr {
@@ -2425,7 +2436,7 @@ fn fastc_emit_interface_declaration(mut scan scanner.Scanner, source_file FastcS
24252436 return tok
24262437}
24272438
2428- fn fastc_emit_alias_declaration (mut scan scanner.Scanner, source_file FastcSourceFile, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, allow_short_placeholders bool , mut struct_fields map [string ]map [string ]string , mut struct_field_info map [string ][]FastcStructField, mut out strings.Builder) ! token.Token {
2439+ fn fastc_emit_alias_declaration (mut scan scanner.Scanner, source_file FastcSourceFile, declared_types map [string ]bool , declared_kinds map [string ]FastcDeclaredTypeKind, allow_short_placeholders bool , mut struct_fields map [string ]map [string ]string , mut struct_field_info map [string ][]FastcStructField, mut alias_base_types map [ string ] string , mut out strings.Builder) ! token.Token {
24292440 mut tok := scan.scan ()
24302441 if tok != .name {
24312442 return error ('fastc parser does not support type alias in ${source_file .path }' )
@@ -2456,6 +2467,7 @@ fn fastc_emit_alias_declaration(mut scan scanner.Scanner, source_file FastcSourc
24562467 out.writeln ('typedef struct { void *_object; u32 _typ; } ${c_name };' )
24572468 } else if fastc_primitive_c_type (name) == none && declared_kinds[key] == .alias_ {
24582469 out.writeln ('typedef ${base } ${c_name };' )
2470+ alias_base_types[c_name] = base
24592471 mut layout_type := base.trim_right ('*' )
24602472 if layout_type.starts_with ('Array_' ) {
24612473 layout_type = 'array'
@@ -4580,6 +4592,23 @@ fn (mut g Parser) parse_block_body() !bool {
45804592}
45814593
45824594fn (mut g Parser) parse_statement () ! bool {
4595+ if g.defer_depth > 0 {
4596+ match g.tok {
4597+ .key_return {
4598+ return g.unsupported ('`return` not allowed inside a `defer` block' )
4599+ }
4600+ .key_break, .key_continue {
4601+ return g.unsupported ('`${g .tok .str ()}` is not allowed in defer statements' )
4602+ }
4603+ .key_goto {
4604+ return g.unsupported ('goto is not allowed in defer statements' )
4605+ }
4606+ .key_defer {
4607+ return g.unsupported ('`defer` blocks cannot be nested' )
4608+ }
4609+ else {}
4610+ }
4611+ }
45834612 return match g.tok {
45844613 .dollar {
45854614 g.parse_comptime_if_statement ()!
@@ -4691,9 +4720,11 @@ fn (mut g Parser) parse_defer() ! {
46914720 previous_capture := g.capturing_defer
46924721 previous_lines := g.captured_defer_lines.clone ()
46934722 g.capturing_defer = true
4723+ g.defer_depth++
46944724 g.captured_defer_lines = []string {}
46954725 _ = g.parse_block_body ()!
46964726 block := g.captured_defer_lines.clone ()
4727+ g.defer_depth--
46974728 g.capturing_defer = previous_capture
46984729 g.captured_defer_lines = previous_lines.clone ()
46994730 g.deferred_block_starts << g.deferred_lines.len
@@ -9245,7 +9276,8 @@ fn (g &Parser) render_string_comparison_expression(tokens []FastcExpressionToken
92459276 right_tokens := tokens[i + 1 ..]
92469277 left_type := g.infer_expression_type (left_tokens) or { return none }
92479278 right_type := g.infer_expression_type (right_tokens) or { return none }
9248- if left_type.trim_right ('*' ) != 'string' || right_type.trim_right ('*' ) != 'string' {
9279+ if g.underlying_alias_type (left_type).trim_right ('*' ) != 'string'
9280+ || g.underlying_alias_type (right_type).trim_right ('*' ) != 'string' {
92499281 return none
92509282 }
92519283 left_source := g.render_comparison_operand (left_tokens, 'string' ) or { return none }
@@ -12174,6 +12206,21 @@ fn (g &Parser) semantic_type_key(c_type string) string {
1217412206 return base
1217512207}
1217612208
12209+ fn (g &Parser) underlying_alias_type (c_type string ) string {
12210+ mut resolved := c_type
12211+ mut seen := map [string ]bool {}
12212+ for {
12213+ base := resolved.trim_right ('*' )
12214+ if base in seen {
12215+ return resolved
12216+ }
12217+ alias_base := g.alias_base_types[base] or { return resolved }
12218+ seen[base] = true
12219+ resolved = alias_base + resolved[base.len..]
12220+ }
12221+ return resolved
12222+ }
12223+
1217712224fn fastc_number_expression_type (literal string ) string {
1217812225 clean := literal.replace ('_' , '' )
1217912226 if clean.contains ('.' ) || (! (clean.starts_with ('0x' ) || clean.starts_with ('0X' ))
0 commit comments