Scdlang v0.2 update overview
Repository
https://github.com/drsensor/scdlang
New Features
One challenge when initiating a project is how to maintain the complexity. To make refactoring easy in the near futures, starting from this version, my strategy for each update is to introduce:
- new syntax
- new transpiler/code-generator/compiler target
- others
However, as it have more features, update in minor version (major.minor.patch) might only have one new syntax which implemented across several transpiler/code-generator/compiler.
Shortcut Syntax (core parser)
In this update, I'm going to introduce new syntax symbols which desugar into several expressions. This concept was inspired from basic concept of multiplication. For example given this expressions:
2 ✕ 3
will desugar into:
3 + 3
3 + 3
Notice that by introducing only new symbol ✕
, it can expand into multiple expressions. If we apply this concept into Scdlang then this is what we get:
A {SHORTCUT_SYMBOL} B @ C
will desugar into:
A {SYMBOL} B {@ C}?
A {SYMBOL} B {@ C}?
@ C
can exists in one or both of the expressions. Some new shortcut syntax that introduced in this update are:
Toggle Transition
A <-> B @ Toggle
👆 will desugar into 👇
A -> B @ Toggle
A <- B @ Toggle
if we visualize that
Toggle
┌───────────────┐
▼ │
┌───┐ Toggle ┌───┐
│ A │ ────────▶ │ B │
└───┘ └───┘
Loop Transition
A ->> B @ Loop
// or
B <<- A @ Loop
👆 will desugar into 👇
A -> B @ Loop
B -> B @ Loop
if we visualize that
Loop
┌──────┐
▼ │
┌───┐ Loop ┌──────────┐
│ A │ ──────▶ │ B │
└───┘ └──────────┘
Transient Loop Transition
A >-> B @ Loop
// or
B <-< A @ Loop
👆 will desugar into 👇
A -> B
B -> B @ Loop
if we visualize that
Loop
┌──────┐
▼ │
┌───┐ ┌──────────┐
│ A │ ──▶ │ B │
└───┘ └──────────┘
Self Transition
Not exactly desugar into multiple expressions but this new syntax can give a clear distinction between normal transition and self transition.
->> B @ Loop
👆 is same as 👇
B -> B @ Loop
// or
B <- B @ Loop
if we visualize that
Loop
┌──────┐
▼ │
┌──────────┐
│ B │
└──────────┘
State Machine Cat transpiler 🐈
State Machine Cat is a drawing language specialize for visualize statecharts. For me it's more like Graphviz but without hasle (decide tail/head of the edge, etc). It also has a CLI (smcat) and AST representation in JSON. Thankfully, it got the JSON schema of the AST which I can generate the Rust serde representation using quicktype then tweak it a bit. In this update, I only implement scdlang to smcat ast-json transpiler instead of the language itself because the CLI also accept JSON. I even create a PR because I find some bugs when piping JSON representation from stdin to the CLI.
Ah yes, it can visualize the error too 🙂
CLI (scrap)
Now you can install Scdlang CLI via Cargo:
cargo install s-crap
$ scrap code --help
Generate from scdlang file declaration to another format
USAGE:
scrap code [FLAGS] [OPTIONS] <FILE> --format <target>
FLAGS:
-h, --help Prints help information
--stream Parse the file line by line
OPTIONS:
-o, --output <DIST> Output the result to this directory / file
--as <format> Select parser output [possible values: json, svg, dot, smcat, html, scxml, xmi, ascii, boxart, txt, bmp, gif, jpg, pdf, png, ps, ps2, tif, eps, fig, gd, gd2, jpeg, jpe,
json0, dot_json, xdot_json, pic, plain, plain-ext, svgz, tiff, tk, vml, vmlz, vrml, wbmp]
-f, --format <target> Select output format [possible values: xstate, smcat, graph]
ARGS:
<FILE> File to print / concatenate
$ scrap repl --help
Evaluate scdlang expression in interactive manner
USAGE:
scrap eval [FLAGS] [OPTIONS] --format <target>
FLAGS:
-h, --help
Prints help information
-i, --interactive
Prints result on each expression
--strict
Exit immediately if an error occurred
OPTIONS:
-o, --output <DIST>
The output depend if it's directory or file:
If directory => It will output a numbered file in sequence everytime the REPL produce output.
Useful if the input is from stdin.
If file => It will be overwriten everytime the REPL produce output, especially if `--interactive` is set.
Useful if combined with live preview
--as <format>
Select parser output [possible values: json, svg, dot, smcat, html, scxml, xmi, ascii, boxart, txt, bmp, gif, jpg, pdf, png, ps, ps2, tif, eps, fig, gd, gd2, jpeg, jpe, json0, dot_json,
xdot_json, pic, plain, plain-ext, svgz, tiff, tk, vml, vmlz, vrml, wbmp]
-f, --format <target>
Select output format [possible values: xstate, smcat, graph]
For more info, see scrap usage
Breaking changes
- In subcommand
code
, positional argument[DIST]
changes to-o, --output
(cause by a bug in clap, probably 🤔) - In subcommand
code
andrepl
, flag--format <target>
must be specified (to avoid favoritism)
Invoke CLI safely
This features will prevent you to use invalid arguments which thanks to the awesome and flexible API that clap has! (it deserve a claps 👏, pun intended)
--output <DIST>
will give an error messages that it must be specified if outputting--as <format>
binary file (e.g--as jpg
)--as <format>
will give an error messages if paired with wrong--format <target>
(e.g--format smcat --as boxart
)- possible values in
--as <format>
will be hidden and disabled if certain others CLI not being installed
Hook to others CLI
In this update, scrap
able to support others formats only if this CLI has been installed.
- smcat
- dot
- graph-easy (as a fallback for some formats if dot not available)
This brings several ability if combined with certain tools, for example:
- Live preview the visual representation in terminal window
- Live preview the visual representation in the VSCode (output must be png, jpg, or similar)
- Live preview the visual representation as SVG format in the web browser
Others
- Add
print
command in non-interactive mode of REPL - Tweak error prompt color
- In subcommand
code
, use special error handle when positional argument<FILE>
is a directory - Semantic check depend on the output format
- Hide empty result when
repl -i
piped from stdin - Display
line-number: expression
when piped to stdout/stderr
Left: before, Right: after update
Changes in the CI release pipelines
- Ship
smcat
,graph-easy
, anddot
on each docker release 🐳 - Make
version.py
compatible withcargo publish
Seems like there is performance boost since Rust 1.36 was released. Probably the performance boost is caused by switching
HashMap<K, V>
implementation withhashbrown
🤔
Closing
Summary, in this update I feel satisfied because not only I can make State Machine of D Flip-flop in 2 lines, it also give me visualization both in terminal and as an image. Hope I can also visualize them as a transition table and timing diagram too. Now, next update will be generating typescript declaration for XState 😎.
Thank you for your contribution. The post is of very high quality and the contribution adds high value to the project. Everything is perfect about this post and contribution, kudos to you.
Since I did not know what is Scdlang, I have to go through your blog to find out more about it, it would be better if you add a link to the introduction.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @codingdefined! Keep up the good work!
Hi @drsensor!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @drsensor!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!