Removed [] block notation in favour of unification with ()

This commit is contained in:
Robert Bendun 2022-10-25 16:10:34 +02:00
parent fe6c1e3bd0
commit 8cda4f4d8e
16 changed files with 74 additions and 130 deletions

View File

@ -1,34 +0,0 @@
-- PAIR definition
pair := [x y | [z | z x y]];
car := [pair | pair [x y | x]];
cdr := [pair | pair [x y | y]];
x := pair 100 200;
say (car x);
say (cdr x);
-- LIST definition
null := pair true true;
is_empty := car;
head := [list | car (cdr list)];
tail := [list | cdr (cdr list)];
cons := [head tail | pair false (pair head tail)];
for_each := [list iterator |
if (is_empty list) [ nil ] [
iterator (head list);
for_each (tail list) iterator ]];
map := [list iterator |
if (is_empty list) [ null ] [|
cons (iterator (head list)) (map (tail list) iterator) ]];
foldr := [list init folder |
if (is_empty list)
[ init ]
[ foldr (tail list) (folder (head list) init) folder ]];
range := [start stop | if (start >= stop) [cons start null] [cons start (range (start+1) stop)]];
xs := range 1 5;
say (foldr xs 1 [x y|x*y]);

View File

@ -1,4 +1,5 @@
map := [fn array | var result = []; for array [v | result = result & [fn v] ]; result]; map := (fn array | result := (); for array (v | result = result & (| fn v) ); result);
drop := [n arr | arr.(range n (len arr))]; drop := (n arr | arr.(range n (len arr)));
take := [n arr | arr.(up n)]; take := (n arr | arr.(up n));
filter := [predicate arr | arr.(map predicate arr)]; filter := (predicate arr | arr.(map predicate arr));

View File

@ -5,26 +5,26 @@ 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
factorial_iterative := [n | factorial_iterative := (n |
x := 1; x := 1;
for (range 1 (n+1)) [i|x *= i]; for (range 1 (n+1)) (i | x *= i);
x x
]; );
-- Calculate factorial using composition of functions -- Calculate factorial using composition of functions
factorial := [n| fold (1 + up n) 1 '*]; factorial := (n | fold (1 + up n) 1 '*);
-- Gather all functions into array, and iterate over it -- Gather all functions into array, and iterate over it
-- This allows to reduce repeatition of this test case -- This allows to reduce repeatition of this test case
for [factorial_recursive; factorial_iterative; factorial] [ factorial | for (factorial_recursive; factorial_iterative; factorial) ( factorial |
for (up 10) [ n | for (up 10) ( n |
say (factorial (n)); say (factorial (n));
]; )
]; );

View File

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

View File

