Parsing¶
Generating AST¶
If you have elected to extend an existing language then there is hopefully an existing compiler you can leverage for parsing. In the case of Algorand Python, it was built on top of mypy and makes use of the AST generated by invoking mypy.build.build
^. Likewise, Algorand TypeScript is built on top of the TypeScript Compiler API and makes use of ts.createProgram
to parse the source files into AST.
^ Depending on when you are reading this, work is underway to replace the use of mypy in puyapy with cpython for performance reasons.
If you are unfortunate enough to have chosen a language which does not have an existing parser you can capitalise on, or you are going down the route of an entirely bespoke language then your option is to write your own lexers and parsers which is well beyond the scope of this guide. Luckily there are plenty of guides available on the internet.
Your end goal here is to have an in memory AST representation of your source code.
Visiting the AST¶
Next you will need a way to visit all the nodes in your abstract syntax tree. It is likely if you are leveraging an existing compiler, that the AST nodes already implement a visitor pattern; but if they do not, it is possible to write your own with the help of an accept function and a large switch/match
block/or some custom dispatch logic.
function accept(node: Node, visitor: StatementVisitor) {
switch (node.kind) {
case SyntaxKind.IfStatement:
visitor.visitIfStatement(node);
// and so on...
}
}
The visitor pattern will be highly advantageous in the next step.