{
"command": {
"symbol": "print",
"args": "Hello, World!"
}
}brew install JunNishimura/tap/JSOP
go install github.com/JunNishimura/jsop@latest
Download exec files from GitHub Releases.
Since REPL is not provided, you can write your program in any file and pass the file path as a command line argument to execute the program.
jsop ./path/to/file.jsop.json- Everything is an expression.
- Only
.jsopand.jsop.jsonare accepted as file extensions.
Integer value is a sequence of numbers.
Example
123String value is a sequence of letters, symbols, and spaces enclosed in double quotation marks.
Example
"this is a string"Boolean value is either true or false.
Example
trueArrays are composed of expressions.
Example
[1, "string", true]Strings beginning with the $ symbol are considered as identifiers.
Example
"$x"Embedding the Identifier in a string is accomplished by using curly brackets.
Example
"{$hello}, world!"To assign a value or function to an identifier, use the set key.
| parent key | children key | explanation |
|---|---|---|
| set | declaration of assignment | |
| var | identifier name | |
| val | value to assign |
Example
[
{
"set": {
"var": "$x",
"val": 10
}
},
"$x"
]Functions can be defined by using set key and lambda expression`.
| parent key | children key | explanation |
|---|---|---|
| lambda | declaration | |
| params | parameters(optional) | |
| body | body of function |
Example
{
"set": {
"var": "$add",
"val": {
"lambda": {
"params": ["$x", "$y"],
"body": {
"command": {
"symbol": "+",
"args": ["$x", "$y"]
}
}
}
}
}
}Functions can be called by using command key.
| parent key | children key | explanation |
|---|---|---|
| command | declaration of function calling | |
| symbol | function to call | |
| args | arguments(optional) |
Example
{
"command": {
"symbol": "+",
"args": [1, 2]
}
}Builtin functions are as follows,
| 関数 | explanation |
|---|---|
| + | addition |
| - | subtraction |
| * | multiplication |
| / | division |
| % | modulo |
| ! | negation |
| && | and operation |
| || | or operation |
| == | equation |
| != | non equation |
| > | greater than |
| >= | greater than equal |
| < | smaller than |
| >= | smaller than equal |
| print to standard output | |
| len | length of array |
| at | access to the element of array |
Conditional branches can be implemented by using the if key.
| parent key | children key | explanation |
|---|---|---|
| if | declaratoin of if | |
| cond | condition | |
| conseq | consequence(the program to execute when cond is true) | |
| alt | alternative(the program to execute when cond is false) |
Example
{
"if": {
"cond": {
"command": {
"symbol": "==",
"args": [1, 2]
}
},
"conseq": {
"command": {
"symbol": "+",
"args": [3, 4]
}
},
"alt": {
"command": {
"symbol": "*",
"args": [5, 6]
}
}
}
}Iterations are handled by using the loop key.
| parent key | children key | explanation |
|---|---|---|
| loop | declaration of loop | |
| for | the identifier for loop counter | |
| from | the initial value of loop counter | |
| until | loop termination condition (break when loop counter equals this value) | |
| do | Iterative processing body |
Example
{
"loop": {
"for": "$i",
"from": 0,
"until": 10,
"do": {
"command": {
"symbol": "print",
"args": "$i"
}
}
}
}You can also perform a loop operation on the elements of an Array. Unlike the example above, the in key specifies an Array.
Example
[
{
"set": {
"var": "$arr",
"val": [10, 20, 30]
}
},
{
"loop": {
"for": "$element",
"in": "$arr",
"do": {
"command": {
"symbol": "print",
"args": "$element"
}
}
}
}
]Also, insert break and continue as keys as follows.
[
{
"set": {
"var": "$sum",
"val": 0
}
},
{
"loop": {
"for": "$i",
"from": 1,
"until": 15,
"do": {
"if": {
"cond": {
"command": {
"symbol": ">",
"args": ["$i", 10]
}
},
"conseq": {
"break": {}
},
"alt": {
"if": {
"cond": {
"command": {
"symbol": "==",
"args": [
{
"command": {
"symbol": "%",
"args": ["$i", 2]
}
},
0
]
}
},
"conseq": {
"set": {
"var": "$sum",
"val": {
"command": {
"symbol": "+",
"args": ["$sum", "$i"]
}
}
}
},
"alt": {
"continue": {}
}
}
}
}
}
}
},
"$sum"
]Use return key when you exit the program with return.
[
{
"set": {
"var": "$f",
"val": {
"lambda": {
"body": [
{
"set": {
"var": "$sum",
"val": 0
}
},
{
"loop": {
"for": "$i",
"from": 1,
"until": 11,
"do": {
"if": {
"cond": {
"command": {
"symbol": ">",
"args": ["$i", 5]
}
},
"conseq": {
"return": "$sum"
},
"alt": {
"set": {
"var": "$sum",
"val": {
"command": {
"symbol": "+",
"args": ["$sum", "$i"]
}
}
}
}
}
}
}
}
]
}
}
}
},
{
"command": {
"symbol": "$f"
}
}
]Macro can be defined by using defmacro key.
| parent key | children key | explanation |
|---|---|---|
| defmacro | declaration of macro definition | |
| name | name of macro | |
| keys | keys | |
| body | the body of macro |
You can also call the quote symbol for quoting, and unquote by adding backquotes to the beginning of the string.
Example
{
"defmacro": {
"name": "unless",
"keys": ["cond", "conseq", "alt"],
"body": {
"command": {
"symbol": "quote",
"args": {
"if": {
"cond": {
"command": {
"symbol": "!",
"args": ",cond"
}
},
"conseq": ",conseq",
"alt": ",alt"
}
}
}
}
}
}Defining function can be much simpler if you use Macro.
Example
[
{
"defmacro": {
"name": "defun",
"keys": ["name", "params", "body"],
"body": {
"command": {
"symbol": "quote",
"args": {
"set": {
"var": ",name",
"val": {
"lambda": {
"params": ",params",
"body": ",body"
}
}
}
}
}
}
}
},
{
"defun": {
"name": "$add",
"params": ["$x", "$y"],
"body": {
"command": {
"symbol": "+",
"args": ["$x", "$y"]
}
}
}
},
{
"command": {
"symbol": "$add",
"args": [1, 2]
}
}
]Comments can be inesrted by using // key.
Example
{
"//": "this is a function to add two values",
"set": {
"var": "$add",
"val": {
"lambda": {
"params": ["$x", "$y"],
"body": {
"command": {
"symbol": "+",
"args": ["$x", "$y"]
}
}
}
}
}
}Finally, I have included an example of solving a FizzBuzz problem in JSOP.
Example
[
{
"set": {
"var": "$num",
"val": 31
}
},
{
"loop": {
"for": "$i",
"from": 1,
"until": "$num",
"do": {
"if": {
"cond": {
"command": {
"symbol": "&&",
"args": [
{
"command": {
"symbol": "==",
"args": [
{
"command": {
"symbol": "%",
"args": ["$i", 3]
}
},
0
]
}
},
{
"command": {
"symbol": "==",
"args": [
{
"command": {
"symbol": "%",
"args": ["$i", 5]
}
},
0
]
}
}
]
}
},
"conseq": {
"command": {
"symbol": "print",
"args": "{$i}: FizzBuzz"
}
},
"alt": {
"if": {
"cond": {
"command": {
"symbol": "==",
"args": [
{
"command": {
"symbol": "%",
"args": ["$i", 3]
}
},
0
]
}
},
"conseq": {
"command": {
"symbol": "print",
"args": "{$i}: Fizz"
}
},
"alt": {
"if": {
"cond": {
"command": {
"symbol": "==",
"args": [
{
"command": {
"symbol": "%",
"args": ["$i", 5]
}
},
0
]
}
},
"conseq": {
"command": {
"symbol": "print",
"args": "{$i}: Buzz"
}
},
"alt": {
"command": {
"symbol": "print",
"args": "$i"
}
}
}
}
}
}
}
}
}
}
]JSOP is released under MIT License. See MIT