Builtin function documentation generates from implementation
This commit is contained in:
parent
b51088a9f0
commit
bda1e503c7
@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Printing version number on non-quiet launch, or when provided `--version` or `:version`
|
||||
- Builtin function documentation generation from C++ Musique implementation source code
|
||||
|
||||
### Removed
|
||||
|
||||
- Release builder, since it's separate part of the project
|
||||
|
||||
## [0.3.1]
|
||||
|
||||
### Fixed
|
||||
|
3
Makefile
3
Makefile
@ -44,6 +44,9 @@ doc/musique-vs-languages-cheatsheet.html: doc/musique-vs-languages-cheatsheet.te
|
||||
doc/wprowadzenie.html: doc/wprowadzenie.md
|
||||
pandoc -o $@ $< -s --toc
|
||||
|
||||
doc/functions.html: musique/interpreter/builtin_functions.cc scripts/document-builtin.py
|
||||
scripts/document-builtin.py -o $@ $<
|
||||
|
||||
.PHONY: clean doc doc-open all test unit-tests release install
|
||||
|
||||
$(shell mkdir -p $(subst musique/,bin/$(os)/,$(shell find musique/* -type d)))
|
||||
|
115
doc/functions.md
115
doc/functions.md
@ -1,115 +0,0 @@
|
||||
# Lista wbudowanych funkcji języka Musique
|
||||
|
||||
* `bmp value` – zmienia wartość BMP z domyślnej na `value`;
|
||||
-`value` musi być liczbą całkowitą, domyślnie `120`;
|
||||
|
||||
* `call function args` – funkcja wywołująca funkcję `function`, która przekazuje `function` `args` jako argumenty wywoływanej fukncji;
|
||||
|
||||
* `ceil value` – operacja podobna do matematycznej funkcji podłogi (zaokrąglenie liczby do pierwszej liczby całkowitej mniejszej lub równej tej liczbie);
|
||||
- `value` – musi być to wartość o typie Number lub tablica takich wartości;
|
||||
|
||||
* `chord (notes)` – konstruuje akord z `notes`:
|
||||
- `notes` – `notes` definiowane są następująco: `(<litera_nuty> <numer_oktawy> <czas_trwania>)`:
|
||||
- np. `(c 4 1)` – dźwięk C w 4 oktawie, o długości całej nuty;
|
||||
|
||||
* `down value` – sekwencyjnie zwraca liczby całkowite, począwszy od `value` do 0:
|
||||
- `value` – musi być liczbą całkowitą;
|
||||
|
||||
* `flat args` – łączy `args` w tablicę bez zagnieżdżeń (tzn. "odpakowuje" zawartość zagnieżdżonych tablic i zawiera je w pojedyńczej tabeli):
|
||||
- `args` - tablica, w tym tablica z zagnieżdżeniami;
|
||||
|
||||
* `floor value` – operacja podobna do matematycznej funkcji podłogi (zaokrąglenie liczby do pierwszej liczby całkowitej większej lub równej tej liczbie);
|
||||
- `value` – musi być to zmienna o typie Number lub tablica takich zmiennych;
|
||||
|
||||
* `fold args` – używa elementów tablicy jako argumentów podanej funkcji:
|
||||
- `args` – postaci `tablica funkcja` lub `tablica wartość_startowa funkcja`;
|
||||
|
||||
* `for vect` – iteruje po elementach wektora `vect`:
|
||||
- `vect` - kontener wartości, musi posiadać typ Vector;
|
||||
|
||||
* `hash vect` – standardowa funkcja haszująca, zwraca jeden hash połączonych wartości z `vect`:
|
||||
- `vect` - kontener wartości, mogą być dowolnego typu;
|
||||
|
||||
* `if cond [if_true] [if_false]` – wyrażenie warunkowe: jeżeli `cond` będzie prawdą, zostanie wykonany kod z `[if_true]`, w przeciwnym wypadku wykonany zostanie kod z `[if_false]` – fragment `[if_false]` jest opcjonalny;
|
||||
|
||||
* `incoming args` – pozwala na rozpatrzenie przychodzących komunikatów MIDI (`note_on` i `note_off`), odpowiednio;
|
||||
- `args` – konstrukcja `komunikat, nuta`;
|
||||
|
||||
* `instrument args` – pozwala na zmianę instrumentu:
|
||||
- `args` – może przyjmować sam numer programu, lub parę `numer_programu, kanał`;
|
||||
|
||||
* `len args` – zwraca długość kontenera `args`, a jeżeli `args` nie jest wektorem ustawia domyślną długość trwania dźwięku, domyślnie ćwierćnuta;
|
||||
|
||||
* `max args` – zwraca maksimum z `args`;
|
||||
|
||||
* `min args` – zwraca minimum z `args`;
|
||||
|
||||
* `mix args` – algorytmicznie miesza wszystkie elementy z `args`:
|
||||
- `args` – tablica elementów, może być tablicą z zagnieżdżeniami;
|
||||
|
||||
* `note_off args` – w zależności od kształtu `args`:
|
||||
- jeżeli `args` są w postaci `(kanał, nuta)` – wyłącza nutę na danym kanale:
|
||||
- `kanał` – liczba całkowita;
|
||||
- `nuta` – postać podobna do `notes` z `chord notes`;
|
||||
- jeżeli `args` są w postaci `(kanał, akord)` – wyłącza wszystkie nuty z danego akordu na danym kanale;
|
||||
|
||||
* `note_on args` – analogicznie do `note_off args`;
|
||||
|
||||
* `nprimes value` – generuje `value` kolejnych liczb pierwszych:
|
||||
- `value` – musi być typu Number;
|
||||
|
||||
* `oct value` – analogicznie do `bpm value`, wartość domyślna to 4;
|
||||
|
||||
* `par args` – gra współbieżnie pierwszy dźwięk z `args` z pozostałymi dźwiękami z `args`:
|
||||
- `args` – postać `(note, ...)`, powinien być rozmiaru co najmniej 2:
|
||||
- `note` – postać podobna do `notes` z `chords notes`;
|
||||
|
||||
* `partition args` – dzieli `args` na dwie grupy wedle danej funkcji:
|
||||
- `args` – powinno przyjąć formę `(funkcja, tablica())`
|
||||
|
||||
* `permute args` – permutuje `args`:
|
||||
- `args` – tablica obiektów;
|
||||
|
||||
* `pgmchange args` – analogicznie do `instrument args`;
|
||||
|
||||
* `play args` – gra `args`:
|
||||
- `args` – mogą być to pojedyncze nuty, tablica nut oraz bloki kodu (nuty analogicznie jak w `chord notes`);
|
||||
|
||||
* `program_change args` – analogicznie do `instrument args`;
|
||||
|
||||
* `range args` – zwraca tablicę wartości liczbowych w podanych w `args` zakresie:
|
||||
- `args` – postać `stop`, `start stop` lub `start stop step`;
|
||||
|
||||
* `reverse args` – odwraca kolejność elementów `args`;
|
||||
- `args` – powinna być to tablica;
|
||||
|
||||
* `rotate args` – przenosi na koniec tablicy wskazaną ilość elementów:
|
||||
- `args` – musi być postaci `liczba tablica`;
|
||||
|
||||
* `round value` – zaokrągla wartość zgodnie z reguałmi matematyki:
|
||||
- `value` – musi być to wartość liczbowa;
|
||||
|
||||
* `shuffle args` – tasuje elementy `args`:
|
||||
- `args` – powinna być to tablica;
|
||||
|
||||
* `sim` – #TODO
|
||||
|
||||
* `sort args` – sortuje elementy `args`:
|
||||
- `args` – powinna być to tablica;
|
||||
|
||||
* `try args` – próbuje wykonać wszystkie bloki kodu poza ostatnim, a jeżeli w trakcie tej próby natrafi na błąd, wykonuje ostatni blok:
|
||||
- `args` – musi być to co najmniej jeden blok kodu Musique;
|
||||
|
||||
* `typeof variable` – zwraca typ wskazanej `variable`;
|
||||
|
||||
* `uniq args` – zwraca tablicę elementów, z której usunięto następujące po sobie powtórzenia:
|
||||
- `args` – powinna być to tablica;
|
||||
|
||||
* `unique args` – zwraca tablicę elementów, z której usunięto powtórzenia:
|
||||
- `args` – powinna być to tablica;
|
||||
|
||||
* `up value` – analogicznie do `down value`;
|
||||
|
||||
* `update args` – aktualizuje element tablicy do nowej wartości:
|
||||
- `args` – postaci `tablica indeks wartość`;
|
||||
|
@ -11,6 +11,14 @@
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
/// This macro implements functions that are only implemented as forwarding
|
||||
/// all arguments to another function
|
||||
#define Forward_Implementation(New_Function_Name, Implementation) \
|
||||
static inline Result<Value> New_Function_Name(Interpreter &interpreter, std::vector<Value> args) \
|
||||
{ \
|
||||
return Implementation(interpreter, std::move(args)); \
|
||||
}
|
||||
|
||||
/// Check if type has index method
|
||||
template<typename T>
|
||||
concept With_Index_Method = requires (T &t, Interpreter interpreter, usize position) {
|
||||
@ -103,6 +111,39 @@ static Result<Value> ctx_read_write_property(Interpreter &interpreter, std::vect
|
||||
return Value{};
|
||||
}
|
||||
|
||||
//: Funkcja `bpm` pozwala na zapisywanie i odczytywanie wartości BPM z aktualnego kontekstu.
|
||||
//:
|
||||
//: Domyślną wartością jest 120.
|
||||
//: # Odczytywanie wartości z kontekstu
|
||||
//: ```
|
||||
//: > call bpm
|
||||
//: 120
|
||||
//: ```
|
||||
//: # Zapisywanie wartości BPM do aktualnego kontekstu
|
||||
//: ```
|
||||
//: > bpm 144
|
||||
//: 144
|
||||
//: ```
|
||||
Forward_Implementation(builtin_bpm, ctx_read_write_property<&Context::bpm>)
|
||||
|
||||
//: Funkcja `oct` pozwala na zapisywanie i odczytywanie wartości oktawy z aktualnego kontekstu.
|
||||
//:
|
||||
//: Wartość ta jest używana w momencie odtwarzania dźwięków nie posiadających ustalonego numeru oktawy:
|
||||
//: `c` zostanie uzupełnione oktawą domyślną z kontekstu, `c5` zachowa swój nr oktawy.
|
||||
//:
|
||||
//: Domyślną wartością jest 120.
|
||||
//: # Odczytywanie wartości z kontekstu
|
||||
//: ```
|
||||
//: > call bpm
|
||||
//: 120
|
||||
//: ```
|
||||
//: # Zapisywanie wartości BPM do aktualnego kontekstu
|
||||
//: ```
|
||||
//: > bpm 144
|
||||
//: 144
|
||||
//: ```
|
||||
Forward_Implementation(builtin_oct, ctx_read_write_property<&Context::octave>)
|
||||
|
||||
/// Iterate over array and it's subarrays to create one flat array
|
||||
static Result<Array> into_flat_array(Interpreter &interpreter, std::span<Value> args)
|
||||
{
|
||||
@ -172,12 +213,16 @@ invalid_argument_type:
|
||||
};
|
||||
}
|
||||
|
||||
Forward_Implementation(builtin_ceil, apply_numeric_transform<&Number::ceil>)
|
||||
Forward_Implementation(builtin_floor, apply_numeric_transform<&Number::floor>)
|
||||
Forward_Implementation(builtin_round, apply_numeric_transform<&Number::round>)
|
||||
|
||||
/// Direction used in range definition (up -> 1, 2, 3; down -> 3, 2, 1)
|
||||
enum class Range_Direction { Up, Down };
|
||||
|
||||
/// Create range according to direction and specification, similar to python
|
||||
template<Range_Direction dir>
|
||||
static Result<Value> builtin_range(Interpreter&, std::vector<Value> args)
|
||||
static Result<Value> range(Interpreter&, std::vector<Value> args)
|
||||
{
|
||||
auto start = Number(0), stop = Number(0), step = Number(1);
|
||||
|
||||
@ -210,7 +255,20 @@ static Result<Value> builtin_range(Interpreter&, std::vector<Value> args)
|
||||
return array;
|
||||
}
|
||||
|
||||
/// Send MIDI Program Change message
|
||||
Forward_Implementation(builtin_range, range<Range_Direction::Up>)
|
||||
Forward_Implementation(builtin_up, range<Range_Direction::Up>)
|
||||
Forward_Implementation(builtin_down, range<Range_Direction::Down>)
|
||||
|
||||
//: Funkcja `instrument` pozwala na wybór instrumentu na danym kanale MIDI.
|
||||
//: # Ustawienie instrumentu 4
|
||||
//: ```
|
||||
//: instrument 4
|
||||
//: ```
|
||||
//: # Ustawienie instrumentu 4 na kanale 6
|
||||
//: ```
|
||||
//: instrument 6 4
|
||||
//: ```
|
||||
//: Przyporządkowanie numerów instrumentów do standardowych nazw znajdziesz [tutaj](http://midi.teragonaudio.com/tutr/gm.htm#Patch)
|
||||
static auto builtin_program_change(Interpreter &i, std::vector<Value> args) -> Result<Value> {
|
||||
if (auto a = match<Number>(args)) {
|
||||
auto [program] = *a;
|
||||
@ -1113,14 +1171,14 @@ void Interpreter::register_builtin_functions()
|
||||
{
|
||||
auto &global = *Env::global;
|
||||
|
||||
global.force_define("bpm", ctx_read_write_property<&Context::bpm>);
|
||||
global.force_define("bpm", builtin_bpm);
|
||||
global.force_define("call", builtin_call);
|
||||
global.force_define("ceil", apply_numeric_transform<&Number::ceil>);
|
||||
global.force_define("ceil", builtin_ceil);
|
||||
global.force_define("chord", builtin_chord);
|
||||
global.force_define("down", builtin_range<Range_Direction::Down>);
|
||||
global.force_define("down", builtin_down);
|
||||
global.force_define("duration", builtin_duration);
|
||||
global.force_define("flat", builtin_flat);
|
||||
global.force_define("floor", apply_numeric_transform<&Number::floor>);
|
||||
global.force_define("floor", builtin_floor);
|
||||
global.force_define("fold", builtin_fold);
|
||||
global.force_define("for", builtin_for);
|
||||
global.force_define("hash", builtin_hash);
|
||||
@ -1134,7 +1192,7 @@ void Interpreter::register_builtin_functions()
|
||||
global.force_define("note_off", builtin_note_off);
|
||||
global.force_define("note_on", builtin_note_on);
|
||||
global.force_define("nprimes", builtin_primes);
|
||||
global.force_define("oct", ctx_read_write_property<&Context::octave>);
|
||||
global.force_define("oct", builtin_oct);
|
||||
global.force_define("par", builtin_par);
|
||||
global.force_define("partition", builtin_partition);
|
||||
global.force_define("permute", builtin_permute);
|
||||
@ -1142,10 +1200,10 @@ void Interpreter::register_builtin_functions()
|
||||
global.force_define("pick", builtin_pick);
|
||||
global.force_define("play", builtin_play);
|
||||
global.force_define("program_change", builtin_program_change);
|
||||
global.force_define("range", builtin_range<Range_Direction::Up>);
|
||||
global.force_define("range", builtin_range);
|
||||
global.force_define("reverse", builtin_reverse);
|
||||
global.force_define("rotate", builtin_rotate);
|
||||
global.force_define("round", apply_numeric_transform<&Number::round>);
|
||||
global.force_define("round", builtin_round);
|
||||
global.force_define("scan", builtin_scan);
|
||||
global.force_define("set_len", builtin_set_len);
|
||||
global.force_define("set_oct", builtin_set_oct);
|
||||
@ -1156,7 +1214,7 @@ void Interpreter::register_builtin_functions()
|
||||
global.force_define("typeof", builtin_typeof);
|
||||
global.force_define("uniq", builtin_uniq);
|
||||
global.force_define("unique", builtin_unique);
|
||||
global.force_define("up", builtin_range<Range_Direction::Up>);
|
||||
global.force_define("up", builtin_up);
|
||||
global.force_define("update", builtin_update);
|
||||
global.force_define("while", builtin_while);
|
||||
}
|
||||
|
256
scripts/document-builtin.py
Executable file
256
scripts/document-builtin.py
Executable file
@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import dataclasses
|
||||
import string
|
||||
import re
|
||||
import itertools
|
||||
import typing
|
||||
import subprocess
|
||||
|
||||
MARKDOWN_CONVERTER = "lowdown -m 'shiftheadinglevelby=3'"
|
||||
CPP_FUNC_IDENT_ALLOWLIST = string.ascii_letters + string.digits + "_"
|
||||
PROGRAM_NAME: str = ""
|
||||
|
||||
HTML_PREFIX = """<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Dokumentacja funkcji języka Musique</title>
|
||||
<style>
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
margin: 10px auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
max-width: 50em;
|
||||
}
|
||||
|
||||
nav a, nav a:link, nav a:visited {
|
||||
color: #07a;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h2 > a, h2>a:visited, h2>a:link {
|
||||
color: gray;
|
||||
text-decoration: none;
|
||||
padding-right: 5px;
|
||||
}
|
||||
h2 > a:hover { color: lightgrey; }
|
||||
|
||||
footer {
|
||||
width: 100%;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Dokumentacja funkcji języka Musique</h1>
|
||||
"""
|
||||
|
||||
HTML_SUFFIX = """
|
||||
<footer>
|
||||
Wszystkie treści podlegają licencji <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def warning(*args, prefix: str | None = None):
|
||||
if prefix is None:
|
||||
prefix = PROGRAM_NAME
|
||||
message = ": ".join(itertools.chain([prefix, "warning"], args))
|
||||
print(message)
|
||||
|
||||
|
||||
def error(*args, prefix=None):
|
||||
if prefix is None:
|
||||
prefix = PROGRAM_NAME
|
||||
message = ": ".join(itertools.chain([prefix, "error"], args))
|
||||
print(message)
|
||||
exit(1)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Builtin:
|
||||
implementation: str
|
||||
definition_location: tuple[str, int] # Filename and line number
|
||||
names: list[str]
|
||||
documentation: str
|
||||
|
||||
|
||||
def builtins_from_file(source_path: str) -> typing.Generator[Builtin, None, None]:
|
||||
with open(source_path) as f:
|
||||
source = f.readlines()
|
||||
|
||||
builtins: dict[str, Builtin] = {}
|
||||
definition = re.compile(
|
||||
r"""force_define.*\("([^"]+)"\s*,\s*(builtin_[a-zA-Z0-9_]+)\)"""
|
||||
)
|
||||
|
||||
current_documentation = []
|
||||
|
||||
for lineno, line in enumerate(source):
|
||||
line = line.strip()
|
||||
|
||||
# Check if line contains force_define with static string and builtin_*
|
||||
# thats beeing defined. It's a one of many names that given builtin
|
||||
# has in Musique
|
||||
if result := definition.search(line):
|
||||
musique_name = result.group(1)
|
||||
builtin_name = result.group(2)
|
||||
|
||||
if builtin_name in builtins:
|
||||
builtins[builtin_name].names.append(musique_name)
|
||||
else:
|
||||
error(
|
||||
f"tried adding Musique name '{musique_name}' to builtin '{builtin_name}' that has not been defined yet",
|
||||
prefix=f"{source_path}:{lineno}",
|
||||
)
|
||||
continue
|
||||
|
||||
# Check if line contains special documentation comment.
|
||||
# We assume that only documentation comments are in given line (modulo whitespace)
|
||||
if line.startswith("//:"):
|
||||
line = line.removeprefix("//:").strip()
|
||||
current_documentation.append(line)
|
||||
continue
|
||||
|
||||
# Check if line contains builtin_* identifier.
|
||||
# If contains then this must be first definition of this function
|
||||
# and therefore all documentation comments before it describe it
|
||||
if (index := line.find("builtin_")) >= 0 and line[
|
||||
index - 1
|
||||
] not in CPP_FUNC_IDENT_ALLOWLIST:
|
||||
identifier = line[index:]
|
||||
for i, char in enumerate(identifier):
|
||||
if char not in CPP_FUNC_IDENT_ALLOWLIST:
|
||||
identifier = identifier[:i]
|
||||
break
|
||||
|
||||
if identifier not in builtins:
|
||||
builtin = Builtin(
|
||||
implementation=identifier,
|
||||
# TODO Allow redefinition of source path with some prefix
|
||||
# to allow website links
|
||||
definition_location=(source_path, lineno),
|
||||
names=[],
|
||||
documentation="\n".join(current_documentation),
|
||||
)
|
||||
builtins[identifier] = builtin
|
||||
current_documentation = []
|
||||
continue
|
||||
|
||||
for builtin in builtins.values():
|
||||
builtin.names.sort()
|
||||
yield builtin
|
||||
|
||||
|
||||
def filter_builtins(builtins: list[Builtin]) -> typing.Generator[Builtin, None, None]:
|
||||
for builtin in builtins:
|
||||
if not builtin.documentation:
|
||||
warning(f"builtin '{builtin.implementation}' doesn't have documentation")
|
||||
continue
|
||||
|
||||
# Testt if builtin is unused
|
||||
if not builtin.names:
|
||||
continue
|
||||
|
||||
yield builtin
|
||||
|
||||
|
||||
def each_musique_name_occurs_once(
|
||||
builtins: typing.Iterable[Builtin],
|
||||
) -> typing.Generator[Builtin, None, None]:
|
||||
names = {}
|
||||
for builtin in builtins:
|
||||
for name in builtin.names:
|
||||
if name in names:
|
||||
error(
|
||||
f"'{name}' has been registered as both '{builtin.implementation}' and '{names[name]}'"
|
||||
)
|
||||
names[name] = builtin.implementation
|
||||
yield builtin
|
||||
|
||||
|
||||
def generate_html_document(builtins: list[Builtin], output_path: str):
|
||||
with open(output_path, "w") as out:
|
||||
out.write(HTML_PREFIX)
|
||||
|
||||
out.write("<nav>")
|
||||
|
||||
names = sorted(
|
||||
[
|
||||
(name, builtin.implementation)
|
||||
for builtin in builtins
|
||||
for name in builtin.names
|
||||
]
|
||||
)
|
||||
|
||||
out.write(", ".join(f"""<a href="#{id}">{name}</a>""" for name, id in names))
|
||||
|
||||
out.write("</nav>")
|
||||
|
||||
out.write("<main>")
|
||||
|
||||
for builtin in builtins:
|
||||
out.write("<p>")
|
||||
out.write(
|
||||
f"""<h2 id="{builtin.implementation}"><a href="#{builtin.implementation}">§</a>{', '.join(builtin.names)}</h2>"""
|
||||
)
|
||||
out.write(
|
||||
subprocess.check_output(
|
||||
MARKDOWN_CONVERTER,
|
||||
input=builtin.documentation,
|
||||
encoding="utf-8",
|
||||
shell=True,
|
||||
)
|
||||
)
|
||||
out.write("</p>")
|
||||
|
||||
out.write("</main>")
|
||||
|
||||
out.write(HTML_SUFFIX)
|
||||
|
||||
|
||||
def main(source_path: str, output_path: str):
|
||||
"Generates documentaiton from file source_path and saves in output_path"
|
||||
|
||||
builtins = builtins_from_file(source_path)
|
||||
builtins = filter_builtins(builtins)
|
||||
builtins = each_musique_name_occurs_once(builtins)
|
||||
builtins = sorted(list(builtins), key=lambda builtin: builtin.names[0])
|
||||
|
||||
generate_html_document(builtins, output_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Builtin functions documentation generator from C++ Musique implementation"
|
||||
)
|
||||
parser.add_argument(
|
||||
"source",
|
||||
type=str,
|
||||
nargs=1,
|
||||
help="C++ source file from which documentation will be generated",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
type=str,
|
||||
nargs=1,
|
||||
required=True,
|
||||
help="path for standalone HTML file containing generated documentation",
|
||||
)
|
||||
|
||||
PROGRAM_NAME = parser.prog
|
||||
args = parser.parse_args()
|
||||
assert len(args.source) == 1
|
||||
assert len(args.output) == 1
|
||||
|
||||
main(source_path=args.source[0], output_path=args.output[0])
|
@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script creates a release of Musique programming language
|
||||
# Release is defined as a zip archive containing source code,
|
||||
# build binaries for supported platforms and build documentation
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
Suffix="$(date +"%Y-%m-%d")"
|
||||
Target="release_$Suffix"
|
||||
Image="musique-builder"
|
||||
|
||||
if [ -d "$Target" ]; then
|
||||
rm -rf "$Target"
|
||||
fi
|
||||
|
||||
mkdir -p "$Target"
|
||||
|
||||
if [[ "$(docker images -q "$Image")" == "" ]]; then
|
||||
docker build -t "$Image" .
|
||||
fi
|
||||
sudo rm -rf bin/
|
||||
docker run -it --rm -v "$(pwd):/musique" -w /musique "$Image" make os=linux CC=gcc-11 CXX=g++-11 >/dev/null
|
||||
|
||||
cp bin/musique "$Target"/musique-x86_64-linux
|
||||
|
||||
sudo rm -rf bin/
|
||||
make os=windows >/dev/null
|
||||
cp bin/musique.exe "$Target"/musique-x86_64-windows.exe
|
||||
|
||||
cp LICENSE "$Target"/LICENSE
|
||||
cp CHANGELOG.md "$Target/CHANGELOG.md"
|
||||
cp -r examples "$Target"/examples
|
||||
sed "s/bin\/musique/musique/" scripts/install > "$Target"/install.sh
|
||||
chmod 0755 "$Target"/install.sh
|
||||
|
||||
lowdown -s doc/functions.md -m "title:Lista funkcji języka Musique" -o "$Target"/functions.html
|
||||
python scripts/language-cmp-cheatsheet.py doc/musique-vs-languages-cheatsheet.template
|
||||
mv doc/musique-vs-languages-cheatsheet.html "${Target}/musique-vs-others-cheatsheet.html"
|
||||
make doc/wprowadzenie.html && mv doc/wprowadzenie.html "${Target}/wprowadzenie.html"
|
||||
|
||||
git clone --recursive --quiet --depth=1 "$(git remote -v | awk '{ print $2 }' | head -n1)" "$Target"/source_code
|
||||
rm -rf "$Target"/source_code/.git
|
||||
|
||||
zip -q -r "musique_$Suffix.zip" "$Target"/*
|
Loading…
Reference in New Issue
Block a user