public ScopeGroup GetRootScope(IndexedVar var, ParsingData parseData, Element target = null) { if (target == null) { target = new V_EventPlayer(); } IndexedVar root = GetRoot(var, parseData, target); root.DefaultTarget = target; ScopeGroup typeScope = new ScopeGroup(parseData.VarCollection); typeScope.This = root; for (int i = 0; i < DefinedVars.Length; i++) { IndexedVar newVar = root.CreateChild(typeScope, DefinedVars[i].VariableName, Element.IntToElement(i), DefinedVars[i]); newVar.DefaultTarget = target; if (DefinedVars[i].Type != null) { newVar.Type = parseData.GetDefinedType(DefinedVars[i].Type, DefinedVars[i].Location); } newVar.AccessLevel = DefinedVars[i].AccessLevel; } for (int i = 0; i < MethodNodes.Length; i++) { UserMethod method = new UserMethod(typeScope, MethodNodes[i]); method.RegisterParameters(parseData); method.AccessLevel = MethodNodes[i].AccessLevel; } return(typeScope); }
public ScopeGroup GetRootScope(IndexedVar var, ParsingData parseData) { ScopeGroup typeScope = new ScopeGroup(parseData.VarCollection); typeScope.This = var; for (int i = 0; i < DefinedVars.Length; i++) { IndexedVar newVar = var.CreateChild(typeScope, DefinedVars[i].VariableName, new int[] { i }, DefinedVars[i]); if (DefinedVars[i].Type != null) { newVar.Type = parseData.GetDefinedType(DefinedVars[i].Type, DefinedVars[i].Location); } newVar.AccessLevel = DefinedVars[i].AccessLevel; } for (int i = 0; i < MethodNodes.Length; i++) { UserMethod method = new UserMethod(typeScope, MethodNodes[i]); method.RegisterParameters(parseData); method.AccessLevel = MethodNodes[i].AccessLevel; } return(typeScope); }
void ParseStatement(ScopeGroup getter, ScopeGroup scope, Node statement, IndexedVar returnVar) { switch (statement) { // Method case MethodNode methodNode: Element method = ParseMethod(getter, scope, methodNode, false); return; // Variable set case VarSetNode varSetNode: ParseVarset(getter, scope, varSetNode); return; // Foreach case ForEachNode forEachNode: { ContinueSkip.Setup(); ScopeGroup forGroup = scope.Child(); Element array = ParseExpression(getter, scope, forEachNode.Array); IndexedVar index = IndexedVar.AssignInternalVarExt(VarCollection, scope, $"'{forEachNode.Variable.VariableName}' for index", IsGlobal); int offset = 0; Element getVariableReference() { return(Element.Part <V_ValueInArray>(array, indexer())); } Element indexer() { if (offset == 0) { return(index.GetVariable()); } else { return(index.GetVariable() + getOffset()); } } V_Number getOffset() { return(new V_Number(offset)); } IndexedVar arrayVar = null; ElementOrigin origin = ElementOrigin.GetElementOrigin(array); if (origin == null && forEachNode.Variable.Type != null) { throw new SyntaxErrorException("Could not get the type source.", forEachNode.Variable.Location); } if (origin != null) { arrayVar = origin.OriginVar(VarCollection, null, null); } // Reset the counter. Actions.AddRange(index.SetVariable(0)); // The action the for loop starts on. int forStartIndex = ContinueSkip.GetSkipCount(); A_SkipIf skipCondition = new A_SkipIf() { ParameterValues = new IWorkshopTree[2] }; skipCondition.ParameterValues[0] = !(index.GetVariable() < Element.Part <V_CountOf>(array) ); Actions.Add(skipCondition); List <A_SkipIf> rangeSkips = new List <A_SkipIf>(); for (; offset < forEachNode.Repeaters; offset++) { if (offset > 0) { //variable.Reference = getVariableReference(); A_SkipIf skipper = new A_SkipIf() { ParameterValues = new Element[2] }; skipper.ParameterValues[0] = !( index.GetVariable() + getOffset() < Element.Part <V_CountOf>(array) ); rangeSkips.Add(skipper); Actions.Add(skipper); } // Parse the for's block. Use a child to prevent conflicts with repeaters. ScopeGroup tempChild = forGroup.Child(); Var variable; if (arrayVar != null) { variable = arrayVar.CreateChild(tempChild, forEachNode.Variable.VariableName, new Element[] { indexer() }, forEachNode.Variable); if (forEachNode.Variable.Type != null) { variable.Type = ParserData.GetDefinedType(forEachNode.Variable.Type, forEachNode.Variable.Location); } } else { variable = new ElementReferenceVar(forEachNode.Variable.VariableName, tempChild, forEachNode, getVariableReference()); } ParseBlock(tempChild, tempChild, forEachNode.Block, false, returnVar); tempChild.Out(this); } // Take the foreach out of scope. forGroup.Out(this); // Increment the index Actions.AddRange(index.SetVariable(index.GetVariable() + forEachNode.Repeaters)); // Add the for's finishing elements ContinueSkip.SetSkipCount(forStartIndex); Actions.Add(Element.Part <A_Loop>()); rangeSkips.ForEach(var => var.ParameterValues[1] = new V_Number(GetSkipCount(var))); // Set the skip if (skipCondition != null) { skipCondition.ParameterValues[1] = new V_Number(GetSkipCount(skipCondition)); } ContinueSkip.ResetSkip(); return; } // For case ForNode forNode: { ContinueSkip.Setup(); ScopeGroup forContainer = scope.Child(); // Set the variable if (forNode.VarSetNode != null) { ParseVarset(getter, scope, forNode.VarSetNode); } if (forNode.DefineNode != null) { ParseDefine(getter, forContainer, forNode.DefineNode); } ScopeGroup forGroup = forContainer.Child(); // The action the for loop starts on. int forStartIndex = ContinueSkip.GetSkipCount(); A_SkipIf skipCondition = null; // Skip if the condition is false. if (forNode.Expression != null) // If it has an expression { skipCondition = new A_SkipIf() { ParameterValues = new IWorkshopTree[2] }; skipCondition.ParameterValues[0] = !(ParseExpression(forGroup, forGroup, forNode.Expression)); Actions.Add(skipCondition); } // Parse the for's block. ParseBlock(forGroup, forGroup, forNode.Block, false, returnVar); // Parse the statement if (forNode.Statement != null) { ParseVarset(forGroup, forGroup, forNode.Statement); } // Take the for out of scope. forGroup.Out(this); ContinueSkip.SetSkipCount(forStartIndex); Actions.Add(Element.Part <A_Loop>()); // Set the skip if (skipCondition != null) { skipCondition.ParameterValues[1] = new V_Number(GetSkipCount(skipCondition)); } // Take the defined variable in the for out of scope forContainer.Out(this); ContinueSkip.ResetSkip(); return; } // While case WhileNode whileNode: { ContinueSkip.Setup(); // The action the while loop starts on. int whileStartIndex = ContinueSkip.GetSkipCount(); A_SkipIf skipCondition = new A_SkipIf() { ParameterValues = new IWorkshopTree[2] }; skipCondition.ParameterValues[0] = !(ParseExpression(getter, scope, whileNode.Expression)); Actions.Add(skipCondition); ScopeGroup whileGroup = scope.Child(); ParseBlock(whileGroup, whileGroup, whileNode.Block, false, returnVar); // Take the while out of scope. whileGroup.Out(this); ContinueSkip.SetSkipCount(whileStartIndex); Actions.Add(Element.Part <A_Loop>()); skipCondition.ParameterValues[1] = new V_Number(GetSkipCount(skipCondition)); ContinueSkip.ResetSkip(); return; } // If case IfNode ifNode: { A_SkipIf if_SkipIf = new A_SkipIf() { ParameterValues = new IWorkshopTree[2] }; if_SkipIf.ParameterValues[0] = !(ParseExpression(getter, scope, ifNode.IfData.Expression)); Actions.Add(if_SkipIf); var ifScope = scope.Child(); // Parse the if body. ParseBlock(ifScope, ifScope, ifNode.IfData.Block, false, returnVar); // Take the if out of scope. ifScope.Out(this); // Determines if the "Skip" action after the if block will be created. // Only if there is if-else or else statements. bool addIfSkip = ifNode.ElseIfData.Length > 0 || ifNode.ElseBlock != null; // Create the "Skip" action. A_Skip if_Skip = new A_Skip(); if (addIfSkip) { Actions.Add(if_Skip); } // Update the initial SkipIf's skip count now that we know the number of actions the if block has. if_SkipIf.ParameterValues[1] = new V_Number(GetSkipCount(if_SkipIf)); // Parse else-ifs A_Skip[] elseif_Skips = new A_Skip[ifNode.ElseIfData.Length]; // The ElseIf's skips for (int i = 0; i < ifNode.ElseIfData.Length; i++) { // Create the SkipIf action for the else if. A_SkipIf elseif_SkipIf = new A_SkipIf() { ParameterValues = new IWorkshopTree[2] }; elseif_SkipIf.ParameterValues[0] = !(ParseExpression(getter, scope, ifNode.ElseIfData[i].Expression)); Actions.Add(elseif_SkipIf); // Parse the else-if body. var elseifScope = scope.Child(); ParseBlock(elseifScope, elseifScope, ifNode.ElseIfData[i].Block, false, returnVar); // Take the else-if out of scope. elseifScope.Out(this); // Determines if the "Skip" action after the else-if block will be created. // Only if there is additional if-else or else statements. bool addIfElseSkip = i < ifNode.ElseIfData.Length - 1 || ifNode.ElseBlock != null; // Create the "Skip" action for the else-if. if (addIfElseSkip) { elseif_Skips[i] = new A_Skip(); Actions.Add(elseif_Skips[i]); } // Set the SkipIf's parameters. elseif_SkipIf.ParameterValues[1] = new V_Number(GetSkipCount(elseif_SkipIf)); } // Parse else body. if (ifNode.ElseBlock != null) { var elseScope = scope.Child(); ParseBlock(elseScope, elseScope, ifNode.ElseBlock, false, returnVar); // Take the else out of scope. elseScope.Out(this); } // Replace dummy skip with real skip now that we know the length of the if, if-else, and else's bodies. // Replace if's dummy. if (addIfSkip) { if_Skip.ParameterValues = new IWorkshopTree[] { new V_Number(GetSkipCount(if_Skip)) } } ; // Replace else-if's dummy. for (int i = 0; i < elseif_Skips.Length; i++) { if (elseif_Skips[i] != null) { elseif_Skips[i].ParameterValues = new IWorkshopTree[] { new V_Number(GetSkipCount(elseif_Skips[i])) }; } } return; } // Return case ReturnNode returnNode: if (returnNode.Value != null) { Element result = ParseExpression(getter, scope, returnNode.Value); if (returnVar != null) { Actions.AddRange(returnVar.SetVariable(result)); } } A_Skip returnSkip = new A_Skip(); Actions.Add(returnSkip); Actions.Add(Element.Part <A_Skip>(new V_Number(-1))); ReturnSkips.Add(returnSkip); return; case DeleteNode deleteNode: DefinedClass.Delete(ParseExpression(getter, scope, deleteNode.Delete), this); return; // Define case DefineNode defineNode: ParseDefine(getter, scope, defineNode); return; case ExpressionTreeNode expressionTree: new ParseExpressionTree(this, getter, scope, expressionTree); return; default: throw new SyntaxErrorException("Expected statement.", statement.Location); } }