GithubHelp home page GithubHelp logo

drsensor / scdlang Goto Github PK

View Code? Open in Web Editor NEW
99.0 5.0 2.0 602 KB

Statechart Description Language (just an experiment, need to be rewritten)

License: Universal Permissive License v1.0

Rust 81.43% Dockerfile 3.28% Shell 5.98% Python 7.09% HCL 2.22%
statecharts statemachine description-language my-experiment

scdlang's Introduction

Scdlang

Statecharts Description Language

current version Docker image size License

🚧Status: 🗶perimental 4ever🤞

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.

quick_demo

Philosophy

  • Readable just like you read then visualize a state diagram
  • Writeable just like you write code which is concise, clear, and can be refactored
  • Transferable to any implementation (e.g platform, programming language, runtime, etc)

Features and Wishlist

For more info, see the changelog in the release page

Getting Started

Currently, this project only have the binary CLI for each OS. Please go to the release page to download then extract it. It also shipped with auto-completions script for your preffered shell.

Installing

Just download the binary in the release page or follow this instructions 👇

Linux🐧

TODO: (AUR, DEB, RPM) or via shellscript just like installing rustup

MacOS🍏

TODO: brew or via shellscript just like installing rustup

Windows🗔

TODO: chocolatey or via msi installer just like installing rustup

using Docker🐳

smcat, dot, and graph-easy are pre-installed in this docker image

docker pull scdlang/scrap

via Cargo📦

cargo install s-crap

Contributing

open "help wanted" issues open "good first issue" issues

Any contributions are welcome as long as it follow Code of Conduct.
If anyone have questions or something to discuss, feel free to DM or mention me in any platform that have my profile picture 👹.

License

This project is licensed under the Universal Permissive License 1.0 - see the LICENSE file for more detail.

Resources

scdlang's People

Contributors

drsensor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

silky bengartner

scdlang's Issues

Style preserving parser

Inspired from TOML Kit

  • Just as the name suggests, I wonder if serde can preserve the order of key-value pair 🤔. This will make the transpiler more consistent and can be used to alter source code.

  • Another use case is to generate Scdlang (#22) from interchangeable format like SCXML or CSV (#24).

Also, watch out if there is the performance penalty!

Generate scdlang from other formats

[Scope] only support formats that (pick one):

  • not being used to describe a state machine or configuration
    • and not literally statecharts or it's derivative
  • or standardized interchangeable formats
    • and generated from another system
Possible formats:
API (prone to changes)
let parser = Scdlang::new();

parser.transform().expressions
    .nth(0).current_state("B")?
    .next_state("A")?.event("C")?;

assert_eq!("A -> B", &parser.to_string());

Possibly, it will use the caches to build the syntax string

Resources

Composability and copy/paste safety

Just lost a long message I was just writing to you so I guess I should make this shorter.

I am the creator and maintainer of Kingly, a state machine library catering mostly to user interfaces, so I am pretty interested in the subject. Follows my feedback.

First of all, wow. You integrated miscellaneous technologies and tools into what seems to be a cohesive tool so congratulations for the end result, it looks good.

On visualization: I like to use yed as a visual graph editor for its nice user interface and impressive array of quality automated visualization algorithms. Now I do have some frustrations with the tool, but I found that better than the PlantUml editor, [state-machine-cat]9https://github.com/sverweij/state-machine-cat) and Cytoscape on real-world graphs. Automatically achieveing an insightful visualization of a graph is a difficult problem and I found that most of the aforementioned tools had troubles with self-loops and backloops to compound states. For small simple graphs though they are great. Cytoscape is open-source and probably the most advanced tool, specially in conjunction with an Elk layout.

References:

On textual languages vs. visual languages: there is a case for textual languages for sure. A great advantage of textual languages is the ease of copy/paste and replacing functionality, not mentioning navigating/search (and tooling) abilities. However I would believe the advantage is a bit dampened when it comes to state machines, as the latter does not compose so nicely. You can't copy a portion of the graph and paste it elsewhere and be done. There is a range of pitfalls there. The great thing is that you seem to check semantic contracts, which would effectively support copy/pasting as long as the contracts guarantee against the pitfalls. But still, a state links computations to given context. If you copy/paste the state, you are not copy/pasting the context -- which might be exactly what you want, or might be the next bug in your design. Contract checking I think would probably only cover against bad syntax and obvious coherency rules, leaving some room for other mistakes.

References:

I recommend you test the language on actual examples. You will find some in Kingly tutorials and examples.

Here for instance are machines for a two-player chessgame, evolving from:

basic chess game

to:

chess game with undo and timer

It would be great to see how a textual format supports more easily the modification of a design with a view to remove, modify and add features.

I have other examples that are not public yet. If you are interested in that I can send them to you out-of-band.

Generate state transition table

Generate two-dimensional transition table as:

  • ./packages/transpiler/table
    • markdown
    • csv

and render it using

How it looks like 👇

Current State Event1 Event2 [guard] Event2
initial State1 / entry, activity
State1 / activity, exit State2 / entry, action, activity State1 / entry, activity finish
State2 / activity finish / action

The table above is called Two-dimensional state tables with some modification to suits Statecharts format.

Resources

Generate timing diagram

How it looks like? (maybe)

entry |> State1 |> exit

state State2 {
  State21 >< activity

  initial -> State21
  State21 -> State22 @ Event
}

initial -> State1
State1 -> State2 @ Event[guard] |> action
State2 -> State1 @ Reset |> action

From 👆 to 👇
Screenshot_20190706_065814

{signal: [
  {name: 'execution', wave: '03524.02350', data: ['entry', 'exit', 'action', 'activity', 'action', 'entry', 'exit']},
  {name: 'trigger',   wave: '0..=0.==0..', data: ['Event [<i>guard</i>]', 'Event', 'Reset']},

  {name: 'State1',    wave: '01.x...1..0'},
  ['State2',
   {name: 'State21',  wave: '0x.1..x...0'},
   {name: 'State22',  wave: '0x....1x..0'},
  ],
],
  config: { hscale: 3 }
}

Paste 👆 to https://wavedrom.com/editor.html

I think I should move action, entry, and exit inside state timeline 🤔. Also separate activity to different lifeline, especially when in the compound state.

However, for easier implementation, it should lay flat. Imagine having an action that executed many times, how long the data will be 😅

Something needs to watch out!

  • waveform doesn't automatically fit the diagram with the texts
  • probably there will be a need for sorting (I hope not because I use wave: 0.x..0) if I want to support Arrows Splines
  • activity inside Compound State could be tricky to visualize. Maybe activity should be separated as a different lifeline
References
Related issues
Viewers
Other approachs
  • transpile into LLHD then visualize using gtkwave or alike
  • generate VCD file

Further plans?

I see this is experimental and not being worked on for a year, but the idea looks great :)
Diagramming is still a hassle, and we don't use the potential of technology to translate between diagrams and code (I did something the other way around, writing a script to get a package diagram from Haskell code).
So do you have any plans to pick this back up?

