AST parser for the Zirconium DSL for Roblox
Abstract Syntax Tree parser for the Zirconium DSL (Domain-specific Language) for Roblox.
More information in the Zirconium project.
# example comment
Basic commands -
cmd hello world
cmd "Hello, World!"
Multiple commands
cmd one
cmd two
cmd three
cmd one; cmd two; cmd three
Multi-line commands
cmd one \
two \
three
Options
cmd -kEwL --options yes
cmd $var
cmd "Interpolated $value string"
cmd1 arg && cmd2 arg
cmd1 | cmd2
cmd1 ~value @value %value ^value *value`
Variable Declarations
$var = 10
$var = string
$var = "a string"
$var = $anotherVar
$var = "Interpolated $value string"
Nested Expressions
cmd $(cmd2 -k xyz)
$var = $(cmd2 -k xyz)
Validation is done via CommmandAstParser.validate
- and returns an object, depending on the value of success
.
type ValidationSuccess = { success: true }
type ValidationError = { success: false, errorNodes: NodeError[] }
errorNodes
is an array of errors, which are
interface NodeError {
node: Node;
message: string;
}
Through this, you can get information about what nodes are causing errors, by using node.startPos
and node.endPos
for the position of the offending text, and message
for the error message.
Inside CommandAstParser
there is a simple assert
function that is like the following:
assert(node: Node) {
const result = this.validate(node);
if (!result.success) {
const firstNode = result.errorNodes[0];
throw `[CmdParser] [${firstNode.node.startPos ?? 0}:${firstNode.node.endPos ?? 0}] ${firstNode.message}`;
}
}
Which will, for example in the case of
$x =
will give
- [CmdParser] [3:3] Expression expected: '$x ='
Which means at character 3, (=
) there is an error - in this case, there is no expression.
Simplified via CommandAstParser.prettyPrint
Regular commands:
cmd hello world
CommandStatement {
CommandName cmd
String `hello`
String `world`
}
cmd "Hello, World!"
CommandStatement {
CommandName cmd
String "Hello, World!"
}
Options
cmd -kEwL --options yes
CommandStatement {
CommandName cmd
Option k
Option E
Option w
Option L
Option options
String `yes`
}
Synchronous binary expression
cmd one && cmd --number two
BinaryExpression {
CommandStatement {
CommandName cmd
String `one`
}
OperatorToken "&&"
CommandStatement {
CommandName cmd
Option number
String `two`
}
}
Pipe binary expression
cmd one | cmd --number two
BinaryExpression {
CommandStatement {
CommandName cmd
String `one`
}
OperatorToken "|"
CommandStatement {
CommandName cmd
Option number
String `two`
}
}
Variable usage
cmd $variable
CommandStatement {
CommandName cmd
Identifier variable
}
cmd "string interpolation $ohYeaaah!"
CommandStatement {
CommandName cmd
InterpolatedString {
String "string interpolation "
Identifier ohYeaaah
String "!"
}
}
Prefix expressions
cmd @special
CommandStatement {
CommandName cmd
PrefixExpression {
Prefix "@"
String `special`
}
}
Variable declarations
$var = 10
VariableDeclarationStatement {
VariableDeclaration {
Identifier var
NumberLiteral 10
}
}
$var = "Hello, World!"
VariableDeclarationStatement {
VariableDeclaration {
Identifier var
String "Hello, World!"
}
}
$var = "Hello $otherVar!"
VariableDeclarationStatement {
VariableDeclaration {
Identifier var
InterpolatedString {
String "Hello "
Identifier otherVar
String "!"
}
}
}
Inner Expressions
cmd $(cmd2 --something else)
CommandStatement {
CommandName cmd
InnerExpression {
CommandStatement {
CommandName cmd2
Option something
String else
}
}
}
$var = $(cmd xyz)
VariableDeclarationStatement {
VariableDeclaration {
Identifier var
InnerExpression {
CommandStatement {
CommandName cmd
String `xyz`
}
}
}
}