// Code ----------------------------------------------------------------------------------------------------------------------------------
calc {
ops = [add,sub,mul,div] // the supported operations
} {
// deal with empty list and number
([],0)^ :- true;
(:v,:v) :- is.number(:v)^;
// deal with unknown operation
([_,:o,_],0) :- peek(ops,:ops), !lst.member(:o,:ops)^, console.puts("sorry ",:o," isn't a supported operand.");
// deal with left or right operands being variables
([:l,:o,:r],:v) :- is.variable(:l)^, !is.variable(:r), #calc(:r,:rv), fun.make(:o,[:l,:rv,:v],:f),
#fzz.eval([primitive],:f);
([:l,:o,:r],:v) :- is.variable(:r)^, !is.variable(:l), #calc(:l,:lv), fun.make(:o,[:lv,:r,:v],:f),
#fzz.eval([primitive],:f);
// deal with left or right operands being non-final
([:l,:o,:r],:v) :- !is.final(:l)^, is.final(:r), is.number(:v), #calc(:r,:rv), fun.make(:o,[:lv,:rv,:v],:f),
#fzz.eval([primitive],:f), #calc(:l,:lv);
([:l,:o,:r],:v) :- !is.final(:r)^, is.final(:l), is.number(:v), #calc(:l,:lv), fun.make(:o,[:lv,:rv,:v],:f),
#fzz.eval([primitive],:f), #calc(:r,:rv);
// main prototype
([:l,:o,:r],:v) :- #calc(:l,:lv), #calc(:r,:rv), fun.make(:o,[:lv,:rv,:v],:f), #fzz.eval([primitive],:f);
}