예제 #1
0
        public override object Validate(ParseInfo parseInfo, IExpression value, DocRange valueRange)
        {
            VariableResolve resolvedVariable = new VariableResolve(Options, value, valueRange, parseInfo.Script.Diagnostics);

            // Syntax error if the expression is not a variable.
            if (!resolvedVariable.DoesResolveToVariable)
            {
                parseInfo.Script.Diagnostics.Error("Expected a variable.", valueRange);
            }

            else if (VariableType != VariableType.Dynamic && resolvedVariable.SetVariable.Calling.VariableType != VariableType)
            {
                if (VariableType == VariableType.Global)
                {
                    parseInfo.Script.Diagnostics.Error($"Expected a global variable.", valueRange);
                }
                else
                {
                    parseInfo.Script.Diagnostics.Error($"Expected a player variable.", valueRange);
                }
            }

            else
            {
                return(resolvedVariable);
            }
            return(null);
        }
예제 #2
0
        public static void GetHook(ParseInfo parseInfo, Scope scope, DeltinScriptParser.HookContext context)
        {
            // Get the hook variable's expression.
            IExpression variableExpression = parseInfo.GetExpression(scope, context.var);

            // Get the hook value.
            IExpression valueExpression = parseInfo.GetExpression(scope, context.value);

            // Resolve the variable.
            VariableResolve resolvedVariable = new VariableResolve(new VariableResolveOptions()
            {
                // Not indexable
                CanBeIndexed = false,
                // Hook variables are not settable.
                ShouldBeSettable = false
            }, variableExpression, DocRange.GetRange(context.var), parseInfo.Script.Diagnostics);

            if (valueExpression == null)
            {
                return;
            }

            // Check if the resolved variable is a HookVar.
            if (resolvedVariable.SetVariable?.Calling is HookVar hookVar)
            {
                // If it is, set the hook.
                hookVar.TrySet(parseInfo, valueExpression, DocRange.GetRange(context.value));
            }
            else
            {
                // Not a hook variable.
                parseInfo.Script.Diagnostics.Error("Expected a hook variable.", DocRange.GetRange(context.var));
            }
        }
예제 #3
0
 public OverloadParameterResult(IExpression value, object additionalData, VariableResolve refResolvedVariable, DocRange parameterRange)
 {
     Value               = value;
     AdditionalData      = additionalData;
     RefResolvedVariable = refResolvedVariable;
     ParameterRange      = parameterRange;
 }
예제 #4
0
        public SetVariableAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.VarsetContext varsetContext)
        {
            IExpression variableExpression = parseInfo.GetExpression(scope, varsetContext.var);

            // Get the variable being set.
            VariableResolve = new VariableResolve(new VariableResolveOptions(), variableExpression, DocRange.GetRange(varsetContext), parseInfo.Script.Diagnostics);

            // Get the operation.
            if (varsetContext.statement_operation() != null)
            {
                Operation = varsetContext.statement_operation().GetText();

                // If there is no value, syntax error.
                if (varsetContext.val == null)
                {
                    parseInfo.Script.Diagnostics.Error("Expected an expression.", DocRange.GetRange(varsetContext).end.ToRange());
                }

                // Parse the value.
                else
                {
                    Value = parseInfo.GetExpression(scope, varsetContext.val);
                }
            }
            else if (varsetContext.INCREMENT() != null)
            {
                Operation = "++";
            }
            else if (varsetContext.DECREMENT() != null)
            {
                Operation = "--";
            }
        }
        public override IWorkshopTree Parse(ActionSet actionSet, IExpression expression, object additionalParameterData, bool asElement)
        {
            return(null);

            VariableResolve resolvedVariable = (VariableResolve)additionalParameterData;

            return(((IndexReference)actionSet.IndexAssigner[resolvedVariable.SetVariable.Calling]).WorkshopVariable);
        }
        public IncrementAction(ParseInfo parseInfo, Scope scope, Increment increment)
        {
            _decrement = increment.Decrement;

            // Get the variable.
            IExpression variableExpr = parseInfo.GetExpression(scope, increment.VariableExpression);

            _resolve = new VariableResolve(new VariableResolveOptions(), variableExpr, increment.VariableExpression.Range, parseInfo.Script.Diagnostics);
        }
