I must admit not understanding 100% of what was touched, feedback welcome.
In evalFuncCall: I wasn't able to find a way to keep the previous behavior: there in now a maximum number of arguments that can be passed to a function.
agagniere/comath:zig-master into main I must admit not understanding 100% of what was touched, feedback welcome.
In evalFuncCall: I wasn't able to find a way to keep the previous behavior: there in now a maximum number of arguments that can be passed to a function.
`@Struct` creates plain structs; to get a tuple that supports indexing and can be passed to `@call`, the argument-list type must use `@Tuple`.
Affects: Order, Relation.Associativity (comath.zig), NestType, ExprNode's tagged union (parse.zig).
Hitting a bug with this in my project in 0.16.0 - I'll see if I can make a minimal repro and figure out what is going on...
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/compiled.zig:334:94: error: unable to resolve comptime value
break :args try comptime evalExprTupleImpl(fc.args, ctx, inputs);
^~~~~~
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/compiled.zig:334:53: note: 'comptime' keyword forces comptime evaluation
break :args try comptime evalExprTupleImpl(fc.args, ctx, inputs);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/compiled.zig:352:58: note: called inline here
const rhs: Rhs = try evalImpl(bin.rhs, ctx, inputs);
~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/compiled.zig:349:58: note: called inline here (2 times)
const lhs: Lhs = try evalImpl(bin.lhs, ctx, inputs);
~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/compiled.zig:190:36: note: called inline here
return evalImpl(root, ctx, inputs);
~~~~~~~~^~~~~~~~~~~~~~~~~~~
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/compiled.zig:137:65: note: called inline here
return Parameterized(@TypeOf(inputs)).evalUnusedMode(.no_unused, self.ctx, inputs);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
zig-pkg/comath-0.1.0-wKZ2n1jdAQAG3Eu-8EXkvyEEKEnFzkcA3KIFIIYrOV-I/src/eval.zig:17:30: note: called inline here
return compiled_expr.eval(inputs);
~~~~~~~~~~~~~~~~~~^~~~~~~~
Test case:
conststd=@import("std");constcomath=@import("comath");constFakeVector=struct{x:f32,y:f32,z:f32,pubfninit(x_:f32,y_:f32,z_:f32,)FakeVector{return.{.x=x_,.y=y_,.z=z_};}pubfnadd(self:@This(),rhs:f32,)FakeVector{return.{.x=self.x+rhs,.y=self.y+rhs,.z=self.z+rhs,};}pubfnformat(self:@This(),writer:*std.Io.Writer,)std.Io.Writer.Error!void{trywriter.print("({d}, {d}, {d})",self);}};/// example context that should allow calling the init function like a/// constructor and the add functionconstFAKE_CTX=(comath.ctx.fn_method.context(comath.ctx.simple.context(comath.ctx.namespace.context(.{.v3=FakeVector.init,},)),.{.@"+"="add",},));test"comath with runtime arguments"{// passes{// note the const hereconstx:i32=12.0;constresult=trycomath.eval("v3(0,0,x) + x",FAKE_CTX,.{.x=x},);trystd.testing.expectEqualDeep(FakeVector.init(15,15,30,),result,);}// broken{// note that this is not comptime constantvarx:i32=12.0;x+=3;constresult=trycomath.eval("v3(0,0,x) + x",FAKE_CTX,.{.x=x},);trystd.testing.expectEqualDeep(FakeVector.init(15,15,30,),result,);}}
And fix to allow it
@stephan_gfx Good catch !
I added you test case as a test.
similarly to evalFuncCall, I wasn't able to figure out an elegant solution, so my solution limits the number of elements in a tuple.
Better ideas welcome !
Don't know if this is any better:
It is indeed nicer to read !
However it is my understanding that it prevents comptime evaluation of functions (as illustrated by the failing test, where the comptime_int arguments are coerced into i32, which, if I understand correctly, prevents the function from being evaluated at comptime)
I'd like to be proven wrong though because I'm not satisfied with my current solution
Code snippet to better illustrate the difference I'm referring to:
conststd=@import("std");inlinefnsub(a:i32,b:i32)i32{returna-b;}pubfnmain()void{// OLD-style: comptime-only tuple, has to be comptimeconstargs_old:@Tuple(&.{comptime_int,comptime_int})=.{19,2};constr_old=@call(.auto,sub,args_old);std.debug.print("OLD comptime_int tuple result: {} (type {s})\n",.{r_old,@typeName(@TypeOf(r_old))});// NEW-style: coerced to param typesconstTupleNew=@Tuple(&.{i32,i32});varargs_new:TupleNew=undefined;args_new[0]=19;args_new[1]=2;constr_new=@call(.auto,sub,args_new);std.debug.print("NEW i32 tuple result: {} (type {s})\n",.{r_new,@typeName(@TypeOf(r_new))});// Check whether the result is comptime-known in NEW pathconstis_comptime_old=@typeInfo(@TypeOf(.{r_old})).@"struct".fields[0].is_comptime;constis_comptime_new=@typeInfo(@TypeOf(.{r_new})).@"struct".fields[0].is_comptime;std.debug.print("OLD result is_comptime in literal: {}\n",.{is_comptime_old});std.debug.print("NEW result is_comptime in literal: {}\n",.{is_comptime_new});}$ zig run snippet.zig
OLD comptime_int tuple result: 17 (type i32)
NEW i32 tuple result: 17 (type i32)
OLD result is_comptime in literal: true
NEW result is_comptime in literal: false
I apologize for the long wait on this. Kept punting this down the list of things I have to do with life getting complicated. I appreciate the contribution.
No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?