-
Notifications
You must be signed in to change notification settings - Fork 1
Parser
Steppable has now got its own language. It is designed to be minimal but powerful. It is also designed for non-programmers to quickly grasp and master. For more information, see Syntax.
The language parsing is handled by Tree-sitter, a fast parsing tool used by editors to colorize code. We aim to compensate the lower performance of Steppable itself with its great efficiency at parsing.
The grammar file of the parser is located in parser/grammar.js
. See the
Tree-sitter documentation for more
information on editing the grammar.js
file.
Steppable code is executed while parsing, i.e., no bytecode or immediate products are produced.
The parser, written in C++, relies on the Tree-sitter C bindings. It recursively descends down the code tree and executes instructions in order.
Before trying to expand Steppable based on the current feature set, please note the following.
- Do not add small features as new syntaxes. Instead, try adding them as new functions.
- Do not change anything in the current syntax. Make sure the updated grammar is still backwards-compatible.
- Do not add or remove operators.
- Do make sure that the new syntax does not collide with any of the existing syntaxes.
Make sure that your feature conforms to all the above-mentioned rules before proceeding.
To add a new syntactical feature...
Decide if you want to add a new expression type, or a new statement type. If your feature is a new statement
type, name it <my_feature>_statement
or <my_feature>_stmt
, where <my_feature>
is the name of your new feature.
Otherwise, name it <my_feature>_expression
or <my_feature>_expr
.
In grammar.js
, add a new rule. See the
Tree-sitter documentation for more
details.
// ...
module.exports = grammar({
name: "stp",
conflicts: $ => [
[$._expression, $.function_call],
// add if needed / prompted
],
rules: {
// ...
my_syntax_statement: $ => seq(
"my_syntax",
$._expression
),
}
});
You will also need to register your syntax feature to either $.statement
or $._expression
.
// ...
module.exports = grammar({
// ...
rules: {
statement: $ => choice(
// ...
$.my_syntax_statement, // <- Add this
),
// ...
_expression: $ => choice(
// ...
$.my_expr, // <- Add this
)
}
});
The parser runtime C library needs to be regenerated and recompiled every time the grammar file is updated. To do this,
run the following in the parser
directory.
npm run gen
To add handling for your new grammar...
- Add a new part in the if-else statement
handleExpr
function inparser/src/stpExprHandler.cpp
.You may choose to add the handling function in the if statement, or write a separate function in another C++ file. However, all C++ files created need to be added to theSTP_LocalValue handleExpr(const TSNode* exprNode, const STP_InterpState& state, const bool printResult = false, const std::string& exprName = "") { assert(exprNode != nullptr); if (ts_node_type(*exprNode) == "ERROR"s or ts_node_is_missing(*exprNode)) STP_throwSyntaxError(*exprNode, state); std::string exprType = ts_node_type(*exprNode); STP_LocalValue retVal(STP_TypeID_NULL); if (exprType == "number") { // ... } // ... if (exprType == "my_expression") { // handle your expression } }
CMakeLists.txt
file.
Copyright (C) Andy Zhang, 2023-2024. Licensed under the MIT License.
- Getting the Source - Cloning the repository to your local machine
- Build the Project (CMake) - Compiling the source code of Steppable using CMake
- Build the Project (build.py) - Compiling the source code of Steppable using build.py
- Workflow - How to contribute to this repository
- Coding Style (Python) - Style guidelines for Python code in this project
- Coding Style (C++) - Style guidelines for CPP code in this project
- Directory Structure - The directory structure used by this project.
- Using the API - How to use the Steppable API
- Supported Platforms
- Performance - Some benchmarks of Steppable for reference
- Status - Status of Steppable, at a glance