aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-07-25 21:56:36 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-07-25 21:56:36 +0200
commit18afea306114de303161f4aa044fb9842db1b10c (patch)
tree483e8dc928d577b0ada6ae61be0cc6aa2a63eabe /src
parent5f37d25310d282c0370f082328b5268e344b131c (diff)
Support soa in generics
Diffstat (limited to 'src')
-rw-r--r--src/common/ast.odin20
-rw-r--r--src/server/analysis.odin26
-rw-r--r--src/server/generics.odin42
-rw-r--r--src/server/symbol.odin1
4 files changed, 87 insertions, 2 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin
index 4f1b25d..267c84d 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -207,6 +207,26 @@ unwrap_pointer_expr :: proc(expr: ^ast.Expr) -> (^ast.Expr, int, bool) {
return expr, n, true
}
+array_is_soa :: proc(array: ast.Array_Type) -> bool {
+ if array.tag != nil {
+ if basic, ok := array.tag.derived.(^ast.Basic_Directive);
+ ok && basic.name == "soa" {
+ return true
+ }
+ }
+ return false
+}
+
+dynamic_array_is_soa :: proc(array: ast.Dynamic_Array_Type) -> bool {
+ if array.tag != nil {
+ if basic, ok := array.tag.derived.(^ast.Basic_Directive);
+ ok && basic.name == "soa" {
+ return true
+ }
+ }
+ return false
+}
+
expr_contains_poly :: proc(expr: ^ast.Expr) -> bool {
if expr == nil {
return false
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 14b1aad..8cc5bee 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -489,7 +489,13 @@ is_symbol_same_typed :: proc(
return false
}
- return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
+ a_is_soa := .Soa in a_symbol.flags
+ b_is_soa := .Soa in a_symbol.flags
+
+ return(
+ is_symbol_same_typed(ast_context, a_symbol, b_symbol) &&
+ a_is_soa == b_is_soa \
+ )
case SymbolFixedArrayValue:
b_value := b.value.(SymbolFixedArrayValue)
@@ -561,7 +567,13 @@ is_symbol_same_typed :: proc(
return false
}
- return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
+ a_is_soa := .Soa in a_symbol.flags
+ b_is_soa := .Soa in a_symbol.flags
+
+ return(
+ is_symbol_same_typed(ast_context, a_symbol, b_symbol) &&
+ a_is_soa == b_is_soa \
+ )
case SymbolMapValue:
b_value := b.value.(SymbolMapValue)
@@ -2826,6 +2838,10 @@ make_symbol_array_from_ast :: proc(
}
}
+ if common.array_is_soa(v) {
+ symbol.flags |= {.Soa}
+ }
+
return symbol
}
@@ -2845,6 +2861,12 @@ make_symbol_dynamic_array_from_ast :: proc(
expr = v.elem,
}
+
+ if common.dynamic_array_is_soa(v) {
+ symbol.flags |= {.Soa}
+ }
+
+
return symbol
}
diff --git a/src/server/generics.odin b/src/server/generics.odin
index 237a271..9b0dc1d 100644
--- a/src/server/generics.odin
+++ b/src/server/generics.odin
@@ -150,6 +150,27 @@ resolve_poly :: proc(
}
case ^ast.Dynamic_Array_Type:
if call_array, ok := call_node.derived.(^ast.Dynamic_Array_Type); ok {
+
+ a_soa := common.dynamic_array_is_soa(p^)
+ b_soa := common.dynamic_array_is_soa(call_array^)
+
+ if (a_soa || b_soa) && a_soa != b_soa {
+ return false
+ }
+
+ //It's not enough for them to both arrays, they also have to share soa attributes
+ if p.tag != nil && call_array.tag != nil {
+ a, ok1 := p.tag.derived.(^ast.Basic_Directive)
+ b, ok2 := call_array.tag.derived.(^ast.Basic_Directive)
+
+ if ok1 &&
+ ok2 &&
+ (a.name == "soa" || b.name == "soa") &&
+ a.name != b.name {
+ return false
+ }
+ }
+
if poly_type, ok := p.elem.derived.(^ast.Poly_Type); ok {
if ident, ok := unwrap_ident(poly_type.type); ok {
save_poly_map(ident, call_array.elem, poly_map)
@@ -170,6 +191,27 @@ resolve_poly :: proc(
case ^ast.Array_Type:
if call_array, ok := call_node.derived.(^ast.Array_Type); ok {
found := false
+
+ a_soa := common.array_is_soa(p^)
+ b_soa := common.array_is_soa(call_array^)
+
+ if (a_soa || b_soa) && a_soa != b_soa {
+ return false
+ }
+
+ //It's not enough for them to both arrays, they also have to share soa attributes
+ if p.tag != nil && call_array.tag != nil {
+ a, ok1 := p.tag.derived.(^ast.Basic_Directive)
+ b, ok2 := call_array.tag.derived.(^ast.Basic_Directive)
+
+ if ok1 &&
+ ok2 &&
+ (a.name == "soa" || b.name == "soa") &&
+ a.name != b.name {
+ return false
+ }
+ }
+
if poly_type, ok := p.elem.derived.(^ast.Poly_Type); ok {
if ident, ok := unwrap_ident(poly_type.type); ok {
save_poly_map(ident, call_array.elem, poly_map)
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 9e0f154..f34e4b6 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -146,6 +146,7 @@ SymbolFlag :: enum {
Local,
ObjC,
ObjCIsClassMethod, // should be set true only when ObjC is enabled
+ Soa,
}
SymbolFlags :: bit_set[SymbolFlag]