aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2022-03-04 12:17:00 +0100
committerDaniel Gavin <danielgavin5@hotmail.com>2022-03-04 12:17:00 +0100
commit58287455d64ab16091522bf8a358b079ef05daad (patch)
tree7b6655d6d34b5ad6d719523e4938b8002c43d8ab /src/common
parent63d0bd412a8817445d6dc18e79d5d54c94caf401 (diff)
strip colons and update ast to use unions
Diffstat (limited to 'src/common')
-rw-r--r--src/common/allocator.odin104
-rw-r--r--src/common/ast.odin1116
-rw-r--r--src/common/fuzzy.odin254
-rw-r--r--src/common/position.odin166
-rw-r--r--src/common/sha1.odin334
-rw-r--r--src/common/uri.odin92
-rw-r--r--src/common/util_windows.odin62
7 files changed, 1059 insertions, 1069 deletions
diff --git a/src/common/allocator.odin b/src/common/allocator.odin
index bbb654c..6d2d371 100644
--- a/src/common/allocator.odin
+++ b/src/common/allocator.odin
@@ -12,119 +12,119 @@ Scratch_Allocator :: struct {
}
scratch_allocator_init :: proc (s: ^Scratch_Allocator, size: int, backup_allocator := context.allocator) {
- s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator);
- s.curr_offset = 0;
- s.prev_allocation = nil;
- s.backup_allocator = backup_allocator;
- s.leaked_allocations.allocator = backup_allocator;
+ s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator)
+ s.curr_offset = 0
+ s.prev_allocation = nil
+ s.backup_allocator = backup_allocator
+ s.leaked_allocations.allocator = backup_allocator
}
scratch_allocator_destroy :: proc (s: ^Scratch_Allocator) {
if s == nil {
- return;
+ return
}
for ptr in s.leaked_allocations {
- mem.free_bytes(ptr, s.backup_allocator);
+ mem.free_bytes(ptr, s.backup_allocator)
}
- delete(s.leaked_allocations);
- delete(s.data, s.backup_allocator);
- s^ = {};
+ delete(s.leaked_allocations)
+ delete(s.data, s.backup_allocator)
+ s^ = {}
}
scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
- s := (^Scratch_Allocator)(allocator_data);
+ s := (^Scratch_Allocator)(allocator_data)
if s.data == nil {
- DEFAULT_BACKING_SIZE :: 1 << 22;
+ DEFAULT_BACKING_SIZE :: 1 << 22
if !(context.allocator.procedure != scratch_allocator_proc &&
context.allocator.data != allocator_data) {
- panic("cyclic initialization of the scratch allocator with itself");
+ panic("cyclic initialization of the scratch allocator with itself")
}
- scratch_allocator_init(s, DEFAULT_BACKING_SIZE);
+ scratch_allocator_init(s, DEFAULT_BACKING_SIZE)
}
- size := size;
+ size := size
switch mode {
case .Alloc:
- size = mem.align_forward_int(size, alignment);
+ size = mem.align_forward_int(size, alignment)
switch {
case s.curr_offset + size <= len(s.data):
- start := uintptr(raw_data(s.data));
- ptr := start + uintptr(s.curr_offset);
- ptr = mem.align_forward_uintptr(ptr, uintptr(alignment));
- mem.zero(rawptr(ptr), size);
-
- s.prev_allocation = rawptr(ptr);
- offset := int(ptr - start);
- s.curr_offset = offset + size;
- return mem.byte_slice(rawptr(ptr), size), nil;
+ start := uintptr(raw_data(s.data))
+ ptr := start + uintptr(s.curr_offset)
+ ptr = mem.align_forward_uintptr(ptr, uintptr(alignment))
+ mem.zero(rawptr(ptr), size)
+
+ s.prev_allocation = rawptr(ptr)
+ offset := int(ptr - start)
+ s.curr_offset = offset + size
+ return mem.byte_slice(rawptr(ptr), size), nil
}
- a := s.backup_allocator;
+ a := s.backup_allocator
if a.procedure == nil {
- a = context.allocator;
- s.backup_allocator = a;
+ a = context.allocator
+ s.backup_allocator = a
}
- ptr, err := mem.alloc_bytes(size, alignment, a, loc);
+ ptr, err := mem.alloc_bytes(size, alignment, a, loc)
if err != nil {
- return ptr, err;
+ return ptr, err
}
if s.leaked_allocations == nil {
- s.leaked_allocations = make([dynamic][]byte, a);
+ s.leaked_allocations = make([dynamic][]byte, a)
}
- append(&s.leaked_allocations, ptr);
+ append(&s.leaked_allocations, ptr)
if logger := context.logger; logger.lowest_level <= .Warning {
if logger.procedure != nil {
- logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc);
+ logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc)
}
}
- return ptr, err;
+ return ptr, err
case .Free:
case .Free_All:
- s.curr_offset = 0;
- s.prev_allocation = nil;
+ s.curr_offset = 0
+ s.prev_allocation = nil
for ptr in s.leaked_allocations {
- mem.free_bytes(ptr, s.backup_allocator);
+ mem.free_bytes(ptr, s.backup_allocator)
}
- clear(&s.leaked_allocations);
+ clear(&s.leaked_allocations)
case .Resize:
- begin := uintptr(raw_data(s.data));
- end := begin + uintptr(len(s.data));
- old_ptr := uintptr(old_memory);
+ begin := uintptr(raw_data(s.data))
+ end := begin + uintptr(len(s.data))
+ old_ptr := uintptr(old_memory)
- data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc);
+ data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc)
if err != nil {
- return data, err;
+ return data, err
}
- runtime.copy(data, mem.byte_slice(old_memory, old_size));
- _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc);
- return data, err;
+ runtime.copy(data, mem.byte_slice(old_memory, old_size))
+ _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc)
+ return data, err
case .Query_Features:
- set := (^mem.Allocator_Mode_Set)(old_memory);
+ set := (^mem.Allocator_Mode_Set)(old_memory)
if set != nil {
- set^ = {.Alloc, .Free, .Free_All, .Resize, .Query_Features};
+ set^ = {.Alloc, .Free, .Free_All, .Resize, .Query_Features}
}
- return nil, nil;
+ return nil, nil
case .Query_Info:
- return nil, nil;
+ return nil, nil
}
- return nil, nil;
+ return nil, nil
}
scratch_allocator :: proc (allocator: ^Scratch_Allocator) -> mem.Allocator {
return mem.Allocator {
procedure = scratch_allocator_proc,
data = allocator,
- };
+ }
}
diff --git a/src/common/ast.odin b/src/common/ast.odin
index 69f35e0..7677634 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -62,7 +62,7 @@ keyword_map: map[string]bool = {
"quaternion64" = true,
"quaternion128" = true,
"quaternion256" = true,
-};
+}
GlobalExpr :: struct {
name: string,
@@ -77,63 +77,63 @@ GlobalExpr :: struct {
unwrap_pointer :: proc(expr: ^ast.Expr) -> (ast.Ident, bool) {
- expr := expr;
+ expr := expr
for expr != nil {
- if pointer, ok := expr.derived.(ast.Pointer_Type); ok {
- expr = pointer.elem;
+ if pointer, ok := expr.derived.(^ast.Pointer_Type); ok {
+ expr = pointer.elem
} else {
- break;
+ break
}
}
if expr != nil {
- ident, ok := expr.derived.(ast.Ident);
- return ident, ok;
+ ident, ok := expr.derived.(^ast.Ident)
+ return ident^, ok
}
- return {}, false;
+ return {}, false
}
collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^ast.Node, skip_private: bool) {
- if value_decl, ok := stmt.derived.(ast.Value_Decl); ok {
+ if value_decl, ok := stmt.derived.(^ast.Value_Decl); ok {
- is_deprecated := false;
- is_private_file := false;
- is_package_file := false;
+ is_deprecated := false
+ is_private_file := false
+ is_package_file := false
for attribute in value_decl.attributes {
for elem in attribute.elems {
- if value, ok := elem.derived.(ast.Field_Value); ok {
- if ident, ok := value.field.derived.(ast.Ident); ok {
+ if value, ok := elem.derived.(^ast.Field_Value); ok {
+ if ident, ok := value.field.derived.(^ast.Ident); ok {
switch ident.name {
case "private":
- if val, ok := value.value.derived.(ast.Basic_Lit); ok {
+ if val, ok := value.value.derived.(^ast.Basic_Lit); ok {
switch val.tok.text {
case "\"file\"":
- is_private_file = true;
+ is_private_file = true
case "package":
- is_package_file = true;
+ is_package_file = true
}
}
case "deprecated":
- is_deprecated = true;
+ is_deprecated = true
}
}
- } else if ident, ok := elem.derived.(ast.Ident); ok {
+ } else if ident, ok := elem.derived.(^ast.Ident); ok {
switch ident.name {
case "deprecated":
- is_deprecated = true;
+ is_deprecated = true
}
}
}
}
if is_private_file && skip_private {
- return;
+ return
}
for name, i in value_decl.names {
- str := get_ast_node_string(name, file.src);
+ str := get_ast_node_string(name, file.src)
if value_decl.type != nil {
append(exprs, GlobalExpr {
@@ -143,7 +143,7 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
docs = value_decl.docs,
attributes = value_decl.attributes[:],
deprecated = is_deprecated,
- });
+ })
} else {
if len(value_decl.values) > i {
append(exprs, GlobalExpr {
@@ -153,7 +153,7 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
docs = value_decl.docs,
attributes = value_decl.attributes[:],
deprecated = is_deprecated,
- });
+ })
}
}
}
@@ -161,98 +161,97 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
}
collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr {
- exprs := make([dynamic]GlobalExpr, context.temp_allocator);
+ exprs := make([dynamic]GlobalExpr, context.temp_allocator)
for decl in file.decls {
- if value_decl, ok := decl.derived.(ast.Value_Decl); ok {
- collect_value_decl(&exprs, file, decl, skip_private);
- } else if when_decl, ok := decl.derived.(ast.When_Stmt); ok {
+ if value_decl, ok := decl.derived.(^ast.Value_Decl); ok {
+ collect_value_decl(&exprs, file, decl, skip_private)
+ } else if when_decl, ok := decl.derived.(^ast.When_Stmt); ok {
if when_decl.cond == nil {
- continue;
+ continue
}
if when_decl.body == nil {
- continue;
+ continue
}
- if binary, ok := when_decl.cond.derived.(ast.Binary_Expr); ok {
+ if binary, ok := when_decl.cond.derived.(^ast.Binary_Expr); ok {
if binary.left == nil || binary.right == nil {
- continue;
+ continue
}
- ident: ^ast.Ident;
- basic_lit: ^ast.Basic_Lit;
+ ident: ^ast.Ident
+ implicit: ^ast.Implicit
- if t, ok := binary.left.derived.(ast.Ident); ok {
- ident = cast(^ast.Ident)binary.left;
- } else if t, ok := binary.left.derived.(ast.Basic_Lit); ok {
- basic_lit = cast(^ast.Basic_Lit)binary.left;
+ if t, ok := binary.left.derived.(^ast.Ident); ok {
+ ident = cast(^ast.Ident)binary.left
+ } else if t, ok := binary.left.derived.(^ast.Basic_Lit); ok {
+ implicit = cast(^ast.Implicit)binary.left
}
- if t, ok := binary.right.derived.(ast.Ident); ok {
- ident = cast(^ast.Ident)binary.right;
- } else if t, ok := binary.right.derived.(ast.Basic_Lit); ok {
- basic_lit = cast(^ast.Basic_Lit)binary.right;
+ if t, ok := binary.right.derived.(^ast.Ident); ok {
+ ident = cast(^ast.Ident)binary.right
+ } else if t, ok := binary.right.derived.(^ast.Basic_Lit); ok {
+ implicit = cast(^ast.Implicit)binary.right
}
- if ident != nil && basic_lit != nil {
- if ident.name == "ODIN_OS" && basic_lit.tok.text[1:len(basic_lit.tok.text)-1] == ODIN_OS {
- if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok {
+ if ident != nil && implicit != nil {
+ if ident.name == "ODIN_OS" && implicit.tok.text == fmt.tprint(ODIN_OS) {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
} else if ident.name != "ODIN_OS" {
- if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
}
}
} else {
- if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
}
- } else if foreign_decl, ok := decl.derived.(ast.Foreign_Block_Decl); ok {
+ } else if foreign_decl, ok := decl.derived.(^ast.Foreign_Block_Decl); ok {
if foreign_decl.body == nil {
- continue;
+ continue
}
- if block, ok := foreign_decl.body.derived.(ast.Block_Stmt); ok {
+ if block, ok := foreign_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
}
}
- return exprs[:];
+ return exprs[:]
}
get_ast_node_string :: proc(node: ^ast.Node, src: string) -> string {
- return string(src[node.pos.offset:node.end.offset]);
+ return string(src[node.pos.offset:node.end.offset])
}
get_doc :: proc(comment: ^ast.Comment_Group, allocator: mem.Allocator) -> string {
-
if comment != nil {
- tmp: string;
+ tmp: string
for doc in comment.list {
- tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator);
+ tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator)
}
if tmp != "" {
- replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator);
- return strings.clone(replaced, allocator);
+ replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator)
+ return strings.clone(replaced, allocator)
}
}
- return "";
+ return ""
}
free_ast :: proc{
@@ -260,451 +259,443 @@ free_ast :: proc{
free_ast_array,
free_ast_dynamic_array,
free_ast_comment,
-};
+}
free_ast_comment :: proc(a: ^ast.Comment_Group, allocator: mem.Allocator) {
if a == nil {
- return;
+ return
}
if len(a.list) > 0 {
- delete(a.list, allocator);
+ delete(a.list, allocator)
}
- free(a, allocator);
+ free(a, allocator)
}
free_ast_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) {
for elem, i in array {
- free_ast(elem, allocator);
+ free_ast(elem, allocator)
}
- delete(array, allocator);
+ delete(array, allocator)
}
free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) {
for elem, i in array {
- free_ast(elem, allocator);
+ free_ast(elem, allocator)
}
- delete(array);
+ delete(array)
}
free_ast_node :: proc(node: ^ast.Node, allocator: mem.Allocator) {
-
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
- case Implicit:
- case Undef:
- case Basic_Directive:
- case Basic_Lit:
- case Ellipsis:
- free_ast(n.expr, allocator);
- case Proc_Lit:
- free_ast(n.type, allocator);
- free_ast(n.body, allocator);
- free_ast(n.where_clauses, allocator);
- case Comp_Lit:
- free_ast(n.type, allocator);
- free_ast(n.elems, allocator);
- case Tag_Expr:
- free_ast(n.expr, allocator);
- case Unary_Expr:
- free_ast(n.expr, allocator);
- case Binary_Expr:
- free_ast(n.left, allocator);
- free_ast(n.right, allocator);
- case Paren_Expr:
- free_ast(n.expr, allocator);
- case Call_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.args, allocator);
- case Selector_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.field, allocator);
- case Implicit_Selector_Expr:
- free_ast(n.field, allocator);
- case Index_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.index, allocator);
- case Deref_Expr:
- free_ast(n.expr, allocator);
- case Slice_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.low, allocator);
- free_ast(n.high, allocator);
- case Field_Value:
- free_ast(n.field, allocator);
- free_ast(n.value, allocator);
- case Ternary_If_Expr:
- free_ast(n.x, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.y, allocator);
- case Ternary_When_Expr:
- free_ast(n.x, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.y, allocator);
- case Type_Assertion:
- free_ast(n.expr, allocator);
- free_ast(n.type, allocator);
- case Type_Cast:
- free_ast(n.type, allocator);
- free_ast(n.expr, allocator);
- case Auto_Cast:
- free_ast(n.expr, allocator);
- case Bad_Stmt:
- case Empty_Stmt:
- case Expr_Stmt:
- free_ast(n.expr, allocator);
- case Tag_Stmt:
- r := cast(^Expr_Stmt)node;
- free_ast(r.expr, allocator);
- case Assign_Stmt:
- free_ast(n.lhs, allocator);
- free_ast(n.rhs, allocator);
- case Block_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.stmts, allocator);
- case If_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.init, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.body, allocator);
- free_ast(n.else_stmt, allocator);
- case When_Stmt:
- free_ast(n.cond, allocator);
- free_ast(n.body, allocator);
- free_ast(n.else_stmt, allocator);
- case Return_Stmt:
- free_ast(n.results, allocator);
- case Defer_Stmt:
- free_ast(n.stmt, allocator);
- case For_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.init, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.post, allocator);
- free_ast(n.body, allocator);
- case Range_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.vals, allocator);
- free_ast(n.expr, allocator);
- free_ast(n.body, allocator);
- case Case_Clause:
- free_ast(n.list, allocator);
- free_ast(n.body, allocator);
- case Switch_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.init, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.body, allocator);
- case Type_Switch_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.tag, allocator);
- free_ast(n.expr, allocator);
- free_ast(n.body, allocator);
- case Branch_Stmt:
- free_ast(n.label, allocator);
- case Using_Stmt:
- free_ast(n.list, allocator);
- case Bad_Decl:
- case Value_Decl:
- free_ast(n.attributes, allocator);
- free_ast(n.names, allocator);
- free_ast(n.type, allocator);
- free_ast(n.values, allocator);
- //free_ast(n.docs);
- //free_ast(n.comment);
- case Package_Decl:
- //free_ast(n.docs);
- //free_ast(n.comment);
- case Import_Decl:
- //free_ast(n.docs);
- //free_ast(n.comment);
- case Foreign_Block_Decl:
- free_ast(n.attributes, allocator);
- free_ast(n.foreign_library, allocator);
- free_ast(n.body, allocator);
- case Foreign_Import_Decl:
- free_ast(n.name, allocator);
- free_ast(n.attributes, allocator);
- case Proc_Group:
- free_ast(n.args, allocator);
- case Attribute:
- free_ast(n.elems, allocator);
- case Field:
- free_ast(n.names, allocator);
- free_ast(n.type, allocator);
- free_ast(n.default_value, allocator);
+ if node.derived != nil do #partial switch n in node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
+ case ^Implicit:
+ case ^Undef:
+ case ^Basic_Directive:
+ case ^Basic_Lit:
+ case ^Ellipsis:
+ free_ast(n.expr, allocator)
+ case ^Proc_Lit:
+ free_ast(n.type, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Comp_Lit:
+ free_ast(n.type, allocator)
+ free_ast(n.elems, allocator)
+ case ^Tag_Expr:
+ free_ast(n.expr, allocator)
+ case ^Unary_Expr:
+ free_ast(n.expr, allocator)
+ case ^Binary_Expr:
+ free_ast(n.left, allocator)
+ free_ast(n.right, allocator)
+ case ^Paren_Expr:
+ free_ast(n.expr, allocator)
+ case ^Call_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.args, allocator)
+ case ^Selector_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.field, allocator)
+ case ^Implicit_Selector_Expr:
+ free_ast(n.field, allocator)
+ case ^Index_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.index, allocator)
+ case ^Deref_Expr:
+ free_ast(n.expr, allocator)
+ case ^Slice_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.low, allocator)
+ free_ast(n.high, allocator)
+ case ^Field_Value:
+ free_ast(n.field, allocator)
+ free_ast(n.value, allocator)
+ case ^Ternary_If_Expr:
+ free_ast(n.x, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.y, allocator)
+ case ^Ternary_When_Expr:
+ free_ast(n.x, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.y, allocator)
+ case ^Type_Assertion:
+ free_ast(n.expr, allocator)
+ free_ast(n.type, allocator)
+ case ^Type_Cast:
+ free_ast(n.type, allocator)
+ free_ast(n.expr, allocator)
+ case ^Auto_Cast:
+ free_ast(n.expr, allocator)
+ case ^Bad_Stmt:
+ case ^Empty_Stmt:
+ case ^Expr_Stmt:
+ free_ast(n.expr, allocator)
+ case ^Tag_Stmt:
+ r := cast(^Expr_Stmt)node
+ free_ast(r.expr, allocator)
+ case ^Assign_Stmt:
+ free_ast(n.lhs, allocator)
+ free_ast(n.rhs, allocator)
+ case ^Block_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.stmts, allocator)
+ case ^If_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.init, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.else_stmt, allocator)
+ case ^When_Stmt:
+ free_ast(n.cond, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.else_stmt, allocator)
+ case ^Return_Stmt:
+ free_ast(n.results, allocator)
+ case ^Defer_Stmt:
+ free_ast(n.stmt, allocator)
+ case ^For_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.init, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.post, allocator)
+ free_ast(n.body, allocator)
+ case ^Range_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.vals, allocator)
+ free_ast(n.expr, allocator)
+ free_ast(n.body, allocator)
+ case ^Case_Clause:
+ free_ast(n.list, allocator)
+ free_ast(n.body, allocator)
+ case ^Switch_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.init, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.body, allocator)
+ case ^Type_Switch_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.tag, allocator)
+ free_ast(n.expr, allocator)
+ free_ast(n.body, allocator)
+ case ^Branch_Stmt:
+ free_ast(n.label, allocator)
+ case ^Using_Stmt:
+ free_ast(n.list, allocator)
+ case ^Bad_Decl:
+ case ^Value_Decl:
+ free_ast(n.attributes, allocator)
+ free_ast(n.names, allocator)
+ free_ast(n.type, allocator)
+ free_ast(n.values, allocator)
+ case ^Package_Decl:
+ case ^Import_Decl:
+ case ^Foreign_Block_Decl:
+ free_ast(n.attributes, allocator)
+ free_ast(n.foreign_library, allocator)
+ free_ast(n.body, allocator)
+ case ^Foreign_Import_Decl:
+ free_ast(n.name, allocator)
+ free_ast(n.attributes, allocator)
+ case ^Proc_Group:
+ free_ast(n.args, allocator)
+ case ^Attribute:
+ free_ast(n.elems, allocator)
+ case ^Field:
+ free_ast(n.names, allocator)
+ free_ast(n.type, allocator)
+ free_ast(n.default_value, allocator)
//free_ast(n.docs);
//free_ast(n.comment);
- case Field_List:
- free_ast(n.list, allocator);
- case Typeid_Type:
- free_ast(n.specialization, allocator);
- case Helper_Type:
- free_ast(n.type, allocator);
- case Distinct_Type:
- free_ast(n.type, allocator);
- case Poly_Type:
- free_ast(n.type, allocator);
- free_ast(n.specialization, allocator);
- case Proc_Type:
- free_ast(n.params, allocator);
- free_ast(n.results, allocator);
- case Pointer_Type:
- free_ast(n.elem, allocator);
- case Array_Type:
- free_ast(n.len, allocator);
- free_ast(n.elem, allocator);
- free_ast(n.tag, allocator);
- case Dynamic_Array_Type:
- free_ast(n.elem, allocator);
- free_ast(n.tag, allocator);
- case Struct_Type:
- free_ast(n.poly_params, allocator);
- free_ast(n.align, allocator);
- free_ast(n.fields, allocator);
- free_ast(n.where_clauses, allocator);
- case Union_Type:
- free_ast(n.poly_params, allocator);
- free_ast(n.align, allocator);
- free_ast(n.variants, allocator);
- free_ast(n.where_clauses, allocator);
- case Enum_Type:
- free_ast(n.base_type, allocator);
- free_ast(n.fields, allocator);
- case Bit_Set_Type:
- free_ast(n.elem, allocator);
- free_ast(n.underlying, allocator);
- case Map_Type:
- free_ast(n.key, allocator);
- free_ast(n.value, allocator);
- case Multi_Pointer_Type:
- free_ast(n.elem, allocator);
- case Matrix_Type:
- free_ast(n.elem, allocator);
+ case ^Field_List:
+ free_ast(n.list, allocator)
+ case ^Typeid_Type:
+ free_ast(n.specialization, allocator)
+ case ^Helper_Type:
+ free_ast(n.type, allocator)
+ case ^Distinct_Type:
+ free_ast(n.type, allocator)
+ case ^Poly_Type:
+ free_ast(n.type, allocator)
+ free_ast(n.specialization, allocator)
+ case ^Proc_Type:
+ free_ast(n.params, allocator)
+ free_ast(n.results, allocator)
+ case ^Pointer_Type:
+ free_ast(n.elem, allocator)
+ case ^Array_Type:
+ free_ast(n.len, allocator)
+ free_ast(n.elem, allocator)
+ free_ast(n.tag, allocator)
+ case ^Dynamic_Array_Type:
+ free_ast(n.elem, allocator)
+ free_ast(n.tag, allocator)
+ case ^Struct_Type:
+ free_ast(n.poly_params, allocator)
+ free_ast(n.align, allocator)
+ free_ast(n.fields, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Union_Type:
+ free_ast(n.poly_params, allocator)
+ free_ast(n.align, allocator)
+ free_ast(n.variants, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Enum_Type:
+ free_ast(n.base_type, allocator)
+ free_ast(n.fields, allocator)
+ case ^Bit_Set_Type:
+ free_ast(n.elem, allocator)
+ free_ast(n.underlying, allocator)
+ case ^Map_Type:
+ free_ast(n.key, allocator)
+ free_ast(n.value, allocator)
+ case ^Multi_Pointer_Type:
+ free_ast(n.elem, allocator)
+ case ^Matrix_Type:
+ free_ast(n.elem, allocator)
case:
- panic(fmt.aprintf("free Unhandled node kind: %T", n));
+ panic(fmt.aprintf("free Unhandled node kind: %T", n))
}
- mem.free(node, allocator);
+ mem.free(node, allocator)
}
free_ast_file :: proc(file: ast.File, allocator := context.allocator) {
for decl in file.decls {
- free_ast(decl, allocator);
+ free_ast(decl, allocator)
}
- free_ast(file.pkg_decl, allocator);
+ free_ast(file.pkg_decl, allocator)
for comment in file.comments {
- free_ast(comment, allocator);
+ free_ast(comment, allocator)
}
- delete(file.comments);
- delete(file.imports);
- delete(file.decls);
+ delete(file.comments)
+ delete(file.imports)
+ delete(file.decls)
}
node_equal :: proc{
node_equal_node,
node_equal_array,
node_equal_dynamic_array,
-};
+}
node_equal_array :: proc(a, b: $A/[]^$T) -> bool {
- ret := true;
+ ret := true
if len(a) != len(b) {
- return false;
+ return false
}
for elem, i in a {
- ret &= node_equal(elem, b[i]);
+ ret &= node_equal(elem, b[i])
}
- return ret;
+ return ret
}
node_equal_dynamic_array :: proc(a, b: $A/[dynamic]^$T) -> bool {
- ret := true;
+ ret := true
if len(a) != len(b) {
- return false;
+ return false
}
for elem, i in a {
- ret &= node_equal(elem, b[i]);
+ ret &= node_equal(elem, b[i])
}
- return ret;
+ return ret
}
node_equal_node :: proc(a, b: ^ast.Node) -> bool {
-
- using ast;
+ using ast
if a == nil || b == nil {
- return false;
+ return false
}
- switch m in b.derived {
- case Bad_Expr:
- if n, ok := a.derived.(Bad_Expr); ok {
- return true;
+ #partial switch m in b.derived {
+ case ^Bad_Expr:
+ if n, ok := a.derived.(^Bad_Expr); ok {
+ return true
}
- case Ident:
- if n, ok := a.derived.(Ident); ok {
- return true;
+ case ^Ident:
+ if n, ok := a.derived.(^Ident); ok {
+ return true
//return n.name == m.name;
}
- case Implicit:
- if n, ok := a.derived.(Implicit); ok {
- return true;
- }
- case Undef:
- if n, ok := a.derived.(Undef); ok {
- return true;
- }
- case Basic_Lit:
- if n, ok := a.derived.(Basic_Lit); ok {
- return true;
- }
- case Poly_Type:
- return true;
- case Ellipsis:
- if n, ok := a.derived.(Ellipsis); ok {
- return node_equal(n.expr, m.expr);
- }
- case Tag_Expr:
- if n, ok := a.derived.(Tag_Expr); ok {
- return node_equal(n.expr, m.expr);
- }
- case Unary_Expr:
- if n, ok := a.derived.(Unary_Expr); ok {
- return node_equal(n.expr, m.expr);
- }
- case Binary_Expr:
- if n, ok := a.derived.(Binary_Expr); ok {
- ret := node_equal(n.left, m.left);
- ret &= node_equal(n.right, m.right);
- return ret;
- }
- case Paren_Expr:
- if n, ok := a.derived.(Paren_Expr); ok {
- return node_equal(n.expr, m.expr);
- }
- case Selector_Expr:
- if n, ok := a.derived.(Selector_Expr); ok {
- ret := node_equal(n.expr, m.expr);
- ret &= node_equal(n.field, m.field);
- return ret;
- }
- case Slice_Expr:
- if n, ok := a.derived.(Slice_Expr); ok {
- ret := node_equal(n.expr, m.expr);
- ret &= node_equal(n.low, m.low);
- ret &= node_equal(n.high, m.high);
- return ret;
- }
- case Distinct_Type:
- if n, ok := a.derived.(Distinct_Type); ok {
- return node_equal(n.type, m.type);
- }
- case Proc_Type:
- if n, ok := a.derived.(Proc_Type); ok {
- ret := node_equal(n.params, m.params);
- ret &= node_equal(n.results, m.results);
- return ret;
- }
- case Pointer_Type:
- if n, ok := a.derived.(Pointer_Type); ok {
- return node_equal(n.elem, m.elem);
- }
- case Array_Type:
- if n, ok := a.derived.(Array_Type); ok {
- ret := node_equal(n.elem, m.elem);
+ case ^Implicit:
+ if n, ok := a.derived.(^Implicit); ok {
+ return true
+ }
+ case ^Undef:
+ if n, ok := a.derived.(^Undef); ok {
+ return true
+ }
+ case ^Basic_Lit:
+ if n, ok := a.derived.(^Basic_Lit); ok {
+ return true
+ }
+ case ^Poly_Type:
+ return true
+ case ^Ellipsis:
+ if n, ok := a.derived.(^Ellipsis); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Tag_Expr:
+ if n, ok := a.derived.(^Tag_Expr); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Unary_Expr:
+ if n, ok := a.derived.(^Unary_Expr); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Binary_Expr:
+ if n, ok := a.derived.(^Binary_Expr); ok {
+ ret := node_equal(n.left, m.left)
+ ret &= node_equal(n.right, m.right)
+ return ret
+ }
+ case ^Paren_Expr:
+ if n, ok := a.derived.(^Paren_Expr); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Selector_Expr:
+ if n, ok := a.derived.(^Selector_Expr); ok {
+ ret := node_equal(n.expr, m.expr)
+ ret &= node_equal(n.field, m.field)
+ return ret
+ }
+ case ^Slice_Expr:
+ if n, ok := a.derived.(^Slice_Expr); ok {
+ ret := node_equal(n.expr, m.expr)
+ ret &= node_equal(n.low, m.low)
+ ret &= node_equal(n.high, m.high)
+ return ret
+ }
+ case ^Distinct_Type:
+ if n, ok := a.derived.(^Distinct_Type); ok {
+ return node_equal(n.type, m.type)
+ }
+ case ^Proc_Type:
+ if n, ok := a.derived.(^Proc_Type); ok {
+ ret := node_equal(n.params, m.params)
+ ret &= node_equal(n.results, m.results)
+ return ret
+ }
+ case ^Pointer_Type:
+ if n, ok := a.derived.(^Pointer_Type); ok {
+ return node_equal(n.elem, m.elem)
+ }
+ case ^Array_Type:
+ if n, ok := a.derived.(^Array_Type); ok {
+ ret := node_equal(n.elem, m.elem)
if n.len != nil && m.len != nil {
- ret &= node_equal(n.len, m.len);
+ ret &= node_equal(n.len, m.len)
}
- return ret;
- }
- case Dynamic_Array_Type:
- if n, ok := a.derived.(Dynamic_Array_Type); ok {
- return node_equal(n.elem, m.elem);
- }
- case Struct_Type:
- if n, ok := a.derived.(Struct_Type); ok {
- ret := node_equal(n.poly_params, m.poly_params);
- ret &= node_equal(n.align, m.align);
- ret &= node_equal(n.fields, m.fields);
- return ret;
- }
- case Field:
- if n, ok := a.derived.(Field); ok {
- ret := node_equal(n.names, m.names);
- ret &= node_equal(n.type, m.type);
- ret &= node_equal(n.default_value, m.default_value);
- return ret;
- }
- case Field_List:
- if n, ok := a.derived.(Field_List); ok {
- return node_equal(n.list, m.list);
- }
- case Field_Value:
- if n, ok := a.derived.(Field_Value); ok {
- ret := node_equal(n.field, m.field);
- ret &= node_equal(n.value, m.value);
- return ret;
- }
- case Union_Type:
- if n, ok := a.derived.(Union_Type); ok {
- ret := node_equal(n.poly_params, m.poly_params);
- ret &= node_equal(n.align, m.align);
- ret &= node_equal(n.variants, m.variants);
- return ret;
- }
- case Enum_Type:
- if n, ok := a.derived.(Enum_Type); ok {
- ret := node_equal(n.base_type, m.base_type);
- ret &= node_equal(n.fields, m.fields);
- return ret;
- }
- case Bit_Set_Type:
- if n, ok := a.derived.(Bit_Set_Type); ok {
- ret := node_equal(n.elem, m.elem);
- ret &= node_equal(n.underlying, m.underlying);
- return ret;
- }
- case Map_Type:
- if n, ok := a.derived.(Map_Type); ok {
- ret := node_equal(n.key, m.key);
- ret &= node_equal(n.value, m.value);
- return ret;
- }
- case Call_Expr:
- if n, ok := a.derived.(Call_Expr); ok {
- ret := node_equal(n.expr, m.expr);
- ret &= node_equal(n.args, m.args);
- return ret;
- }
- case Typeid_Type:
- return true;
+ return ret
+ }
+ case ^Dynamic_Array_Type:
+ if n, ok := a.derived.(^Dynamic_Array_Type); ok {
+ return node_equal(n.elem, m.elem)
+ }
+ case ^Struct_Type:
+ if n, ok := a.derived.(^Struct_Type); ok {
+ ret := node_equal(n.poly_params, m.poly_params)
+ ret &= node_equal(n.align, m.align)
+ ret &= node_equal(n.fields, m.fields)
+ return ret
+ }
+ case ^Field:
+ if n, ok := a.derived.(^Field); ok {
+ ret := node_equal(n.names, m.names)
+ ret &= node_equal(n.type, m.type)
+ ret &= node_equal(n.default_value, m.default_value)
+ return ret
+ }
+ case ^Field_List:
+ if n, ok := a.derived.(^Field_List); ok {
+ return node_equal(n.list, m.list)
+ }
+ case ^Field_Value:
+ if n, ok := a.derived.(^Field_Value); ok {
+ ret := node_equal(n.field, m.field)
+ ret &= node_equal(n.value, m.value)
+ return ret
+ }
+ case ^Union_Type:
+ if n, ok := a.derived.(^Union_Type); ok {
+ ret := node_equal(n.poly_params, m.poly_params)
+ ret &= node_equal(n.align, m.align)
+ ret &= node_equal(n.variants, m.variants)
+ return ret
+ }
+ case ^Enum_Type:
+ if n, ok := a.derived.(^Enum_Type); ok {
+ ret := node_equal(n.base_type, m.base_type)
+ ret &= node_equal(n.fields, m.fields)
+ return ret
+ }
+ case ^Bit_Set_Type:
+ if n, ok := a.derived.(^Bit_Set_Type); ok {
+ ret := node_equal(n.elem, m.elem)
+ ret &= node_equal(n.underlying, m.underlying)
+ return ret
+ }
+ case ^Map_Type:
+ if n, ok := a.derived.(^Map_Type); ok {
+ ret := node_equal(n.key, m.key)
+ ret &= node_equal(n.value, m.value)
+ return ret
+ }
+ case ^Call_Expr:
+ if n, ok := a.derived.(^Call_Expr); ok {
+ ret := node_equal(n.expr, m.expr)
+ ret &= node_equal(n.args, m.args)
+ return ret
+ }
+ case ^Typeid_Type:
+ return true
case:
- log.warn("Unhandled poly node kind: %T", m);
+ log.warn("Unhandled poly node kind: %T", m)
}
- return false;
+ return false
}
/*
@@ -712,199 +703,198 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool {
*/
node_to_string :: proc(node: ^ast.Node) -> string {
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
- build_string(node, &builder);
+ build_string(node, &builder)
- return strings.to_string(builder);
+ return strings.to_string(builder)
}
build_string :: proc{
build_string_ast_array,
build_string_dynamic_array,
build_string_node,
-};
+}
build_string_dynamic_array :: proc(array: $A/[]^$T, builder: ^strings.Builder) {
for elem, i in array {
- build_string(elem, builder);
+ build_string(elem, builder)
}
}
build_string_ast_array :: proc(array: $A/[dynamic]^$T, builder: ^strings.Builder) {
for elem, i in array {
- build_string(elem, builder);
+ build_string(elem, builder)
}
}
build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder) {
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
+ #partial switch n in node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
if strings.contains(n.name, "/") {
- strings.write_string(builder, path.base(n.name, false, context.temp_allocator));
+ strings.write_string(builder, path.base(n.name, false, context.temp_allocator))
} else {
- strings.write_string(builder, n.name);
- }
- case Implicit:
- strings.write_string(builder, n.tok.text);
- case Undef:
- case Basic_Lit:
- strings.write_string(builder, n.tok.text);
- case Basic_Directive:
- strings.write_string(builder, n.name);
- case Implicit_Selector_Expr:
- strings.write_string(builder, ".");
- build_string(n.field, builder);
- case Ellipsis:
- strings.write_string(builder, "..");
- build_string(n.expr, builder);
- case Proc_Lit:
- build_string(n.type, builder);
- build_string(n.body, builder);
- case Comp_Lit:
- build_string(n.type, builder);
- strings.write_string(builder, "{");
- build_string(n.elems, builder);
- strings.write_string(builder, "}");
- case Tag_Expr:
- build_string(n.expr, builder);
- case Unary_Expr:
- build_string(n.expr, builder);
- case Binary_Expr:
- build_string(n.left, builder);
- build_string(n.right, builder);
- case Paren_Expr:
- strings.write_string(builder, "(");
- build_string(n.expr, builder);
- strings.write_string(builder, ")");
- case Call_Expr:
- build_string(n.expr, builder);
- strings.write_string(builder, "(");
+ strings.write_string(builder, n.name)
+ }
+ case ^Implicit:
+ strings.write_string(builder, n.tok.text)
+ case ^Undef:
+ case ^Basic_Lit:
+ strings.write_string(builder, n.tok.text)
+ case ^Basic_Directive:
+ strings.write_string(builder, n.name)
+ case ^Implicit_Selector_Expr:
+ strings.write_string(builder, ".")
+ build_string(n.field, builder)
+ case ^Ellipsis:
+ strings.write_string(builder, "..")
+ build_string(n.expr, builder)
+ case ^Proc_Lit:
+ build_string(n.type, builder)
+ build_string(n.body, builder)
+ case ^Comp_Lit:
+ build_string(n.type, builder)
+ strings.write_string(builder, "{")
+ build_string(n.elems, builder)
+ strings.write_string(builder, "}")
+ case ^Tag_Expr:
+ build_string(n.expr, builder)
+ case ^Unary_Expr:
+ build_string(n.expr, builder)
+ case ^Binary_Expr:
+ build_string(n.left, builder)
+ build_string(n.right, builder)
+ case ^Paren_Expr:
+ strings.write_string(builder, "(")
+ build_string(n.expr, builder)
+ strings.write_string(builder, ")")
+ case ^Call_Expr:
+ build_string(n.expr, builder)
+ strings.write_string(builder, "(")
for arg, i in n.args {
- build_string(arg, builder);
+ build_string(arg, builder)
if len(n.args) - 1 != i {
- strings.write_string(builder, ", ");
+ strings.write_string(builder, ", ")
}
}
- strings.write_string(builder, ")");
- case Selector_Expr:
- build_string(n.expr, builder);
- strings.write_string(builder, ".");
- build_string(n.field, builder);
- case Index_Expr:
- build_string(n.expr, builder);
- strings.write_string(builder, "[");
- build_string(n.index, builder);
- strings.write_string(builder, "]");
- case Deref_Expr:
- build_string(n.expr, builder);
- case Slice_Expr:
- build_string(n.expr, builder);
- build_string(n.low, builder);
- build_string(n.high, builder);
- case Field_Value:
- build_string(n.field, builder);
- strings.write_string(builder, ": ");
- build_string(n.value, builder);
- case Type_Cast:
- build_string(n.type, builder);
- build_string(n.expr, builder);
- case Bad_Stmt:
- case Bad_Decl:
- case Attribute:
- build_string(n.elems, builder);
- case Field:
-
+ strings.write_string(builder, ")")
+ case ^Selector_Expr:
+ build_string(n.expr, builder)
+ strings.write_string(builder, ".")
+ build_string(n.field, builder)
+ case ^Index_Expr:
+ build_string(n.expr, builder)
+ strings.write_string(builder, "[")
+ build_string(n.index, builder)
+ strings.write_string(builder, "]")
+ case ^Deref_Expr:
+ build_string(n.expr, builder)
+ case ^Slice_Expr:
+ build_string(n.expr, builder)
+ build_string(n.low, builder)
+ build_string(n.high, builder)
+ case ^Field_Value:
+ build_string(n.field, builder)
+ strings.write_string(builder, ": ")
+ build_string(n.value, builder)
+ case ^Type_Cast:
+ build_string(n.type, builder)
+ build_string(n.expr, builder)
+ case ^Bad_Stmt:
+ case ^Bad_Decl:
+ case ^Attribute:
+ build_string(n.elems, builder)
+ case ^Field:
for name, i in n.names {
- build_string(name, builder);
+ build_string(name, builder)
if len(n.names) - 1 != i {
- strings.write_string(builder, ", ");
+ strings.write_string(builder, ", ")
}
}
if len(n.names) > 0 && n.type != nil {
- strings.write_string(builder, ": ");
- build_string(n.type, builder);
+ strings.write_string(builder, ": ")
+ build_string(n.type, builder)
if n.default_value != nil && n.type != nil {
- strings.write_string(builder, " = ");
+ strings.write_string(builder, " = ")
}
} else if len(n.names) > 0 && n.default_value != nil {
- strings.write_string(builder, " := ");
+ strings.write_string(builder, " := ")
} else {
- build_string(n.type, builder);
+ build_string(n.type, builder)
}
- build_string(n.default_value, builder);
- case Field_List:
+ build_string(n.default_value, builder)
+ case ^Field_List:
for field, i in n.list {
- build_string(field, builder);
+ build_string(field, builder)
if len(n.list) - 1 != i {
- strings.write_string(builder, ",");
+ strings.write_string(builder, ",")
}
}
- case Typeid_Type:
- strings.write_string(builder, "$");
- build_string(n.specialization, builder);
- case Helper_Type:
- build_string(n.type, builder);
- case Distinct_Type:
- build_string(n.type, builder);
- case Poly_Type:
- strings.write_string(builder, "$");
+ case ^Typeid_Type:
+ strings.write_string(builder, "$")
+ build_string(n.specialization, builder)
+ case ^Helper_Type:
+ build_string(n.type, builder)
+ case ^Distinct_Type:
+ build_string(n.type, builder)
+ case ^Poly_Type:
+ strings.write_string(builder, "$")
- build_string(n.type, builder);
+ build_string(n.type, builder)
if n.specialization != nil {
- strings.write_string(builder, "/");
- build_string(n.specialization, builder);
- }
- case Proc_Type:
- strings.write_string(builder, "proc(");
- build_string(n.params, builder);
- strings.write_string(builder, ") -> ");
- build_string(n.results, builder);
- case Pointer_Type:
- strings.write_string(builder, "^");
- build_string(n.elem, builder);
- case Array_Type:
- strings.write_string(builder, "[");
- build_string(n.len, builder);
- strings.write_string(builder, "]");
- build_string(n.elem, builder);
- case Dynamic_Array_Type:
- strings.write_string(builder, "[dynamic]");
- build_string(n.elem, builder);
- case Struct_Type:
- build_string(n.poly_params, builder);
- build_string(n.align, builder);
- build_string(n.fields, builder);
- case Union_Type:
- build_string(n.poly_params, builder);
- build_string(n.align, builder);
- build_string(n.variants, builder);
- case Enum_Type:
- build_string(n.base_type, builder);
- build_string(n.fields, builder);
- case Bit_Set_Type:
- build_string(n.elem, builder);
- build_string(n.underlying, builder);
- case Map_Type:
- strings.write_string(builder, "map");
- strings.write_string(builder, "[");
- build_string(n.key, builder);
- strings.write_string(builder, "]");
- build_string(n.value, builder);
+ strings.write_string(builder, "/")
+ build_string(n.specialization, builder)
+ }
+ case ^Proc_Type:
+ strings.write_string(builder, "proc(")
+ build_string(n.params, builder)
+ strings.write_string(builder, ") -> ")
+ build_string(n.results, builder)
+ case ^Pointer_Type:
+ strings.write_string(builder, "^")
+ build_string(n.elem, builder)
+ case ^Array_Type:
+ strings.write_string(builder, "[")
+ build_string(n.len, builder)
+ strings.write_string(builder, "]")
+ build_string(n.elem, builder)
+ case ^Dynamic_Array_Type:
+ strings.write_string(builder, "[dynamic]")
+ build_string(n.elem, builder)
+ case ^Struct_Type:
+ build_string(n.poly_params, builder)
+ build_string(n.align, builder)
+ build_string(n.fields, builder)
+ case ^Union_Type:
+ build_string(n.poly_params, builder)
+ build_string(n.align, builder)
+ build_string(n.variants, builder)
+ case ^Enum_Type:
+ build_string(n.base_type, builder)
+ build_string(n.fields, builder)
+ case ^Bit_Set_Type:
+ build_string(n.elem, builder)
+ build_string(n.underlying, builder)
+ case ^Map_Type:
+ strings.write_string(builder, "map")
+ strings.write_string(builder, "[")
+ build_string(n.key, builder)
+ strings.write_string(builder, "]")
+ build_string(n.value, builder)
}
}
diff --git a/src/common/fuzzy.odin b/src/common/fuzzy.odin
index 68223e0..f6c8b11 100644
--- a/src/common/fuzzy.odin
+++ b/src/common/fuzzy.odin
@@ -7,15 +7,15 @@ import "core:fmt"
Ported from https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clangd/FuzzyMatch.cpp
*/
-max_pattern :: 63;
-max_word :: 127;
+max_pattern :: 63
+max_word :: 127
-awful_score: int = -(1 << 13);
-perfect_bonus :: 4;
-miss :: 0;
-match :: 1;
+awful_score: int = -(1 << 13)
+perfect_bonus :: 4
+miss :: 0
+match :: 1
-FuzzyCharTypeSet :: u8;
+FuzzyCharTypeSet :: u8
//do bitfield instead
FuzzyScoreInfo :: struct {
@@ -60,7 +60,7 @@ char_roles: []u8 = {
/*Prev=Upper */0x00,0x55,0x59,0xff, // Ditto, but U(U)U->Tail
/*Prev=Separ */0x00,0xaa,0xaa,0xff, // After separator, like at start
// clang-format on
-};
+}
char_types: []u8 = {
0x00,0x00,0x00,0x00, // Control characters
@@ -75,266 +75,266 @@ char_types: []u8 = {
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, // (probably UTF-8).
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-};
+}
make_fuzzy_matcher :: proc(pattern: string, allocator := context.temp_allocator) -> ^FuzzyMatcher {
- matcher := new(FuzzyMatcher, allocator);
+ matcher := new(FuzzyMatcher, allocator)
- matcher.pattern_count = min(len(pattern), max_pattern);
- matcher.score_scale = matcher.pattern_count > 0 ? 1 / cast(f32)(perfect_bonus * matcher.pattern_count) : 0;
- matcher.pattern = pattern[0:matcher.pattern_count];
- matcher.lower_pattern = strings.to_lower(matcher.pattern, context.temp_allocator);
+ matcher.pattern_count = min(len(pattern), max_pattern)
+ matcher.score_scale = matcher.pattern_count > 0 ? 1 / cast(f32)(perfect_bonus * matcher.pattern_count) : 0
+ matcher.pattern = pattern[0:matcher.pattern_count]
+ matcher.lower_pattern = strings.to_lower(matcher.pattern, context.temp_allocator)
- score_info_miss: FuzzyScoreInfo;
- score_info_miss.score = 0;
- score_info_miss.prev = miss;
+ score_info_miss: FuzzyScoreInfo
+ score_info_miss.score = 0
+ score_info_miss.prev = miss
- matcher.scores[0][0][miss] = score_info_miss;
+ matcher.scores[0][0][miss] = score_info_miss
- score_info_match: FuzzyScoreInfo;
- score_info_match.score = awful_score;
- score_info_match.prev = match;
+ score_info_match: FuzzyScoreInfo
+ score_info_match.score = awful_score
+ score_info_match.prev = match
- matcher.scores[0][0][match] = score_info_match;
+ matcher.scores[0][0][match] = score_info_match
for p := 0; p < matcher.pattern_count; p += 1 {
for w := 0; w < p; w += 1 {
for a := 0; a < 2; a += 1 {
- score_info: FuzzyScoreInfo;
- score_info.score = awful_score;
- score_info.prev = miss;
- matcher.scores[p][w][a] = score_info;
- ref := matcher.pattern_role[:matcher.pattern_count];
- matcher.pattern_type_set = fuzzy_calculate_roles(matcher.pattern, &ref);
+ score_info: FuzzyScoreInfo
+ score_info.score = awful_score
+ score_info.prev = miss
+ matcher.scores[p][w][a] = score_info
+ ref := matcher.pattern_role[:matcher.pattern_count]
+ matcher.pattern_type_set = fuzzy_calculate_roles(matcher.pattern, &ref)
}
}
}
- return matcher;
+ return matcher
}
fuzzy_to_acronym :: proc(word: string) -> (string, bool) {
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
if len(word) <= 1 {
- return "", false;
+ return "", false
}
- i := 1;
- last_char := word[0];
+ i := 1
+ last_char := word[0]
- strings.write_byte(&builder, last_char);
+ strings.write_byte(&builder, last_char)
for i < len(word) {
if last_char == '_' {
- strings.write_byte(&builder, word[i]);
+ strings.write_byte(&builder, word[i])
}
- last_char = word[i];
+ last_char = word[i]
- i += 1;
+ i += 1
}
- str := strings.to_string(builder);
+ str := strings.to_string(builder)
if len(str) <= 1 {
- return "", false;
+ return "", false
}
- return str, true;
+ return str, true
}
//changed from bool to int because of a linux bug - 10.05.2021
fuzzy_match :: proc(matcher: ^FuzzyMatcher, word: string) -> (f32, int) {
if !fuzzy_init(matcher, word) {
- return 0, 0;
+ return 0, 0
}
if matcher.pattern_count <= 0 {
- return 1, 1;
+ return 1, 1
}
if acronym, ok := fuzzy_to_acronym(word); ok {
if acronym == matcher.pattern {
- return 20, 1;
+ return 20, 1
}
}
- fuzzy_build_graph(matcher);
+ fuzzy_build_graph(matcher)
best := max(cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][miss].score,
- cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][match].score);
+ cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][match].score)
if fuzzy_is_awful(best) {
- return 0.0, 0;
+ return 0.0, 0
}
- score := matcher.score_scale * min(perfect_bonus * cast(f32)matcher.pattern_count, cast(f32)max(0, best));
+ score := matcher.score_scale * min(perfect_bonus * cast(f32)matcher.pattern_count, cast(f32)max(0, best))
if matcher.word_count == matcher.pattern_count {
- score *= 2;
+ score *= 2
}
- return score, 1;
+ return score, 1
}
fuzzy_is_awful :: proc(s: int) -> bool {
- return s < awful_score / 2;
+ return s < awful_score / 2
}
fuzzy_calculate_roles :: proc(text: string, roles: ^[]FuzzyCharRole) -> FuzzyCharTypeSet {
- assert(len(text) == len(roles));
+ assert(len(text) == len(roles))
if len(text) == 0 {
- return 0;
+ return 0
}
- type: FuzzyCharType = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[0]);
+ type: FuzzyCharType = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[0])
- type_set: FuzzyCharTypeSet = cast(u8)(1 << cast(uint)type);
+ type_set: FuzzyCharTypeSet = cast(u8)(1 << cast(uint)type)
- types := type;
+ types := type
for i := 0; i < len(text) - 1; i += 1 {
- type = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[i + 1]);
- type_set |= 1 << cast(uint)type;
+ type = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[i + 1])
+ type_set |= 1 << cast(uint)type
- fuzzy_rotate(type, &types);
+ fuzzy_rotate(type, &types)
- roles[i] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types);
+ roles[i] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types)
}
- fuzzy_rotate(.Empty, &types);
+ fuzzy_rotate(.Empty, &types)
- roles[len(text) - 1] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types);
+ roles[len(text) - 1] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types)
- return type_set;
+ return type_set
}
fuzzy_rotate :: proc(t: FuzzyCharType, types: ^FuzzyCharType) {
- types^ = cast(FuzzyCharType)(((cast(uint)types^ << 2) | cast(uint)t) & 0x3f);
+ types^ = cast(FuzzyCharType)(((cast(uint)types^ << 2) | cast(uint)t) & 0x3f)
}
fuzzy_packed_lookup :: proc(data: $A/[]$T, i: uint) -> T {
- return (data[i >> 2] >> ((i & 3) * 2)) & 3;
+ return (data[i >> 2] >> ((i & 3) * 2)) & 3
}
fuzzy_init :: proc(matcher: ^FuzzyMatcher, word: string) -> bool {
- matcher.word = word;
- matcher.word_count = min(max_word, len(matcher.word));
+ matcher.word = word
+ matcher.word_count = min(max_word, len(matcher.word))
if matcher.pattern_count > matcher.word_count {
- return false;
+ return false
}
if matcher.pattern_count == 0 {
- return true;
+ return true
}
- matcher.lower_word = strings.to_lower(word, context.temp_allocator);
+ matcher.lower_word = strings.to_lower(word, context.temp_allocator)
- w, p := 0, 0;
+ w, p := 0, 0
for ; p != matcher.pattern_count; w += 1 {
if w == matcher.word_count {
- return false;
+ return false
}
if matcher.lower_word[w] == matcher.lower_pattern[p] {
- p += 1;
+ p += 1
}
}
- ref := matcher.word_role[:matcher.word_count];
+ ref := matcher.word_role[:matcher.word_count]
- matcher.word_type_set = fuzzy_calculate_roles(word, &ref);
+ matcher.word_type_set = fuzzy_calculate_roles(word, &ref)
- return true;
+ return true
}
fuzzy_skip_penalty :: proc(matcher: ^FuzzyMatcher, w: int) -> int {
if w == 0 { // Skipping the first character.
- return 3;
+ return 3
}
if matcher.word_role[w] == .Head { // Skipping a segment.
- return 1;
+ return 1
}
- return 0;
+ return 0
}
fuzzy_build_graph :: proc(matcher: ^FuzzyMatcher) {
for w := 0; w < matcher.word_count; w += 1 {
- s: FuzzyScoreInfo;
+ s: FuzzyScoreInfo
- score := cast(int)matcher.scores[0][w][miss].score;
- penalty := fuzzy_skip_penalty(matcher, w);
- sum := score - penalty;
+ score := cast(int)matcher.scores[0][w][miss].score
+ penalty := fuzzy_skip_penalty(matcher, w)
+ sum := score - penalty
- s.score = sum;
- s.prev = miss;
+ s.score = sum
+ s.prev = miss
- matcher.scores[0][w + 1][miss] = s;
+ matcher.scores[0][w + 1][miss] = s
- s.score = awful_score;
- s.prev = miss;
+ s.score = awful_score
+ s.prev = miss
- matcher.scores[0][w + 1][match] = s;
+ matcher.scores[0][w + 1][match] = s
}
for p := 0; p < matcher.pattern_count; p += 1 {
for w := p; w < matcher.word_count; w += 1 {
- score := &matcher.scores[p + 1][w + 1];
- pre_miss := &matcher.scores[p + 1][w];
+ score := &matcher.scores[p + 1][w + 1]
+ pre_miss := &matcher.scores[p + 1][w]
- match_miss_score := pre_miss[match].score;
- miss_miss_score := pre_miss[miss].score;
+ match_miss_score := pre_miss[match].score
+ miss_miss_score := pre_miss[miss].score
if p < matcher.pattern_count - 1 {
- match_miss_score -= fuzzy_skip_penalty(matcher, w);
- miss_miss_score -= fuzzy_skip_penalty(matcher, w);
+ match_miss_score -= fuzzy_skip_penalty(matcher, w)
+ miss_miss_score -= fuzzy_skip_penalty(matcher, w)
}
if match_miss_score > miss_miss_score {
- s: FuzzyScoreInfo;
- s.score = match_miss_score;
- s.prev = match;
- score[miss] = s;
+ s: FuzzyScoreInfo
+ s.score = match_miss_score
+ s.prev = match
+ score[miss] = s
} else {
- s: FuzzyScoreInfo;
- s.score = miss_miss_score;
- s.prev = miss;
- score[miss] = s;
+ s: FuzzyScoreInfo
+ s.score = miss_miss_score
+ s.prev = miss
+ score[miss] = s
}
- pre_match := &matcher.scores[p][w];
+ pre_match := &matcher.scores[p][w]
- match_match_score := fuzzy_allow_match(matcher, p, w, match) ? cast(int)pre_match[match].score + fuzzy_match_bonus(matcher, p, w, match) : awful_score;
+ match_match_score := fuzzy_allow_match(matcher, p, w, match) ? cast(int)pre_match[match].score + fuzzy_match_bonus(matcher, p, w, match) : awful_score
- miss_match_score := fuzzy_allow_match(matcher, p, w, miss) ? cast(int)pre_match[miss].score + fuzzy_match_bonus(matcher, p, w, miss) : awful_score;
+ miss_match_score := fuzzy_allow_match(matcher, p, w, miss) ? cast(int)pre_match[miss].score + fuzzy_match_bonus(matcher, p, w, miss) : awful_score
if match_match_score > miss_match_score {
- s: FuzzyScoreInfo;
- s.score = match_match_score;
- s.prev = match;
- score[match] = s;
+ s: FuzzyScoreInfo
+ s.score = match_match_score
+ s.prev = match
+ score[match] = s
} else {
- s: FuzzyScoreInfo;
- s.score = miss_match_score;
- s.prev = miss;
- score[match] = s;
+ s: FuzzyScoreInfo
+ s.score = miss_match_score
+ s.prev = miss
+ score[match] = s
}
}
}
@@ -342,12 +342,12 @@ fuzzy_build_graph :: proc(matcher: ^FuzzyMatcher) {
fuzzy_match_bonus :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> int {
- assert(matcher.lower_pattern[p] == matcher.lower_word[w]);
+ assert(matcher.lower_pattern[p] == matcher.lower_word[w])
- s := 1;
+ s := 1
- is_pattern_single_case := (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Lower);
- is_pattern_single_case |= (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Upper);
+ is_pattern_single_case := (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Lower)
+ is_pattern_single_case |= (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Upper)
// Bonus: case matches, or a Head in the pattern aligns with one in the word.
// Single-case patterns lack segmentation signals and we assume any character
@@ -355,53 +355,53 @@ fuzzy_match_bonus :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) ->
if matcher.pattern[p] == matcher.word[w] ||
(matcher.word_role[w] == FuzzyCharRole.Head &&
(is_pattern_single_case || matcher.pattern_role[p] == FuzzyCharRole.Head)) {
- s += 1;
+ s += 1
//fmt.println("match 1");
}
// Bonus: a consecutive match. First character match also gets a bonus to
// ensure prefix final match score normalizes to 1.0.
if w == 0 || last == match {
- s += 2;
+ s += 2
//fmt.println("match 2");
}
// Penalty: matching inside a segment (and previous char wasn't matched).
if matcher.word_role[w] == FuzzyCharRole.Tail && p > 0 && last == miss {
- s -= 3;
+ s -= 3
//fmt.println("match 3");
}
// Penalty: a Head in the pattern matches in the middle of a word segment.
if matcher.pattern_role[p] == FuzzyCharRole.Head && matcher.word_role[w] == FuzzyCharRole.Tail {
- s -= 1;
+ s -= 1
//fmt.println("match 4");
}
// Penalty: matching the first pattern character in the middle of a segment.
if p == 0 && matcher.word_role[w] == FuzzyCharRole.Tail {
- s -= 4;
+ s -= 4
//fmt.println("match 5");
}
- assert(s <= perfect_bonus);
+ assert(s <= perfect_bonus)
- return s;
+ return s
}
fuzzy_allow_match :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> bool {
if matcher.lower_pattern[p] != matcher.lower_word[w] {
- return false;
+ return false
}
if last == miss {
if matcher.word_role[w] == FuzzyCharRole.Tail && (matcher.word[w] == matcher.lower_word[w] ||
0 >= (cast(uint)matcher.word_type_set & 1 << cast(uint)FuzzyCharType.Lower)) {
- return false;
+ return false
}
}
- return true;
+ return true
}
diff --git a/src/common/position.odin b/src/common/position.odin
index 4e84568..2ccd0a8 100644
--- a/src/common/position.odin
+++ b/src/common/position.odin
@@ -31,219 +31,219 @@ AbsoluteRange :: struct {
end: int,
}
-AbsolutePosition :: int;
+AbsolutePosition :: int
get_absolute_position :: proc(position: Position, document_text: []u8) -> (AbsolutePosition, bool) {
- absolute: AbsolutePosition;
+ absolute: AbsolutePosition
if len(document_text) == 0 {
- absolute = 0;
- return absolute, true;
+ absolute = 0
+ return absolute, true
}
- line_count := 0;
- index := 1;
- last := document_text[0];
+ line_count := 0
+ index := 1
+ last := document_text[0]
if !get_index_at_line(&index, &line_count, &last, document_text, position.line) {
- return absolute, false;
+ return absolute, false
}
- absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:]);
+ absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:])
- return absolute, true;
+ return absolute, true
}
get_relative_token_position :: proc(offset: int, document_text: []u8, current_start: int) -> Position {
- start_index := current_start;
+ start_index := current_start
- data := document_text[start_index:];
+ data := document_text[start_index:]
- i: int;
+ i: int
- position: Position;
+ position: Position
for i + start_index < offset {
- r, w := utf8.decode_rune(data[i:]);
+ r, w := utf8.decode_rune(data[i:])
if r == '\n' { //\r?
- position.character = 0;
- position.line += 1;
- i += 1;
+ position.character = 0
+ position.line += 1
+ i += 1
} else if w == 0 {
- return position;
+ return position
} else {
if r < 0x10000 {
- position.character += 1;
+ position.character += 1
} else {
- position.character += 2;
+ position.character += 2
}
- i += w;
+ i += w
}
}
- return position;
+ return position
}
/*
Get the range of a token in utf16 space
*/
get_token_range :: proc(node: ast.Node, document_text: string) -> Range {
- range: Range;
+ range: Range
go_backwards_to_endline :: proc(offset: int, document_text: []u8) -> int {
- index := offset;
+ index := offset
for index > 0 && document_text[index] != '\n' && document_text[index] != '\r' {
- index -= 1;
+ index -= 1
}
if index == 0 {
- return 0;
+ return 0
}
- return index + 1;
- };
+ return index + 1
+ }
- pos_offset := min(len(document_text) - 1, node.pos.offset);
- end_offset := min(len(document_text) - 1, node.end.offset);
+ pos_offset := min(len(document_text) - 1, node.pos.offset)
+ end_offset := min(len(document_text) - 1, node.end.offset)
- offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text);
+ offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text)
- range.start.line = node.pos.line - 1;
- range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:]);
+ range.start.line = node.pos.line - 1
+ range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:])
- offset = go_backwards_to_endline(end_offset, transmute([]u8)document_text);
+ offset = go_backwards_to_endline(end_offset, transmute([]u8)document_text)
- range.end.line = node.end.line - 1;
- range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:]);
+ range.end.line = node.end.line - 1
+ range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:])
- return range;
+ return range
}
get_absolute_range :: proc(range: Range, document_text: []u8) -> (AbsoluteRange, bool) {
- absolute: AbsoluteRange;
+ absolute: AbsoluteRange
if len(document_text) == 0 {
- absolute.start = 0;
- absolute.end = 0;
- return absolute, true;
+ absolute.start = 0
+ absolute.end = 0
+ return absolute, true
}
- line_count := 0;
- index := 1;
- last := document_text[0];
+ line_count := 0
+ index := 1
+ last := document_text[0]
if !get_index_at_line(&index, &line_count, &last, document_text, range.start.line) {
- return absolute, false;
+ return absolute, false
}
- absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:]);
+ absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:])
//if the last line was indexed at zero we have to move it back to index 1.
//This happens when line = 0
if index == 0 {
- index = 1;
+ index = 1
}
if !get_index_at_line(&index, &line_count, &last, document_text, range.end.line) {
- return absolute, false;
+ return absolute, false
}
- absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:]);
+ absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:])
- return absolute, true;
+ return absolute, true
}
get_index_at_line :: proc(current_index: ^int, current_line: ^int, last: ^u8, document_text: []u8, end_line: int) -> bool {
if end_line == 0 {
- current_index^ = 0;
- return true;
+ current_index^ = 0
+ return true
}
if current_line^ == end_line {
- return true;
+ return true
}
for ; current_index^ < len(document_text); current_index^ += 1 {
- current := document_text[current_index^];
+ current := document_text[current_index^]
if last^ == '\r' {
- current_line^ += 1;
+ current_line^ += 1
if current_line^ == end_line {
- last^ = current;
- current_index^ += 1;
- return true;
+ last^ = current
+ current_index^ += 1
+ return true
}
} else if current == '\n' {
- current_line^ += 1;
+ current_line^ += 1
if current_line^ == end_line {
- last^ = current;
- current_index^ += 1;
- return true;
+ last^ = current
+ current_index^ += 1
+ return true
}
}
- last^ = document_text[current_index^];
+ last^ = document_text[current_index^]
}
- return false;
+ return false
}
get_character_offset_u16_to_u8 :: proc(character_offset: int, document_text: []u8) -> int {
- utf8_idx := 0;
- utf16_idx := 0;
+ utf8_idx := 0
+ utf16_idx := 0
for utf16_idx < character_offset {
- r, w := utf8.decode_rune(document_text[utf8_idx:]);
+ r, w := utf8.decode_rune(document_text[utf8_idx:])
if r == '\n' || r == '\r' {
- return utf8_idx;
+ return utf8_idx
} else if w == 0 {
- return utf8_idx;
+ return utf8_idx
} else if r < 0x10000 {
- utf16_idx += 1;
+ utf16_idx += 1
} else {
- utf16_idx += 2;
+ utf16_idx += 2
}
- utf8_idx += w;
+ utf8_idx += w
}
- return utf8_idx;
+ return utf8_idx
}
get_character_offset_u8_to_u16 :: proc(character_offset: int, document_text: []u8) -> int {
- utf8_idx := 0;
- utf16_idx := 0;
+ utf8_idx := 0
+ utf16_idx := 0
for utf8_idx < character_offset {
- r, w := utf8.decode_rune(document_text[utf8_idx:]);
+ r, w := utf8.decode_rune(document_text[utf8_idx:])
if r == '\n' || r == '\r' {
- return utf16_idx;
+ return utf16_idx
} else if w == 0 {
- return utf16_idx;
+ return utf16_idx
} else if r < 0x10000 {
- utf16_idx += 1;
+ utf16_idx += 1
} else {
- utf16_idx += 2;
+ utf16_idx += 2
}
- utf8_idx += w;
+ utf8_idx += w
}
- return utf16_idx;
+ return utf16_idx
} \ No newline at end of file
diff --git a/src/common/sha1.odin b/src/common/sha1.odin
index 4516467..4f1d62f 100644
--- a/src/common/sha1.odin
+++ b/src/common/sha1.odin
@@ -5,58 +5,58 @@ import "core:fmt"
//ported version of https://llvm.org/doxygen/SHa1_8cpp_source.html
rol :: proc (number: u32, bits: u32) -> u32 {
- return number << bits | number >> (32 - bits);
+ return number << bits | number >> (32 - bits)
}
blk0 :: proc (buf: []u32, i: int) -> u32 {
- return buf[i];
+ return buf[i]
}
blk :: proc (buf: []u32, i: int) -> u32 {
buf[i & 15] = rol(buf[(i + 13) & 15] ~ buf[(i + 8) & 15] ~ buf[(i + 2) & 15] ~
- buf[i & 15], 1);
+ buf[i & 15], 1)
- return buf[i & 15];
+ return buf[i & 15]
}
r0 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5);
- b^ = rol(b^, 30);
+ e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5)
+ b^ = rol(b^, 30)
}
r1 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5)
+ b^ += rol(b^, 30)
}
r2 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5)
+ b^ += rol(b^, 30)
}
r3 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5)
+ b^ += rol(b^, 30)
}
r4 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5)
+ b^ += rol(b^, 30)
}
-SHA1_K0 :: 0x5a827999;
-SHA1_K20 :: 0x6ed9eba1;
-SHA1_K40 :: 0x8f1bbcdc;
-SHA1_K60 :: 0xca62c1d6;
+SHA1_K0 :: 0x5a827999
+SHA1_K20 :: 0x6ed9eba1
+SHA1_K40 :: 0x8f1bbcdc
+SHA1_K60 :: 0xca62c1d6
-SEED_0 :: 0x67452301;
-SEED_1 :: 0xefcdab89;
-SEED_2 :: 0x98badcfe;
-SEED_3 :: 0x10325476;
-SEED_4 :: 0xc3d2e1f0;
+SEED_0 :: 0x67452301
+SEED_1 :: 0xefcdab89
+SEED_2 :: 0x98badcfe
+SEED_3 :: 0x10325476
+SEED_4 :: 0xc3d2e1f0
-BLOCK_LENGTH :: 64;
-HASH_LENGTH :: 20;
+BLOCK_LENGTH :: 64
+HASH_LENGTH :: 20
Sha1context :: struct {
buf: struct #raw_union {
@@ -69,222 +69,222 @@ Sha1context :: struct {
}
sha1_init :: proc (state_context: ^Sha1context) {
- state_context.state[0] = SEED_0;
- state_context.state[1] = SEED_1;
- state_context.state[2] = SEED_2;
- state_context.state[3] = SEED_3;
- state_context.state[4] = SEED_4;
- state_context.byte_count = 0;
- state_context.buf_offset = 0;
+ state_context.state[0] = SEED_0
+ state_context.state[1] = SEED_1
+ state_context.state[2] = SEED_2
+ state_context.state[3] = SEED_3
+ state_context.state[4] = SEED_4
+ state_context.byte_count = 0
+ state_context.buf_offset = 0
}
sha1_hash_block :: proc (state_context: ^Sha1context) {
- a := state_context.state[0];
- b := state_context.state[1];
- c := state_context.state[2];
- d := state_context.state[3];
- e := state_context.state[4];
+ a := state_context.state[0]
+ b := state_context.state[1]
+ c := state_context.state[2]
+ d := state_context.state[3]
+ e := state_context.state[4]
// 4 rounds of 20 operations each. loop unrolled.
- r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:]);
- r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:]);
- r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:]);
- r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:]);
- r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:]);
- r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:]);
- r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:]);
- r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:]);
- r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:]);
- r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:]);
- r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:]);
- r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:]);
- r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:]);
- r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:]);
- r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:]);
- r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:]);
- r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:]);
- r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:]);
- r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:]);
- r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:]);
-
- r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:]);
- r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:]);
- r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:]);
- r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:]);
-
- r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:]);
- r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:]);
- r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:]);
- r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:]);
-
- r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:]);
- r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:]);
- r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:]);
- r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:]);
-
- state_context.state[0] += a;
- state_context.state[1] += b;
- state_context.state[2] += c;
- state_context.state[3] += d;
- state_context.state[4] += e;
+ r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:])
+ r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:])
+ r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:])
+ r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:])
+ r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:])
+ r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:])
+ r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:])
+ r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:])
+ r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:])
+ r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:])
+ r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:])
+ r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:])
+ r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:])
+ r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:])
+ r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:])
+ r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:])
+ r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:])
+ r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:])
+ r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:])
+ r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:])
+
+ r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:])
+ r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:])
+ r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:])
+ r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:])
+
+ r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:])
+ r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:])
+ r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:])
+ r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:])
+
+ r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:])
+ r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:])
+ r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:])
+ r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:])
+
+ state_context.state[0] += a
+ state_context.state[1] += b
+ state_context.state[2] += c
+ state_context.state[3] += d
+ state_context.state[4] += e
}
sha1_add_uncounted :: proc (state_context: ^Sha1context, data: byte) {
when ODIN_ENDIAN == .Big {
- state_context.buf.c[state_context.buf_offset] = data;
+ state_context.buf.c[state_context.buf_offset] = data
} else
{
- state_context.buf.c[state_context.buf_offset ~ 3] = data;
+ state_context.buf.c[state_context.buf_offset ~ 3] = data
}
- state_context.buf_offset += 1;
+ state_context.buf_offset += 1
if state_context.buf_offset == BLOCK_LENGTH {
- sha1_hash_block(state_context);
- state_context.buf_offset = 0;
+ sha1_hash_block(state_context)
+ state_context.buf_offset = 0
}
}
sha1_write_byte :: proc (state_context: ^Sha1context, data: byte) {
- state_context.byte_count += 1;
- sha1_add_uncounted(state_context, data);
+ state_context.byte_count += 1
+ sha1_add_uncounted(state_context, data)
}
sha1_update :: proc (state_context: ^Sha1context, data: []byte) {
- state_context.byte_count += cast(u32)len(data);
+ state_context.byte_count += cast(u32)len(data)
- current_data := data;
+ current_data := data
if state_context.buf_offset > 0 {
- remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset);
+ remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset)
for i := 0; i < remainder; i += 1 {
- sha1_add_uncounted(state_context, current_data[i]);
+ sha1_add_uncounted(state_context, current_data[i])
}
- current_data = current_data[remainder - 1:];
+ current_data = current_data[remainder - 1:]
}
for len(current_data) >= BLOCK_LENGTH {
- assert(state_context.buf_offset == 0);
- assert(BLOCK_LENGTH % 4 == 0);
+ assert(state_context.buf_offset == 0)
+ assert(BLOCK_LENGTH % 4 == 0)
- BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4;
+ BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4
for i := 0; i < BLOCK_LENGTH_32; i += 1 {
- n := (transmute([]u32)current_data)[i];
+ n := (transmute([]u32)current_data)[i]
state_context.buf.l[i] = (((n & 0xFF) << 24) |
((n & 0xFF00) << 8) |
((n & 0xFF0000) >> 8) |
- ((n & 0xFF000000) >> 24));
+ ((n & 0xFF000000) >> 24))
}
- sha1_hash_block(state_context);
+ sha1_hash_block(state_context)
- current_data = current_data[BLOCK_LENGTH - 1:];
+ current_data = current_data[BLOCK_LENGTH - 1:]
}
for c in current_data {
- sha1_add_uncounted(state_context, c);
+ sha1_add_uncounted(state_context, c)
}
}
sha1_pad :: proc (state_context: ^Sha1context) {
- sha1_add_uncounted(state_context, 0x80);
+ sha1_add_uncounted(state_context, 0x80)
for state_context.buf_offset != 56 {
- sha1_add_uncounted(state_context, 0x00);
+ sha1_add_uncounted(state_context, 0x00)
}
- sha1_add_uncounted(state_context, 0); // We're only using 32 bit lengths
- sha1_add_uncounted(state_context, 0); // But SHA-1 supports 64 bit lengths
- sha1_add_uncounted(state_context, 0); // So zero pad the top bits
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)); // Shifting to multiply by 8
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)); // as SHA-1 supports bitstreams as well as
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)); // byte.
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5));
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3));
+ sha1_add_uncounted(state_context, 0) // We're only using 32 bit lengths
+ sha1_add_uncounted(state_context, 0) // But SHA-1 supports 64 bit lengths
+ sha1_add_uncounted(state_context, 0) // So zero pad the top bits
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)) // Shifting to multiply by 8
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)) // as SHA-1 supports bitstreams as well as
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)) // byte.
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5))
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3))
}
sha1_final :: proc (state_context: ^Sha1context, result: ^[5]u32) {
- sha1_pad(state_context);
+ sha1_pad(state_context)
when ODIN_ENDIAN == .Big {
for i := 0; i < 5; i += 1 {
- result[i] = state_context.state[i];
+ result[i] = state_context.state[i]
}
} else {
for i := 0; i < 5; i += 1 {
result[i] = (((state_context.state[i]) << 24) & 0xff000000) |
(((state_context.state[i]) << 8) & 0x00ff0000) |
(((state_context.state[i]) >> 8) & 0x0000ff00) |
- (((state_context.state[i]) >> 24) & 0x000000ff);
+ (((state_context.state[i]) >> 24) & 0x000000ff)
}
}
}
sha1_hash :: proc (data: []byte) -> [20]byte {
- sha1_context: Sha1context;
- sha1_init(&sha1_context);
- sha1_update(&sha1_context, data);
+ sha1_context: Sha1context
+ sha1_init(&sha1_context)
+ sha1_update(&sha1_context, data)
- result: [20]byte;
+ result: [20]byte
- sha1_final(&sha1_context, cast(^[5]u32)&result);
+ sha1_final(&sha1_context, cast(^[5]u32)&result)
- ret: [20]byte;
+ ret: [20]byte
- copy(ret[:], result[:]);
+ copy(ret[:], result[:])
- return ret;
+ return ret
}
diff --git a/src/common/uri.odin b/src/common/uri.odin
index ee25393..d93eab3 100644
--- a/src/common/uri.odin
+++ b/src/common/uri.odin
@@ -17,116 +17,116 @@ Uri :: struct {
parse_uri :: proc(value: string, allocator: mem.Allocator) -> (Uri, bool) {
- uri: Uri;
+ uri: Uri
- decoded, ok := decode_percent(value, allocator);
+ decoded, ok := decode_percent(value, allocator)
if !ok {
- return uri, false;
+ return uri, false
}
- starts := "file:///";
+ starts := "file:///"
- start_index := len(starts);
+ start_index := len(starts)
if !starts_with(decoded, starts) {
- return uri, false;
+ return uri, false
}
- when ODIN_OS != "windows" {
- start_index -= 1;
+ when ODIN_OS != .Windows {
+ start_index -= 1
}
- uri.uri = strings.clone(value, allocator);
- uri.decode_full = decoded;
- uri.path = decoded[start_index:];
+ uri.uri = strings.clone(value, allocator)
+ uri.decode_full = decoded
+ uri.path = decoded[start_index:]
- return uri, true;
+ return uri, true
}
//Note(Daniel, Again some really incomplete and scuffed uri writer)
create_uri :: proc(path: string, allocator: mem.Allocator) -> Uri {
- path_forward, _ := filepath.to_slash(path, context.temp_allocator);
+ path_forward, _ := filepath.to_slash(path, context.temp_allocator)
- builder := strings.make_builder(allocator);
+ builder := strings.make_builder(allocator)
//bad
- when ODIN_OS == "windows" {
- strings.write_string(&builder, "file:///");
+ when ODIN_OS == .Windows {
+ strings.write_string(&builder, "file:///")
} else {
- strings.write_string(&builder, "file://");
+ strings.write_string(&builder, "file://")
}
- strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator));
+ strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator))
- uri: Uri;
+ uri: Uri
- uri.uri = strings.to_string(builder);
- uri.decode_full = strings.clone(path_forward, allocator);
- uri.path = uri.decode_full;
+ uri.uri = strings.to_string(builder)
+ uri.decode_full = strings.clone(path_forward, allocator)
+ uri.path = uri.decode_full
- return uri;
+ return uri
}
delete_uri :: proc(uri: Uri) {
if uri.uri != "" {
- delete(uri.uri);
+ delete(uri.uri)
}
if uri.decode_full != "" {
- delete(uri.decode_full);
+ delete(uri.decode_full)
}
}
encode_percent :: proc(value: string, allocator: mem.Allocator) -> string {
- builder := strings.make_builder(allocator);
+ builder := strings.make_builder(allocator)
- data := transmute([]u8)value;
- index: int;
+ data := transmute([]u8)value
+ index: int
for index < len(value) {
- r, w := utf8.decode_rune(data[index:]);
+ r, w := utf8.decode_rune(data[index:])
if r > 127 || r == ':' {
for i := 0; i < w; i += 1 {
strings.write_string(&builder, strings.concatenate({"%", fmt.tprintf("%X", data[index + i])},
- context.temp_allocator));
+ context.temp_allocator))
}
} else {
- strings.write_byte(&builder, data[index]);
+ strings.write_byte(&builder, data[index])
}
- index += w;
+ index += w
}
- return strings.to_string(builder);
+ return strings.to_string(builder)
}
@(private)
starts_with :: proc(value: string, starts_with: string) -> bool {
if len(value) < len(starts_with) {
- return false;
+ return false
}
for i := 0; i < len(starts_with); i += 1 {
if value[i] != starts_with[i] {
- return false;
+ return false
}
}
- return true;
+ return true
}
@(private)
decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool) {
- builder := strings.make_builder(allocator);
+ builder := strings.make_builder(allocator)
for i := 0; i < len(value); i += 1 {
@@ -134,24 +134,24 @@ decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool
if i + 2 < len(value) {
- v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16);
+ v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16)
if !ok {
- strings.destroy_builder(&builder);
- return "", false;
+ strings.destroy_builder(&builder)
+ return "", false
}
- strings.write_byte(&builder, cast(byte)v);
+ strings.write_byte(&builder, cast(byte)v)
- i += 2;
+ i += 2
} else {
- strings.destroy_builder(&builder);
- return "", false;
+ strings.destroy_builder(&builder)
+ return "", false
}
} else {
- strings.write_byte(&builder, value[i]);
+ strings.write_byte(&builder, value[i])
}
}
- return strings.to_string(builder), true;
+ return strings.to_string(builder), true
}
diff --git a/src/common/util_windows.odin b/src/common/util_windows.odin
index 835348a..bf89c47 100644
--- a/src/common/util_windows.odin
+++ b/src/common/util_windows.odin
@@ -11,71 +11,71 @@ foreign import kernel32 "system:kernel32.lib"
@(default_calling_convention = "std")
foreign kernel32 {
- @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 ---;
+ @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 ---
}
run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte) {
- stdout_read: win32.Handle;
- stdout_write: win32.Handle;
+ stdout_read: win32.Handle
+ stdout_write: win32.Handle
- command := strings.clone_to_cstring(command, context.temp_allocator);
+ command := strings.clone_to_cstring(command, context.temp_allocator)
- attributes: win32.Security_Attributes;
- attributes.length = size_of(win32.Security_Attributes);
- attributes.inherit_handle = true;
- attributes.security_descriptor = nil;
+ attributes: win32.Security_Attributes
+ attributes.length = size_of(win32.Security_Attributes)
+ attributes.inherit_handle = true
+ attributes.security_descriptor = nil
if create_pipe(&stdout_read, &stdout_write, &attributes, 0) == 0 {
- return 0, false, stdout[0:];
+ return 0, false, stdout[0:]
}
if !win32.set_handle_information(stdout_read, win32.HANDLE_FLAG_INHERIT, 0) {
- return 0, false, stdout[0:];
+ return 0, false, stdout[0:]
}
- startup_info: win32.Startup_Info;
- process_info: win32.Process_Information;
+ startup_info: win32.Startup_Info
+ process_info: win32.Process_Information
- startup_info.cb = size_of(win32.Startup_Info);
+ startup_info.cb = size_of(win32.Startup_Info)
- startup_info.stderr = stdout_write;
- startup_info.stdout = stdout_write;
- startup_info.flags |= win32.STARTF_USESTDHANDLES;
+ startup_info.stderr = stdout_write
+ startup_info.stdout = stdout_write
+ startup_info.flags |= win32.STARTF_USESTDHANDLES
if !win32.create_process_a(nil, command, nil, nil, true, 0, nil, nil, &startup_info, &process_info) {
- return 0, false, stdout[0:];
+ return 0, false, stdout[0:]
}
- win32.close_handle(stdout_write);
+ win32.close_handle(stdout_write)
- index: int;
- read: i32;
+ index: int
+ read: i32
- read_buffer: [50]byte;
+ read_buffer: [50]byte
- success: win32.Bool = true;
+ success: win32.Bool = true
for success {
- success = win32.read_file(stdout_read, &read_buffer[0], len(read_buffer), &read, nil);
+ success = win32.read_file(stdout_read, &read_buffer[0], len(read_buffer), &read, nil)
if read > 0 && index + cast(int)read <= len(stdout) {
- mem.copy(&stdout[index], &read_buffer[0], cast(int)read);
+ mem.copy(&stdout[index], &read_buffer[0], cast(int)read)
}
- index += cast(int)read;
+ index += cast(int)read
}
- stdout[index + 1] = 0;
+ stdout[index + 1] = 0
- exit_code: u32;
+ exit_code: u32
- win32.wait_for_single_object(process_info.process, win32.INFINITE);
+ win32.wait_for_single_object(process_info.process, win32.INFINITE)
- win32.get_exit_code_process(process_info.process, &exit_code);
+ win32.get_exit_code_process(process_info.process, &exit_code)
- win32.close_handle(stdout_read);
+ win32.close_handle(stdout_read)
- return exit_code, true, stdout[0:index];
+ return exit_code, true, stdout[0:index]
} \ No newline at end of file