-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Negation
and Not
nodes.
#35
Comments
I'd like to see this in 0.2.0, but it's not necessary. I'm more inclined to keep it open for someone else to tackle as a first contribution :) |
Nobody yet, really ? |
Hi @faultyserver, before I continue implementation, let me know if the current one seems good to you : https://github.com/rainbru/myst/blob/5e973c3786794f0be2addeab5d8cc26abeab5688/src/myst/interpreter/nodes/unary_ops.cr#L4-27 I'm really not sure of this current try. Got many type/cast errors and the negation of |
So, something to think about is how these could be used on types other than integers or floats. For example, I might have a custom type that I want to define a Negation for, and I could then write an expression like It would be basically impossible to try to cover all of these cases inside of the Instead of trying to use The rest of the method, where you're calling the The implementation of |
Something I just realized, though (which it looks like you've already noticed based on your comment about For now, I would suggest changing the name of the Then, you can implement the new NativeLib.def_instance_method(float_type, :negate, :float_negate) This method will need to be defined for Finally, for result =
if (not_method = self.__scopeof(value)["not"]?).as(TFunctor)
# This code is only reached if `value` has a method named `not` defined.
# As such, the invocation can be run to get the result.
Invocation.new(self, not_method, nil, [v] , nil).invoke
else
# Otherwise, use the default behavior of checking the truthiness of the value.
TBoolean.new(value.truthy?)
end
stack.push(result) That's a lot of information, but I hope it helps :) If you have more questions, feel free to ask them here, or in |
Ok, it gives me new search paths, thanks! Will try to a abstract level up with a very generic |
I keep forgetting to tag PRs with Anyway, this was implemented in #46. Thanks, @rainbru :) |
Negation and Not are probably the most common unary operations that can be done. The parser is already set up and tested to parse unary operations properly, but there is no support in the interpreter for them. For example, running the simple program
1 + -1
, will yield a "Compiler bug:" error for the-
on-1
, saying thatNegation
nodes are not yet supported. A similar error is raised for a program like!true
.Adding interpreter support for
Negation
s andNot
s will just require addingvisit
methods for them. Ideally, the methods for both of these nodes, as well as all future unary operations, will live undersrc/myst/interpreter/nodes/unary_ops.cr
, to compliment the existingbinary_ops.cr
at the same level.To actually implement these methods, the interpreter should evaluate the
value
property of the node, then call the appropriate unary method on it and push the result to the stack. There is no defined standard for what this method should look like, but since Myst allows multi-clause definitions, I think using!
for Not and-
for Negation is sufficient, even if it slightly degrades performance.To do the call to the appropriate method, there isn't a nice convenience method available from the interpreter. However, there is
NativeLib.call_func_by_name
, which provides the same functionality forNativeLib
methods:myst/src/myst/interpreter/native_lib.cr
Lines 15 to 18 in bd7faff
Just copy-pasting these two lines and replacing
name
should be sufficient for calling!
or-
on the value. Alternatively, if you can come up with a nicer way for doing these calls, that would be great :)Also, be sure to add some specs for these new features! There are already specs for parsing them, but specs for their interpretation should live in
spec/interpreter/nodes/unary_ops_spec.cr
. If you need some inspiration for some specs to include, you can look at the parser specs, though these are a little hard to read, since they're inside of a macro.Hopefully that's a sufficient explanation to get started, but feel free to ask any questions if you have them :) Also, if you want to tackle this, be sure to add a comment or a 🎉 reaction so everyone can be aware!
The text was updated successfully, but these errors were encountered: