コード例 #1
0
        public static ParameterBase[] GetParameters(ParsingData parser, ParameterDefineNode[] defineNodes)
        {
            ParameterBase[] parameters = new ParameterBase[defineNodes.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                EnumData    enumData = null;
                DefinedType type     = null;
                if (defineNodes[i].Type != null)
                {
                    enumData = EnumData.GetEnum(defineNodes[i].Type);
                    type     = parser.GetDefinedType(defineNodes[i].Type, null);

                    if (enumData == null && type == null)
                    {
                        throw SyntaxErrorException.NonexistentType(defineNodes[i].Type, defineNodes[i].Location);
                    }
                }

                if (enumData != null)
                {
                    parameters[i] = new EnumParameter(defineNodes[i].VariableName, enumData.Type);
                }

                else if (type != null)
                {
                    parameters[i] = new TypeParameter(defineNodes[i].VariableName, type);
                }

                else
                {
                    parameters[i] = new Parameter(defineNodes[i].VariableName, Elements.ValueType.Any, null);
                }
            }
            return(parameters);
        }
コード例 #2
0
        public ClassObjectResult CreateObject(ActionSet actionSet, string internalName)
        {
            var classReference = actionSet.VarCollection.Assign(internalName, actionSet.IsGlobal, true);

            DefinedType.GetClassIndex(classReference, actionSet, this);
            var classObject = ClassArray.CreateChild((Element)classReference.GetVariable());

            return(new ClassObjectResult(classReference, classObject));
        }
コード例 #3
0
        public DefinedType GetDefinedType(string name, Location location)
        {
            DefinedType type = DefinedTypes.FirstOrDefault(dt => dt.Name == name);

            if (type == null && location != null)
            {
                throw SyntaxErrorException.NonexistentType(name, location);
            }
            return(type);
        }
コード例 #4
0
        void Translate()
        {
            // Get the reserved variables and IDs
            foreach (ScriptFile script in ScriptFiles)
            {
                if (script.Context.reserved_global()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_global().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), true);
                    }
                    foreach (var id in script.Context.reserved_global().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), true, null, null);
                    }
                }
                if (script.Context.reserved_player()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_player().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), false);
                    }
                    foreach (var id in script.Context.reserved_player().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), false, null, null);
                    }
                }
            }

            // Get the enums
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var enumContext in script.Context.enum_define())
                {
                    var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext);
                    types.Add(newEnum);
                    definedTypes.Add(newEnum);
                }
            }

            // Get the types
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var typeContext in script.Context.type_define())
                {
                    var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext);
                    types.Add(newType);
                    definedTypes.Add(newType);
                }
            }

            // Get the methods and macros
            foreach (ScriptFile script in ScriptFiles)
            {
                // Get the methods.
                foreach (var methodContext in script.Context.define_method())
                {
                    var newMethod = new DefinedMethod(new ParseInfo(script, this), RulesetScope, RulesetScope, methodContext, null);
                }

                // Get the macros.
                foreach (var macroContext in script.Context.define_macro())
                {
                    GetMacro(new ParseInfo(script, this), RulesetScope, RulesetScope, macroContext);
                }
            }

            // Get the defined variables.
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var varContext in script.Context.define())
                {
                    Var newVar = new RuleLevelVariable(RulesetScope, new DefineContextHandler(new ParseInfo(script, this), varContext));
                    rulesetVariables.Add(newVar);

                    // Add the variable to the player variables scope if it is a player variable.
                    if (newVar.VariableType == VariableType.Player)
                    {
                        PlayerVariableScope.CopyVariable(newVar);
                    }
                }
            }

            foreach (var applyType in types)
            {
                if (applyType is ClassType classType)
                {
                    classType.ResolveElements();
                }
            }
            foreach (var apply in applyBlocks)
            {
                apply.SetupParameters();
            }
            foreach (var apply in applyBlocks)
            {
                apply.SetupBlock();
            }
            foreach (var apply in applyBlocks)
            {
                apply.CallInfo?.CheckRecursion();
            }

            // Get the rules
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var ruleContext in script.Context.ow_rule())
                {
                    rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext));
                }
            }
        }
コード例 #5
0
        void Translate()
        {
            List <IApplyBlock> applyMethods = new List <IApplyBlock>();

            // Get the reserved variables and IDs
            foreach (ScriptFile script in ScriptFiles)
            {
                if (script.Context.reserved_global()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_global().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), true);
                    }
                    foreach (var id in script.Context.reserved_global().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), true, null, null);
                    }
                }
                if (script.Context.reserved_player()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_player().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), false);
                    }
                    foreach (var id in script.Context.reserved_player().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), false, null, null);
                    }
                }
            }

            // Get the enums
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var enumContext in script.Context.enum_define())
                {
                    var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext);
                    types.Add(newEnum);
                    definedTypes.Add(newEnum);
                }
            }

            // Get the types
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var typeContext in script.Context.type_define())
                {
                    var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext, applyMethods);
                    types.Add(newType);
                    definedTypes.Add(newType);
                }
            }

            // Get the methods and macros
            foreach (ScriptFile script in ScriptFiles)
            {
                // Get the methods.
                foreach (var methodContext in script.Context.define_method())
                {
                    var newMethod = new DefinedMethod(new ParseInfo(script, this), RulesetScope, methodContext);
                    applyMethods.Add(newMethod);
                    //RulesetScope.AddMethod(newMethod, script.Diagnostics, DocRange.GetRange(methodContext.name));
                }

                // Get the macros.
                foreach (var macroContext in script.Context.define_macro())
                {
                    GetMacro(new ParseInfo(script, this), RulesetScope, macroContext, applyMethods);
                }
            }

            // Get the defined variables.
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var varContext in script.Context.define())
                {
                    var newVar = Var.CreateVarFromContext(VariableDefineType.RuleLevel, new ParseInfo(script, this), varContext);
                    newVar.Finalize(RulesetScope);
                    rulesetVariables.Add(newVar);
                    // Add the variable to the player variables scope if it is a player variable.
                    if (newVar.VariableType == VariableType.Player)
                    {
                        PlayerVariableScope.AddVariable(newVar, null, null);
                    }
                }
            }

            foreach (var apply in applyMethods)
            {
                apply.SetupBlock();
            }
            foreach (var apply in applyMethods)
            {
                apply.CallInfo.CheckRecursion();
            }

            // Get the rules
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var ruleContext in script.Context.ow_rule())
                {
                    rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext));
                }
            }
        }