Error on Parser::parse when a file doesn't have expressions (max 3 lines)

Given this file then execute scrap code $file -f xstate:

3 lines empty.scl



will produce:

ERROR: can't parse
---
 --> examples/test.scl:3:1
  |
3 | 
  | ^---
  |
  = expected expression
---
3 lines with comment.scl
// A -> B @ Click
// A <-> B @ Toggle
// ->> B @ Click

will produce:

ERROR: can't parse
---
 --> examples/test.scl:3:17
  |
3 | // ->> B @ Click
  |                 ^---
  |
  = expected expression
---
end with with comment.scl
// A -> B @ Click

// ->> B @ Click

will produce:

ERROR: can't parse
---
 --> examples/test.scl:3:17
  |
3 | // ->> B @ Click
  |                 ^---
  |
  = expected expression
---
end with with empty line.scl
// A -> B @ Click
// ->> B @ Click

will produce:

ERROR: can't parse
---
 --> examples/test.scl:3:1
  |
3 | 
  | ^---
  |
  = expected expression
---

Support transpiling to CI/CD configuration file

This feature is just for experiments to test if it can support others than Harel's State Machine 🤔
(although the grammar specifically designed for statecharts).

  • transpile into bash script 😍
  • transpile into various Serverless States configuration (e.g Amazon States Language or Facebook StateService)
  • transpile into various CI config that have workflow (e.g azure-pipelines.yml, .circle/config.yml, .gitlab-ci.yml, .github/main.workflow, etc)

Separate grammar for query syntax

Rather than having a bunch of helper function like this:

/// Filter by the current state
fn filter_from(self, state: &str) -> Self::Iter;
/// Filter by the target/next state
fn filter_to(self, state: &str) -> Self::Iter;
/// Group by the current state
fn group_by_from(self, state: &str) -> Self::Map;
/// Group by the target/next state
fn group_by_to(self, state: &str) -> Self::Map;
/// Remove duplicated current state
fn dedupe_from(self, state: &str) -> Self::Iter;
/// Remove duplicated target/next state
fn dedupe_to(self, state: &str) -> Self::Iter;

I think it would be efficient to create separate grammar specialize for querying the state machine. This might be handy when the declaration can be visualized and you want to filter it out using the query syntax.

The query syntax probably will rely on the globbing pattern and boolean operation. For example:

(* -> *) | (A -> * @ Power*) & (* -> C @ *)

☝️ Read as: seach all transient transition or all transition from state A with event name prefixed with Power and all transtition to state C on all event (including empty-event/transiten-transition)

Generate typescript declaration for XState

json_typegen results
{
  "states": {
    "set": {
      "on": {
        "TOGGLE": "reset",
        "RESET": "reset",
        "OFF": "set"
      }
    },
    "reset": {
      "on": {
        "TOGGLE": "set",
        "SET": "set",
        "DATA": "set"
      }
    }
  }
}

json_typegen above.json -O typescript --name MachineConfig > below.ts

interface MachineConfig {
    states: States;
}
interface States {
    set: Set;
    reset: Reset;
}
interface Set {
    on: On;
}
interface On {
    TOGGLE: string;
    RESET: string;
    OFF: string;
}
interface Reset {
    on: On2;
}
interface On2 {
    TOGGLE: string;
    SET: string;
    DATA: string;
}

Things to keep track

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.