aboutsummaryrefslogtreecommitdiff
path: root/src/index
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-29 19:25:15 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-29 19:25:15 +0100
commit0a49dec8e063d44b86c8c28bf77dbde17cdb35c8 (patch)
treedb86b6e300135df3474eda8625f5f957c7a86a2f /src/index
parent1b1860976d0a4ab6e23601c714df3f86f39e5691 (diff)
added sha1, fixed leaks, fixed crash on bad expr
Diffstat (limited to 'src/index')
-rw-r--r--src/index/clone.odin133
-rw-r--r--src/index/collector.odin48
-rw-r--r--src/index/memory_index.odin4
-rw-r--r--src/index/symbol.odin24
4 files changed, 123 insertions, 86 deletions
diff --git a/src/index/clone.odin b/src/index/clone.odin
index 92e79d9..19a4526 100644
--- a/src/index/clone.odin
+++ b/src/index/clone.odin
@@ -24,33 +24,33 @@ clone_type :: proc{
clone_dynamic_array,
};
-clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) -> A {
+clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator, unique_strings: ^map[string] string) -> A {
if len(array) == 0 {
return nil;
}
res := make(A, len(array), allocator);
for elem, i in array {
- res[i] = auto_cast clone_type(elem, allocator);
+ res[i] = auto_cast clone_type(elem, allocator, unique_strings);
}
return res;
}
-clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) -> A {
+clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator, unique_strings: ^map[string] string) -> A {
if len(array) == 0 {
return nil;
}
res := make(A, len(array), allocator);
for elem, i in array {
- res[i] = auto_cast clone_type(elem, allocator);
+ res[i] = auto_cast clone_type(elem, allocator, unique_strings);
}
return res;
}
-clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator) -> ^ast.Expr {
- return cast(^ast.Expr)clone_node(node, allocator);
+clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator, unique_strings: ^map[string] string) -> ^ast.Expr {
+ return cast(^ast.Expr)clone_node(node, allocator, unique_strings);
}
-clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node {
+clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator, unique_strings: ^map[string] string) -> ^ast.Node {
using ast;
@@ -81,127 +81,132 @@ clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node {
case Bad_Expr:
case Ident:
r := cast(^Ident)res;
- r.name = strings.clone(n.name, allocator);
+ if unique_strings == nil {
+ r.name = strings.clone(n.name, allocator);
+ }
+ else {
+ r.name = get_index_unique_string(unique_strings, allocator, n.name);
+ }
case Implicit:
case Undef:
case Basic_Lit:
case Basic_Directive:
case Ellipsis:
r := cast(^Ellipsis)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Tag_Expr:
r := cast(^Tag_Expr)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Unary_Expr:
r := cast(^Unary_Expr)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Binary_Expr:
r := cast(^Binary_Expr)res;
- r.left = clone_type(r.left, allocator);
- r.right = clone_type(r.right, allocator);
+ r.left = clone_type(r.left, allocator, unique_strings);
+ r.right = clone_type(r.right, allocator, unique_strings);
case Paren_Expr:
r := cast(^Paren_Expr)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Selector_Expr:
r := cast(^Selector_Expr)res;
- r.expr = clone_type(r.expr, allocator);
- r.field = auto_cast clone_type(r.field, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
+ r.field = auto_cast clone_type(r.field, allocator, unique_strings);
case Implicit_Selector_Expr:
r := cast(^Implicit_Selector_Expr)res;
- r.field = auto_cast clone_type(r.field, allocator);
+ r.field = auto_cast clone_type(r.field, allocator, unique_strings);
case Slice_Expr:
r := cast(^Slice_Expr)res;
- r.expr = clone_type(r.expr, allocator);
- r.low = clone_type(r.low, allocator);
- r.high = clone_type(r.high, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
+ r.low = clone_type(r.low, allocator, unique_strings);
+ r.high = clone_type(r.high, allocator, unique_strings);
case Attribute:
r := cast(^Attribute)res;
- r.elems = clone_type(r.elems, allocator);
+ r.elems = clone_type(r.elems, allocator, unique_strings);
case Distinct_Type:
r := cast(^Distinct_Type)res;
- r.type = clone_type(r.type, allocator);
+ r.type = clone_type(r.type, allocator, unique_strings);
case Opaque_Type:
r := cast(^Opaque_Type)res;
- r.type = clone_type(r.type, allocator);
+ r.type = clone_type(r.type, allocator, unique_strings);
case Proc_Type:
r := cast(^Proc_Type)res;
- r.params = auto_cast clone_type(r.params, allocator);
- r.results = auto_cast clone_type(r.results, allocator);
+ r.params = auto_cast clone_type(r.params, allocator, unique_strings);
+ r.results = auto_cast clone_type(r.results, allocator, unique_strings);
case Pointer_Type:
r := cast(^Pointer_Type)res;
- r.elem = clone_type(r.elem, allocator);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
case Array_Type:
r := cast(^Array_Type)res;
- r.len = clone_type(r.len, allocator);
- r.elem = clone_type(r.elem, allocator);
- r.tag = clone_type(r.tag, allocator);
+ r.len = clone_type(r.len, allocator, unique_strings);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
+ r.tag = clone_type(r.tag, allocator, unique_strings);
case Dynamic_Array_Type:
r := cast(^Dynamic_Array_Type)res;
- r.elem = clone_type(r.elem, allocator);
- r.tag = clone_type(r.tag, allocator);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
+ r.tag = clone_type(r.tag, allocator, unique_strings);
case Struct_Type:
r := cast(^Struct_Type)res;
- r.poly_params = auto_cast clone_type(r.poly_params, allocator);
- r.align = clone_type(r.align, allocator);
- r.fields = auto_cast clone_type(r.fields, allocator);
- r.where_clauses = clone_type(r.where_clauses, allocator);
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings);
+ r.align = clone_type(r.align, allocator, unique_strings);
+ r.fields = auto_cast clone_type(r.fields, allocator, unique_strings);
+ r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings);
case Field:
r := cast(^Field)res;
- r.names = clone_type(r.names, allocator);
- r.type = clone_type(r.type, allocator);
- r.default_value = clone_type(r.default_value, allocator);
+ r.names = clone_type(r.names, allocator, unique_strings);
+ r.type = clone_type(r.type, allocator, unique_strings);
+ r.default_value = clone_type(r.default_value, allocator, unique_strings);
case Field_List:
r := cast(^Field_List)res;
- r.list = clone_type(r.list, allocator);
+ r.list = clone_type(r.list, allocator, unique_strings);
case Field_Value:
r := cast(^Field_Value)res;
- r.field = clone_type(r.field, allocator);
- r.value = clone_type(r.value, allocator);
+ r.field = clone_type(r.field, allocator, unique_strings);
+ r.value = clone_type(r.value, allocator, unique_strings);
case Union_Type:
r := cast(^Union_Type)res;
- r.poly_params = auto_cast clone_type(r.poly_params, allocator);
- r.align = clone_type(r.align, allocator);
- r.variants = clone_type(r.variants, allocator);
- r.where_clauses = clone_type(r.where_clauses, allocator);
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings);
+ r.align = clone_type(r.align, allocator, unique_strings);
+ r.variants = clone_type(r.variants, allocator, unique_strings);
+ r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings);
case Enum_Type:
r := cast(^Enum_Type)res;
- r.base_type = clone_type(r.base_type, allocator);
- r.fields = clone_type(r.fields, allocator);
+ r.base_type = clone_type(r.base_type, allocator, unique_strings);
+ r.fields = clone_type(r.fields, allocator, unique_strings);
case Bit_Field_Type:
r := cast(^Bit_Field_Type)res;
- r.fields = clone_type(r.fields, allocator);
- r.align = clone_type(r.align, allocator);
+ r.fields = clone_type(r.fields, allocator, unique_strings);
+ r.align = clone_type(r.align, allocator, unique_strings);
case Bit_Set_Type:
r := cast(^Bit_Set_Type)res;
- r.elem = clone_type(r.elem, allocator);
- r.underlying = clone_type(r.underlying, allocator);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
+ r.underlying = clone_type(r.underlying, allocator, unique_strings);
case Map_Type:
r := cast(^Map_Type)res;
- r.key = clone_type(r.key, allocator);
- r.value = clone_type(r.value, allocator);
+ r.key = clone_type(r.key, allocator, unique_strings);
+ r.value = clone_type(r.value, allocator, unique_strings);
case Call_Expr:
r := cast(^Call_Expr)res;
- r.expr = clone_type(r.expr, allocator);
- r.args = clone_type(r.args, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
+ r.args = clone_type(r.args, allocator, unique_strings);
case Typeid_Type:
r := cast(^Typeid_Type)res;
- r.specialization = clone_type(r.specialization, allocator);
+ r.specialization = clone_type(r.specialization, allocator, unique_strings);
case Ternary_When_Expr:
r := cast(^Ternary_When_Expr)res;
- r.x = clone_type(r.x, allocator);
- r.cond = clone_type(r.cond, allocator);
- r.y = clone_type(r.y, allocator);
+ r.x = clone_type(r.x, allocator, unique_strings);
+ r.cond = clone_type(r.cond, allocator, unique_strings);
+ r.y = clone_type(r.y, allocator, unique_strings);
case Poly_Type:
r := cast(^Poly_Type)res;
- r.type = auto_cast clone_type(r.type, allocator);
- r.specialization = clone_type(r.specialization, allocator);
+ r.type = auto_cast clone_type(r.type, allocator, unique_strings);
+ r.specialization = clone_type(r.specialization, allocator, unique_strings);
case Proc_Group:
r := cast(^Proc_Group)res;
- r.args = clone_type(r.args, allocator);
+ r.args = clone_type(r.args, allocator, unique_strings);
case Comp_Lit:
r := cast(^Comp_Lit)res;
- r.type = clone_type(r.type, allocator);
- r.elems = clone_type(r.elems, allocator);
+ r.type = clone_type(r.type, allocator, unique_strings);
+ r.elems = clone_type(r.elems, allocator, unique_strings);
case:
log.error("Clone type Unhandled node kind: %T", n);
}
diff --git a/src/index/collector.odin b/src/index/collector.odin
index 73ff8b9..f8dfb63 100644
--- a/src/index/collector.odin
+++ b/src/index/collector.odin
@@ -15,28 +15,34 @@ import "shared:common"
SymbolCollection :: struct {
allocator: mem.Allocator,
config: ^common.Config,
- symbols: map[string] Symbol,
+ symbols: map[uint] Symbol,
unique_strings: map[string] string, //store all our strings as unique strings and reference them to save memory.
};
+get_index_unique_string :: proc {
+ get_index_unique_string_collection,
+ get_index_unique_string_collection_raw,
+};
-get_index_unique_string :: proc(collection: ^SymbolCollection, s: string) -> string {
+get_index_unique_string_collection :: proc(collection: ^SymbolCollection, s: string) -> string {
+ return get_index_unique_string_collection_raw(&collection.unique_strings, collection.allocator, s);
+}
+get_index_unique_string_collection_raw :: proc(unique_strings: ^map[string] string, allocator: mem.Allocator, s: string) -> string {
//i'm hashing this string way to much
- if _, ok := collection.unique_strings[s]; !ok {
- str := strings.clone(s, collection.allocator);
- collection.unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions.
+ if _, ok := unique_strings[s]; !ok {
+ str := strings.clone(s, allocator);
+ unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions.
}
- return collection.unique_strings[s];
+ return unique_strings[s];
}
-
make_symbol_collection :: proc(allocator := context.allocator, config: ^common.Config) -> SymbolCollection {
return SymbolCollection {
allocator = allocator,
config = config,
- symbols = make(map[string] Symbol, 16, allocator),
+ symbols = make(map[uint] Symbol, 16, allocator),
unique_strings = make(map[string] string, 16, allocator),
};
}
@@ -44,8 +50,7 @@ make_symbol_collection :: proc(allocator := context.allocator, config: ^common.C
delete_symbol_collection :: proc(collection: SymbolCollection) {
for k, v in collection.symbols {
- free_symbol(v);
- delete(k, collection.allocator);
+ free_symbol(v, collection.allocator);
}
for k, v in collection.unique_strings {
@@ -63,13 +68,13 @@ collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast.
args := make([dynamic] ^ast.Field, 0, collection.allocator);
for ret in return_list.list {
- cloned := cast(^ast.Field)clone_type(ret, collection.allocator);
+ cloned := cast(^ast.Field)clone_type(ret, collection.allocator, &collection.unique_strings);
replace_package_alias(cloned, package_map, collection);
append(&returns, cloned);
}
for arg in arg_list.list {
- cloned := cast(^ast.Field)clone_type(arg, collection.allocator);
+ cloned := cast(^ast.Field)clone_type(arg, collection.allocator, &collection.unique_strings);
replace_package_alias(cloned, package_map, collection);
append(&args, cloned);
}
@@ -94,7 +99,7 @@ collect_struct_fields :: proc(collection: ^SymbolCollection, fields: ^ast.Field_
identifier := n.derived.(ast.Ident);
append(&names, get_index_unique_string(collection, identifier.name));
- cloned := clone_type(field.type, collection.allocator);
+ cloned := clone_type(field.type, collection.allocator, &collection.unique_strings);
replace_package_alias(cloned, package_map, collection);
append(&types, cloned);
}
@@ -148,7 +153,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
token = v;
token_type = .Function;
symbol.value = SymbolProcedureGroupValue {
- group = clone_type(value_decl.values[0], collection.allocator),
+ group = clone_type(value_decl.values[0], collection.allocator, &collection.unique_strings),
};
case ast.Struct_Type:
token = v;
@@ -164,9 +169,20 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
symbol.type = token_type;
symbol.uri = get_index_unique_string(collection, uri);
- //id := hash.murmur64(transmute([]u8)strings.concatenate({symbol.scope, name}, context.temp_allocator));
+ cat := strings.concatenate({symbol.scope, name}, context.temp_allocator);
+
+ id := get_symbol_id(cat);
+
+ //right now i'm not checking comments whether is for windows, linux, etc, and some packages do not specify that(os)
+ if v, ok := collection.symbols[id]; !ok {
+ collection.symbols[id] = symbol;
+ //fmt.printf("FAILED COLLOSION! %v %v \n", id, cat);
+ }
+
+ else {
+ free_symbol(symbol, collection.allocator);
+ }
- collection.symbols[strings.concatenate({symbol.scope, name}, collection.allocator)] = symbol;
}
}
diff --git a/src/index/memory_index.odin b/src/index/memory_index.odin
index e99d759..05de53b 100644
--- a/src/index/memory_index.odin
+++ b/src/index/memory_index.odin
@@ -28,7 +28,9 @@ make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
memory_index_lookup :: proc(index: ^MemoryIndex, name: string, scope: string) -> (Symbol, bool) {
//hashed := hash.murmur64(transmute([]u8)strings.concatenate({scope, name}, context.temp_allocator));
- return index.collection.symbols[strings.concatenate({scope, name}, context.temp_allocator)];
+
+ id := get_symbol_id(strings.concatenate({scope, name}, context.temp_allocator));
+ return index.collection.symbols[id];
}
memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, scope: [] string) -> ([] Symbol, bool) {
diff --git a/src/index/symbol.odin b/src/index/symbol.odin
index 8c672d9..6630015 100644
--- a/src/index/symbol.odin
+++ b/src/index/symbol.odin
@@ -7,6 +7,7 @@ import "core:mem"
import "core:fmt"
import "core:path/filepath"
import "core:path"
+import "core:slice"
import "shared:common"
@@ -89,16 +90,29 @@ SymbolType :: enum {
Struct = 22,
};
-free_symbol :: proc(symbol: Symbol) {
+free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
#partial switch v in symbol.value {
case SymbolProcedureValue:
- common.free_ast(v.return_types);
- common.free_ast(v.arg_types);
+ common.free_ast(v.return_types, allocator);
+ common.free_ast(v.arg_types, allocator);
case SymbolStructValue:
- common.free_ast(v.types);
+ delete(v.names, allocator);
+ common.free_ast(v.types, allocator);
case SymbolGenericValue:
- common.free_ast(v.expr);
+ common.free_ast(v.expr, allocator);
+ case SymbolProcedureGroupValue:
+ common.free_ast(v.group, allocator);
+ case SymbolEnumValue:
+ delete(v.names, allocator);
+ case SymbolUnionValue:
+ delete(v.names, allocator);
}
+}
+
+get_symbol_id :: proc(str: string) -> uint {
+ ret := common.sha1_hash(transmute([]byte)str);
+ r := cast(^uint)slice.first_ptr(ret[:]);
+ return r^;
} \ No newline at end of file