Let's go!

This commit is contained in:
Robert Bendun 2022-04-24 15:27:09 +02:00
commit 06f9b35c6c
14 changed files with 7071 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.ccls-cache
bin/*
compile_commands.json

12
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,12 @@
image: gcc
stages:
- build
build:
stage: build
script:
- make
artifacts:
path:
- main

22
Makefile Normal file
View File

@ -0,0 +1,22 @@
MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)"
CXXFLAGS=-std=c++20 -Wall -Wextra -O2 -Werror=switch
CPPFLAGS=-Ilib/expected/ -Ilib/ut/
Obj=bin/lexer.o \
bin/errors.o \
bin/main.o
all: bin/musique
bin/%.o: src/%.cc src/*.hh
g++ $(CXXFLAGS) $(CPPFLAGS) -o $@ $< -c
bin/musique: $(Obj) src/*.hh
g++ $(CXXFLAGS) $(CPPFLAGS) -o $@ $(Obj)
clean:
rm -rf bin
.PHONY: clean
$(shell mkdir -p bin)

1
README.md Normal file
View File

@ -0,0 +1 @@
# Musique interpreter

54
doc/składnia.txt Normal file
View File

@ -0,0 +1,54 @@
program = ws*, expression, ws*, { expression, ws* }
block = "[", program, "]" ;
(* At interpreter runtime it is determined which symbols pass as operators, and which not *)
expression = value, ws*, operator, ws*, expression
| operator, ws*, value
| value ;
value = note
| chord
| symbol
| block
| number
| ( "(", expression, ")" ) ;
symbol = ( valid-symbol-start-characters, { valid-symbol-characters } ) - note - chord;
valid-symbol-start-characters = uniletter | "_" | "@" | "$" | "#" ;
valid-symbol-characters = valid-symbol-start-characters | unidigit | "-" ;
operator = operator-symbols, { operator-symbols } ;
operator-symbols = "+" | "-" | "*" | "/" | "%" | "!"
| "<" | ">" | "v" | "^" | "=" | ":" ;
(********************************* Literały liczbowe *********************************)
number = floating-point | fraction ;
(* Dopuszcza następujące zapisy: 1/2, *)
fraction = digits+, ws*, "/", ws*, digits+ ;
(* Dopuszcza następujące zapisy: -123.456, 123.456, .456; Notacja naukowa nie jest wspierana *)
floating-point = ( ["-"], digits+, [ ".", digits+ ] ) | ( ".", digits+ );
(********************************* Literały muzyczne *********************************)
(* DSL do definiowania muzycznych wartości. Brakuje notacji dla akordów, przewrotów itd *)
note = note-letter, ["#"], [ws*, octave] ;
note-letter = "c" | "C" | "d" | "D" | "e" | "E" | "f" | "F" | "g" | "G" | "a" | "A" | "h" | "H" | "b" | "B" ;
octave = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" ;
chord = note-letter, ["#"], [ ("1" | "2" | "5" | "7" ), [ "," | "'" ] ];
(********************************* Definicje pomocnicze *********************************)
(* Unicode helpers, based on Go's compiler source code *)
uniletter = ? all characters that are considered letters in unicode ?;
unidigit = ? all characters that are considered digits in unicode ?;
digits+ = digit, { digits } ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
(* Whitespace helpers *)
ws* = { ws } ;
ws+ = ws, { ws } ;
ws = ? all characters that are considered ascii whitespace ? ;

91
lib/expected/README.md Normal file
View File

@ -0,0 +1,91 @@
# expected
Single header implementation of `std::expected` with functional-style extensions.
[![Documentation Status](https://readthedocs.org/projects/tl-docs/badge/?version=latest)](https://tl.tartanllama.xyz/en/latest/?badge=latest)
Clang + GCC: [![Linux Build Status](https://travis-ci.org/TartanLlama/expected.png?branch=master)](https://travis-ci.org/TartanLlama/expected)
MSVC: [![Windows Build Status](https://ci.appveyor.com/api/projects/status/k5x00xa11y3s5wsg?svg=true)](https://ci.appveyor.com/project/TartanLlama/expected)
Available on [Vcpkg](https://github.com/microsoft/vcpkg/tree/master/ports/tl-expected) and [Conan](https://github.com/yipdw/conan-tl-expected).
[`std::expected`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0323r3.pdf) is proposed as the preferred way to represent object which will either have an expected value, or an unexpected value giving information about why something failed. Unfortunately, chaining together many computations which may fail can be verbose, as error-checking code will be mixed in with the actual programming logic. This implementation provides a number of utilities to make coding with `expected` cleaner.
For example, instead of writing this code:
```cpp
std::expected<image,fail_reason> get_cute_cat (const image& img) {
auto cropped = crop_to_cat(img);
if (!cropped) {
return cropped;
}
auto with_tie = add_bow_tie(*cropped);
if (!with_tie) {
return with_tie;
}
auto with_sparkles = make_eyes_sparkle(*with_tie);
if (!with_sparkles) {
return with_sparkles;
}
return add_rainbow(make_smaller(*with_sparkles));
}
```
You can do this:
```cpp
tl::expected<image,fail_reason> get_cute_cat (const image& img) {
return crop_to_cat(img)
.and_then(add_bow_tie)
.and_then(make_eyes_sparkle)
.map(make_smaller)
.map(add_rainbow);
}
```
The interface is the same as `std::expected` as proposed in [p0323r3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0323r3.pdf), but the following member functions are also defined. Explicit types are for clarity.
- `map`: carries out some operation on the stored object if there is one.
* `tl::expected<std::size_t,std::error_code> s = exp_string.map(&std::string::size);`
- `map_error`: carries out some operation on the unexpected object if there is one.
* `my_error_code translate_error (std::error_code);`
* `tl::expected<int,my_error_code> s = exp_int.map_error(translate_error);`
- `and_then`: like `map`, but for operations which return a `tl::expected`.
* `tl::expected<ast, fail_reason> parse (const std::string& s);`
* `tl::expected<ast, fail_reason> exp_ast = exp_string.and_then(parse);`
- `or_else`: calls some function if there is no value stored.
* `exp.or_else([] { throw std::runtime_error{"oh no"}; });`
### Compiler support
Tested on:
- Linux
* clang 6.0.1
* clang 5.0.2
* clang 4.0.1
* clang 3.9
* clang 3.8
* clang 3.7
* clang 3.6
* clang 3.5
* g++ 8.0.1
* g++ 7.3
* g++ 6.4
* g++ 5.5
* g++ 4.9
* g++ 4.8
- Windows
* MSVC 2015
* MSVC 2017
### Acknowledgements
Thanks to [Kévin Alexandre Boissonneault](https://github.com/KABoissonneault) and [Björn Fahller](https://github.com/rollbear) for various bug fixes.
----------
[![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)]("http://creativecommons.org/publicdomain/zero/1.0/")
To the extent possible under law, [Sy Brand](https://twitter.com/TartanLlama) has waived all copyright and related or neighboring rights to the `expected` library. This work is published from: United Kingdom.

2326
lib/expected/tl/expected.hpp Normal file

File diff suppressed because it is too large Load Diff

23
lib/ut/LICENSE.md Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

2027
lib/ut/README.md Normal file

File diff suppressed because it is too large Load Diff

2391
lib/ut/boost/ut.hpp Normal file

File diff suppressed because it is too large Load Diff

6
src/errors.cc Normal file
View File

@ -0,0 +1,6 @@
#include "musique.hh"
std::ostream& operator<<(std::ostream& os, Error const&)
{
return os << "generic error";
}

12
src/lexer.cc Normal file
View File

@ -0,0 +1,12 @@
#include "musique.hh"
auto Lexer::next_token() -> Result<Token>
{
return {};
}
std::ostream& operator<<(std::ostream& os, Token const&)
{
os << "Token";
return os;
}

26
src/main.cc Normal file
View File

@ -0,0 +1,26 @@
#include <iostream>
#include "musique.hh"
std::string_view Source = R"musique(
nums = [ 1 2 3 ]
say ( min nums + max nums )
)musique";
tl::expected<void, Error> Main()
{
Lexer lexer{Source};
for (;;) {
auto token = Try(lexer.next_token());
std::cout << token << '\n';
}
}
int main()
{
auto result = Main();
if (not result.has_value()) {
std::cerr << result.error() << std::endl;
return 1;
}
}

77
src/musique.hh Normal file
View File

@ -0,0 +1,77 @@
#pragma once
#include <cstdint>
#include <string_view>
#include <ostream>
#include <tl/expected.hpp>
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using i8 = std::int8_t;
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
struct Error
{
std::string_view message;
Error *child = nullptr;
};
template<typename T>
using Result = tl::expected<T, Error>;
std::ostream& operator<<(std::ostream& os, Error const& err);
// NOTE This implementation requires C++ language extension: statement expressions
// It's supported by GCC, other compilers i don't know
#define Try(Value) ({ \
auto try_value = (Value); \
if (not try_value.has_value()) return tl::unexpected(try_value.error()); \
*std::move(try_value); \
})
struct Token
{
enum class Type
{
// like repeat or choose or chord
Symbol,
// chord literal, like c125
Chord,
// numeric literal (floating point or integer)
Numeric,
// "|" separaters arguments from block body, and provides variable introduction syntax
Variable_Separator,
// "[" and "]", delimit anonymous block of code (potentially a function)
Open_Block,
Close_Block,
// "(" and ")", used in arithmetic or as function invocation sarrounding (like in Haskell)
Open_Paren,
Close_Paren
};
std::string_view source;
};
std::ostream& operator<<(std::ostream& os, Token const& tok);
struct Lexer
{
// Source that is beeing lexed
std::string_view source;
// Determine location of tokens to produce nice errors
std::string_view source_name = "<unnamed>";
unsigned column = 1, row = 1;
auto next_token() -> Result<Token>;
};