예제 #7
0
        public override void Translate(ActionSet actionSet)
        {
            WorkshopVariable variable;
            Element          target;
            Element          start;

            // Existing variable being used in for.
            if (VariableResolve != null)
            {
                VariableElements elements = VariableResolve.ParseElements(actionSet);
                variable = elements.IndexReference.WorkshopVariable;
                target   = elements.Target;
                start    = (Element)InitialResolveValue?.Parse(actionSet) ?? new V_Number(0);
            }
            // New variable being use in for.
            else
            {
                actionSet.IndexAssigner.Add(actionSet.VarCollection, DefinedVariable, actionSet.IsGlobal, null);
                variable = ((IndexReference)actionSet.IndexAssigner[DefinedVariable]).WorkshopVariable;
                target   = new V_EventPlayer();
                start    = (Element)DefinedVariable.InitialValue?.Parse(actionSet) ?? new V_Number(0);
            }

            Element stop = (Element)Stop.Parse(actionSet);
            Element step = (Element)Step.Parse(actionSet);

            // Global
            if (variable.IsGlobal)
            {
                actionSet.AddAction(Element.Part <A_ForGlobalVariable>(
                                        variable,
                                        start, stop, step
                                        ));
            }
            // Player
            else
            {
                actionSet.AddAction(Element.Part <A_ForPlayerVariable>(
                                        target,
                                        variable,
                                        start, stop, step
                                        ));
            }

            // Translate the block.
            Block.Translate(actionSet.Indent());

            // Resolve continues.
            ResolveContinues(actionSet);

            // Cap the for.
            actionSet.AddAction(new A_End());

            // Resolve breaks.
            ResolveBreaks(actionSet);
        }
        public SetVariableAction(ParseInfo parseInfo, Scope scope, Assignment assignmentContext)
        {
            IExpression variableExpression = parseInfo.GetExpression(scope, assignmentContext.VariableExpression);

            // Get the variable being set.
            VariableResolve = new VariableResolve(new VariableResolveOptions(), variableExpression, assignmentContext.VariableExpression.Range, parseInfo.Script.Diagnostics);

            // Get the operation.
            Operation = assignmentContext.AssignmentToken;

            Value = parseInfo.GetExpression(scope, assignmentContext.Value);
        }
예제 #9
0
        public void Translate(ActionSet actionSet)
        {
            VariableElements elements = VariableResolve.ParseElements(actionSet);

            Element value = null;

            if (Value != null)
            {
                value = (Element)Value.Parse(actionSet);
            }

            Elements.Operation?modifyOperation = null;
            switch (Operation)
            {
            case "=": break;

            case "^=": modifyOperation = Elements.Operation.RaiseToPower; break;

            case "*=": modifyOperation = Elements.Operation.Multiply;     break;

            case "/=": modifyOperation = Elements.Operation.Divide;       break;

            case "%=": modifyOperation = Elements.Operation.Modulo;       break;

            case "+=": modifyOperation = Elements.Operation.Add;          break;

            case "-=": modifyOperation = Elements.Operation.Subtract;     break;

            case "++": value = 1; modifyOperation = Elements.Operation.Add;      break;

            case "--": value = 1; modifyOperation = Elements.Operation.Subtract; break;

            default: throw new Exception($"Unknown operation {Operation}.");
            }

            if (modifyOperation == null)
            {
                actionSet.AddAction(elements.IndexReference.SetVariable(value, elements.Target, elements.Index));
            }
            else
            {
                actionSet.AddAction(elements.IndexReference.ModifyVariable((Elements.Operation)modifyOperation, value, elements.Target, elements.Index));
            }
        }
        public SetVariableAction(ParseInfo parseInfo, Scope scope, Assignment assignmentContext)
        {
            // Get the variable expression.
            IExpression variableExpression = parseInfo.GetExpression(scope, assignmentContext.VariableExpression);

            // Extract the variable data.
            _variableResolve = new VariableResolve(parseInfo, new VariableResolveOptions()
            {
                ShouldBeSettable = true
            }, variableExpression, assignmentContext.VariableExpression.Range);

            // Get the value.
            _value = parseInfo.SetExpectType(_variableResolve.SetVariable?.Type()).GetExpression(scope, assignmentContext.Value);

            // Get the operation.
            Token              assignmentToken = assignmentContext.AssignmentToken;
            CodeType           variableType = variableExpression.Type(), valueType = _value.Type();
            AssignmentOperator op = AssignmentOperation.OperatorFromTokenType(assignmentToken.TokenType);

            _operation = variableType.Operations.GetOperation(op, valueType);

            // No operators exist for the variable and value pair.
            if (_operation == null)
            {
                // If the variable type is any, use default operation.
                if (assignmentToken.TokenType == TokenType.Equal && variableType.Operations.DefaultAssignment && TypeComparison.IsAny(parseInfo.Types, variableType))
                {
                    _operation = new AssignmentOperation(op, parseInfo.Types.Any());
                }
                // Otherwise, add an error.
                else
                {
                    parseInfo.Script.Diagnostics.Error("Operator '" + assignmentToken.Text + "' cannot be applied to the types '" + variableType.GetNameOrAny() + "' and '" + valueType.GetNameOrAny() + "'.", assignmentToken.Range);
                }
            }
        }
        public static void GetHook(ParseInfo parseInfo, Scope scope, Hook context)
        {
            parseInfo = parseInfo.SetCallInfo(new CallInfo(parseInfo.Script));

            // Get the hook variable's expression.
            IExpression variableExpression = parseInfo.GetExpression(scope, context.Variable);

            // Resolve the variable.
            VariableResolve resolvedVariable = new VariableResolve(parseInfo, new VariableResolveOptions()
            {
                // Not indexable
                CanBeIndexed = false,
                // Hook variables are not settable.
                ShouldBeSettable = false
            }, variableExpression, context.Variable.Range);

            // Check if the resolved variable is a HookVar.
            if (resolvedVariable.SetVariable?.Calling is HookVar hookVar)
            {
                // Get the hook value.
                IExpression valueExpression = parseInfo.SetExpectType(hookVar.CodeType.GetCodeType(parseInfo.TranslateInfo)).GetExpression(scope, context.Value);

                if (valueExpression == null)
                {
                    return;
                }

                // If it is, set the hook.
                hookVar.TrySet(parseInfo, valueExpression, context.Value.Range);
            }
            else
            {
                // Not a hook variable.
                parseInfo.Script.Diagnostics.Error("Expected a hook variable.", context.Variable.Range);
            }
        }
