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 -- Calculate factorial using recursive approach
factorial_recursive := (n | factorial_recursive := (n |
if (n <= 1) if (n <= 1)
(| 1) 1
(| n * (factorial_recursive (n-1))) (n * (factorial_recursive (n-1)))
); );
-- Calculate factorial using iterative approach -- Calculate factorial using iterative approach

View File

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

View File

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

View File

@ -1,6 +1,6 @@
for (up 10) ( n | for (up 10) ( n |
snd := c + (shuffle (up 12)).0; snd := c + (shuffle (up 12)).0;
oct := if (n % 2 == 0) (| 3 ) (| 4 ); oct := if (n % 2 == 0) 3 4;
say snd oct; say snd oct;
play (snd oct qn); 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 /// 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> { static constexpr auto guard = Guard<2> {
.name = "if", .name = "if",
.possibilities = { .possibilities = {
@ -592,12 +592,10 @@ static Result<Value> builtin_if(Interpreter &i, std::vector<Value> args) {
return guard.yield_error(); return guard.yield_error();
} }
if (args.front().truthy()) { if (Try(i.eval((Ast)args.front())).truthy()) {
auto fun = Try(guard.match<Function>(args[1])); return i.eval((Ast)args[1]);
return (*fun)(i, {});
} else if (args.size() == 3) { } else if (args.size() == 3) {
auto fun = Try(guard.match<Function>(args[2])); return i.eval((Ast)args[2]);
return (*fun)(i, {});
} }
return Value{}; return Value{};

View File

@ -167,6 +167,10 @@ Result<Value> Interpreter::eval(Ast &&ast)
auto call_location = ast.arguments.front().location; auto call_location = ast.arguments.front().location;
Value func = Try(eval(std::move(ast.arguments.front()))); 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; std::vector<Value> values;
values.reserve(ast.arguments.size()); values.reserve(ast.arguments.size());
for (auto& a : std::span(ast.arguments).subspan(1)) { for (auto& a : std::span(ast.arguments).subspan(1)) {

View File

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