1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: add g.push_existing_comptime_values and g.pop_existing_comptime_values, use them inside Gen.comptime_for (#16821)

This commit is contained in:
Delyan Angelov 2022-12-31 18:29:19 +02:00 committed by GitHub
parent 1c151fbec9
commit 3364bf8600
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 14 deletions

View File

@ -197,6 +197,7 @@ mut:
comptime_for_field_value ast.StructField // value of the field variable comptime_for_field_value ast.StructField // value of the field variable
comptime_for_field_type ast.Type // type of the field variable inferred from `$if field.typ is T {}` comptime_for_field_type ast.Type // type of the field variable inferred from `$if field.typ is T {}`
comptime_var_type_map map[string]ast.Type comptime_var_type_map map[string]ast.Type
comptime_values_stack []CurrentComptimeValues // stores the values from the above on each $for loop, to make nesting them easier
prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type
// used in match multi branch // used in match multi branch
// TypeOne, TypeTwo {} // TypeOne, TypeTwo {}

View File

@ -506,6 +506,33 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) bool {
} }
} }
//
struct CurrentComptimeValues {
inside_comptime_for_field bool
comptime_for_method string
comptime_for_field_var string
comptime_for_field_value ast.StructField
comptime_for_field_type ast.Type
comptime_var_type_map map[string]ast.Type
}
fn (mut g Gen) push_existing_comptime_values() {
g.comptime_values_stack << CurrentComptimeValues{g.inside_comptime_for_field, g.comptime_for_method, g.comptime_for_field_var, g.comptime_for_field_value, g.comptime_for_field_type, g.comptime_var_type_map.clone()}
}
fn (mut g Gen) pop_existing_comptime_values() {
old := g.comptime_values_stack.pop()
g.inside_comptime_for_field = old.inside_comptime_for_field
g.comptime_for_method = old.comptime_for_method
g.comptime_for_field_var = old.comptime_for_field_var
g.comptime_for_field_value = old.comptime_for_field_value
g.comptime_for_field_type = old.comptime_for_field_type
g.comptime_var_type_map = old.comptime_var_type_map.clone()
}
//
fn (mut g Gen) comptime_for(node ast.ComptimeFor) { fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
sym := g.table.final_sym(g.unwrap_generic(node.typ)) sym := g.table.final_sym(g.unwrap_generic(node.typ))
g.writeln('/* \$for ${node.val_var} in ${sym.name}(${node.kind.str()}) */ {') g.writeln('/* \$for ${node.val_var} in ${sym.name}(${node.kind.str()}) */ {')
@ -522,6 +549,7 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
} }
typ_vweb_result := g.table.find_type_idx('vweb.Result') typ_vweb_result := g.table.find_type_idx('vweb.Result')
for method in methods { for method in methods {
g.push_existing_comptime_values()
// filter vweb route methods (non-generic method) // filter vweb route methods (non-generic method)
if method.receiver_type != 0 && method.return_type == typ_vweb_result { if method.receiver_type != 0 && method.return_type == typ_vweb_result {
rec_sym := g.table.sym(method.receiver_type) rec_sym := g.table.sym(method.receiver_type)
@ -529,6 +557,7 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
if _ := g.table.find_field_with_embeds(rec_sym, 'Context') { if _ := g.table.find_field_with_embeds(rec_sym, 'Context') {
if method.generic_names.len > 0 if method.generic_names.len > 0
|| (method.params.len > 1 && method.attrs.len == 0) { || (method.params.len > 1 && method.attrs.len == 0) {
g.pop_existing_comptime_values()
continue continue
} }
} }
@ -589,16 +618,7 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
g.stmts(node.stmts) g.stmts(node.stmts)
i++ i++
g.writeln('}') g.writeln('}')
// g.pop_existing_comptime_values()
mut delete_keys := []string{}
for key, _ in g.comptime_var_type_map {
if key.starts_with(node.val_var) {
delete_keys << key
}
}
for key in delete_keys {
g.comptime_var_type_map.delete(key)
}
} }
} else if node.kind == .fields { } else if node.kind == .fields {
// TODO add fields // TODO add fields
@ -607,8 +627,9 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
if sym_info.fields.len > 0 { if sym_info.fields.len > 0 {
g.writeln('\tFieldData ${node.val_var} = {0};') g.writeln('\tFieldData ${node.val_var} = {0};')
} }
g.inside_comptime_for_field = true
for field in sym_info.fields { for field in sym_info.fields {
g.push_existing_comptime_values()
g.inside_comptime_for_field = true
g.comptime_for_field_var = node.val_var g.comptime_for_field_var = node.val_var
g.comptime_for_field_value = field g.comptime_for_field_value = field
g.comptime_for_field_type = field.typ g.comptime_for_field_type = field.typ
@ -648,10 +669,8 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
g.stmts(node.stmts) g.stmts(node.stmts)
i++ i++
g.writeln('}') g.writeln('}')
g.comptime_for_field_type = 0 g.pop_existing_comptime_values()
} }
g.inside_comptime_for_field = false
g.comptime_var_type_map.delete(node.val_var)
} }
} else if node.kind == .attributes { } else if node.kind == .attributes {
if sym.info is ast.Struct { if sym.info is ast.Struct {