diff --git a/lib/std/collections/priorityqueue.c3 b/lib/std/collections/priorityqueue.c3 index 253a050cc..db88bdb90 100644 --- a/lib/std/collections/priorityqueue.c3 +++ b/lib/std/collections/priorityqueue.c3 @@ -34,7 +34,7 @@ struct PrivatePriorityQueue (Printable) List{Type} heap; } -fn PrivatePriorityQueue* PrivatePriorityQueue.init(&self, Allocator allocator, usz initial_capacity = 16, ) @inline +fn PrivatePriorityQueue* PrivatePriorityQueue.init(&self, Allocator allocator, usz initial_capacity = 16) @inline { self.heap.init(allocator, initial_capacity); return self; diff --git a/lib/std/math/math_vector.c3 b/lib/std/math/math_vector.c3 index 3e96be962..080a898cf 100644 --- a/lib/std/math/math_vector.c3 +++ b/lib/std/math/math_vector.c3 @@ -51,6 +51,49 @@ fn double[<3>] double[<3>].unproject(self, Matrix4 projection, Matrix4 view) => fn void ortho_normalize(float[<3>]* v1, float[<3>]* v2) => ortho_normalize3(v1, v2); fn void ortho_normalized(double[<3>]* v1, double[<3>]* v2) => ortho_normalize3(v1, v2); +/* determinants */ +macro float[<*>].determinant2(self, float[<*>] b) => determinant2(self,b); +macro double[<*>].determinant2(self, double[<*>] b) => determinant2(self,b); + +macro float[<*>].determinant3(self, float[<*>] b, float[<*>] c) => determinant3(self, b, c); +macro double[<*>].determinant3(self, double[<*>] b, double[<*>] c) => determinant3(self, b, c); + +macro float[<*>].determinant4(self, float[<*>] b, float[<*>] c, float[<*>] d) => determinant4(self, b, c, d); +macro double[<*>].determinant4(self, double[<*>] b, double[<*>] c, double[<*>] d) => determinant4(self, b, c, d); + +/* laplace */ +macro float[<*>].laplace2(self) => laplace2(self); +macro double[<*>].laplace2(self) => laplace2(self); + +macro float[<*>].laplace3(self, float[<*>] b) => laplace3(self, b); +macro double[<*>].laplace3(self, double[<*>] b) => laplace3(self, b); + +macro float[<*>].laplace4(self, float[<*>] b, float[<*>] c) => laplace4(self, b, c); +macro double[<*>].laplace4(self, double[<*>] b, double[<*>] c) => laplace4(self, b, c); + +/* cross[2,3,4] products */ +macro float[<*>].cross2(self, uint winding = 0x901) => cross2(self, winding); +macro double[<*>].cross2(self, uint winding = 0x901) => cross2(self, winding); + +macro float[<*>].cross3(self, float[<*>] other) => cross3(self, other); +macro double[<*>].cross3(self, double[<*>] other) => cross3(self, other); + +macro float[<*>].cross4(self, float[<*>] b, float[<*>] c) => cross4(self, b, c); +macro double[<*>].cross4(self, double[<*>] b, double[<*>] c) => cross4(self, b, c); + +macro determinant2(a, b) => ({ 1,-1 } * a.xy * laplace2(b )).sum(); +macro determinant3(a, b, c) => ({ 1,-1, 1 } * a.xyz * laplace3(b.xyz,c.xyz )).sum(); +macro determinant4(a, b, c, d) => ({ 1,-1, 1, -1 } * a.xyzw * laplace4(b.xyzw,c.xyzw,d.xyzw)).sum(); + +macro laplace2(a) => a.yx; +macro laplace3(a, b) => ($typeof(a)){ determinant2(a.yz,b.yz), determinant2(a.xz,b.xz), determinant2(a.xy,b.xy) }; +macro laplace4(a, b, c) => ($typeof(a)){ determinant3(a.yzw,b.yzw,c.yzw), determinant3(a.xzw,b.xzw,c.xzw), determinant3(a.xyw,b.xyw,c.xyw), determinant3(a.xyz,b.xyz,c.xyz) }; + +/* use GL_CW=0x900/GL_CCW=0x901 or 0/1 as winding */ +macro cross2(a, uint winding = 0x901) => { (winding % 2 == 0 ? -1 : 1), 1 } * laplace2(a); +macro cross3(a, b) => a.yzx * b.zxy - a.zxy * b.yzx; +macro cross4(a, b, c) => {-1, 1, -1, 1} * laplace4(a.xyzw,b.xyzw,c.xyzw); + macro towards(v, target, max_distance) @private { var delta = target - v; @@ -102,13 +145,6 @@ macro perpendicular3(v) @private return cross3(v, cardinal_axis); } -macro cross3(v1, v2) @private -{ - var a = v1.yzx * v2.zxy; - var b = v1.zxy * v2.yzx; - return a - b; -} - macro transform2(v, mat) @private { return $typeof(v) { diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 84e876e95..30b972636 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1353,11 +1353,7 @@ bool parse_parameters(ParseContext *c, Decl ***params_ref, Variadic *variadic, i // We might have Foo... if (ellipsis) { - if (!variadic) - { - PRINT_ERROR_HERE("Variadic arguments are not allowed."); - return false; - } + if (!variadic) RETURN_PRINT_ERROR_HERE("Variadic arguments are not allowed."); if (var_arg_found) { print_error_at(extend_span_with_token(type->span, c->prev_span), "Only a single variadic parameter is allowed."); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index f20d245de..5c480df30 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1229,12 +1229,13 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, if (!sema_resolve_type_info(context, type_info, is_macro ? RESOLVE_TYPE_ALLOW_INFER : RESOLVE_TYPE_DEFAULT)) return decl_poison(param); - param->type = type_info->type; - } - if (type_info && param->var.no_alias && !type_is_pointer(param->type) && type_flatten(param->type)->type_kind != TYPE_SLICE) - { - SEMA_ERROR(param, "The parameter was set to @noalias, but it was neither a slice nor a pointer. You need to either remove '@noalias' or use pointer/slice type."); - return decl_poison(param); + + Type *type = param->type = type_info->type; + if (param->var.no_alias && !type_is_pointer(type) && type_flatten(type)->type_kind != TYPE_SLICE) + { + SEMA_ERROR(param, "The parameter was set to @noalias, but it was neither a slice nor a pointer. You need to either remove '@noalias' or use pointer/slice type."); + return decl_poison(param); + } } switch (var_kind) { diff --git a/test/unit/stdlib/math/math_vector.c3 b/test/unit/stdlib/math/math_vector.c3 index cd4fe8af9..31a458ab9 100644 --- a/test/unit/stdlib/math/math_vector.c3 +++ b/test/unit/stdlib/math/math_vector.c3 @@ -122,4 +122,24 @@ fn void test_type_consistency() @test double[<3>] v3d = { 1.0, 2.0, 3.0 }; $assert @typeis(v3f.cross(v3f)[0], float); $assert @typeis(v3d.cross(v3d)[0], double); -} \ No newline at end of file +} + +fn void test_vec_cross() @test +{ + float[<4>] u = { 1,0,0,0 }; + float[<4>] v = { 0,1,0,0 }; + float[<4>] w = { 0,0,1,0 }; + float[<4>] t = { 0,0,0,1 }; + + float[<3>] d = { u.determinant2(v), u.determinant3(v,w), u.determinant4(v,w,t) }; + assert(d == { 1, 1, 1 }); + + float[<4>] x = vector::cross4(u,v,w); + float[<3>] y = vector::cross3(u,v); + float[<2>] z = vector::cross2(u); + + assert(x == {-0, 0,-0, 1 }); + assert(y == { 0, 0, 1 }); + assert(z == { 0, 1 }); +} +