I want to have something at least resembling algebraic data types in Yuescript - these are called enums in Rust, variants in OCaml, tagged unions in C. These are types that you can construct and they carry the underlying variant and some fields that the variant has. An example of this in Rust can be seen here: https://doc.rust-lang.org/rust-by-example/custom_types/enum.html
To that end I've been trying to use existing pattern matching functionality and macros to get this behavior. For the sake of example, let's say we want to encode variants of an enum as an array ['VariantName', ...fields], for example:
lang =
BinOp: (lhs, op, rhs) => ['BinOp', lhs, op, rhs]
Var: (name, expr) => ['Var', name, expr]
Const: (val) => ['Const', val]
Then I'd like to do pattern matching on different variants, but have a bit nicer syntax:
macro binop = (x,y,z) -> {
code: "['Binop', #{x}, #{y}, #{z}]"
type: "yue"
}
switch e
when $binop a,b,c
print "foo"
But this compiles to:
if {
'Binop',
a,
b,
c
} == e then
return print("foo")
end
But this isn't what I want, as it does not assign a, b, c variables for me to use inside the 'when' block. If I use the expected output of the macro directly:
switch e
when ['Binop', a, b, c]
print "bar"
I get what I expected - a, b, c are assigned values of e[2..4]:
local _type_0 = type(e)
local _tab_0 = "table" == _type_0 or "userdata" == _type_0
if _tab_0 then
local a = e[2]
local b = e[3]
local c = e[4]
if 'Binop' == e[1] and a ~= nil and b ~= nil and c ~= nil then
return print("bar")
end
end
This behavior is a bit unexpected, seems like macro evaluation happens at some later stage of compilation so instead of variable capture I get table comparison. Is this a bug or working as intended?
I want to have something at least resembling algebraic data types in Yuescript - these are called enums in Rust, variants in OCaml, tagged unions in C. These are types that you can construct and they carry the underlying variant and some fields that the variant has. An example of this in Rust can be seen here: https://doc.rust-lang.org/rust-by-example/custom_types/enum.html
To that end I've been trying to use existing pattern matching functionality and macros to get this behavior. For the sake of example, let's say we want to encode variants of an enum as an array
['VariantName', ...fields], for example:Then I'd like to do pattern matching on different variants, but have a bit nicer syntax:
But this compiles to:
But this isn't what I want, as it does not assign a, b, c variables for me to use inside the 'when' block. If I use the expected output of the macro directly:
I get what I expected - a, b, c are assigned values of e[2..4]:
This behavior is a bit unexpected, seems like macro evaluation happens at some later stage of compilation so instead of variable capture I get table comparison. Is this a bug or working as intended?