コード例 #6
0
        private void GetObjects(RulesetNode rulesetNode, string file, TranslateRule globalTranslate, TranslateRule playerTranslate)
        {
            string absolute = new Uri(file).AbsolutePath;

            // Get the defined types
            foreach (var definedType in rulesetNode.DefinedTypes)
            {
                try
                {
                    if (DefinedTypes.Any(type => type.Name == definedType.Name))
                    {
                        throw SyntaxErrorException.NameAlreadyDefined(definedType.Location);
                    }
                    DefinedTypes.Add(DefinedType.GetDefinedType(definedType));
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            // Get the user methods.
            for (int i = 0; i < rulesetNode.UserMethods.Length; i++)
            {
                try
                {
                    UserMethods.Add(UserMethod.CreateUserMethod(Root, rulesetNode.UserMethods[i]));
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            // Get the rules
            RuleNodes.AddRange(rulesetNode.Rules);

            List <string> importedFiles = new List <string>();

            foreach (ImportObjectNode importObject in rulesetNode.ObjectImports)
            {
                try
                {
                    Importer importer = new Importer(Diagnostics, importedFiles, importObject.File, file, importObject.Location);
                    if (!importer.AlreadyImported)
                    {
                        importedFiles.Add(importer.ResultingPath);
                        switch (importer.FileType)
                        {
                        case ".obj":
                            importer.FileData.Update();
                            string content  = importer.FileData.Content;
                            Model  newModel = Model.ImportObj(content);
                            new ModelVar(importObject.Name, Root, importObject, newModel);
                            break;

                        case ".pathmap":
                            PathMap pathMap = PathMap.ImportFromXML(importer.ResultingPath);
                            new PathMapVar(this, importObject.Name, Root, importObject, pathMap);
                            break;
                        }
                    }
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            // Get the variables
            foreach (var definedVar in rulesetNode.DefinedVars)
            {
                try
                {
                    IndexedVar var;

                    if (!definedVar.Extended)
                    {
                        if (definedVar.OverrideID == -1)
                        {
                            var = IndexedVar.AssignVar(VarCollection, Root, definedVar.VariableName, definedVar.IsGlobal, definedVar);
                        }
                        else
                        {
                            var = IndexedVar.AssignVar(
                                VarCollection,
                                Root,
                                definedVar.VariableName,
                                definedVar.IsGlobal,
                                new WorkshopVariable(definedVar.IsGlobal, definedVar.OverrideID, VarCollection.WorkshopNameFromCodeName(definedVar.IsGlobal, definedVar.VariableName)),
                                definedVar
                                );
                        }
                    }
                    else
                    {
                        var = IndexedVar.AssignVarExt(VarCollection, Root, definedVar.VariableName, definedVar.IsGlobal, definedVar);
                    }


                    if (definedVar.Type != null)
                    {
                        var.Type = GetDefinedType(definedVar.Type, definedVar.Location);
                    }
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }
        }
コード例 #7
0
        void Translate()
        {
            // Get the reserved variables and IDs
            // foreach (ScriptFile script in Importer.ScriptFiles)
            // {
            //     if (script.Context.reserved_global()?.reserved_list() != null)
            //     {
            //         foreach (var name in script.Context.reserved_global().reserved_list().PART()) VarCollection.Reserve(name.GetText(), true);
            //         foreach (var id in script.Context.reserved_global().reserved_list().NUMBER()) VarCollection.Reserve(int.Parse(id.GetText()), true, null, null);
            //     }
            //     if (script.Context.reserved_player()?.reserved_list() != null)
            //     {
            //         foreach (var name in script.Context.reserved_player().reserved_list().PART()) VarCollection.Reserve(name.GetText(), false);
            //         foreach (var id in script.Context.reserved_player().reserved_list().NUMBER()) VarCollection.Reserve(int.Parse(id.GetText()), false, null, null);
            //     }
            // }

            // Get the enums
            foreach (ScriptFile script in Importer.ScriptFiles)
            {
                foreach (var enumContext in script.Context.Enums)
                {
                    var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext);
                    Types.AllTypes.Add(newEnum);
                    Types.DefinedTypes.Add(newEnum);
                    Types.CalledTypes.Add(newEnum);
                }
            }

            // Get the types
            foreach (ScriptFile script in Importer.ScriptFiles)
            {
                foreach (var typeContext in script.Context.Classes)
                {
                    var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext);
                    Types.AllTypes.Add(newType);
                    Types.DefinedTypes.Add(newType);
                    Types.CalledTypes.Add(newType);
                }
            }

            // Get the declarations
            foreach (ScriptFile script in Importer.ScriptFiles)
            {
                ParseInfo parseInfo = new ParseInfo(script, this);

                // Get the functions.
                foreach (var declaration in script.Context.Declarations)
                {
                    // Function
                    if (declaration is FunctionContext function)
                    {
                        new DefinedMethod(parseInfo, RulesetScope, RulesetScope, function, null);
                    }
                    // Macro function
                    else if (declaration is MacroFunctionContext macroFunction)
                    {
                        parseInfo.GetMacro(RulesetScope, RulesetScope, macroFunction);
                    }
                    // Macro var
                    else if (declaration is MacroVarDeclaration macroVar)
                    {
                        parseInfo.GetMacro(RulesetScope, RulesetScope, macroVar);
                    }
                    // Variables
                    else if (declaration is VariableDeclaration variable)
                    {
                        Var newVar = new RuleLevelVariable(RulesetScope, new DefineContextHandler(new ParseInfo(script, this), variable));
                        rulesetVariables.Add(newVar);

                        // Add the variable to the player variables scope if it is a player variable.
                        if (newVar.VariableType == VariableType.Player)
                        {
                            PlayerVariableScope.CopyVariable(newVar);
                        }
                    }
                }
            }

            foreach (var applyType in Types.AllTypes)
            {
                if (applyType is ClassType classType)
                {
                    classType.ResolveElements();
                }
            }
            foreach (var apply in _applyBlocks)
            {
                apply.SetupParameters();
            }
            foreach (var apply in _applyBlocks)
            {
                apply.SetupBlock();
            }
            foreach (var callInfo in _recursionCheck)
            {
                callInfo.CheckRecursion();
            }

            // Get hooks
            foreach (ScriptFile script in Importer.ScriptFiles)
            {
                foreach (var hookContext in script.Context.Hooks)
                {
                    HookVar.GetHook(new ParseInfo(script, this), RulesetScope, hookContext);
                }
            }

            // Get the rules
            foreach (ScriptFile script in Importer.ScriptFiles)
            {
                foreach (var ruleContext in script.Context.Rules)
                {
                    rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext));
                }
            }
        }
コード例 #8
0
        private void GetObjects(string document, string file, TranslateRule globalTranslate, TranslateRule playerTranslate, bool isRoot)
        {
            // If this file was already loaded, don't load it again.
            if (Imported.Contains(file))
            {
                return;
            }
            Imported.Add(file);
            Diagnostics.AddFile(file);

            // Get the ruleset.
            RulesetNode ruleset = GetRuleset(file, document);

            Rulesets.Add(file, ruleset);

            if (ruleset != null && !Diagnostics.ContainsErrors())
            {
                if (isRoot)
                {
                    VarCollection = new VarCollection(ruleset.UseGlobalVar, ruleset.UsePlayerVar, ruleset.UseBuilderVar);
                    Root          = new ScopeGroup(VarCollection);
                }

                // Get the defined types
                foreach (var definedType in ruleset.DefinedTypes)
                {
                    try
                    {
                        if (DefinedTypes.Any(type => type.Name == definedType.Name))
                        {
                            throw SyntaxErrorException.NameAlreadyDefined(definedType.Location);
                        }
                        DefinedTypes.Add(DefinedType.GetDefinedType(definedType));
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Get the user methods.
                for (int i = 0; i < ruleset.UserMethods.Length; i++)
                {
                    try
                    {
                        UserMethods.Add(new UserMethod(Root, ruleset.UserMethods[i]));
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Get the rules
                RuleNodes.AddRange(ruleset.Rules);

                List <string> importedFiles = new List <string>();

                foreach (ImportObjectNode importObject in ruleset.ObjectImports)
                {
                    try
                    {
                        Importer importer = new Importer(Diagnostics, importedFiles, importObject.File, file, importObject.Location);
                        if (!importer.AlreadyImported)
                        {
                            importedFiles.Add(importer.ResultingPath);
                            string content = importer.GetFile();
                            switch (importer.FileType)
                            {
                            case ".obj":
                                Model newModel = Model.ImportObj(content);
                                new ModelVar(importObject.Name, Root, importObject, newModel);
                                break;
                            }
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Check the imported files.
                foreach (ImportNode importNode in ruleset.Imports)
                {
                    try
                    {
                        Importer importer = new Importer(Diagnostics, importedFiles, importNode.File, file, importNode.Location);
                        if (!importer.AlreadyImported)
                        {
                            string content = File.ReadAllText(importer.ResultingPath);
                            GetObjects(content, importer.ResultingPath, globalTranslate, playerTranslate, false);
                            importedFiles.Add(importer.ResultingPath);
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Get the variables
                foreach (var definedVar in ruleset.DefinedVars)
                {
                    try
                    {
                        IndexedVar var;
                        if (definedVar.UseVar == null)
                        {
                            var = VarCollection.AssignVar(Root, definedVar.VariableName, definedVar.IsGlobal, definedVar);
                        }
                        else
                        {
                            var = VarCollection.AssignVar(
                                Root,
                                definedVar.VariableName,
                                definedVar.IsGlobal,
                                definedVar.UseVar.Variable,
                                definedVar.UseVar.Index,
                                definedVar
                                );
                        }
                        if (definedVar.Type != null)
                        {
                            var.Type = GetDefinedType(definedVar.Type, definedVar.Location);
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }
            }
        }
コード例 #9
0
        public Element ParseExpression(ScopeGroup getter, ScopeGroup scope, Node expression)
        {
            switch (expression)
            {
            // Math and boolean operations.
            case OperationNode operationNode:
            {
                Element left  = ParseExpression(getter, scope, operationNode.Left);
                Element right = ParseExpression(getter, scope, operationNode.Right);

                /*
                 * if (Constants.BoolOperations.Contains(operationNode.Operation))
                 * {
                 *  if (left.ElementData.ValueType != Elements.ValueType.Any && left.ElementData.ValueType != Elements.ValueType.Boolean)
                 *      throw new SyntaxErrorException($"Expected boolean, got {left .ElementData.ValueType.ToString()} instead.", ((Node)operationNode.Left).Range);
                 *
                 *  if (right.ElementData.ValueType != Elements.ValueType.Any && right.ElementData.ValueType != Elements.ValueType.Boolean)
                 *      throw new SyntaxErrorException($"Expected boolean, got {right.ElementData.ValueType.ToString()} instead.", ((Node)operationNode.Right).Range);
                 * }
                 */

                switch (operationNode.Operation)
                {
                // Math: ^, *, %, /, +, -
                case "^":
                    return(Element.Part <V_RaiseToPower>(left, right));

                case "*":
                    return(left * right);

                case "%":
                    return(left % right);

                case "/":
                    return(left / right);

                case "+":
                    return(left + right);

                case "-":
                    return(left - right);


                // BoolCompare: &&, ||
                case "&&":
                    return(Element.Part <V_And>(left, right));

                case "||":
                    return(Element.Part <V_Or>(left, right));

                // Compare: <, <=, ==, >=, >, !=
                case "<":
                    return(left < right);

                case "<=":
                    return(left <= right);

                case "==":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.Equal), right));

                case ">=":
                    return(left >= right);

                case ">":
                    return(left > right);

                case "!=":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.NotEqual), right));
                }

                throw new Exception($"Operation {operationNode.Operation} not implemented.");
            }

            // Number
            case NumberNode numberNode:
                return(numberNode.Value);

            // Bool
            case BooleanNode boolNode:
                if (boolNode.Value)
                {
                    return(new V_True());
                }
                else
                {
                    return(new V_False());
                }

            // Not operation
            case NotNode notNode:
                return(!(ParseExpression(getter, scope, notNode.Value)));

            case InvertNode invertNode:
                return(-ParseExpression(getter, scope, invertNode.Value));

            // Strings
            case StringNode stringNode:

                Element[] stringFormat = new Element[stringNode.Format?.Length ?? 0];
                for (int i = 0; i < stringFormat.Length; i++)
                {
                    stringFormat[i] = ParseExpression(getter, scope, stringNode.Format[i]);
                }
                if (stringNode.Localized)
                {
                    return(V_String.ParseString(stringNode.Location, stringNode.Value, stringFormat));
                }
                else
                {
                    return(V_CustomString.ParseString(stringNode.Location, stringNode.Value, stringFormat));
                }

            // Null
            case NullNode nullNode:
                return(new V_Null());

            // TODO check if groups need to be implemented here

            // Methods
            case MethodNode methodNode:
                return(ParseMethod(getter, scope, methodNode, true));

            // Variable
            case VariableNode variableNode:

                Element[] index = new Element[variableNode.Index.Length];
                for (int i = 0; i < index.Length; i++)
                {
                    index[i] = ParseExpression(getter, scope, variableNode.Index[i]);
                }

                Var var = scope.GetVar(getter, variableNode.Name, variableNode.Location);
                if (!var.Gettable())
                {
                    throw SyntaxErrorException.VariableIsReadonly(var.Name, variableNode.Location);
                }

                Element result = var.GetVariable();
                for (int i = 0; i < index.Length; i++)
                {
                    result = Element.Part <V_ValueInArray>(result, index[i]);
                }

                return(result);

            // Get value in array
            case ValueInArrayNode viaNode:
                return(Element.Part <V_ValueInArray>(ParseExpression(getter, scope, viaNode.Value), ParseExpression(getter, scope, viaNode.Index)));

            // Create array
            case CreateArrayNode createArrayNode:
            {
                Element prev    = null;
                Element current = null;

                for (int i = 0; i < createArrayNode.Values.Length; i++)
                {
                    current = new V_Append()
                    {
                        ParameterValues = new IWorkshopTree[2]
                    };

                    if (prev != null)
                    {
                        current.ParameterValues[0] = prev;
                    }
                    else
                    {
                        current.ParameterValues[0] = new V_EmptyArray();
                    }

                    current.ParameterValues[1] = ParseExpression(getter, scope, createArrayNode.Values[i]);
                    prev = current;
                }

                return(current ?? new V_EmptyArray());
            }

            // Ternary Conditional (a ? b : c)
            case TernaryConditionalNode ternaryNode:
                return(Element.TernaryConditional
                       (
                           ParseExpression(getter, scope, ternaryNode.Condition),
                           ParseExpression(getter, scope, ternaryNode.Consequent),
                           ParseExpression(getter, scope, ternaryNode.Alternative)
                       ));

            // Enums
            case EnumNode enumNode:
                return(EnumData.ToElement(enumNode.EnumMember)
                       ?? throw SyntaxErrorException.EnumCantBeValue(enumNode.Type, enumNode.Location));

            // New object
            case CreateObjectNode createObjectNode:
                DefinedType typeData = ParserData.GetDefinedType(createObjectNode.TypeName, createObjectNode.Location);
                return(typeData.New(createObjectNode, getter, scope, this));

            // Expression tree
            case ExpressionTreeNode expressionTree:
                return(new ParseExpressionTree(this, getter, scope, expressionTree).ResultingElement);

            // This
            case ThisNode thisNode:
                return(getter.GetThis(thisNode.Location));

            // Type convert
            case TypeConvertNode typeConvertNode:
                DefinedType type    = ParserData.GetDefinedType(typeConvertNode.Type, typeConvertNode.Location);
                Element     element = ParseExpression(getter, scope, typeConvertNode.Expression);
                type.GetSource(this, element, typeConvertNode.Location);
                return(element);

            case RootNode rootNode: throw new SyntaxErrorException("'root' cannot be used like an expression.", rootNode.Location);
            }

            throw new Exception();
        }