Skip to content

Commit e8d7eeb

Browse files
committed
v2: self compilation works!!! 5 levels deep
1 parent c5cb1d2 commit e8d7eeb

6 files changed

Lines changed: 494 additions & 291 deletions

File tree

‎vlib/v2/gen/cleanc/cleancnew.v‎

Lines changed: 104 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -766,12 +766,12 @@ fn (mut g Gen) collect_module_type_names() {
766766
}
767767
fields[field.name] = true
768768
}
769-
cloned_fields := fields.clone()
770-
g.enum_type_fields[enum_name] = cloned_fields
769+
mut cloned_fields := fields.clone()
770+
g.enum_type_fields[enum_name] = cloned_fields.move()
771771
if enum_name.contains('__') {
772772
short_name := enum_name.all_after_last('__')
773-
short_cloned_fields := fields.clone()
774-
g.enum_type_fields[short_name] = short_cloned_fields
773+
mut short_cloned_fields := fields.clone()
774+
g.enum_type_fields[short_name] = short_cloned_fields.move()
775775
}
776776
}
777777
ast.TypeDecl {
@@ -952,8 +952,9 @@ fn (mut g Gen) collect_aliases_from_type(t types.Type) {
952952
g.register_alias_type('_result_${base}')
953953
}
954954
types.Alias {
955-
g.collect_aliases_from_type(t.base_type)
956-
g.register_alias_type(t.name)
955+
// Alias payloads from self-host env caches can be malformed.
956+
// Decls are collected from AST, so skip runtime alias recursion here.
957+
return
957958
}
958959
types.Pointer {
959960
g.collect_aliases_from_type(t.base_type)
@@ -2384,7 +2385,7 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
23842385
}
23852386
}
23862387
}
2387-
if typ == '' {
2388+
if typ == '' || typ == 'void' {
23882389
typ = 'int'
23892390
}
23902391
g.sb.write_string('${typ} ${name} = ')
@@ -3233,7 +3234,7 @@ fn (mut g Gen) gen_interface_cast(type_name string, value_expr ast.Expr) bool {
32333234
return false
32343235
}
32353236
mut is_iface := false
3236-
if scope := g.env_scope(g.cur_module) {
3237+
if mut scope := g.env_scope(g.cur_module) {
32373238
if obj := scope.lookup_parent(type_name, 0) {
32383239
if obj is types.Type && obj is types.Interface {
32393240
is_iface = true
@@ -3304,7 +3305,7 @@ fn (g &Gen) is_enum_type(name string) bool {
33043305
// Also check the types.Environment
33053306
if g.env != unsafe { nil } {
33063307
mut found := false
3307-
if scope := g.env_scope(g.cur_module) {
3308+
if mut scope := g.env_scope(g.cur_module) {
33083309
if obj := scope.lookup_parent(name, 0) {
33093310
if obj is types.Type && obj is types.Enum {
33103311
found = true
@@ -3396,7 +3397,7 @@ fn (mut g Gen) is_module_ident(name string) bool {
33963397
}
33973398
if g.env != unsafe { nil } {
33983399
mut found := false
3399-
if scope := g.env_scope(g.cur_module) {
3400+
if mut scope := g.env_scope(g.cur_module) {
34003401
if obj := scope.lookup_parent(name, 0) {
34013402
found = obj is types.Module
34023403
}
@@ -3719,17 +3720,17 @@ fn (mut g Gen) gen_expr(node ast.Expr) {
37193720
if node.name in g.global_var_modules
37203721
&& g.global_var_modules[node.name] == g.cur_module {
37213722
g.sb.write_string('${g.cur_module}__${node.name}')
3722-
} else {
3723-
is_local_var := g.get_local_var_c_type(node.name) != none
3724-
const_key := 'const_${g.cur_module}__${node.name}'
3725-
global_key := 'global_${g.cur_module}__${node.name}'
3726-
if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
3727-
&& !node.name.contains('__') && !is_local_var
3728-
&& ((const_key in g.emitted_types || global_key in g.emitted_types)
3729-
|| g.is_module_local_const_or_global(node.name)) {
3730-
g.sb.write_string('${g.cur_module}__${node.name}')
3731-
} else if g.cur_module != '' && g.cur_module != 'main'
3732-
&& g.cur_module != 'builtin' && !node.name.contains('__') && !is_local_var
3723+
} else {
3724+
is_local_var := g.get_local_var_c_type(node.name) != none
3725+
const_key := 'const_${g.cur_module}__${node.name}'
3726+
global_key := 'global_${g.cur_module}__${node.name}'
3727+
if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
3728+
&& !node.name.contains('__') && !is_local_var
3729+
&& ((const_key in g.emitted_types || global_key in g.emitted_types)
3730+
|| g.is_module_local_const_or_global(node.name)) {
3731+
g.sb.write_string('${g.cur_module}__${node.name}')
3732+
} else if g.cur_module != '' && g.cur_module != 'main'
3733+
&& g.cur_module != 'builtin' && !node.name.contains('__') && !is_local_var
37333734
&& !g.is_module_ident(node.name) && g.is_module_local_fn(node.name)
37343735
&& !g.is_type_name(node.name) {
37353736
g.sb.write_string('${g.cur_module}__${sanitize_fn_ident(node.name)}')
@@ -4505,15 +4506,15 @@ fn (mut g Gen) gen_expr(node ast.Expr) {
45054506
return
45064507
}
45074508
}
4508-
// Fixed-size array `.len` becomes compile-time length.
4509-
if node.rhs.name == 'len' {
4510-
if node.lhs is ast.Ident {
4511-
mut fixed_name := node.lhs.name
4512-
module_const_key := 'const_${g.cur_module}__${node.lhs.name}'
4513-
if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
4514-
&& module_const_key in g.emitted_types {
4515-
fixed_name = '${g.cur_module}__${node.lhs.name}'
4516-
}
4509+
// Fixed-size array `.len` becomes compile-time length.
4510+
if node.rhs.name == 'len' {
4511+
if node.lhs is ast.Ident {
4512+
mut fixed_name := node.lhs.name
4513+
module_const_key := 'const_${g.cur_module}__${node.lhs.name}'
4514+
if g.cur_module != '' && g.cur_module != 'main' && g.cur_module != 'builtin'
4515+
&& module_const_key in g.emitted_types {
4516+
fixed_name = '${g.cur_module}__${node.lhs.name}'
4517+
}
45174518
if fixed_name in g.fixed_array_globals {
45184519
g.sb.write_string('((int)(sizeof(${fixed_name}) / sizeof(${fixed_name}[0])))')
45194520
return
@@ -5940,23 +5941,85 @@ struct SumVariantMatch {
59405941
}
59415942

59425943
fn (mut g Gen) infer_sum_variant_from_expr(type_name string, variants []string, expr ast.Expr) SumVariantMatch {
5944+
// Handle module constants used as sum variants in selfhosted checker code
5945+
// (e.g. char_, string_, void_, nil_, none_).
5946+
if expr is ast.Ident {
5947+
variant_hint := match expr.name {
5948+
'char_' {
5949+
'Char'
5950+
}
5951+
'string_' {
5952+
'String'
5953+
}
5954+
'void_' {
5955+
'Void'
5956+
}
5957+
'nil_' {
5958+
'Nil'
5959+
}
5960+
'none_' {
5961+
'None'
5962+
}
5963+
'rune_' {
5964+
'Rune'
5965+
}
5966+
'usize_' {
5967+
'USize'
5968+
}
5969+
'isize_' {
5970+
'ISize'
5971+
}
5972+
'thread_' {
5973+
'Thread'
5974+
}
5975+
'chan_' {
5976+
'Channel'
5977+
}
5978+
'bool_', 'i8_', 'i16_', 'i32_', 'int_', 'i64_', 'u8_', 'u16_', 'u32_', 'u64_', 'f32_',
5979+
'f64_', 'int_literal_', 'float_literal_' {
5980+
'Primitive'
5981+
}
5982+
else {
5983+
''
5984+
}
5985+
}
5986+
if variant_hint != '' {
5987+
for i, v in variants {
5988+
v_short := if v.contains('__') { v.all_after_last('__') } else { v }
5989+
if v_short == variant_hint || v == variant_hint || v.ends_with('__${variant_hint}') {
5990+
return SumVariantMatch{
5991+
tag: i
5992+
field_name: v
5993+
is_primitive: variant_hint == 'Primitive'
5994+
inner_type: ''
5995+
}
5996+
}
5997+
}
5998+
}
5999+
}
6000+
59436001
// For InitExpr, infer from the struct type name
59446002
if expr is ast.InitExpr {
59456003
init_type := g.expr_type_to_c(expr.typ)
5946-
if init_type != '' {
5947-
init_short := if init_type.contains('__') {
5948-
init_type.all_after_last('__')
6004+
mut resolved_init_type := init_type
6005+
if (resolved_init_type == '' || resolved_init_type == 'int') && expr.typ is ast.Ident {
6006+
resolved_init_type = expr.typ.name.replace('.', '__')
6007+
}
6008+
if resolved_init_type != '' {
6009+
init_short := if resolved_init_type.contains('__') {
6010+
resolved_init_type.all_after_last('__')
59496011
} else {
5950-
init_type
6012+
resolved_init_type
59516013
}
59526014
for i, v in variants {
5953-
if v == init_short || v == init_type || init_type.ends_with('__${v}')
5954-
|| v.ends_with('__${init_type}') {
6015+
if v == init_short || v == resolved_init_type
6016+
|| resolved_init_type.ends_with('__${v}')
6017+
|| v.ends_with('__${resolved_init_type}') {
59556018
return SumVariantMatch{
59566019
tag: i
59576020
field_name: v
59586021
is_primitive: false
5959-
inner_type: init_type
6022+
inner_type: resolved_init_type
59606023
}
59616024
}
59626025
}
@@ -7665,7 +7728,7 @@ fn (g &Gen) lookup_module_scope_object(name string) ?types.Object {
76657728
if g.cur_module == '' {
76667729
return none
76677730
}
7668-
if module_scope := g.env_scope(g.cur_module) {
7731+
if mut module_scope := g.env_scope(g.cur_module) {
76697732
if obj := module_scope.lookup(name) {
76707733
return obj
76717734
}
@@ -7736,7 +7799,7 @@ fn (mut g Gen) get_raw_type(node ast.Expr) ?types.Type {
77367799
}
77377800
// Fallback to module scopes when function scope chain misses the symbol.
77387801
if g.cur_module != '' {
7739-
if mod_scope := g.env_scope(g.cur_module) {
7802+
if mut mod_scope := g.env_scope(g.cur_module) {
77407803
if obj := mod_scope.lookup_parent(node.name, 0) {
77417804
if obj !is types.Module {
77427805
return obj.typ()
@@ -7745,7 +7808,7 @@ fn (mut g Gen) get_raw_type(node ast.Expr) ?types.Type {
77457808
}
77467809
}
77477810
if g.cur_module != 'builtin' {
7748-
if builtin_scope := g.env_scope('builtin') {
7811+
if mut builtin_scope := g.env_scope('builtin') {
77497812
if obj := builtin_scope.lookup_parent(node.name, 0) {
77507813
if obj !is types.Module {
77517814
return obj.typ()
@@ -7778,7 +7841,7 @@ fn (mut g Gen) get_raw_type(node ast.Expr) ?types.Type {
77787841
}
77797842
}
77807843
if g.cur_module != '' {
7781-
if mod_scope := g.env_scope(g.cur_module) {
7844+
if mut mod_scope := g.env_scope(g.cur_module) {
77827845
if obj := mod_scope.lookup_parent(node.lhs.name, 0) {
77837846
if obj is types.Module {
77847847
if rhs_obj := obj.lookup(node.rhs.name) {

0 commit comments

Comments
 (0)