diff --git a/.gitignore b/.gitignore index b5a1739..dbcd30a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ doc/musique doc/build doc/source/api __pycache__ +drafts.cc diff --git a/doc/cheatsheet.txt b/doc/cheatsheet.txt new file mode 100644 index 0000000..5faff5f --- /dev/null +++ b/doc/cheatsheet.txt @@ -0,0 +1,79 @@ +--------------------------------------------------------------------------- +Składnia +--------------------------------------------------------------------------- + +Zapis nut (dostępna notacja zachodnia) + c + d + +Arytmetyka + (aktualnie brak wsparcia dla precedensji operatorów) + 3 * (4 * 12 - 8) + +Wywołanie funkcji + foo 1 2 3 + +Kilka wywołań obok siebie + foo 1; bar 2 + +Stworzenie zmiennej + var variable = 20 + +Blok + Jako tablica + [1;2;3] + + Jako odroczona ewaluacja + [say 42] + + Jako funkcja anonimowa jednoparametrowa + [i | i * i ] + + Poniższe zapisy są równoważne + [ say 42 ] + [| say 42 ] + +--------------------------------------------------------------------------- +Dostępne stałe +--------------------------------------------------------------------------- + +fn 1 +dfn 3/2 +hn 1/2 +dhn 3/4 +ddhn 7/8 +qn 1/4 +dqn 3/8 +ddqn 7/16 +en 1/8 +den 3/16 +dden 7/32 +sn 1/16 +dsn 3/32 +tn 1/32 +dtn 3/64 + +--------------------------------------------------------------------------- +Dostępne funkcje +--------------------------------------------------------------------------- + +if : condition: bool, block: block -> (eval block) + wywołuje block jeśli condition jest: + dla b: bool jest b == true + dla n: number jest n != 0 + dla nil jest false + dla typu music, block, intrinsic, symbol zawsze prawdziwe + +if : condition: Bool, then: Block, else: Block -> (eval then or eval else) + jeśli condition jest prawdziwe wg zasad wyżej wywołaj then + w innym przypadku wywołaj else + +len : block -> number + zwraca ilość elementów (liczbę indeksowalnych pozycji) wewnątrz bloku + Przykład: + len [1;2;3] == 3 + len [foo;bar] == 2 + len [foo bar] == 1 + +play : music... -> nil + odtwarza sekwencyjnie otrzymane wartości muzyczne diff --git a/src/interpreter.cc b/src/interpreter.cc index 12c2d25..35de34a 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -53,6 +53,27 @@ constexpr auto comparison_operator() }; } +/// Registers constants like `fn = full note = 1/1` +static inline void register_note_length_constants() +{ + auto &global = *Env::global; + global.force_define("fn", Value::number(Number(1, 1))); + global.force_define("dfn", Value::number(Number(3, 2))); + global.force_define("hn", Value::number(Number(1, 2))); + global.force_define("dhn", Value::number(Number(3, 4))); + global.force_define("ddhn", Value::number(Number(7, 8))); + global.force_define("qn", Value::number(Number(1, 4))); + global.force_define("dqn", Value::number(Number(3, 8))); + global.force_define("ddqn", Value::number(Number(7, 16))); + global.force_define("en", Value::number(Number(1, 8))); + global.force_define("den", Value::number(Number(3, 16))); + global.force_define("dden", Value::number(Number(7, 32))); + global.force_define("sn", Value::number(Number(1, 16))); + global.force_define("dsn", Value::number(Number(3, 32))); + global.force_define("tn", Value::number(Number(1, 32))); + global.force_define("dtn", Value::number(Number(3, 64))); +} + Interpreter::Interpreter() { { // Context initialization @@ -64,6 +85,9 @@ Interpreter::Interpreter() } { // Global default functions initialization auto &global = *Env::global; + + register_note_length_constants(); + global.force_define("typeof", +[](Interpreter&, std::vector args) -> Result { assert(args.size() == 1, "typeof expects only one argument"); return Value::symbol(std::string(type_name(args.front().type))); @@ -80,7 +104,6 @@ Interpreter::Interpreter() } }); - global.force_define("len", +[](Interpreter &, std::vector args) -> Result { assert(args.size() == 1, "len only accepts one argument"); assert(args.front().type == Value::Type::Block, "Only blocks can be measure");