Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

guard, action, internal transition, and typescript #30

Draft
wants to merge 27 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
163e91c
Define which syntax to implement
DrSensor Jul 16, 2019
8567a22
Update grammar for the new syntax
DrSensor Jul 16, 2019
98d21e7
Fix `Perf cargo` action (#31)
DrSensor Jul 17, 2019
35061ab
Create initial implementation for the new syntax
DrSensor Jul 17, 2019
81700d6
Implement the new syntax for xstate transpiler
DrSensor Jul 17, 2019
5e4f00c
Fix unreachable!(EOI) on internal transition ➕
DrSensor Jul 18, 2019
e6091f9
Implement the new syntax for smcat transpiler
DrSensor Jul 17, 2019
73841e4
Fix incorrect output on internal transition ➕
DrSensor Jul 18, 2019
9769d7f
Fix multiple internal transition on smcat transpiler
DrSensor Jul 19, 2019
81333b2
Unlock --format graph --as vcg,gdl,graphml
DrSensor Jul 21, 2019
be06a6d
Support typescript output on xstate transpiler ⚠️
DrSensor Jul 24, 2019
e64cd9c
Add CLI flag --format xstate --as typescript
DrSensor Jul 24, 2019
bbf49e0
Refactor typescript generator in xstate transpiler
DrSensor Jul 27, 2019
f52cca4
ci: add smoke tests to test nodejs-xstate example
DrSensor Jul 28, 2019
3788da1
Infer event value to obj list in xstate transpiler
DrSensor Jul 30, 2019
d5384b2
Fix false alarm on semantics-check guards
DrSensor Jul 30, 2019
6673392
Move semantics-check guards to warning level
DrSensor Aug 3, 2019
0b58caf
Fix and refine the error messages
DrSensor Aug 6, 2019
16eb018
Add `just smoke` while fix doc tests
DrSensor Aug 20, 2019
6bc6e2e
Replace lazy_static with once_cell
DrSensor Aug 20, 2019
b0d921b
Fix internal-transition can't be rendered in boxart
DrSensor Aug 20, 2019
31757d0
Fix gh-action `Smoke tests`
DrSensor Aug 23, 2019
9510922
Refactor core parser
DrSensor Aug 24, 2019
47fadcc
Fix duplicate warnings
DrSensor Aug 24, 2019
f911c4c
Move generating shell completion at run-time
DrSensor Aug 25, 2019
a86a2b2
Refactor custom option implementation
DrSensor Aug 26, 2019
4496b9c
Refactor transpiler all transpiler
DrSensor Aug 31, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/action/perf/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:slim AS helper
FROM python:slim-buster AS helper

RUN apt-get update && \
apt-get install --no-install-recommends -y \
Expand All @@ -12,7 +12,7 @@ RUN pip install pyinstaller && \
pyinstaller wrap-args.py --onefile --distpath /bin

# ----------------- Github Action ------------------------
FROM rust:slim
FROM rust:slim-buster

LABEL "name"="perf" \
"maintainer"="Fahmi Akbar Wildana <[email protected]>" \
Expand All @@ -23,12 +23,12 @@ LABEL "com.github.actions.name"="GitHub Action for Measuring Performance" \
"com.github.actions.icon"="clock" \
"com.github.actions.color"="orange"

ADD https://github.com/sharkdp/hyperfine/releases/download/v1.5.0/hyperfine_1.5.0_amd64.deb \
ADD https://github.com/sharkdp/hyperfine/releases/download/v1.6.0/hyperfine_1.6.0_amd64.deb \
https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 \
/tmp/

RUN chmod +x /tmp/* && \
dpkg -i /tmp/hyperfine_1.5.0_amd64.deb && \
dpkg -i /tmp/hyperfine_1.6.0_amd64.deb && \
mv /tmp/jq-linux64 /usr/bin/jq && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Expand Down
24 changes: 15 additions & 9 deletions .github/action/perf/wrap-args.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
#!/usr/bin/env python
import re,sys
import re
import sys
from itertools import zip_longest
from subprocess import run

assert len(sys.argv) > 1


# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)


def group_command(flatten_commands, commands):
"Group string by it's command name"
separator = f"({'|'.join(list_command)})"
separated_cmd_params = [s.strip() for s in re.split(separator, flatten_commands)[1:]]
return [' '.join(s) for s in grouper(separated_cmd_params, 2)]
separated_cmd_params = [
s.strip() for s in re.split(separator, flatten_commands)[1:]
]
return [" ".join(s) for s in grouper(separated_cmd_params, 2)]


cargo_list = run(['cargo', '--list'], capture_output=True)
stdout = cargo_list.stdout.decode('utf-8')
cargo_list = run(["cargo", "--list"], capture_output=True)
stdout = cargo_list.stdout.decode("utf-8")

command_help = stdout.split('\n')[1:-1] # remove endline and title string
list_command =[s.split(maxsplit=1)[0] for s in command_help] # remove help description
command_help = stdout.split("\n")[1:-1] # remove endline and title string
list_command = [s.split(maxsplit=1)[0] for s in command_help] # remove help description

grouped = group_command(' '.join(sys.argv[1:]), list_command)
grouped = group_command(" ".join(sys.argv[1:]), list_command)

prefix_command = lambda f: '"{prefix} {}"'.format(f'" "{f} '.join(grouped), prefix=f)
print(prefix_command('cargo'))
print(prefix_command("cargo"))
5 changes: 3 additions & 2 deletions .github/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/bin/sh
set -e

export PATH="$HOME/.cargo/bin:$PATH"
mkdir --parents ${HOME}/.bin/
export PATH="$HOME/.cargo/bin:${HOME}/.bin:$PATH"

[ -z $WORKDIR ] || cd $WORKDIR
for cmd in "$@"; do
echo "Running '$cmd'..."
if sh -c "$cmd"; then
# no op
echo
echo "Successfully ran '$cmd'"
else
Expand Down
48 changes: 31 additions & 17 deletions .github/main.workflow
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
workflow "Testing" {
on = "push"
resolves = ["Test all rust project"]
resolves = ["Test all rust project", "Smoke tests"]
}

workflow "Measure Performance" {
Expand Down Expand Up @@ -41,6 +41,32 @@ action "Summarize perf" {
# ---------------------------------------------------------------

# ------------------------ Process ------------------------------
action "Test all rust project" {
uses = "docker://rust:slim-buster"
runs = "./.github/entrypoint.sh"
args = [
"cargo install just",
"just test",
"mv target/debug/${BIN} ${HOME}/.bin/${BIN}",
]
env = { BIN = "scrap" }
}

action "Smoke tests" {
needs = "Test all rust project"
uses = "docker://node:buster"
runs = "./.github/entrypoint.sh"
args = [
"git submodule update --init --recursive",
"npm install",
"scrap generate src/${filestem}.scl --format xstate --as typescript > src/fsm/${filestem}.ts",
"scrap generate src/${filestem}.scl --format xstate --as javascript >> src/fsm/${filestem}.ts",
"npx tsc --build",
"node dist/index.js",
]
env = { WORKDIR = "examples/xstate/nodejs", filestem = "light" }
}

action "Perf cargo" {
needs = "On Push"
uses = "./.github/action/perf"
Expand All @@ -52,17 +78,6 @@ action "Perf cargo" {
]
}

action "Test all rust project" {
uses = "docker://rust:slim"
runs = "./.github/entrypoint.sh"
args = [
"cargo install just",
"just unit",
"just integration || true",
]
env = { PWD = "/github/workspace" }
}

action "Build Release cli as musl" {
needs = "On Push"
uses = "docker://rust:slim"
Expand All @@ -71,7 +86,6 @@ action "Build Release cli as musl" {
"rustup target add x86_64-unknown-linux-musl",
"apt-get update && apt-get install -y musl-tools",
"cargo build --target x86_64-unknown-linux-musl --release --bin ${BIN}",
"mkdir -p ${HOME}/.bin/",
"mv target/x86_64-unknown-linux-musl/release/${BIN} ${HOME}/.bin/${BIN}",
]
env = { BIN = "scrap" }
Expand All @@ -82,10 +96,10 @@ action "Perf CLI release" {
uses = "docker://python:alpine"
runs = "./.github/profiler.sh"
args = [
"${HOME}/.bin/scrap code examples/simple.scl --format xstate",
"${HOME}/.bin/scrap code examples/simple.scl --format xstate --stream",
"${HOME}/.bin/scrap code examples/simple.scl --format smcat",
"${HOME}/.bin/scrap code examples/simple.scl --format smcat --stream",
"scrap code examples/simple.scl --format xstate",
"scrap code examples/simple.scl --format xstate --stream",
"scrap code examples/simple.scl --format smcat",
"scrap code examples/simple.scl --format smcat --stream",
],
env = { PREPARE = "./scripts/gensample.py 1000 > examples/simple.scl" }
}
Expand Down
2 changes: 2 additions & 0 deletions .github/profiler.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# 4. Add environment variable for preparation (e.g execute script to generate sample data)
set -e

export PATH="$HOME/.cargo/bin:${HOME}/.bin:$PATH"

json='{
"command": "%C",
"memory": {
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "examples/xstate/nodejs"]
path = examples/xstate/nodejs
url = https://github.com/DrSensor/nodejs-scdlang_xstate.git
48 changes: 47 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ check: clear
watchexec --restart --clear 'just {{command}} {{args}}'

# Run all kind of tests
test: unit integration
test: unit integration smoke

# Generate and open the documentation
docs +args='':
Expand Down Expand Up @@ -63,14 +63,20 @@ release version:
build args='':
cargo build {{args}}

# Run all unit test
# Run all unit tests
unit:
cargo test --lib --all --exclude s-crap -- --test-threads=1

# Run all integration test
# Run all integration tests
integration:
cargo test --tests -p s-crap -- --test-threads=1

# Run all examples and doc-tests
smoke:
cargo test --doc --all --exclude s-crap
cargo test --examples
# TODO: `mask --maskfile examples/xstate/nodejs/maskfile.md start` should link `scrap` to target/debug/scrap

# Show reports of macro-benchmark
@stats git-flags='':
./scripts/summary.sh {{git-flags}} | ./scripts/perfsum.py
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![License](https://img.shields.io/github/license/drsensor/scdlang.svg)](./LICENSE)
[![Chats](https://img.shields.io/badge/community-grey.svg?logo=matrix)](https://matrix.to/#/+statecharts:matrix.org)

> 🚧 Still **Work in Progress** 🏗️
> 🚧 Slowly **Work in Progress** 🏗️

## About
Scdlang (pronounced `/ˈesˌsi:ˈdi:ˈlæŋ/`) is a description language for describing Statecharts that later can be used to generate code or just transpile it into another format. This project is more focus on how to describe Statecharts universally that can be used in another language/platform rather than drawing a Statecharts diagram. For drawing, see [State Machine Cat][].
Expand All @@ -35,11 +35,12 @@ Scdlang (pronounced `/ˈesˌsi:ˈdi:ˈlæŋ/`) is a description language for des
- [ ] [WaveDrom](https://observablehq.com/@drom/wavedrom)
- Compile into other formats (hopefully, no promise):
- [ ] WebAssembly (using [parity-wasm](https://github.com/paritytech/parity-wasm))
- Code generation 🤔
- [ ] Julia via [`@generated`](https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions-1) implemented as [parametric](https://docs.julialang.org/en/v1/manual/methods/#Parametric-Methods-1) [multiple-dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch#Julia) [functors](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects-1)
- [ ] Rust via [`#[proc_macro_attribute]`](https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros) implemented as [typestate programming](https://rust-embedded.github.io/book/static-guarantees/typestate-programming.html)? (I'm still afraid if it will conflict with another crates)
- [ ] Elixir via [`use`](https://elixir-lang.org/getting-started/alias-require-and-import.html#use) macro which desugar into [gen_statem](https://andrealeopardi.com/posts/connection-managers-with-gen_statem/) 💪
- [ ] Flutter via [`builder_factories`](https://github.com/flutter/flutter/wiki/Code-generation-in-Flutter) (waiting for the [FFI](https://github.com/dart-lang/sdk/issues/34452) to be stable)
- Code generation (all of them can be non-embedded and it will be the priority) 🤔
- [ ] Julia via [`@generated`](https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions-1) implemented as [parametric](https://docs.julialang.org/en/v1/manual/methods/#Parametric-Methods-1) [multiple-dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch#Julia) [functors](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects-1) [non-embedded until there is a project like PyO3 but for Julia]
- [ ] Rust via [`#[proc_macro_attribute]`](https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros) implemented as [typestate programming](https://rust-embedded.github.io/book/static-guarantees/typestate-programming.html)? (Need to figure out how to support async, non-async, and no-std in single abstraction) [embedded]
- [ ] Elixir via [`use`](https://elixir-lang.org/getting-started/alias-require-and-import.html#use) macro and [rustler](https://github.com/rusterlium/rustler) which desugar into [gen_statem](https://andrealeopardi.com/posts/connection-managers-with-gen_statem/) [embedded]
- [ ] Flutter via [`builder_factories`](https://github.com/flutter/flutter/wiki/Code-generation-in-Flutter) (waiting for the [FFI](https://github.com/dart-lang/sdk/issues/34452) to be stable) [embedded]
- [ ] Typescript or **AssemblyScript** implemented as [typestate interface or abstract-class](https://spectrum.chat/statecharts/general/typestate-guard~d1ec4eb1-6db7-45bb-8b79-836c9a22cd5d) (usefull for building smart contract) [non-embedded]

> For more info, see the changelog in the [release page][]

Expand Down
Loading