예제 #12
0
        public AutoForAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.For_autoContext autoForContext)
        {
            RawContinue = true;

            // Get the auto-for variable. (Required)
            if (autoForContext.forVariable != null)
            {
                IExpression variable = parseInfo.GetExpression(scope, autoForContext.forVariable);

                // Get the variable being set.
                VariableResolve = new VariableResolve(new VariableResolveOptions()
                {
                    // The for cannot be indexed and should be on the rule-level.
                    CanBeIndexed = false,
                    FullVariable = true
                }, variable, DocRange.GetRange(autoForContext.forVariable), parseInfo.Script.Diagnostics);

                if (autoForContext.EQUALS() != null)
                {
                    if (autoForContext.start == null)
                    {
                        parseInfo.Script.Diagnostics.Error("Expected expression.", DocRange.GetRange(autoForContext.EQUALS()));
                    }
                    else
                    {
                        InitialResolveValue = parseInfo.GetExpression(scope, autoForContext.start);
                    }
                }
            }
            // Get the defined variable.
            else if (autoForContext.forDefine != null)
            {
                DefinedVariable = new AutoForVariable(scope, new DefineContextHandler(parseInfo, autoForContext.forDefine));
            }
            else
            {
                parseInfo.Script.Diagnostics.Error("Expected define or variable.", DocRange.GetRange(autoForContext.FOR()));
            }

            // Get the auto-for end. (Required)
            if (autoForContext.stop == null)
            {
                parseInfo.Script.Diagnostics.Error("Expected end expression.", DocRange.GetRange(autoForContext.startSep));
            }
            else
            {
                Stop = parseInfo.GetExpression(scope, autoForContext.stop);
            }

            // Get the auto-for step. (Not Required)
            if (autoForContext.step == null)
            {
                Step = new ExpressionOrWorkshopValue(new V_Number(1));
            }
            else
            {
                Step = new ExpressionOrWorkshopValue(parseInfo.GetExpression(scope, autoForContext.step));
            }

            // Get the block.
            if (autoForContext.block() == null)
            {
                parseInfo.Script.Diagnostics.Error("Missing block.", DocRange.GetRange(autoForContext.RIGHT_PAREN()));
            }
            else
            {
                Block = new BlockAction(parseInfo.SetLoop(this), scope, autoForContext.block());
                Path  = new PathInfo(Block, DocRange.GetRange(autoForContext.block()), false);
            }
        }
