-
Notifications
You must be signed in to change notification settings - Fork 8
CHIML
goFrendiAsgard edited this page May 23, 2018
·
15 revisions
CHIML
is a superset of YAML. So, any valid YAML
is also a valid CHIML
. And as YAML
itself is a superset of JSON, any valid JSON
is also a valid CHIML
The only thing that make CHIML
diferent from YAML
is you are allowed to write any string after block delimiter (|
and >
). Under the hood, this |someString
will be translated into "someString"
. If the string contains "
, it is going to be automatically escaped, so you don't need to worry about it.
The CHIML-script
should contain a single <program>
.
<program> ::= <completeVars>
<completeVerbose>
<command>
<completeCatch>
<completeThrow>
<command> ::= <completeCommand>
| <shortCommand>
<completeCommand> ::= <completeIns>
<completeOut>
<completeIf>
"do: "<singleCommand><newLine>
<completeWhile>
| <completeIns>
<completeOut>
<completeIf>
"parallel: "<singleCommand><newLine>
<completeWhile>
| <completeIns>
<completeOut>
<completeIf>
"do: "<commandList>
<completeWhile>
| <completeIns>
<completeOut>
<completeIf>
"parallel: "<commandList>
<completeWhile>
| "map: "<variableName>
"into: "<variableName>
<completeCommand>
| "filter: "<variableName>
"into: "<variableName>
<completeCommand>
<shortCommand> ::= "|("<ins>") -> " <singleCommand> " -> " <out><newLine>
| "|("<ins>") -> " <singleCommand> "<newLine>
| "|"<singleCommand> " -> " <out><newLine>
| "|("<ins>") --> " <out><newLine>
| "|"<out> " <-- ("<ins>")"<newLine>
<commandList> ::= "- "<command>
| <commandList><commandList>
<completeCatch> ::= ""
| "catch: "<condition><newLine>
<completeThrow> ::= ""
| "throw: "<string><newLine>
<completeVars> ::= ""
| "vars: "<variableList><newLine>
<completeVerbose> ::= ""
| "verbose: "<verbosity><newLine>
<completeIns> ::= ""
| "ins: "<ins><newLine>
<completeOut> ::= ""
| "out: "<out><newLine>
<completeIf> ::= ""
| "if: "<condition><newLine>
<completeWhile> ::= ""
| "While: "<condition><newLine>
<ins> ::= <variableList>
<out> ::= <variableName>
<singleCommand> ::= <cliCommand>
| <jsArrowFunction>
| "{"<jsNormalFunction>"}"
| "["<jsFunctionWithCallback>"]"
| "<"<jsPromise>">"
<variableName> ::= <alpha>
| <alpha><alphaNumeric>
<variableList> ::= <variableName>
| <variableName>","<variableList>
<float> ::= <integer>
| <integer>"."<integer>
<verbosity> ::= "1"
| "2"
| "3"
| "4"
<condition> ::= "true"
| "false"
| Any JavaScript statement evaluated to either "true" or "false"
<string> ::= <string><string>
| <alphanumeric>
| <space>
| <symbol>
<alphanumeric> ::= <alphanumeric><alphanumeric>
| <alpha>
| <integer>
<alpha> ::= <letter><alpha>
<letter> ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
| "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
| "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
<space> ::= " "
<newLine> ::= "\n"
<symbol> ::= "|" | " " | "!" | "#" | "$" | "%" | "&" | "(" | ")" | "*" | "+" | "," | "-"
| "." | "/" | ":" | ";" | ">" | "=" | "<" | "?" | "@" | "[" | "\" | "]" | "^"
| "_" | "`" | "{" | "}" | "~"
<integer> ::= <digit>
| <digit><integer>
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<cliCommand> ::= Any valid CLI command (e.g: ls, python, java, javac, node)
<jsArrowFunction> ::= Javascript arrow function (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
<jsNormalFunction> ::= Javascript function returning a value (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions)
<jsFunctionWithCallback> ::= Javascript function that has "error-first-callback" (i.e: "function (error, value) {/*...*/}") as it's last parameter.
<jsPromise> ::= Javascript promise
There are some default variables in every CHIML script:
-
_chain_cwd
: String, current working directory of CHIML script. -
_process_cwd
: String, current working directory of program that invoike CHIML script. -
_error
: Boolean, error status. -
_error_message
: String, error message. -
_verbose
: Integer, verbosity level, default to0
. -
_ans
: Default output variable. -
_runChain (chain, ...ins, callback)
: function to run other chain. -
_maps (list, chain, callback)
: function to map an array into a new array. Under the hood, this will process each element in parallel. -
_filter (list, chain, callback)
: function to filter an array into a new array. Under the hood, this will process each element in parallel.
Every <command>
has some keys including ins
, out
, if
, do
, and while
. The control flow of a chain
is as follow:
# filename: cal.chiml
# execute: chimera cal.chiml
# expected output: calendar of current year
cal
# filename: cal.chiml
# execute: chimera cal.chiml 3 2018
# expected output: calendar of March, 2018
ins: month, year
do: cal
or
# filename: cal.chiml
# execute: chimera cal.chiml 3 2018
# expected output: calendar of March, 2018
do: |(month, year) -> cal
or
# filename: cal.chiml
# execute: chimera cal.chiml 3 2018
# expected output: calendar of March, 2018
|(month, year) -> cal
or
# filename: cal.chiml
# execute: chimera cal.chiml 3 2018
# expected output: calendar of March, 2018
|(month, year) -> cal -> output
# filename: cowsay-cal.chiml
# execute: chimera cowsay-cal.chiml 3 2018
# expected output: calendar of March, 2018 inside cowsay
ins: month, year
out: output
do:
- |(month, year) -> cal -> calendar
- |(calendar) -> cowsay -> output
# filename: cal2.chiml
# execute: chimera cal2.chiml 3 4 2018
# expected output: calendar of March, 2018 and April, 2018
ins: month1, month2, year
out: output
do:
- parallel:
- |(month1, year) -> cal -> calendar1
- |(month2, year) -> cal -> calendar2
- |(calendar1, calendar2) -> {$.concat} -> output
# filename: add.chiml
# execute: chimera add.chiml 4 5
# expected output: 9
|(num1, num2) -> {(a, b) => {return a+b}}
# filename: add.chiml
# execute: chimera add.chiml 4 5
# expected output: 9
|(num1, num2) -> [(a, b, callback) => {callback(null, a + b)}]
# filename: add.chiml
# execute: chimera add.chiml 4 5
# expected output: 9
ins: num1, num2
do: |<new Promise((resolve, reject) => {resolve(num1 + num2)})>
# filename: functional.chiml
# execute: chimera functional.chiml
# expected output: {"map":[2,3,4,5,6,7,8,9,10,11],"filter":[2,4,6,8,10]}
vars:
numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plus: 1
divide: 2
out: result
parallel:
- map: numbers
into: result.map
do: |(n) -> (x) => {return x+plus} -> y
- filter: numbers
into: result.filter
ins: x
out: y
do:
- if: x % divide === 0
do: y <-- true
else: y <-- false