@maniascript/parser
Version:
Maniascript parser
1,296 lines • 96.8 kB
JavaScript
// Loosely follow the estree syntax
import {} from 'antlr4ng';
import { ProgramContext, ProgramContentContext, RequireContextDirectiveContext, ExtendsDirectiveContext, IncludeDirectiveContext, SettingDirectiveContext, CommandDirectiveContext, StructDirectiveContext, StructDeclarationContext, StructMemberContext, StructAliasingContext, ConstDirectiveContext, ConstDeclarationContext, ConstAliasingContext, TypeContext, InitializerTypeContext, BaseTypeContext, ArrayTypeContext, SimpleTypeContext, EnumTypeContext, CustomTypeContext, TextLiteralContext, LiteralContext, TextContext, IntegerContext, RealContext, BooleanContext, NullContext, NullIdContext, EnumContext, ExpressionContext, VectorContext, ArrayContext, ArrayExpressionContext, StructureContext, StructureMemberInitializationContext, FunctionCallExpressionContext, FunctionCallContext, LiteralExpressionContext, FunctionDeclarationContext, LabelDeclarationContext, StorageSpecifierContext, BlockContext, ParameterContext, StatementContext, MainStatementContext, ExpressionStatementContext, AsExpressionContext, IsExpressionContext, DotAccessExpressionContext, IndexAccessExpressionContext, UnaryMinusExpressionContext, NotExpressionContext, MultiplicativeExpressionContext, AdditiveExpressionContext, ConcatenationExpressionContext, RelationalExpressionContext, EqualityExpressionContext, OrExpressionContext, AndExpressionContext, TextInterpolationExpressionContext, DumptypeExpressionContext, DumpExpressionContext, CastExpressionContext, IdentifierExpressionContext, VectorExpressionContext, ThisExpressionContext, NowExpressionContext, ParenthesisExpressionContext, AssignmentStatementContext, ManiaScriptParser, ReturnStatementContext, LabelStatementContext, AssertStatementContext, ForeachStatementContext, ForStatementContext, WhileStatementContext, MeanwhileStatementContext, BreakStatementContext, ContinueStatementContext, SwitchStatementContext, SwitchCaseContext, SwitchDefaultContext, SwitchtypeStatementContext, SwitchtypeCaseContext, SwitchtypeDefaultContext, ConditionalStatementContext, IfBranchContext, ElseIfBranchContext, ElseBranchContext, LogStatementContext, SleepStatementContext, TuningstartStatementContext, TuningendStatementContext, TuningmarkStatementContext, WaitStatementContext, YieldStatementContext, StructureExpressionContext, VariableDeclarationWithTypeContext, VariableDeclarationWithoutTypeContext, VariableDeclarationLetContext } from '../antlr/ManiaScriptParser.js';
import { SourceLocationRange } from './position.js';
var Kind;
(function (Kind) {
Kind["Program"] = "Program";
Kind["SimpleType"] = "SimpleType";
Kind["ClassType"] = "ClassType";
Kind["EnumType"] = "EnumType";
Kind["CustomType"] = "CustomType";
Kind["InvalidType"] = "InvalidType";
Kind["ArrayType"] = "ArrayType";
Kind["InvalidLiteral"] = "InvalidLiteral";
Kind["TextLiteral"] = "TextLiteral";
Kind["IntegerLiteral"] = "IntegerLiteral";
Kind["RealLiteral"] = "RealLiteral";
Kind["BooleanLiteral"] = "BooleanLiteral";
Kind["NullLiteral"] = "NullLiteral";
Kind["NullIdLiteral"] = "NullIdLiteral";
Kind["EnumLiteral"] = "EnumLiteral";
Kind["Identifier"] = "Identifier";
Kind["InvalidIdentifier"] = "InvalidIdentifier";
Kind["RequireContextDirective"] = "RequireContextDirective";
Kind["InvalidDirective"] = "InvalidDirective";
Kind["ExtendsDirective"] = "ExtendsDirective";
Kind["IncludeDirective"] = "IncludeDirective";
Kind["InvalidSettingValue"] = "InvalidSettingValue";
Kind["SettingDirective"] = "SettingDirective";
Kind["CommandDirective"] = "CommandDirective";
Kind["StructMemberDeclaration"] = "StructMemberDeclaration";
Kind["StructDeclaration"] = "StructDeclaration";
Kind["StructAliasing"] = "StructAliasing";
Kind["StructDirective"] = "StructDirective";
Kind["InvalidConstValue"] = "InvalidConstValue";
Kind["ConstDeclaration"] = "ConstDeclaration";
Kind["ConstAliasing"] = "ConstAliasing";
Kind["ConstDirective"] = "ConstDirective";
Kind["InvalidDeclaration"] = "InvalidDeclaration";
Kind["VariableDeclaration"] = "VariableDeclaration";
Kind["FunctionParameterDeclaration"] = "FunctionParameterDeclaration";
Kind["FunctionDeclaration"] = "FunctionDeclaration";
Kind["LabelDeclaration"] = "LabelDeclaration";
Kind["BlockStatement"] = "BlockStatement";
Kind["InvalidStatement"] = "InvalidStatement";
Kind["ExpressionStatement"] = "ExpressionStatement";
Kind["InvalidExpression"] = "InvalidExpression";
Kind["VectorExpression"] = "VectorExpression";
Kind["ArrayExpression"] = "ArrayExpression";
Kind["StructMemberExpression"] = "StructMemberExpression";
Kind["StructExpression"] = "StructExpression";
Kind["FunctionCallExpression"] = "FunctionCallExpression";
Kind["AsExpression"] = "AsExpression";
Kind["IsExpression"] = "IsExpression";
Kind["DotAccessExpression"] = "DotAccessExpression";
Kind["IndexAccessExpression"] = "IndexAccessExpression";
Kind["UnaryExpression"] = "UnaryExpression";
Kind["BinaryExpression"] = "BinaryExpression";
Kind["LogicalExpression"] = "LogicalExpression";
Kind["TemplateTextLiteral"] = "TemplateTextLiteral";
Kind["TemplateTextElement"] = "TemplateTextElement";
Kind["DumptypeExpression"] = "DumptypeExpression";
Kind["DumpExpression"] = "DumpExpression";
Kind["CastExpression"] = "CastExpression";
Kind["ThisExpression"] = "ThisExpression";
Kind["NowExpression"] = "NowExpression";
Kind["AssignmentStatement"] = "AssignmentStatement";
Kind["ReturnStatement"] = "ReturnStatement";
Kind["LabelStatement"] = "LabelStatement";
Kind["AssertStatement"] = "AssertStatement";
Kind["ForeachStatement"] = "ForeachStatement";
Kind["ForStatement"] = "ForStatement";
Kind["WhileStatement"] = "WhileStatement";
Kind["MeanwhileStatement"] = "MeanwhileStatement";
Kind["BreakStatement"] = "BreakStatement";
Kind["ContinueStatement"] = "ContinueStatement";
Kind["SwitchStatement"] = "SwitchStatement";
Kind["SwitchCase"] = "SwitchCase";
Kind["SwitchtypeStatement"] = "SwitchtypeStatement";
Kind["SwitchtypeCase"] = "SwitchtypeCase";
Kind["ConditionalStatement"] = "ConditionalStatement";
Kind["ConditionalBranch"] = "ConditionalBranch";
Kind["LogStatement"] = "LogStatement";
Kind["SleepStatement"] = "SleepStatement";
Kind["TuningstartStatement"] = "TuningstartStatement";
Kind["TuningendStatement"] = "TuningendStatement";
Kind["TuningmarkStatement"] = "TuningmarkStatement";
Kind["WaitStatement"] = "WaitStatement";
Kind["YieldStatement"] = "YieldStatement";
Kind["Main"] = "Main";
})(Kind || (Kind = {}));
function isNullish(value) {
return value === undefined || value === null;
}
class ASTBuildError extends Error {
}
class Node {
source;
parent;
constructor(parent, start, stop) {
if (start === null) {
throw new ASTBuildError('Failed to build node. Missing start token');
}
else {
this.source = new SourceLocationRange(start, stop);
}
this.parent = parent;
}
enter(enterCb) {
if (enterCb !== null)
enterCb(this);
}
exit(exitCb) {
if (exitCb !== null)
exitCb(this);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.exit(exitCb);
}
}
class Program extends Node {
kind = Kind.Program;
directives;
declarations;
main;
constructor(program) {
super(undefined, program.start, program.stop);
this.directives = [];
this.declarations = [];
}
visit(enterCb, exitCb) {
this.enter(enterCb);
for (const directives of this.directives) {
directives.visit(enterCb, exitCb);
}
for (const declaration of this.declarations) {
declaration.visit(enterCb, exitCb);
}
this.main?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
var TypeName;
(function (TypeName) {
TypeName["Boolean"] = "Boolean";
TypeName["Ident"] = "Ident";
TypeName["Int2"] = "Int2";
TypeName["Int3"] = "Int3";
TypeName["Integer"] = "Integer";
TypeName["Real"] = "Real";
TypeName["Text"] = "Text";
TypeName["Vec2"] = "Vec2";
TypeName["Vec3"] = "Vec3";
TypeName["Void"] = "Void";
TypeName["Invalid"] = "Invalid";
})(TypeName || (TypeName = {}));
function isBaseType(node) {
return (node.kind === Kind.SimpleType ||
node.kind === Kind.ClassType ||
node.kind === Kind.EnumType ||
node.kind === Kind.CustomType);
}
function isInitializerType(node) {
return (node.kind === Kind.ArrayType ||
node.kind === Kind.SimpleType ||
node.kind === Kind.ClassType);
}
function isType(node) {
return (node.kind === Kind.ArrayType ||
isBaseType(node));
}
class SimpleType extends Node {
kind = Kind.SimpleType;
name;
constructor(parent, simpleType) {
super(parent, simpleType.start, simpleType.stop);
if (simpleType.TYPE_BOOLEAN() !== null) {
this.name = TypeName.Boolean;
}
else if (simpleType.TYPE_IDENT() !== null) {
this.name = TypeName.Ident;
}
else if (simpleType.TYPE_INT2() !== null) {
this.name = TypeName.Int2;
}
else if (simpleType.TYPE_INT3() !== null) {
this.name = TypeName.Int3;
}
else if (simpleType.TYPE_INTEGER() !== null) {
this.name = TypeName.Integer;
}
else if (simpleType.TYPE_REAL() !== null) {
this.name = TypeName.Real;
}
else if (simpleType.TYPE_TEXT() !== null) {
this.name = TypeName.Text;
}
else if (simpleType.TYPE_VEC2() !== null) {
this.name = TypeName.Vec2;
}
else if (simpleType.TYPE_VEC3() !== null) {
this.name = TypeName.Vec3;
}
else if (simpleType.TYPE_VOID() !== null) {
this.name = TypeName.Void;
}
else {
this.name = TypeName.Invalid;
}
}
}
class ClassType extends Node {
kind = Kind.ClassType;
name;
constructor(parent, className) {
super(parent, className);
this.name = className.text ?? '';
}
}
class EnumType extends Node {
kind = Kind.EnumType;
class;
name;
constructor(parent, enumType) {
super(parent, enumType.start, enumType.stop);
const classToken = enumType.className()?.CLASS().symbol;
if (classToken !== undefined) {
this.class = new ClassType(this, classToken);
}
this.name = new Identifier(this, enumType.enumName().IDENTIFIER().symbol);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.class?.visit(enterCb, exitCb);
this.name.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class CustomType extends Node {
kind = Kind.CustomType;
name;
constructor(parent, customType) {
super(parent, customType.start, customType.stop);
this.name = new Identifier(this, customType.structName().IDENTIFIER().symbol, customType.namespaceName()?.IDENTIFIER().symbol);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class InvalidType extends Node {
kind = Kind.InvalidType;
error;
constructor(parent, start, stop, error) {
super(parent, start, stop);
if (error instanceof Error) {
this.error = error;
}
else {
this.error = null;
}
}
}
class ArrayType extends Node {
kind = Kind.ArrayType;
value;
keys;
constructor(parent, arrayType) {
super(parent, arrayType.start, arrayType.stop);
this.value = createBaseTypeNode(this, arrayType.baseType());
this.keys = [];
for (const keyType of arrayType.arrayTypeDimension()) {
const baseType = keyType.baseType();
if (baseType !== null) {
this.keys.push(createBaseTypeNode(this, baseType));
}
else {
this.keys.push('EmptyKey');
}
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.value.visit(enterCb, exitCb);
for (const key of this.keys) {
if (key !== 'EmptyKey') {
key.visit(enterCb, exitCb);
}
}
this.exit(exitCb);
}
}
function createBaseTypeNode(parent, baseType) {
try {
const simpleType = baseType.simpleType();
const classType = baseType.className();
const enumType = baseType.enumType();
const customType = baseType.customType();
if (simpleType != null) {
return new SimpleType(parent, simpleType);
}
else if (classType !== null) {
return new ClassType(parent, classType.CLASS().symbol);
}
else if (enumType !== null) {
return new EnumType(parent, enumType);
}
else if (customType !== null) {
return new CustomType(parent, customType);
}
else {
return new InvalidType(parent, baseType.start, baseType.stop);
}
}
catch (error) {
if (error instanceof Error) {
return new InvalidType(parent, baseType.start, baseType.stop, error);
}
else {
return new InvalidType(parent, baseType.start, baseType.stop, new ASTBuildError('Failed to build `BaseType` node. Something went wrong while reading `BaseTypeContext`.'));
}
}
}
function createInitializerTypeNode(parent, type) {
try {
const arrayType = type.arrayType();
const simpleType = type.simpleType();
const classType = type.className();
if (arrayType !== null) {
return new ArrayType(parent, arrayType);
}
else if (simpleType !== null) {
return new SimpleType(parent, simpleType);
}
else if (classType !== null) {
return new ClassType(parent, classType.CLASS().symbol);
}
else {
return new InvalidType(parent, type.start, type.stop);
}
}
catch (error) {
if (error instanceof Error) {
return new InvalidType(parent, type.start, type.stop, error);
}
else {
return new InvalidType(parent, type.start, type.stop, new ASTBuildError('Failed to build `InitializerType` node. Something went wrong while reading `BaseTypeContext`.'));
}
}
}
function createTypeNode(parent, type) {
try {
const arrayType = type.arrayType();
const baseType = type.baseType();
if (arrayType !== null) {
return new ArrayType(parent, arrayType);
}
else if (baseType !== null) {
return createBaseTypeNode(parent, baseType);
}
else {
return new InvalidType(parent, type.start, type.stop);
}
}
catch (error) {
if (error instanceof Error) {
return new InvalidType(parent, type.start, type.stop, error);
}
else {
return new InvalidType(parent, type.start, type.stop, new ASTBuildError('Failed to build `Type` node. Something went wrong while reading `TypeContext`.'));
}
}
}
function isLiteral(node) {
return (node.kind === Kind.TextLiteral ||
node.kind === Kind.IntegerLiteral ||
node.kind === Kind.RealLiteral ||
node.kind === Kind.BooleanLiteral ||
node.kind === Kind.NullLiteral ||
node.kind === Kind.NullIdLiteral ||
node.kind === Kind.EnumLiteral);
}
class InvalidLiteral extends Node {
kind = Kind.InvalidLiteral;
error;
constructor(parent, start, stop, error) {
super(parent, start, stop);
if (error instanceof Error) {
this.error = error;
}
else {
this.error = null;
}
}
}
class TextLiteral extends Node {
kind = Kind.TextLiteral;
isTranslated;
isMultiline;
value;
raw;
constructor(parent, textLiteral) {
super(parent, textLiteral.start, textLiteral.stop);
this.isMultiline = false;
this.value = '';
this.raw = '';
const textTranslatedLiteral = textLiteral.textTranslatedLiteral();
this.isTranslated = textTranslatedLiteral !== null;
let textBaseLiteral = textLiteral.textBaseLiteral();
if (textTranslatedLiteral !== null) {
textBaseLiteral = textTranslatedLiteral.textBaseLiteral();
this.raw = textTranslatedLiteral.getText();
}
if (textBaseLiteral !== null) {
const textSingleQuoteLiteral = textBaseLiteral.textSingleQuoteLiteral();
const textTripleQuoteLiteral = textBaseLiteral.textTripleQuoteLiteral();
if (textSingleQuoteLiteral !== null) {
this.value = textSingleQuoteLiteral.getText().slice(textSingleQuoteLiteral.OPERATOR_OPEN_TEXT_SINGLE().getText().length, -textSingleQuoteLiteral.OPERATOR_CLOSE_TEXT_SINGLE().getText().length);
if (this.raw === '')
this.raw = textSingleQuoteLiteral.getText();
}
else if (textTripleQuoteLiteral !== null) {
this.isMultiline = true;
this.value = textTripleQuoteLiteral.getText().slice(textTripleQuoteLiteral.OPERATOR_OPEN_TEXT_TRIPLE().getText().length, -textTripleQuoteLiteral.OPERATOR_CLOSE_TEXT_TRIPLE().getText().length);
if (this.raw === '')
this.raw = textTripleQuoteLiteral.getText();
}
}
}
}
class IntegerLiteral extends Node {
kind = Kind.IntegerLiteral;
value;
raw;
constructor(parent, integerLiteral) {
super(parent, integerLiteral.start, integerLiteral.stop);
this.raw = integerLiteral.LITERAL_INTEGER().getText();
if (integerLiteral.OPERATOR_MINUS() !== null) {
this.raw = `-${this.raw}`;
}
this.value = Number(this.raw);
}
}
class RealLiteral extends Node {
kind = Kind.RealLiteral;
value;
raw;
constructor(parent, realLiteral) {
super(parent, realLiteral.start, realLiteral.stop);
this.raw = realLiteral.LITERAL_REAL().getText();
if (realLiteral.OPERATOR_MINUS() !== null) {
this.raw = `-${this.raw}`;
}
this.value = Number(this.raw);
}
}
class BooleanLiteral extends Node {
kind = Kind.BooleanLiteral;
value;
constructor(parent, booleanLiteral) {
super(parent, booleanLiteral.start, booleanLiteral.stop);
if (booleanLiteral.LITERAL_BOOLEAN().getText() === 'True') {
this.value = true;
}
else {
this.value = false;
}
}
}
class NullLiteral extends Node {
kind = Kind.NullLiteral;
constructor(parent, nullLiteral) {
super(parent, nullLiteral.start, nullLiteral.stop);
}
}
class NullIdLiteral extends Node {
kind = Kind.NullIdLiteral;
constructor(parent, nullIdLiteral) {
super(parent, nullIdLiteral.start, nullIdLiteral.stop);
}
}
class EnumLiteral extends Node {
kind = Kind.EnumLiteral;
class;
name;
value;
constructor(parent, enumLiteral) {
super(parent, enumLiteral.start, enumLiteral.stop);
const name = enumLiteral.enumLiteral().enumName().IDENTIFIER().symbol;
const value = enumLiteral.enumLiteral().enumValue().IDENTIFIER().symbol;
const classClass = enumLiteral.enumLiteral().className()?.CLASS().symbol;
const classLib = enumLiteral.enumLiteral().namespaceName()?.IDENTIFIER().symbol;
if (classClass !== undefined) {
this.class = new ClassType(this, classClass);
}
else if (classLib !== undefined) {
this.class = new Identifier(this, classLib);
}
this.name = new Identifier(this, name);
this.value = new Identifier(this, value);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.class?.visit(enterCb, exitCb);
this.name.visit(enterCb, exitCb);
this.value.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
function createLiteralNode(parent, literal) {
try {
if (literal instanceof TextContext) {
return new TextLiteral(parent, literal.textLiteral());
}
else if (literal instanceof IntegerContext) {
return new IntegerLiteral(parent, literal);
}
else if (literal instanceof RealContext) {
return new RealLiteral(parent, literal);
}
else if (literal instanceof BooleanContext) {
return new BooleanLiteral(parent, literal);
}
else if (literal instanceof NullContext) {
return new NullLiteral(parent, literal);
}
else if (literal instanceof NullIdContext) {
return new NullIdLiteral(parent, literal);
}
else if (literal instanceof EnumContext) {
return new EnumLiteral(parent, literal);
}
else {
return new InvalidLiteral(parent, literal.start, literal.stop);
}
}
catch (error) {
if (error instanceof Error) {
return new InvalidLiteral(parent, literal.start, literal.stop, error);
}
else {
return new InvalidLiteral(parent, literal.start, literal.stop, new ASTBuildError('Failed to build `Literal` node. Something went wrong while reading `LiteralContext`.'));
}
}
}
class Identifier extends Node {
kind;
namespace;
name;
isExpression;
constructor(parent, identifier, namespace, isExpression) {
if (namespace !== undefined && namespace !== null) {
super(parent, namespace, identifier);
this.namespace = namespace.text;
}
else {
super(parent, identifier);
}
this.kind = Kind.Identifier;
this.name = identifier.text ?? '';
this.isExpression = isExpression ?? false;
}
}
class InvalidIdentifier extends Node {
kind = Kind.InvalidIdentifier;
}
function isDirective(node) {
return (node.kind === Kind.RequireContextDirective ||
node.kind === Kind.ExtendsDirective ||
node.kind === Kind.IncludeDirective ||
node.kind === Kind.SettingDirective ||
node.kind === Kind.CommandDirective ||
node.kind === Kind.StructDirective ||
node.kind === Kind.ConstDirective);
}
class InvalidDirective extends Node {
kind = Kind.InvalidDirective;
error;
constructor(parent, start, stop, error) {
super(parent, start, stop);
if (error instanceof Error) {
this.error = error;
}
else {
this.error = null;
}
}
}
class RequireContextDirective extends Node {
kind = Kind.RequireContextDirective;
class;
constructor(parent, requireContextDirective) {
super(parent, requireContextDirective.start, requireContextDirective.stop);
this.class = new ClassType(this, requireContextDirective.className().CLASS().symbol);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.class.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class ExtendsDirective extends Node {
kind = Kind.ExtendsDirective;
path;
constructor(parent, extendsDirective) {
super(parent, extendsDirective.start, extendsDirective.stop);
this.path = new TextLiteral(this, extendsDirective.extendsPath().textLiteral());
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.path.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class IncludeDirective extends Node {
kind = Kind.IncludeDirective;
path;
alias;
constructor(parent, includeDirective) {
super(parent, includeDirective.start, includeDirective.stop);
this.path = new TextLiteral(this, includeDirective.includePath().textLiteral());
const identifier = includeDirective.includeAlias()?.namespaceDefinition().IDENTIFIER().symbol;
if (identifier !== undefined) {
this.alias = new Identifier(this, identifier);
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.path.visit(enterCb, exitCb);
this.alias?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class InvalidSettingValue extends Node {
kind = Kind.InvalidSettingValue;
}
class SettingDirective extends Node {
kind = Kind.SettingDirective;
name;
value;
description;
constructor(parent, settingDirective) {
super(parent, settingDirective.start, settingDirective.stop);
this.name = new Identifier(this, settingDirective.settingName().IDENTIFIER().symbol);
const literal = settingDirective.literal();
const vector = settingDirective.vector();
if (literal !== null) {
this.value = createLiteralNode(this, literal);
}
else if (vector !== null) {
this.value = new VectorExpression(this, vector);
}
else {
this.value = new InvalidSettingValue(this, settingDirective.start, settingDirective.stop);
}
const descriptionAlias = settingDirective.textAlias()?._alias;
if (descriptionAlias !== undefined) {
this.description = new TextLiteral(this, descriptionAlias);
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.value.visit(enterCb, exitCb);
this.description?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class CommandDirective extends Node {
kind = Kind.CommandDirective;
name;
type;
description;
constructor(parent, commandDirective) {
super(parent, commandDirective.start, commandDirective.stop);
this.name = new Identifier(this, commandDirective.commandName().IDENTIFIER().symbol);
this.type = createTypeNode(this, commandDirective.type());
const alias = commandDirective.textAlias()?._alias;
if (alias !== undefined) {
this.description = new TextLiteral(this, alias);
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.type.visit(enterCb, exitCb);
this.description?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class StructMemberDeclaration extends Node {
kind = Kind.StructMemberDeclaration;
type;
name;
constructor(parent, structMember) {
super(parent, structMember.start, structMember.stop);
this.type = createTypeNode(this, structMember.type());
this.name = new Identifier(this, structMember.IDENTIFIER().symbol);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.type.visit(enterCb, exitCb);
this.name.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class StructDeclaration extends Node {
kind = Kind.StructDeclaration;
name;
members;
constructor(parent, structDeclaration) {
super(parent, structDeclaration.start, structDeclaration.stop);
this.name = new Identifier(this, structDeclaration.IDENTIFIER().symbol);
this.members = [];
const structMembers = structDeclaration.structMembers()?.structMember();
if (structMembers !== undefined) {
for (const structMember of structMembers) {
this.members.push(new StructMemberDeclaration(this, structMember));
}
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
for (const member of this.members) {
member.visit(enterCb, exitCb);
}
this.exit(exitCb);
}
}
class StructAliasing extends Node {
kind = Kind.StructAliasing;
name;
alias;
constructor(parent, structAliasing) {
super(parent, structAliasing.start, structAliasing.stop);
const structName = structAliasing.structName().IDENTIFIER().symbol;
const structNamespace = structAliasing.namespaceName().IDENTIFIER().symbol;
const structAlias = structAliasing.identifierAlias().IDENTIFIER().symbol;
this.name = new Identifier(this, structName, structNamespace);
this.alias = new Identifier(this, structAlias);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.alias.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class StructDirective extends Node {
kind = Kind.StructDirective;
declaration;
aliasing;
constructor(parent, structDirective) {
super(parent, structDirective.start, structDirective.stop);
const structDeclaration = structDirective.structDeclaration();
const structAliasing = structDirective.structAliasing();
if (structDeclaration !== null) {
this.declaration = new StructDeclaration(this, structDeclaration);
}
if (structAliasing !== null) {
this.aliasing = new StructAliasing(this, structAliasing);
}
if (this.declaration === undefined && this.aliasing === undefined) {
throw new ASTBuildError('Failed to build `StructDirective` node. `declaration` and `aliasing` cannot both be `undefined`.');
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.declaration?.visit(enterCb, exitCb);
this.aliasing?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class InvalidConstValue extends Node {
kind = Kind.InvalidConstValue;
}
class ConstDeclaration extends Node {
kind = Kind.ConstDeclaration;
name;
value;
constructor(parent, constDeclaration) {
super(parent, constDeclaration.start, constDeclaration.stop);
this.name = new Identifier(this, constDeclaration.IDENTIFIER().symbol);
const literal = constDeclaration.literal();
const vector = constDeclaration.vector();
const array = constDeclaration.array();
const structure = constDeclaration.structure();
if (literal !== null) {
this.value = createLiteralNode(this, literal);
}
else if (vector !== null) {
this.value = new VectorExpression(this, vector);
}
else if (array !== null) {
this.value = new ArrayExpression(this, array);
}
else if (structure !== null) {
this.value = new StructExpression(this, structure);
}
else {
this.value = new InvalidConstValue(this, constDeclaration.start, constDeclaration.stop);
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.value.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class ConstAliasing extends Node {
kind = Kind.ConstAliasing;
name;
alias;
constructor(parent, constAliasing) {
super(parent, constAliasing.start, constAliasing.stop);
const constName = constAliasing.constName().IDENTIFIER().symbol;
const constNamespace = constAliasing.namespaceName().IDENTIFIER().symbol;
const constAlias = constAliasing.identifierAlias().IDENTIFIER().symbol;
this.name = new Identifier(this, constName, constNamespace);
this.alias = new Identifier(this, constAlias);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.alias.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class ConstDirective extends Node {
kind = Kind.ConstDirective;
declaration;
aliasing;
constructor(parent, constDirective) {
super(parent, constDirective.start, constDirective.stop);
const constDeclaration = constDirective.constDeclaration();
const constAliasing = constDirective.constAliasing();
if (constDeclaration !== null) {
this.declaration = new ConstDeclaration(this, constDeclaration);
}
if (constAliasing !== null) {
this.aliasing = new ConstAliasing(this, constAliasing);
}
if (this.declaration === undefined && this.aliasing === undefined) {
throw new ASTBuildError('Failed to build `ConstDirective` node. `declaration` and `aliasing` cannot both be `undefined`.');
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.declaration?.visit(enterCb, exitCb);
this.aliasing?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
function isDeclaration(node) {
return (node.kind === Kind.VariableDeclaration ||
node.kind === Kind.FunctionDeclaration ||
node.kind === Kind.LabelDeclaration);
}
var Storage;
(function (Storage) {
Storage["cloud"] = "cloud";
Storage["metadata"] = "metadata";
Storage["netread"] = "netread";
Storage["netwrite"] = "netwrite";
Storage["persistent"] = "persistent";
Storage["invalid"] = "invalid";
})(Storage || (Storage = {}));
var InitializerSign;
(function (InitializerSign) {
InitializerSign["="] = "=";
InitializerSign["<=>"] = "<=>";
InitializerSign["invalid"] = "invalid";
})(InitializerSign || (InitializerSign = {}));
function toStorageEnum(storage) {
if (storage.STORAGESPECIFIER_CLOUD() !== null) {
return Storage.cloud;
}
else if (storage.STORAGESPECIFIER_METADATA() !== null) {
return Storage.metadata;
}
else if (storage.STORAGESPECIFIER_NETREAD() !== null) {
return Storage.netread;
}
else if (storage.STORAGESPECIFIER_NETWRITE() !== null) {
return Storage.netwrite;
}
else if (storage.STORAGESPECIFIER_PERSISTENT() !== null) {
return Storage.persistent;
}
else {
return Storage.invalid;
}
}
function toInitializerSign(sign) {
if (sign.type === ManiaScriptParser.OPERATOR_ASSIGN) {
return InitializerSign['='];
}
else if (sign.type === ManiaScriptParser.OPERATOR_ARROWASSIGN) {
return InitializerSign['<=>'];
}
else {
return InitializerSign.invalid;
}
}
class InvalidDeclaration extends Node {
kind = Kind.InvalidDeclaration;
error;
constructor(parent, start, stop, error) {
super(parent, start, stop);
if (error instanceof Error) {
this.error = error;
}
else {
this.error = null;
}
}
}
class VariableDeclaration extends Node {
kind = Kind.VariableDeclaration;
isGlobal;
isLet;
storage;
type;
name;
alias;
forTarget;
initializerSign;
initializerExpression;
initializerType;
constructor(parent, variableDeclaration, isGlobal) {
super(parent, variableDeclaration.start, variableDeclaration.stop);
this.isGlobal = isGlobal;
this.isLet = variableDeclaration instanceof VariableDeclarationLetContext;
if (variableDeclaration instanceof VariableDeclarationWithTypeContext) {
const storageSpecifier = variableDeclaration.storageSpecifier();
if (storageSpecifier !== null) {
this.storage = toStorageEnum(storageSpecifier);
}
this.type = createTypeNode(this, variableDeclaration.type());
this.name = new Identifier(this, variableDeclaration.variableName().IDENTIFIER().symbol);
const identifierAlias = variableDeclaration.identifierAlias();
if (identifierAlias !== null) {
this.alias = new Identifier(this, identifierAlias.IDENTIFIER().symbol);
}
if (variableDeclaration._forTarget !== undefined) {
this.forTarget = createExpressionNode(this, variableDeclaration._forTarget);
}
const initializer = variableDeclaration.initializer();
if (initializer !== null) {
if (isNullish(initializer._sign)) {
throw new ASTBuildError('Failed to build `VariableDeclaration` node. Missing initializer sign.');
}
this.initializerSign = toInitializerSign(initializer._sign);
const initializerExpression = initializer.expression();
const initializerType = initializer.initializerType();
if (initializerExpression !== null) {
this.initializerExpression = createExpressionNode(this, initializerExpression);
}
else if (initializerType !== null) {
this.initializerType = createInitializerTypeNode(this, initializerType);
}
}
}
else if (variableDeclaration instanceof VariableDeclarationWithoutTypeContext) {
const storageSpecifier = variableDeclaration.storageSpecifier();
if (storageSpecifier !== null) {
this.storage = toStorageEnum(storageSpecifier);
}
this.name = new Identifier(this, variableDeclaration.variableName().IDENTIFIER().symbol);
const identifierAlias = variableDeclaration.identifierAlias();
if (identifierAlias !== null) {
this.alias = new Identifier(this, identifierAlias.IDENTIFIER().symbol);
}
if (variableDeclaration._forTarget !== undefined) {
this.forTarget = createExpressionNode(this, variableDeclaration._forTarget);
}
const initializer = variableDeclaration.initializer();
if (isNullish(initializer._sign)) {
throw new ASTBuildError('Failed to build `VariableDeclaration` node. Missing initializer sign.');
}
this.initializerSign = toInitializerSign(initializer._sign);
const initializerExpression = initializer.expression();
const initializerType = initializer.initializerType();
if (initializerExpression !== null) {
this.initializerExpression = createExpressionNode(this, initializerExpression);
}
else if (initializerType !== null) {
this.initializerType = createInitializerTypeNode(this, initializerType);
}
}
else {
this.name = new Identifier(this, variableDeclaration.IDENTIFIER().symbol);
this.initializerSign = toInitializerSign(variableDeclaration.OPERATOR_ASSIGN().symbol);
const initializerExpression = variableDeclaration.expression();
const intializerArrayType = variableDeclaration.arrayType();
if (initializerExpression !== null) {
this.initializerExpression = createExpressionNode(this, initializerExpression);
}
else if (intializerArrayType !== null) {
this.initializerType = new ArrayType(this, intializerArrayType);
}
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.type?.visit(enterCb, exitCb);
this.name.visit(enterCb, exitCb);
this.alias?.visit(enterCb, exitCb);
this.forTarget?.visit(enterCb, exitCb);
this.initializerExpression?.visit(enterCb, exitCb);
this.initializerType?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class FunctionParameterDeclaration extends Node {
kind = Kind.FunctionParameterDeclaration;
type;
name;
constructor(parent, parameter) {
super(parent, parameter.start, parameter.stop);
this.type = createTypeNode(this, parameter.type());
this.name = new Identifier(this, parameter.IDENTIFIER().symbol);
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.type.visit(enterCb, exitCb);
this.name.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class FunctionDeclaration extends Node {
kind = Kind.FunctionDeclaration;
type;
name;
parameters;
body;
constructor(parent, functionDeclaration) {
super(parent, functionDeclaration.start, functionDeclaration.stop);
this.type = createTypeNode(this, functionDeclaration.type());
this.name = new Identifier(this, functionDeclaration.functionName().IDENTIFIER().symbol);
this.parameters = [];
const parameters = functionDeclaration.parameters();
if (parameters !== null) {
for (const parameter of parameters.parameter()) {
this.parameters.push(new FunctionParameterDeclaration(this, parameter));
}
}
this.body = new BlockStatement(this, functionDeclaration.block());
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.type.visit(enterCb, exitCb);
this.name.visit(enterCb, exitCb);
for (const parameter of this.parameters) {
parameter.visit(enterCb, exitCb);
}
this.body.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class LabelDeclaration extends Node {
kind = Kind.LabelDeclaration;
name;
body;
constructor(parent, labelDeclaration) {
super(parent, labelDeclaration.start, labelDeclaration.stop);
this.name = new Identifier(this, labelDeclaration.labelName().IDENTIFIER().symbol);
this.body = [];
for (const statement of labelDeclaration.statements().statement()) {
this.body.push(createStatementNode(this, statement));
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
for (const statement of this.body) {
statement.visit(enterCb, exitCb);
}
this.exit(exitCb);
}
}
function isStatement(node) {
return (node.kind === Kind.BlockStatement ||
node.kind === Kind.VariableDeclaration ||
node.kind === Kind.ExpressionStatement ||
node.kind === Kind.AssignmentStatement ||
node.kind === Kind.ReturnStatement ||
node.kind === Kind.LabelStatement ||
node.kind === Kind.AssertStatement ||
node.kind === Kind.ForeachStatement ||
node.kind === Kind.ForStatement ||
node.kind === Kind.WhileStatement ||
node.kind === Kind.MeanwhileStatement ||
node.kind === Kind.BreakStatement ||
node.kind === Kind.ContinueStatement ||
node.kind === Kind.SwitchStatement ||
node.kind === Kind.SwitchtypeStatement ||
node.kind === Kind.ConditionalStatement ||
node.kind === Kind.ConditionalBranch ||
node.kind === Kind.LogStatement ||
node.kind === Kind.SleepStatement ||
node.kind === Kind.TuningstartStatement ||
node.kind === Kind.TuningendStatement ||
node.kind === Kind.TuningmarkStatement ||
node.kind === Kind.WaitStatement ||
node.kind === Kind.YieldStatement);
}
class BlockStatement extends Node {
kind = Kind.BlockStatement;
body;
constructor(parent, block) {
super(parent, block.start, block.stop);
this.body = [];
const statements = block.statements()?.statement();
if (statements !== undefined) {
for (const statement of statements) {
this.body.push(createStatementNode(this, statement));
}
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
for (const statement of this.body) {
statement.visit(enterCb, exitCb);
}
this.exit(exitCb);
}
}
class InvalidStatement extends Node {
kind = Kind.InvalidStatement;
error;
constructor(parent, start, stop, error) {
super(parent, start, stop);
if (error instanceof Error) {
this.error = error;
}
else {
this.error = null;
}
}
}
class ExpressionStatement extends Node {
kind = Kind.ExpressionStatement;
expression;
constructor(parent, expressionStatement) {
super(parent, expressionStatement.start, expressionStatement.stop);
this.expression = createExpressionNode(this, expressionStatement.expression());
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.expression.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
var AssignmentOperator;
(function (AssignmentOperator) {
AssignmentOperator["="] = "=";
AssignmentOperator["<=>"] = "<=>";
AssignmentOperator["*="] = "*=";
AssignmentOperator["/="] = "/=";
AssignmentOperator["+="] = "+=";
AssignmentOperator["-="] = "-=";
AssignmentOperator["%="] = "%=";
AssignmentOperator["^="] = "^=";
})(AssignmentOperator || (AssignmentOperator = {}));
class AssignmentStatement extends Node {
kind = Kind.AssignmentStatement;
left;
right;
operator;
isInitializedByType;
constructor(parent, assignmentStatement) {
super(parent, assignmentStatement.start, assignmentStatement.stop);
if (assignmentStatement._left === undefined) {
throw new ASTBuildError('Failed to build `AssignmentStatement` node. Missing left part of the assignment.');
}
this.left = createExpressionNode(this, assignmentStatement._left);
const initializerType = assignmentStatement.initializerType();
if (initializerType !== null) {
this.right = createInitializerTypeNode(this, initializerType);
this.isInitializedByType = true;
}
else {
if (assignmentStatement._right === undefined) {
throw new ASTBuildError('Failed to build `AssignmentStatement` node. Missing right part of the assignment.');
}
this.right = createExpressionNode(this, assignmentStatement._right);
this.isInitializedByType = false;
}
const assignmentOperator = assignmentStatement.assignmentOperator();
if (assignmentOperator !== null) {
if (assignmentOperator.OPERATOR_ARROWASSIGN() !== null) {
this.operator = AssignmentOperator['<=>'];
}
else if (assignmentOperator.OPERATOR_CONCATASSIGN() !== null) {
this.operator = AssignmentOperator['^='];
}
else if (assignmentOperator.OPERATOR_DIVIDEASSIGN() !== null) {
this.operator = AssignmentOperator['/='];
}
else if (assignmentOperator.OPERATOR_MINUSASSIGN() !== null) {
this.operator = AssignmentOperator['-='];
}
else if (assignmentOperator.OPERATOR_MODULOASSIGN() !== null) {
this.operator = AssignmentOperator['%='];
}
else if (assignmentOperator.OPERATOR_MULTIPLYASSIGN() !== null) {
this.operator = AssignmentOperator['*='];
}
else if (assignmentOperator.OPERATOR_PLUSASSIGN() !== null) {
this.operator = AssignmentOperator['+='];
}
else {
this.operator = AssignmentOperator['='];
}
}
else if (assignmentStatement.OPERATOR_ARROWASSIGN() !== null) {
this.operator = AssignmentOperator['<=>'];
}
else {
this.operator = AssignmentOperator['='];
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.left.visit(enterCb, exitCb);
this.right.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class ReturnStatement extends Node {
kind = Kind.ReturnStatement;
argument;
isReturningType;
constructor(parent, returnStatement) {
super(parent, returnStatement.start, returnStatement.stop);
this.isReturningType = false;
const initializerType = returnStatement.initializerType();
const returnExpression = returnStatement.expression();
if (initializerType !== null) {
this.argument = createInitializerTypeNode(this, initializerType);
this.isReturningType = true;
}
else if (returnExpression !== null) {
this.argument = createExpressionNode(this, returnExpression);
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.argument?.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class LabelStatement extends Node {
kind = Kind.LabelStatement;
isOverwrite;
name;
constructor(parent, labelStatement) {
super(parent, labelStatement.start, labelStatement.stop);
const labelInsert = labelStatement.labelInsert();
const labelOverwrite = labelStatement.labelOverwrite();
if (labelInsert !== null) {
this.isOverwrite = false;
this.name = new Identifier(this, labelInsert.IDENTIFIER().symbol);
}
else if (labelOverwrite !== null) {
this.isOverwrite = true;
this.name = new Identifier(this, labelOverwrite.IDENTIFIER().symbol);
}
else {
this.isOverwrite = false;
this.name = new InvalidIdentifier(this, labelStatement.start, labelStatement.stop);
}
}
visit(enterCb, exitCb) {
this.enter(enterCb);
this.name.visit(enterCb, exitCb);
this.exit(exitCb);
}
}
class AssertStatement extends Node {
kind = Kind.AssertStatement;
test;
message;
constructor(parent, assertStatement) {
super(parent, assertStatement.start, assertStatement.stop);
if (assertStatement._test === undefined) {
throw new ASTBuildError('Failed to build `AssertStatement` node. Missing assert test.');
}
this.test = createExpressionNode(this, assertStatement._test);
if (assertStatement._message !== undefined) {
this.message = createExpressionNode(this, assertStatement._mes