Skip to content

Commit

Permalink
tests passing again
Browse files Browse the repository at this point in the history
  • Loading branch information
StoneCypher committed Oct 29, 2017
1 parent 1adc251 commit 0f4e652
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,3 +1,4 @@
* [[`1adc251876`](https://github.com/StoneCypher/jssm/commit/1adc251876)] - More towards cycles. Also started on mixed-unicode arrows (John Haugeland)
* [[`04c514f1d1`](https://github.com/StoneCypher/jssm/commit/04c514f1d1)] - Post-merge and mostly done (John Haugeland)
* [[`80416ccdd5`](https://github.com/StoneCypher/jssm/commit/80416ccdd5)] - Merge branch 'master' of github.com:StoneCypher/jssm (John Haugeland)
* [[`8ac6b35409`](https://github.com/StoneCypher/jssm/commit/8ac6b35409)] - State declarations (John Haugeland)
Expand Down
104 changes: 88 additions & 16 deletions README.md
Expand Up @@ -29,14 +29,16 @@ Language test cases for Belorussian, English, German, Hebrew, Italian, Russian,

</div>



<br/><br/>

## TL;DR
Specify finite state machines with a brief syntax. Run them; they're fast. Derive charts. Save and load states, and
histories. Make machine factories to churn out dozens or thousands of instances. Impress friends and loved ones. Cure corns and callouses.

```javascript
const traffic_light = sm`
Red 'Proceed' -> Green 'Proceed' -> Yellow 'Proceed' -> Red;
`;
```fsl
Red 'Proceed' -> Green 'Proceed' -> Yellow 'Proceed' -> Red;
```

This will produce the following FSM (graphed with [jssm-viz](https://github.com/StoneCypher/jssm-viz)):
Expand All @@ -55,6 +57,10 @@ You'll build an executable state machine.

As usual, a valid question.



<br/>

### Why state machines

State machines are a method of making your software better able to prevent illegal states. Similar to type systems, SQL
Expand All @@ -77,6 +83,10 @@ So, to look at the same traffic light as above, you'll notice some things.
Along with other common sense things, a good state machine implementation can help eliminate large classes of error in
software. State machines are often applied when the stakes on having things correct are high.



<br/>

### Why this implementation

Brevity.
Expand All @@ -91,13 +101,19 @@ to produce state machines in otherwise comparatively tiny and easily read code.



<br/><br/>

## Quick Start

> A state machine in `JSSM` is defined in one of two ways: through the DSL, or through a datastructure.
So yeah, let's start by getting some terminology out of the way, and then we can go right back to that impenetrable
sentence, so that it'll make sense.



<br/>

### Quick Terminology

Finite state machines have been around forever, are used by everyone, and are hugely important. As a result, the
Expand All @@ -118,6 +134,10 @@ For this quick overview, we'll define six basic concepts:

There's other stuff, of course, but these five are enough to wrap your head around `finite state machine`s.



<br/>

#### Basic concepts

This is a trivial traffic light `FSM`, with three states, three transitions, and one action:
Expand Down Expand Up @@ -196,6 +216,10 @@ visualizations in [jssm-viz](https://github.com/StoneCypher/jssm-viz) by way of

Enough history lesson. On with the tooling.



<br/>

### And now, that Quick Start we were talking about

So let's put together a trivial four-state traffic light: the three colors, plus **Off**. This will give us an
Expand All @@ -205,6 +229,10 @@ At any time, you can take the code and put it into the
[graph explorer](https://stonecypher.github.io/jssm-viz-demo/graph_explorer.html) for an opportunity to mess with the
code as you see fit.



<br/>

#### 0: Lights always have an off state

Our light will start in the **Off** `state`, with the ability to switch to the **Red** `state`.
Expand All @@ -227,7 +255,7 @@ So far, our machine is simple:



<br/><br/>
<br/>

#### 1: Traffic lights have a three-color cycle

Expand All @@ -251,7 +279,7 @@ Machine's still pretty simple:



<br/><br/>
<br/>

#### 2: Traffic lights can be shut down

Expand Down Expand Up @@ -285,6 +313,10 @@ Machine's still not too bad:

![](https://raw.githubusercontent.com/StoneCypher/jssm/master/src/assets/traffic%20light%20quick%20start%20tutorial/Off%20To%20From%20RGY.png)



<br/>

### Let's actually use the traffic light

That's actually the bulk of the language. There are other little add-ons here and there, but, primarily you now know
Expand All @@ -299,7 +331,7 @@ Let's load it and use it! 😀



<br/><br/>
<br/>

### An introduction to machine design

Expand All @@ -316,7 +348,8 @@ Remember, at any time, you can take the code and put it into the
code as you see fit.


<br/><br/>

<br/>

#### 0: Empty machine

Expand All @@ -330,7 +363,7 @@ EmptyWaiting 'Wait' -> EmptyWaiting;



<br/><br/>
<br/>

#### 1: Should be able to eject cards

Expand All @@ -348,7 +381,7 @@ EjectCardAndReset -> EmptyWaiting;



<br/><br/>
<br/>

#### 2: Should be able to insert cards

Expand All @@ -370,7 +403,7 @@ That will change as we go back to adding more nodes. `terminal node`s are usual



<br/><br/>
<br/>

#### 3: Should be able to cancel and recover the card

Expand All @@ -391,7 +424,7 @@ EjectCardAndReset -> EmptyWaiting;



<br/><br/>
<br/>

#### 4: Can give the wrong PIN

Expand All @@ -417,7 +450,7 @@ EjectCardAndReset -> EmptyWaiting;



<br/><br/>
<br/>

#### 5: Can give the correct PIN

Expand All @@ -444,7 +477,7 @@ EjectCardAndReset -> EmptyWaiting;



<br/><br/>
<br/>

#### 6: Can check balance from main menu

Expand Down Expand Up @@ -472,7 +505,7 @@ EjectCardAndReset -> EmptyWaiting;



<br/><br/>
<br/>

#### 7: Can deposit money from main menu

Expand Down Expand Up @@ -548,7 +581,7 @@ EjectCardAndReset -> EmptyWaiting;



<br/><br/>
<br/>

#### 8: Can withdraw money from main menu

Expand Down Expand Up @@ -629,6 +662,9 @@ As you can see, building up even very complex state machines is actually relativ
amount of time.



<br/><br/>

## Features
### DSL
### States
Expand All @@ -651,8 +687,16 @@ amount of time.
### State history
### Automatic visualization



<br/><br/>

## How to think in state machines



<br/><br/>

## Example Machines
### Door lock
### Traffic lights
Expand All @@ -675,14 +719,30 @@ amount of time.
### [BGP](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/BGP_FSM.svg/549px-BGP_FSM.svg.png)
### [LibGCrypt FIPS mode FSM](https://www.gnupg.org/documentation/manuals/gcrypt/fips-fsm.png)



<br/><br/>

## How to debug



<br/><br/>

## How to publish



<br/><br/>

## Notation Comparison
### Their notations, one by one
### Apples to Apples - Traffic Light



<br/><br/>

## Other state machines
There are a lot of state machine impls for JS, many quite a bit more mature than this one. Here are some options:

Expand Down Expand Up @@ -717,10 +777,18 @@ And some similar stuff:
1. [GraphViz](http://www.graphviz.org/)
1. [Viz.js](https://github.com/mdaines/viz.js/), which we use



<br/><br/><br/>

# Thanks

JSSM and FSL have had a lot of help.



<br/><br/>

## Internationalization

* [Mykhaylo Les](https://github.com/miles91) provided three translation test cases ([Ukrainian](https://github.com/StoneCypher/jssm/blob/master/src/js/tests/language_data/ukrainian.json), [Belarussian](https://github.com/StoneCypher/jssm/blob/master/src/js/tests/language_data/belarussian.json), and [Russian](https://github.com/StoneCypher/jssm/blob/master/src/js/tests/language_data/russian.json),) and the corresponding Traffic Light translations (also [Ukrainian](https://github.com/StoneCypher/fsl_traffic_light_ukrainian/blob/master/traffic%20light.fsl), [Belarussian](https://github.com/StoneCypher/fsl_traffic_light_belarussian/blob/master/traffic_light.fsl), and [Russian](https://github.com/StoneCypher/fsl_traffic_light_russian/blob/master/traffic%20light.fsl).)
Expand All @@ -738,6 +806,10 @@ If you'd like to help, it's straightforward.
1. Easy mode: open a PR with [this file](https://github.com/StoneCypher/jssm/blob/master/src/js/tests/language_data/english.json) translated into your language
1. Extra mile: create a new repo containing [this file](https://github.com/StoneCypher/fsl_traffic_light/blob/master/traffic_light.fsl) translated



<br/><br/>

## Code and Language

[Forest Belton](https://github.com/forestbelton) has provided guidance, bugfixes, parser and language commentary.
Expand Down
2 changes: 1 addition & 1 deletion build/jssm.es5.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/js/jssm.js
Expand Up @@ -180,8 +180,8 @@ function makeTransition<mNT, mDT>(
main_path : kind === 'main'
};

if ((wasList !== undefined) && (wasIndex === undefined)) { throw "Must have an index if transition was in a list"; }
if ((wasIndex !== undefined) && (wasList === undefined)) { throw "Must be in a list if transition has an index"; }
if ((wasList !== undefined) && (wasIndex === undefined)) { throw "Must have an index if transition was in a list"; }
if ((wasIndex !== undefined) && (wasList === undefined)) { throw "Must be in a list if transition has an index"; }
/*
if (typeof edge.to === 'object') {
Expand Down
12 changes: 8 additions & 4 deletions src/js/tests/cycles.js
Expand Up @@ -49,19 +49,23 @@ describe('cycle strategies', async _it => {


describe('bidi basic cycle', async it => {
is_v('+1 <- [a b c] -> +1;', [{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'cycle', value: 1}}}], it);
is_v('+1 <- [a b c] -> +1;', [{from: {key: 'cycle', value: 1}, key: 'transition', se: {kind: '<-', se: {kind: '->', to: {key: 'cycle', value: 1}}, to: ['a','b','c']}}], it);
});

describe('bidi negative cycle', async it => {
is_v('-1 <- [a b c] -> -1;', [{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'cycle', value: -1}}}], it);
is_v('-1 <- [a b c] -> -1;', [{from: {key: 'cycle', value: -1}, key: 'transition', se: {kind: '<-', se: {kind: '->', to: {key: 'cycle', value: -1}}, to: ['a','b','c']}}], it);
});

describe('bidi basic/negative cycle', async it => {
is_v('+1 <- [a b c] -> -1;', [{from: {key: 'cycle', value: 1}, key: 'transition', se: {kind: '<-', se: {kind: '->', to: {key: 'cycle', value: -1}}, to: ['a','b','c']}}], it);
});

describe('bidi nullary cycle', async it => {
is_v('+0 <- [a b c] -> +0;', [{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'cycle', value: 0}}}], it);
is_v('+0 <- [a b c] -> +0;', [{from: {key: 'cycle', value: 0}, key: 'transition', se: {kind: '<-', se: {kind: '->', to: {key: 'cycle', value: 0}}, to: ['a','b','c']}}], it);
});

describe('bidi wide cycle', async it => {
is_v('+2 <- [a b c] -> +2;', [{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'cycle', value: 2}}}], it);
is_v('+2 <- [a b c] -> -2;', [{from: {key: 'cycle', value: 2}, key: 'transition', se: {kind: '<-', se: {kind: '->', to: {key: 'cycle', value: -2}}, to: ['a','b','c']}}], it);
});

/*
Expand Down

0 comments on commit 0f4e652

Please sign in to comment.