From: Brendan Hansen Date: Mon, 29 Nov 2021 18:21:43 +0000 (-0600) Subject: added test cases X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a12914f47012c7ecb479ba3ffea6eedb58ed399f;p=onyx.git added test cases --- diff --git a/include/astnodes.h b/include/astnodes.h index bc948eb6..d0ad9662 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -1027,10 +1027,10 @@ struct AstInterface { }; typedef enum ConstraintPhase { - Constraint_Phase_Waiting_To_Be_Queued, - Constraint_Phase_Cloning_Expressions, - Constraint_Phase_Checking_Expressions, - Constraint_Phase_Finished, + Constraint_Phase_Waiting_To_Be_Queued = 0, + Constraint_Phase_Cloning_Expressions = 1, + Constraint_Phase_Checking_Expressions = 2, + Constraint_Phase_Finished = 3, } ConstraintPhase; struct AstConstraint { diff --git a/src/checker.c b/src/checker.c index d13312e5..6d9c94cd 100644 --- a/src/checker.c +++ b/src/checker.c @@ -2467,7 +2467,9 @@ CheckStatus check_constraint(AstConstraint *constraint) { case Constraint_Phase_Cloning_Expressions: { if (constraint->interface->kind != Ast_Kind_Interface) { // CLEANUP: This error message might not look totally right in some cases. - ERROR_(constraint->token->pos, "'%b' is not an interface.", constraint->token->text, constraint->token->length); + ERROR_(constraint->token->pos, "'%b' is not an interface. It is a '%s'.", + constraint->token->text, constraint->token->length, + onyx_ast_node_kind_string(constraint->interface->kind)); } bh_arr_new(global_heap_allocator, constraint->exprs, bh_arr_length(constraint->interface->exprs)); diff --git a/src/clone.c b/src/clone.c index b1411deb..e2b577d1 100644 --- a/src/clone.c +++ b/src/clone.c @@ -447,6 +447,7 @@ AstNode* ast_clone(bh_allocator a, void* n) { bh_arr_push(dc->type_args, (AstType *) ast_clone(a, (AstNode *) *type_arg)); } + dc->phase = Constraint_Phase_Waiting_To_Be_Queued; break; } diff --git a/src/symres.c b/src/symres.c index 3fddd70f..55f22e35 100644 --- a/src/symres.c +++ b/src/symres.c @@ -125,7 +125,6 @@ static SymresStatus symres_struct_type(AstStructType* s_node) { } } -struct_symres_done: if (s_node->scope) scope_leave(); return Symres_Success; } diff --git a/tests/caller_location b/tests/caller_location new file mode 100644 index 00000000..8d59fc34 --- /dev/null +++ b/tests/caller_location @@ -0,0 +1,6 @@ +Hello +I was called from caller_location.onyx:12:19 +1234.0000 +I was called from caller_location.onyx:13:19 +1234 +I was called from caller_location.onyx:24:23 diff --git a/tests/caller_location.onyx b/tests/caller_location.onyx new file mode 100644 index 00000000..9e4a0737 --- /dev/null +++ b/tests/caller_location.onyx @@ -0,0 +1,26 @@ +#load "core/std" + +use package core + +using_callsite :: (value: $T, site := #callsite) { + println(value); + path := string.split(site.file, #char "/"); + printf("I was called from {}:{}:{}\n", path[path.count - 1], site.line, site.column); +} + +main :: (args: [] cstr) { + using_callsite("Hello"); + using_callsite(1234.0f); + + something := Something.{}; + something->method(); +} + + +Something :: struct { + member := cast(u32) 1234; + + method :: (use s: ^Something) { + using_callsite(member); + } +} \ No newline at end of file diff --git a/tests/interfaces b/tests/interfaces new file mode 100644 index 00000000..4526d7c7 --- /dev/null +++ b/tests/interfaces @@ -0,0 +1,10 @@ +-1500840774 +OnyxContext is not hashable! +Allocator is not hashable! +19 +-460.00 + 1060.00i +7 +[ 4.0000, 2.0000, 4.0000, 7.0000, 4.0000 ] +[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] +true +false diff --git a/tests/interfaces.onyx b/tests/interfaces.onyx new file mode 100644 index 00000000..9ba92e06 --- /dev/null +++ b/tests/interfaces.onyx @@ -0,0 +1,111 @@ +#load "core/std" + +use package core + +Hashable :: interface (T: type_expr) { + hash.to_u32(T); +} + +try_hash :: #match { + macro (x: $T) where Hashable(T) { + println(hash.to_u32(x)); + }, + + (x: any) { + printf("{} is not hashable!\n", x.type); + }, +} + +CanCastTo :: interface (T: type_expr, D: type_expr) { + cast(typeof D) T; +} + +// I don't know why this doesn't work... It is complaining that it couldn't match +// either of these cases, but if I remove the first, it matches the second. This +// is clearly wrong behavior, but I don't immediately see where the problem is. +// cast_able :: #match { +// (_: $T, $D: type_expr) -> bool where CanCastTo(T, D) do return true; , +// (_: any, d: type_expr) -> bool { return false; }, +// } + +cast_able_to_int :: #match { + macro (_: $T) -> bool where CanCastTo(T, i32) { return true; }, + macro (_: any) -> bool { return false; }, +} + +do_math :: macro (x, y: $T) -> T where SemiRing(T) { + return x + y + x * y; +} + +SemiRing :: interface (T: type_expr) { + T + T; + T * T; +} + +bit_math :: (x, y: $T) -> T where BitField(T) { + return (x & y) | (x ^ y); +} + +BitField :: interface (T: type_expr) { + ~T; + T & T; + T | T; + T ^ T; +} + +Complex :: struct { x, y: f32; } +#match io.write (w: ^io.Writer, c: Complex) { + io.write_format(w, "{.2} + {.2}i", c.x, c.y); +} + +#operator + (c1, c2: Complex) => Complex.{ c1.x + c2.x, c1.y + c2.y }; +#operator * (c1, c2: Complex) => Complex.{ c1.x * c2.x - c1.y * c2.y, c1.x * c2.y + c1.y * c2.x }; + +consume :: macro (x: $T) -> #auto where iter.Iterable(T) { + // This is a weird limitation of the Onyx type system. + // In order to be able tell what the iterator produces, you + // have to pattern match it in a procedure parameter. This means + // that you have to declare an internal macro that pattern + // matches the variable out. Also, you need to use #auto as the + // return type otherwise you can't say the correct type. + // I can't think of a better way of doing this without making + // everything WAY more complicated. + consume_inner :: #match { + // Iterator over pointers get dereferenced + macro (iter: Iterator(^$T)) -> [..] T { + arr := array.make(T); + for it: iter do arr << *it; + return arr; + }, + + macro (iter: Iterator($T)) -> [..] T { + arr := array.make(T); + for it: iter do arr << it; + return arr; + }, + } + + iterator := iter.as_iterator(x); + return consume_inner(iterator); +} + +main :: (args: [] cstr) { + try_hash("This is a test"); + try_hash(context); + try_hash(context.allocator); + + printf("{p}\n", do_math(3, 4)); + println(do_math(Complex.{ 10, 20 }, .{ 30, 40 })); + + println(bit_math(3, 5)); + // println(bit_math(3.0, 4.0)); + + a := consume(f32.[4,2,4,7,4]); + defer array.free(^a); + println(a); + + consume(1 .. 10) |> println(); + + println(cast_able_to_int(12.34)); + println(cast_able_to_int("test")); +}