A reduced variant of my oboe[1] language inspired by, and with equivalent functionality to, picol[2].
Although overall size was not a determining factor, I budgeted, and achieved, 1000 lines or less. It could be made smaller, but I am happy with it as it is.
[1] https://github.com/stytri/oboe
[2] https://github.com/stytri/picol
https://en.wikipedia.org/wiki/Piccolo_oboe
All operators (including delimeters and brackets) are binary operators, parsing is left to right, use parenthesis to specify precedence.
From low to high:
- sequence (delimeted expressions)
- operation (binary operator expressions)
- binding (adjacent primarys invoke the
.operator, albeit at higher precedence) - primary (terminal-tokens and bracketed expressions)
'#' Comment to end of line
',' Primarily used to delimit function arguments.
';' Primarily used to delimit expression statements.
':' Primarily used to delimit
alternate consequents of conditional expressions.
'+' addition
'-' subtraction
'*' multiplication
'/' division
'==' equal
'!=' not equal
'<' less than
'<=' less than or equal
'>' greater than
'>=' greater than or equal
'?' if : left-hand-expression is the condition, right-hand-expression is the consequent(s). Automatically enters a new scope. A ; delimeter in the condition indicates that the left-hand-part is intializtion, and the right-hand-part is the evaluated condition.
'?*' while : left-hand-expression is the condition, right-hand-expression is the loo body. Automatically enters a new scope. A ; delimeter in the condition indicates that the left-hand-part is intializtion, and the right-hand-part is the evaluated condition.
'?/' break : left-hand-expression specifies a pre-condition, or _ if there is no condition; right-hand-expression is evaluated if the pre-condition is satisfied.
'?.' continue : left-hand-expression specifies a pre-condition, or _ if there is no condition; right-hand-expression is evaluated if the pre-condition is satisfied.
'=>' lambda : creates anonymous functions; left-hand-expression specifies a parameter list, right-hand-expression is the function body.
'.' apply : applies one expression to another. If the left-hand-expression is an identifier it specifies a named-dunction, and the right-hand-expression is a list of function arguments. Otherwise the left and right-hand-expressions are multiplied together.
'=' assign : creates a symbol named by the identifier in the left-hand-expression ans assigns it the value of the right-hand-expression. If the right-hand-expression is an anonymous-function then a named-function is created.
'<:' output : outputs the string representation of its arguments; output is automatically terminated with a new-line. Arguments are not delimeted; if an expression is given as an argument, it should be enclosed in either { }, or [ ] brackets.
':>' input : reads a line from stdin, and tokenizes it. Integer and string tokens only are acceptable; they are assigned in order to the identifiers given as arguments. As per output, arguments are separated by spaces.
'`'identifier'`' User defined named operator, where identifier is the name of a function that should take 2 aruments.
'(' ')' Primarily used to indicate a sub-expression; is not representated in the execution tree.
'[' ']' Primarily used to indicate a sub-expression; is represented in the execution tree.
'{' '}' Primarily used to indicate a sub-expression in a new scope; is represented in the execution tree.
integer decimal, binary(0b prefix), hexadecimal(0x prefix) and octal(0 prefix).
string Between 2 double-quote (") characters. Escape (and control) code representation included.
identifier C-style identifier rules apply.
bracketed-expression An expression, in brackets.
'VERSION' Gives the program's version number as an integer.
'_' Represents Zero Empty Null (ZEN), so that we do not use too many parenthesis - this is not lisp ;)