Note
Language maintanance has ended after
09/06/2022.thank you for using this language.
Sesan Interpreter offical repository.
It can be used directly as a Web Playground, and can be built according to the build instructions.
- Introduce
- Web Playground
- Interpreter
- Built-in functions
- Standard library
- Options
- Npm package
- Examples
- Documentation
Todo
git clone https://github.com/ky0422/sesan.git
cd sesan# Install dependencies
npm i
# REPL
npm run start:repl
# You can also from a file.
npm run start:repl [file]//command ...args
| Command | Description |
|---|---|
exit |
Exit the repl |
mode |
Change the mode (repl, lexer, parser, env) |
| Token | Identifier | Token | Identifier |
|---|---|---|---|
EOF |
EOF |
ILLEGAL |
ILLEGAL |
NUMBER |
NUMBER |
IDENT |
IDENT |
TRUE |
TRUE |
STRING |
STRING |
FUNCTION |
FUNCTION |
FALSE |
FALSE |
ASSIGN |
= |
COMMENT |
COMMENT |
MINUS |
- |
PLUS |
+ |
ASTERISK |
* |
BANG |
! |
PERCENT |
% |
SLASH |
/ |
GT |
> |
LT |
< |
NOT_EQUAL |
!= |
EQUAL |
== |
COLON |
: |
COMMA |
, |
LPAREN |
( |
SEMICOLON |
; |
LBRACE |
{ |
RPAREN |
) |
LBRACKET |
[ |
RBRACE |
} |
LET |
LET |
RBRACKET |
] |
ELSE |
ELSE |
IF |
IF |
WHILE |
WHILE |
RETURN |
RETURN |
QUOTE |
" |
SINGLE_QUOTE |
' |
Except for If, Function Expression, all expressions must be preceded by a semicolon (;);
| Expression | Syntax | Expression | Syntax |
|---|---|---|---|
Literal |
Block |
{ [expr] } |
|
If |
if (expr) [block] else [block]; |
Function |
func [name?](args) [block] |
Call |
ident(args) |
Ident |
|
Array |
[expr, expr, ...] |
Index |
ident[number] |
Object |
{ string: expr, ... } |
Assign |
[ident / index] = expr |
| Statement | Syntax | Statement | Syntax |
|---|---|---|---|
Let |
let ident = expr; |
While |
while (expr) [block]; |
Return |
return expr; |
Block |
{ statement } |
1 < ... < 10
| Priority Number | Operator |
|---|---|
10 |
Nullish (??), Element (<-, .), Index ([]) |
9 |
Function Call |
8 |
typeof, delete, throw, use, Prefix (!, -, +) |
7 |
Multiplication (*, /, %) |
6 |
Addition (+, -) |
5 |
Comparison (>, <, >=, <=, in) |
4 |
Equality (==, !=) |
3 |
Logical (&&, ||) |
2 |
Assignment (=) |
1 |
... |
| Operator | Syntax | Literal Type |
|---|---|---|
+ |
... + ... |
number, array, string, object |
- |
... - ... |
number |
* |
... * ... |
number |
/ |
... / ... |
number |
% |
... % ... |
number |
== |
... == ... |
number, string, boolean, array, object |
!= |
... != ... |
number, string, boolean, array, object |
< |
... < ... |
number |
> |
... > ... |
number |
<= |
... <= ... |
number |
>= |
... >= ... |
number |
<- |
... <- ... |
array, object, Any |
. |
extends <- |
extends <- |
?? |
... ?? ... |
Any |
in |
... in ... |
string, number, object, string, number, object, array |
| Type | Syntax |
|---|---|
string |
"String", 'String' |
number |
[-?]Number.[Number?] |
boolean |
true, false |
dict |
{ [key (String, Number)]: [value (Any)], } |
array |
[value (Any)] |
func |
func [name?]([args]) [block] |
| Function | Arguments |
|---|---|
import |
string |
eval |
string |
js |
string |
to_s |
Any |
to_n |
Any |
to_b |
Any |
to_a |
Any |
options |
|
regExp |
@std/libioprint(args*) -> NULLprintln(args*) -> NULL
arraypush(array, value) -> arraypop(array) -> arrayshift(array) -> arrayunshift(array, value) -> arrayslice(array, start, end) -> arrayjoin(array, separator) -> stringforEach(array, callback) -> NULLcallback(value, index)
repeat(value, count) -> array,repeat(count) -> arrayreduce(array, callback, initial) -> Anycallback(previous, current)
map(array, callback) -> arraycallback(value, index)
utilfuncTools -> objectlength(array) -> numbermatch(value, [pattern], default) -> Anyternary(condition, trueValue, falseValue) -> Any
- [
string]split(string, separator) -> arrayconcat(args*) -> stringreplace(string, pattern, replacement) -> stringsubString(string, start, end) -> stringregExp(regexExpression, Options) -> stringregexExpressionpattern:[Regex Pattern]flags:[Regex Flags]
Optionstype:match,test,replacestr:stringreplace?:string
regex(pattern, flags, string) -> functionmatch() -> stringtest() -> booleanreplace(string, replace) -> string
If sesan.config.json dose not exist in root (./), it extends Default.
| Option | Description | Default |
|---|---|---|
allowEval |
Allow eval() feature |
false |
allowJavaScript |
Allow js() feature |
false |
useStdLibAutomatically |
Use standard library automatically | false |
stderrPrefix |
Prefix for stderr | true |
stderrColor |
Color for stderr | true |
locale |
Locale | en |
Warning
Some features may not be updated immediately.
when updating fatal errors, npm package is also updated immediately.
npm i @ky0422/sesanimport sesan, { NULL } from '@ky0422/sesan'
console.log(
new sesan('let x = "World!"; println("Hello, " + x);', {
useStdLibAutomatically: true,
})
.setBuiltins(new Map([['test', () => NULL]]))
.applyBuiltins()
.eval()
)@std/ must exist in root (./).
curl -O https://raw.githubusercontent.com/ky0422/sesan/main/scripts/dl-stds.sh && . ./dl-stds.sh && rm ./dl-stds.sh- Variables
- Operators
- Control flow
- Import
- Decorator
- Built-in functions
- Standard library
- Expression
- Block Expression
- Statement
- Keywords
- Return
For examples, see Examples
let <identifier> = <expression>;
<identifier> = <expression>;
extends
<expression>
let foo = 1;
foo = 2;
variable names use camelCase or snake_case and, cannot use numbers as variable prefixes.
'Hello, World!'
"안녕, 세상아!"
Can start the string with ' or ", and the content supports all Unicode.
12345
3.141592
true, false
To convert another value to a boolean value, you can use the boolean, or use the !! prefix.
[1, 2, 3, 'Foo', 'Bar', [1, 2, 3]]
[1, 2, 3][1] // 2
[1, 2, 3] <- 1 // 2
Array elements can be accessed via the index or element operator.
let object = {
'foo': 'bar',
bar: false,
baz: [1, 2, 3],
5: {
x: func() {
return 1;
}
}
}
object['foo'] // 'bar'
object.bar // false
object <- 5 <- x() // 1
object <- qux // UNDEFINED
Object is a pair of keys and values.
the key must be of type string or number, and the value can be any type.
object pairs are can be accessed via the index or element operator.
<arguments>: <identifier>, <identifier>, ...
func <identifier>(<arguments>) <block expression>;
func(<arguments>) <block expression>;
extends
<block expression>
func foo(a, b) {
return a + b;
}
let bar = func(a, b) {
return a + b;
};
Functions can be declared with hard coding, and supports anonymous functions.
function names use camelCase or snake_case and, cannot use numbers as variable prefixes.
null
void <expression>
extends
<expression>
Returns undefined after executing the expression.
<operator>: +, -, *, /, %, ==, !=, <, >, <=, >=, <-, ., ??, in
<left expression> <operator> <right expression>
extends
<expression>
The + operator is addition, and can add number, string, array, object.
number + number : Add the right operand to the left operand.
string + string : Concatenate the right operand to the left operand.
array + array : Concatenate the right operand to the left operand.
object + object : Add the right operand to the left operand. if there are duplicate keys, the right operand is overwritten.
The - operator is subtraction, and can subtract number.
The * operator is multiplication, and can multiply number.
The / operator is division, and can divide number.
The % operator is modulo, and can modulo number.
The ==, !=, <, >, <=, >= operators are comparison operators, and can compare any type.
The element operator, which can access array or object elements.
[1, 2, 3] <- 1 // 2
[1, 2, 3].1 // 2
let object = {
foo: {
bar: 'baz'
},
};
object <- foo <- bar // 'baz'
object.foo.bar // 'baz'
object['foo']['bar'] = 'qux';
Cannot reassign values with the element operator, must use index.
if <condition expression [boolean]> <block expression>
else <block expression>
if <condition expression [boolean]> <expression> else <expression>
extends
<block expression>
if (condition) {
implement();
} else if (condition) {
implement();
} else implement();
Can use if, else and else if.
the condition of if is a boolean value, non-boolean values should use !!.
!!2 // true
!!0 // false
!!null // false
while <condition expression [boolean]> <block expression>
extends
<block expression>
while (condition) {
implement();
}
If condition is true, the block expression is executed.
the condition of while is a boolean value, non-boolean values should use !!.
does not support break and continue. This can be used with forEach.
<use> <string>;
extends
string
use './module/myLib';
Executes external source code and can import executed environments.
path follows the project root (default ./).
if .sesan is not included in path, .sesan will be added automatically.
@<object>
<function> // func <identifier>(<arguments>) <block expression>;
extends
<object>,<function>
let myObject = { foo: 'bar' };
@myObject
func myFunc() {
println(this <- decorator <- foo);
}
myFunc();
decorator starts with the prefix @ and requires a object value.
after that, a function is required, anonymous functions cannot be used.
import("./module/myLib");
extends
import
eval("5 + 5"); // 10
Execute the provided code. The code can access the current environment variable.
allowEval must be true.
this feature is a dangerous feature. be careful.
js("console.log('foo')");
allowJavaScript must be true.
this feature is a dangerous feature. be careful.
options(); // object
Get project options. this cannot be modified.
println("Hello, World!", 10);
Prints the provided value.
println("Hello, World!");
Prints the provided value with a new line (\n).
length([1, 2, 3]); // 3
length("Hello, World!"); // 13
Gets the length of an array or string.
println(match(3, [
[ 1, func(v) { return value + 1; } ],
[ 2, func(v) { return value + 2; } ]
], func(v) {
println('nothing');
return v * 10;
}));
to_s(1); // '1'
to_n('1'); // 1
to_b(1); // true
to_a({ foo: 'bar', bar: 1 }); // ['bar', 1]
ternary(true, "foo", "bar"); // "foo"
ternary(false, "foo", "bar"); // "bar"
If the supplied value is true, the left parameter is returned, otherwise the right parameter is returned.
let arr = [1, 2, 3];
Arrays can contain values of any type.
extends
array
push(array, 4); // [1, 2, 3, 4]
Adds the provided values to an array.
Since this is a deep copy, array is not changed.
pop(array); // [1, 2]
Removes the last element of an array.
Since this is a deep copy, array is not changed.
shift(array); // [2, 3]
Removes the first element of an array.
Since this is a deep copy, array is not changed.
unshift(array, 0); // [0, 1, 2, 3]
Adds the provided values to the beginning of an array.
Since this is a deep copy, array is not changed.
slice(array, 1, 3); // [2, 3]
Divide array by the range of the two provided parameters.
Since this is a deep copy, array is not changed.
join(array, ", "); // "1, 2, 3"
Adds array to the provided string.
Since this is a deep copy, array is not changed.
forEach(array, func (value, index) {
println(index, value);
});
Iterate through the array.
callback is given a value to traverse and an index value.
forEach(true, func (i) {
if (i % 2 == 0) { return true };
if (i >= 10) { return false };
println(i);
});
forEach can be used as a while statement.
provide a true value instead of an array for the parameter, and the index value is provided in the callback.
repeat(5); // [NULL, NULL, NULL, NULL, NULL]
repeat("foo", 3); // ["foo", "foo", "foo"]
If there is one parameter provided, iterates the null value by the number of provided values,
if there are two parameters, it iterates the first parameter by the second parameter.
reduce([ 1, 2, 3 ], func (prev, curr) prev + curr, 0);
Iterates through each element of the provided array, accumulating the return value of the callback and returning it.
can specify the initial value of the accumulated values.
map([1, 2, 3], func (x, _) x * 10);
Iterates through each element of the provided array, returning a new array with the return value of the callback.
split("foo bar baz", " "); // ["foo", "bar", "baz"]
Splits the supplied string into the second parameter.
concat("foo", "bar", "baz"); // "foobarbaz"
Combines the provided parameters.
replace("foo bar baz", " ", ", "); // "foo, bar, baz"
Replaces the value of the second parameter in the provided string with the value of the third parameter.
subString("foo bar baz", 4, 7); // "bar"
Divides a string by the number of parameters provided.
let pattern = regex('[a-z]', 'g', 'asdf');
println(pattern <- match());
println(pattern <- test());
println(pattern <- replace('b'));
<expression>;
<keywords> {
implement();
}
<keywords> implement();
extends
<keywords>,<if>
IIFE (Immediately Invoked Function Expression) pattern
(func () {
implement();
})();
<let>, <return>, <while>, <block expression>, <expression statement>
extends
<let>,<return>,<while>,<block expression>,<expression statement>
<let>, <func>, <true>, <false>, <if>, <else>, <return>, <while>, <in>, <typeof>, <null>, <throw>, <delete>, <use>, <void>, <expr>
Not used, but may be added later
<class>, <for>, <const>
extends
<let>,<func>,<true>,<false>,<if>,<else>,<return>,<while>,<in>,<use>,<void>,<expr>
<typeof> <expr>
Returns the type of the given expression.
typeof 10; // number
typeof 'foo'; // string
typeof true; // boolean
typeof {}; // object
typeof []; // array
typeof null; // null
typeof func() {}; // function
typeof void 0; // undefined
null; // NULL
<throw> <expr>
Throws an error in the provided expression.
expr <expression>
extends
expression
Evaluates the expression, and if the result is an error,
{
'message': 'error message',
'filename': 'file name',
'line': 0, // line number
'column': 0, // column number
'error': true // true if error
}
an Object containing the error message is returned.
throw 'Error'; // Error
<delete> <expr>
Deletes the provided key from environment variables.
let a = 10;
delete a;
a; // Identifier 'a' is not defined.
<keywords> {
implement();
return null;
} // `NULL`
<if> null; // `NULL`
Returns a value.
extends
<keywords>,<if>,<block expression>
Warning
This plan is subject to change at any time.Language maintanance has ended after
09/06/2022.
switch(match) expression[switch|match] <expr> { ...<case>, <default|_>: body }case<expr>: body
conststatementconst <identifier> = <expr>;
classstatementclass <identifier> { ...<method> }method<identifier> ( ...<parameter> ) <body>
forstatementfor (<identifier> [in|of] <expr>) <body>of<expr> of <expr>
- Bitwise operators
<expr> & <expr><expr> | <expr><expr> ^ <expr><expr> << <expr><expr> >> <expr><expr> >>> <expr>
- Power operator
<expr> ** <expr>
- Compiling to JavaScript
- CLI, Repl refectoring