Skip to content

JunNishimura/JSOP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JSOP

write program in JSON

GitHub release (latest by date) GitHub Go Report Card

{
    "command": {
      "symbol": "print",
      "args": "Hello, World!"
    }
}

💾 Installation

Homebrew Tap

brew install JunNishimura/tap/JSOP

go intall

go install github.com/JunNishimura/jsop@latest

GitHub Releases

Download exec files from GitHub Releases.

💾 How to use

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

📖 Language Specification

  1. Everything is an expression.
  2. Only .jsop and .jsop.json are accepted as file extensions.

Integer

Integer value is a sequence of numbers.

Example
123

String

String value is a sequence of letters, symbols, and spaces enclosed in double quotation marks.

Example
"this is a string"

Boolean

Boolean value is either true or false.

Example
true

Array

Arrays are composed of expressions.

Example
[1, "string", true]

Identifiers

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!"

Assignment

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"
]

Function

Function Definition

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"]
                    }
                }
            }
        }
    }
}

Function Call

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

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 print to standard output
len length of array
at access to the element of array

If

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]
            }
        }
    }
}

Loop

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"
]

Retrun

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

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]
        }
    }
]

Comment

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"]
                    }
                }
            }
        }
    }
}

🤔 FizzBuzz Problem

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"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
]

🪧 License

JSOP is released under MIT License. See MIT