@ -4,12 +4,12 @@ WIP implemntation
---------------------------------------------- ----------------------------------------------
oct 5; bpm 72; len (1/16); oct 5; bpm 72; len (1/16);
subsection1 := [ subsection1 := (
sim (a 4 en) (a 2 e 3 a 3); sim (a 4 en) (a 2 e 3 a 3);
play [oct 4; c e a]; play (oct 4; c e a);
sim (b 4 en) (e 2 e 3 g# 3); sim (b 4 en) (e 2 e 3 g# 3);
play [oct 4; e g# b]; play (oct 4; e g# b);
sim (c 5 en) (a 2 e 3 a 3); sim (c 5 en) (a 2 e 3 a 3);
play (e 4 e 5 d# 5); play (e 4 e 5 d# 5);
@ -21,22 +21,22 @@ subsection1 := [
sim (b 4 en) (e 2 e 3 g# 3); sim (b 4 en) (e 2 e 3 g# 3);
play (d 4 c 5 b 4); play (d 4 c 5 b 4);
]; );
section1 := [ n | section1 := ( n |
play (e d#); play e d#;
play (e d# e b 4 d c); play (e d# e b 4 d c);
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)
] )
]; );
section2 := [ n | section2 := ( n |
sim (e 5 den) (c 3 g 3 c 4); sim (e 5 den) (c 3 g 3 c 4);
play (g 4 f e); play (g 4 f e);
@ -55,10 +55,10 @@ section2 := [ n |
call subsection1; call subsection1;
if (n == 1) if (n == 1)
[ 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)
] )
]; );
section1 1; section1 1;
section1 2; section1 2;

View File

@ -1,11 +1,11 @@
factorial := [n | if (n < 2) [1] [factorial (n-1) * n]]; factorial := (n | fold (1 + up n) '*);
for_all_permutations := [array fun |
iter := [start stop x | if (start >= stop) [x] [iter (start+1) stop (fun x)]];
iter 0 (factorial (len array)) array
];
for_all_permutations (flat 1 2 3 4 5) [array| list_all_permutations := ( array |
for (up (factorial (len array))) (|
say array; say array;
permute array array = permute array;
]; );
);
list_all_permutations (1 + up 5);

View File

@ -1,5 +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;
play (snd oct qn); play (snd oct qn);
]; );

View File

@ -25,9 +25,9 @@ play c d c e (c & d) c d (c & e)
-------------------------------------------------------------- --------------------------------------------------------------
Length := 20; Length := 40;
cmajor := [c;d;e;f;g]; cmajor := (c;d;e;f;g);
scale := reverse cmajor; scale := reverse cmajor;
primes := nprimes (len scale); primes := nprimes (len scale);
indicies := up (len scale); indicies := up (len scale);
@ -35,4 +35,6 @@ indicies := up (len scale);
oct 3; oct 3;
len (1/16); len (1/16);
for (2 + up Length) [ i | play (chord scale.(indicies.(i % primes == 0))); ]; for (2 + up Length) ( i |
play (chord scale.(indicies.(i % primes == 0)));
);

View File

@ -1,10 +0,0 @@
bpm 120; len hn; oct 2;
play [
f# & c# 4;
par g# [d# 4; g# 3 (5/16)];
f & d# 4;
par a# [oct 4; f; len sn; a#; f#; f; c#];
f# & c# 4;
g# & d# 4;
];

View File

@ -1,7 +1,7 @@
bpm 150; bpm 150;
len sn; len sn;
play [ play (
oct 3; 4 * h; h 3 en; oct 3; 4 * h; h 3 en;
oct 3; 6 * h; h 3 en; oct 3; 6 * h; h 3 en;
oct 4; 7 * e; oct 4; 7 * e;
@ -9,5 +9,5 @@ play [
oct 3; a; a; 5 * h; oct 3; a; a; 5 * h;
oct 3; 7 * h; oct 3; 7 * h;
oct 4; 2 * d; 4 * (h 3); h 3 en oct 4; 2 * d; 4 * (h 3); h 3 en
]; );

View File

@ -1,2 +0,0 @@
x := 10;
say (x + 1)

View File

@ -88,10 +88,8 @@ auto Lexer::next_token() -> Result<std::variant<Token, End_Of_File>>
} }
switch (peek()) { switch (peek()) {
case '(': consume(); return Token { Token::Type::Open_Paren, finish(), token_location }; case '(': consume(); return Token { Token::Type::Open_Block, finish(), token_location };
case ')': consume(); return Token { Token::Type::Close_Paren, finish(), token_location }; case ')': consume(); return Token { Token::Type::Close_Block, finish(), token_location };
case '[': consume(); return Token { Token::Type::Open_Block, finish(), token_location };
case ']': consume(); return Token { Token::Type::Close_Block, finish(), token_location };
case ';': consume(); return Token { Token::Type::Expression_Separator, finish(), token_location }; case ';': consume(); return Token { Token::Type::Expression_Separator, finish(), token_location };
case '|': case '|':
@ -258,12 +256,10 @@ std::ostream& operator<<(std::ostream& os, Token::Type type)
switch (type) { switch (type) {
case Token::Type::Chord: return os << "CHORD"; case Token::Type::Chord: return os << "CHORD";
case Token::Type::Close_Block: return os << "CLOSE BLOCK"; case Token::Type::Close_Block: return os << "CLOSE BLOCK";
case Token::Type::Close_Paren: return os << "CLOSE PAREN";
case Token::Type::Expression_Separator: return os << "EXPRESSION SEPARATOR"; case Token::Type::Expression_Separator: return os << "EXPRESSION SEPARATOR";
case Token::Type::Keyword: return os << "KEYWORD"; case Token::Type::Keyword: return os << "KEYWORD";
case Token::Type::Numeric: return os << "NUMERIC"; case Token::Type::Numeric: return os << "NUMERIC";
case Token::Type::Open_Block: return os << "OPEN BLOCK"; case Token::Type::Open_Block: return os << "OPEN BLOCK";
case Token::Type::Open_Paren: return os << "OPEN PAREN";
case Token::Type::Operator: return os << "OPERATOR"; case Token::Type::Operator: return os << "OPERATOR";
case Token::Type::Parameter_Separator: return os << "PARAMETER SEPARATOR"; case Token::Type::Parameter_Separator: return os << "PARAMETER SEPARATOR";
case Token::Type::Symbol: return os << "SYMBOL"; case Token::Type::Symbol: return os << "SYMBOL";
@ -275,13 +271,11 @@ std::string_view type_name(Token::Type type)
{ {
switch (type) { switch (type) {
case Token::Type::Chord: return "chord"; case Token::Type::Chord: return "chord";
case Token::Type::Close_Block: return "]"; case Token::Type::Close_Block: return ")";
case Token::Type::Close_Paren: return ")";
case Token::Type::Expression_Separator: return "|"; case Token::Type::Expression_Separator: return "|";
case Token::Type::Keyword: return "keyword"; case Token::Type::Keyword: return "keyword";
case Token::Type::Numeric: return "numeric"; case Token::Type::Numeric: return "numeric";
case Token::Type::Open_Block: return "["; case Token::Type::Open_Block: return "(";
case Token::Type::Open_Paren: return "(";
case Token::Type::Operator: return "operator"; case Token::Type::Operator: return "operator";
case Token::Type::Parameter_Separator: return "parameter separator"; case Token::Type::Parameter_Separator: return "parameter separator";
case Token::Type::Symbol: return "symbol"; case Token::Type::Symbol: return "symbol";

View File

@ -19,8 +19,6 @@ struct Token
Expression_Separator, ///< ";" separates expressions. Used mainly to separate calls, like `foo 1 2; bar 3 4` Expression_Separator, ///< ";" separates expressions. Used mainly to separate calls, like `foo 1 2; bar 3 4`
Open_Block, ///< "[" delimits anonymous block of code (potentially a function) Open_Block, ///< "[" delimits anonymous block of code (potentially a function)
Close_Block, ///< "]" delimits anonymous block of code (potentially a function) Close_Block, ///< "]" delimits anonymous block of code (potentially a function)
Open_Paren, ///< "(" used in arithmetic or as function invocation sarrounding
Close_Paren ///< ")" used in arithmetic or as function invocation sarrounding
}; };
/// Type of token /// Type of token

View File

@ -68,13 +68,11 @@ Result<Ast> Parser::parse(std::string_view source, std::string_view filename, un
auto const result = parser.parse_sequence(); auto const result = parser.parse_sequence();
if (result.has_value() && parser.token_id < parser.tokens.size()) { if (result.has_value() && parser.token_id < parser.tokens.size()) {
if (parser.expect(Token::Type::Close_Paren) || parser.expect(Token::Type::Close_Block)) { if (parser.expect(Token::Type::Close_Block)) {
auto const tok = parser.consume(); auto const tok = parser.consume();
return Error { return Error {
.details = errors::Closing_Token_Without_Opening { .details = errors::Closing_Token_Without_Opening {
.type = tok.type == Token::Type::Close_Paren errors::Closing_Token_Without_Opening::Paren
? errors::Closing_Token_Without_Opening::Paren
: errors::Closing_Token_Without_Opening::Block
}, },
.location = tok.location .location = tok.location
}; };
@ -287,30 +285,15 @@ Result<Ast> Parser::parse_atomic_expression()
if (is_lambda) { if (is_lambda) {
return Ast::lambda(opening.location, std::move(ast), std::move(parameters)); return Ast::lambda(opening.location, std::move(ast), std::move(parameters));
} else { } else {
ensure(ast.type == Ast::Type::Sequence, "I dunno if this is a valid assumption tbh");
if (ast.arguments.size() == 1) {
return std::move(ast.arguments.front());
}
return Ast::block(opening.location, std::move(ast)); return Ast::block(opening.location, std::move(ast));
} }
}); });
} }
case Token::Type::Open_Paren:
{
consume();
auto ast = Try(parse_sequence());
if (not expect(Token::Type::Close_Paren)) {
auto const& token = Try(peek());
return Error {
.details = errors::internal::Unexpected_Token {
.type = type_name(token.type),
.source = token.source,
.when = "waiting for closing paren ')'"
},
.location = token.location
};
}
consume();
return ast;
}
break; case Token::Type::Operator: break; case Token::Type::Operator:
return Error { return Error {
.details = errors::Wrong_Arity_Of { .details = errors::Wrong_Arity_Of {

View File

@ -121,6 +121,9 @@ Result<Value> Chord::operator()(Interpreter& interpreter, std::vector<Value> arg
std::move(current.begin(), current.end(), std::back_inserter(array)); std::move(current.begin(), current.end(), std::back_inserter(array));
ensure(not array.empty(), "At least *this should be in this array"); ensure(not array.empty(), "At least *this should be in this array");
if (array.size() == 1) {
return array.front();
}
return array; return array;
} }

View File

@ -56,6 +56,10 @@ struct Number
std::ostream& operator<<(std::ostream& os, Number const& num); std::ostream& operator<<(std::ostream& os, Number const& num);
template<> struct std::hash<Number> { std::size_t operator()(Number const&) const; }; template<>
struct std::hash<Number>
{
std::size_t operator()(Number const&) const;
};
#endif #endif