Abstract Syntax Tree parser for the Zirconium DSL (Domain-specific Language) for Roblox. More information in the Zirconium project.
-
Comments
# 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
-
Variables
cmd $var
-
String Interpolation
cmd "Interpolated $value string"
-
Synchronous Execution
cmd1 arg && cmd2 arg
-
Pipes
cmd1 | cmd2
-
Prefixes
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` } } } }