aboutsummaryrefslogtreecommitdiff
path: root/src/server/analysis.odin
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2023-09-01 20:17:57 +0200
committerDanielGavin <danielgavin5@hotmail.com>2023-09-01 20:17:57 +0200
commitc967c9be431cc22b60ed6a100bc3c6beeef6edd7 (patch)
tree16bd0e5c1bab6a73286b8b7ef76ee5c89459c9f0 /src/server/analysis.odin
parenta72ac2941a1a54e05b4051a00ca25b0b3822b1c6 (diff)
Add support for generics in struct that use arrays
Diffstat (limited to 'src/server/analysis.odin')
-rw-r--r--src/server/analysis.odin76
1 files changed, 57 insertions, 19 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index d28e7ae..a114b92 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2271,21 +2271,27 @@ resolve_symbol_return :: proc(
}
case SymbolUnionValue:
if v.poly != nil {
- //Todo(daniel): Maybe change the function to return a new symbol instead of referencing it.
- //resolving the poly union means changing the type, so we do a copy of it.
types := make([dynamic]^ast.Expr, ast_context.allocator)
- append_elems(&types, ..v.types)
+
+ for type in v.types {
+ append(&types, clone_expr(type, context.temp_allocator, nil))
+ }
+
v.types = types[:]
+
resolve_poly_union(ast_context, v.poly, &symbol)
}
return symbol, ok
case SymbolStructValue:
if v.poly != nil {
- //Todo(daniel): Maybe change the function to return a new symbol instead of referencing it.
- //resolving the struct union means changing the type, so we do a copy of it.
types := make([dynamic]^ast.Expr, ast_context.allocator)
- append_elems(&types, ..v.types)
+
+ for type in v.types {
+ append(&types, clone_expr(type, context.temp_allocator, nil))
+ }
+
v.types = types[:]
+
resolve_poly_struct(ast_context, v.poly, &symbol)
}
@@ -3214,24 +3220,56 @@ resolve_poly_struct :: proc(
}
}
- for type, i in symbol_value.types {
- if ident, ok := type.derived.(^ast.Ident); ok {
- if expr, ok := poly_map[ident.name]; ok {
- symbol_value.types[i] = expr
- }
- } else if call_expr, ok := type.derived.(^ast.Call_Expr); ok {
- if call_expr.args == nil {
- continue
- }
+ Visit_Data :: struct {
+ poly_map: map[string]^ast.Expr,
+ symbol_value: ^SymbolStructValue,
+ parent: ^ast.Node,
+ i: int,
+ }
- for arg, i in call_expr.args {
- if ident, ok := arg.derived.(^ast.Ident); ok {
- if expr, ok := poly_map[ident.name]; ok {
- symbol_value.types[i] = expr
+ visit :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor {
+ if node == nil || visitor == nil {
+ return nil
+ }
+
+ data := cast(^Visit_Data)visitor.data
+
+ if ident, ok := node.derived.(^ast.Ident); ok {
+ if expr, ok := data.poly_map[ident.name]; ok {
+ if data.parent != nil {
+ #partial switch &v in data.parent.derived {
+ case ^ast.Array_Type:
+ v.elem = expr
+ case ^ast.Dynamic_Array_Type:
+ v.elem = expr
}
+ } else {
+ data.symbol_value.types[data.i] = expr
}
}
}
+
+ #partial switch v in node.derived {
+ case ^ast.Array_Type, ^ast.Dynamic_Array_Type, ^ast.Selector_Expr:
+ data.parent = node
+ }
+
+ return visitor
+ }
+
+ for type, i in symbol_value.types {
+ data := Visit_Data {
+ poly_map = poly_map,
+ symbol_value = symbol_value,
+ i = i,
+ }
+
+ visitor := ast.Visitor {
+ data = &data,
+ visit = visit,
+ }
+
+ ast.walk(&visitor, type)
}
}