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); }
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)); } }
public OverloadParameterResult(IExpression value, object additionalData, VariableResolve refResolvedVariable, DocRange parameterRange) { Value = value; AdditionalData = additionalData; RefResolvedVariable = refResolvedVariable; ParameterRange = parameterRange; }
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); }
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); }
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); } }
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); } }
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); }
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; } } } }