예제 #13
0
        public ForAction(ParseInfo parseInfo, Scope scope, For forContext)
        {
            Scope varScope = scope.Child();

            IsAutoFor = forContext.Iterator is ExpressionStatement;

            // Get the initializer.
            if (!IsAutoFor)
            {
                // Normal for loop initializer.
                if (forContext.Initializer != null)
                {
                    // Declaration for initializer.
                    if (forContext.Initializer is VariableDeclaration declaration)
                    {
                        DefinedVariable = new ScopedVariable(varScope, new DefineContextHandler(parseInfo, declaration));
                    }
                    // Variable assignment for initializer
                    else if (forContext.Initializer is Assignment assignment)
                    {
                        Initializer = new SetVariableAction(parseInfo, varScope, assignment);
                    }

                    // TODO: Throw error on incorrect initializer type.
                }
            }
            else
            {
                // Auto-for initializer.
                // Missing initializer.
                if (forContext.Initializer == null)
                {
                    // Error if there is no initializer.
                    if (forContext.InitializerSemicolon)
                    {
                        parseInfo.Script.Diagnostics.Error("Auto-for loops require an initializer.", forContext.InitializerSemicolon.Range);
                    }
                }
                // Declaration
                else if (forContext.Initializer is VariableDeclaration declaration)
                {
                    DefinedVariable = new ScopedVariable(varScope, new DefineContextHandler(parseInfo, declaration));
                }
                // Assignment
                else if (forContext.Initializer is Assignment assignment)
                {
                    // Get the variable being set.
                    VariableResolve = new VariableResolve(new VariableResolveOptions()
                    {
                        // The for cannot be indexed and should be on the rule-level.
                        CanBeIndexed = false,
                        FullVariable = true
                    }, parseInfo.GetExpression(varScope, assignment.VariableExpression), assignment.VariableExpression.Range, parseInfo.Script.Diagnostics);

                    InitialResolveValue = parseInfo.GetExpression(scope, assignment.Value);
                }
                // Variable
                else if (forContext.Initializer is ExpressionStatement exprStatement && exprStatement.Expression is Identifier identifier)
                {
                    // The variable is defined but no start value was given. In this case, just start at 0.
                    // Get the variable.
                    VariableResolve = new VariableResolve(new VariableResolveOptions()
                    {
                        // The for cannot be indexed and should be on the rule-level.
                        CanBeIndexed = false,
                        FullVariable = true
                    }, parseInfo.GetExpression(varScope, identifier), identifier.Range, parseInfo.Script.Diagnostics);
                }
예제 #14
0
        public void Translate(ActionSet actionSet)
        {
            VariableElements elements = VariableResolve.ParseElements(actionSet);

            Element value = null;

            if (Value != null)
            {
                value = (Element)Value.Parse(actionSet);
            }

            Elements.Operation?modifyOperation = null;
            switch (Operation)
            {
            case "=": break;

            case "^=": modifyOperation = Elements.Operation.RaiseToPower; break;

            case "*=": modifyOperation = Elements.Operation.Multiply;     break;

            case "/=": modifyOperation = Elements.Operation.Divide;       break;

            case "%=": modifyOperation = Elements.Operation.Modulo;       break;

            case "+=": modifyOperation = Elements.Operation.Add;          break;

            case "-=": modifyOperation = Elements.Operation.Subtract;     break;

            case "++": value = 1; modifyOperation = Elements.Operation.Add;      break;

            case "--": value = 1; modifyOperation = Elements.Operation.Subtract; break;

            default: throw new Exception($"Unknown operation {Operation}.");
            }

            // The actions used to set the variable.
            Element[] actions;

            // Set Variable actions
            if (modifyOperation == null)
            {
                actions = elements.IndexReference.SetVariable(value, elements.Target, elements.Index);
            }
            // Modify Variable actions
            else
            {
                actions = elements.IndexReference.ModifyVariable((Elements.Operation)modifyOperation, value, elements.Target, elements.Index);
            }

            // Add the actions to the action set.
            actionSet.AddAction(actions);

            // Set action comments
            if (Comment != null)
            {
                // If there is just one action used to set or modify the variable, set that action's comment.
                if (actions.Length == 1)
                {
                    actions[0].Comment = Comment;
                }
                // If multiple actions are required, precede the comment with (#) where # is the order of the relevent action.
                else
                {
                    for (int i = 0; i < actions.Length; i++)
                    {
                        actions[i].Comment = "(" + i + ") " + Comment;
                    }
                }
            }
        }