Added macros; if is now macro and not a function

This commit is contained in:
Robert Bendun 2022-10-26 16:50:40 +02:00
parent 0529a84fb7
commit b612209914
7 changed files with 22 additions and 13 deletions

View File

@ -7,8 +7,8 @@ using Musique programming language
-- Calculate factorial using recursive approach
factorial_recursive := (n |
if (n <= 1)
(| 1)
(| n * (factorial_recursive (n-1)))
1
(n * (factorial_recursive (n-1)))
);
-- Calculate factorial using iterative approach

View File

@ -1,5 +1,5 @@
fib := (n |
if (n <= 1)
(| n)
(| fib (n-1) + fib (n-2))
n
(fib (n-1) + fib (n-2))
);

View File

@ -30,7 +30,7 @@ section1 := ( n |
call subsection1;
if (n == 1)
(| sim (a 4 qn) (a 2 e 3 a 3) )
( sim (a 4 qn) (a 2 e 3 a 3) )
( sim (a 4 en) (a 2 e 3 a 3)
; play (b 4 c 5 d 5)
)

View File

@ -1,6 +1,6 @@
for (up 10) ( n |
snd := c + (shuffle (up 12)).0;
oct := if (n % 2 == 0) (| 3 ) (| 4 );
oct := if (n % 2 == 0) 3 4;
say snd oct;
play (snd oct qn);
);

View File

@ -579,7 +579,7 @@ static Result<Value> builtin_scan(Interpreter &interpreter, std::vector<Value> a
}
/// Execute blocks depending on condition
static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) {
static Result<Value> builtin_if(Interpreter &i, std::span<Ast> args) {
static constexpr auto guard = Guard<2> {
.name = "if",
.possibilities = {
@ -592,12 +592,10 @@ static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) {
return guard.yield_error();
}
if (args.front().truthy()) {
auto fun = Try(guard.match<Function>(args[1]));
return (*fun)(i, {});
if (Try(i.eval((Ast)args.front())).truthy()) {
return i.eval((Ast)args[1]);
} else if (args.size() == 3) {
auto fun = Try(guard.match<Function>(args[2]));
return (*fun)(i, {});
return i.eval((Ast)args[2]);
}
return Value{};

View File

@ -167,6 +167,10 @@ Result<Value> Interpreter::eval(Ast &&ast)
auto call_location = ast.arguments.front().location;
Value func = Try(eval(std::move(ast.arguments.front())));
if (auto macro = std::get_if<Macro>(&func.data)) {
return (*macro)(*this, std::span(ast.arguments).subspan(1));
}
std::vector<Value> values;
values.reserve(ast.arguments.size());
for (auto& a : std::span(ast.arguments).subspan(1)) {

View File

@ -19,6 +19,8 @@ struct Nil
using Bool = bool;
using Symbol = std::string;
using Macro = Result<Value>(*)(Interpreter &i, std::span<Ast>);
/// Representation of any value in language
struct Value
{
@ -52,7 +54,8 @@ struct Value
Intrinsic,
Block,
Array,
Chord
Chord,
Macro
> data = Nil{};
Value();
@ -71,6 +74,10 @@ struct Value
{
}
inline Value(Macro m) : data(m)
{
}
/// Returns truth judgment for current type, used primarly for if function
bool truthy() const;