void ParseDefine(ScopeGroup getter, ScopeGroup scope, DefineNode defineNode) { IndexedVar var; if (!defineNode.Extended) { var = IndexedVar.AssignVar(VarCollection, scope, defineNode.VariableName, IsGlobal, defineNode); } else { var = IndexedVar.AssignVarExt(VarCollection, scope, defineNode.VariableName, IsGlobal, defineNode); } // Set the defined variable if the variable is defined like "define var = 1" Element[] inScopeActions = var.InScope(defineNode.Value != null ? ParseExpression(getter, scope, defineNode.Value) : null); if (inScopeActions != null) { Actions.AddRange(inScopeActions); } if (defineNode.Type != null) { var.Type = ParserData.GetDefinedType(defineNode.Type, defineNode.Location); } }
public Var[] AssignParameterVariables(ScopeGroup methodScope, ParameterBase[] parameters, IWorkshopTree[] values, Node methodNode) { Var[] parameterVars = new Var[values.Length]; for (int i = 0; i < values.Length; i++) { if (values[i] is Element) { // Create a new variable using the parameter. if (!parameters[i].Extended) { parameterVars[i] = IndexedVar.AssignVar(VarCollection, methodScope, parameters[i].Name, IsGlobal, methodNode); } else { parameterVars[i] = IndexedVar.AssignVarExt(VarCollection, methodScope, parameters[i].Name, IsGlobal, methodNode); } ((IndexedVar)parameterVars[i]).Type = ((Element)values[i]).SupportedType?.Type; Actions.AddRange(((IndexedVar)parameterVars[i]).SetVariable((Element)values[i])); } else if (values[i] is EnumMember) { parameterVars[i] = new ElementReferenceVar(parameters[i].Name, methodScope, methodNode, values[i]); } else { throw new NotImplementedException(); } } return(parameterVars); }
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); } } }
override public Element Get(TranslateRule context, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters) { Element result; if (!IsRecursive) { // Check the method stack if this method was already called. // Throw a syntax error if it was. if (context.MethodStackNotRecursive.Contains(this)) { throw SyntaxErrorException.RecursionNotAllowed(methodNode.Location); } var methodScope = scope.Root().Child(); // Add the parameter variables to the scope. context.AssignParameterVariables(methodScope, Parameters, parameters, methodNode); // The variable that stores the return value. IndexedVar returns = null; if (DoesReturn) { returns = IndexedVar.AssignVar(context.VarCollection, scope, $"{methodNode.Name} return", context.IsGlobal, null); returns.Type = Type; } // Add the method to the method stack context.MethodStackNotRecursive.Add(this); Block.RelatedScopeGroup = methodScope; // Parse the block of the method context.ParseBlock(methodScope, methodScope, Block, true, returns); // Take the method scope out of scope. methodScope.Out(context); // Remove the method from the stack. context.MethodStackNotRecursive.Remove(this); if (DoesReturn) { result = returns.GetVariable(); } else { result = new V_Null(); } } else { // Check the method stack if this method was already called. It will be null if it wasn't called. MethodStack lastMethod = context.MethodStackRecursive.FirstOrDefault(ms => ms.UserMethod == this); if (lastMethod != null) { context.ContinueSkip.Setup(); // Re-push the paramaters. for (int i = 0; i < lastMethod.ParameterVars.Length; i++) { if (lastMethod.ParameterVars[i] is RecursiveVar) { context.Actions.AddRange ( ((RecursiveVar)lastMethod.ParameterVars[i]).InScope((Element)parameters[i]) ); } } // Add to the continue skip array. context.Actions.AddRange( lastMethod.ContinueSkipArray.SetVariable( Element.Part <V_Append>(lastMethod.ContinueSkipArray.GetVariable(), new V_Number(context.ContinueSkip.GetSkipCount() + 3)) ) ); // Loop back to the start of the method. context.ContinueSkip.SetSkipCount(lastMethod.ActionIndex); context.Actions.Add(Element.Part <A_Loop>()); result = lastMethod.Return.GetVariable(); } else { var methodScope = scope.Root().Child(true); // Add the parameter variables to the scope. Var[] parameterVars = new Var[Parameters.Length]; for (int i = 0; i < parameterVars.Length; i++) { if (parameters[i] is Element) { // Create a new variable using the parameter input. parameterVars[i] = (RecursiveVar)IndexedVar.AssignVar(context.VarCollection, methodScope, Parameters[i].Name, context.IsGlobal, methodNode); ((RecursiveVar)parameterVars[i]).Type = ((Element)parameters[i]).SupportedType?.Type; context.Actions.AddRange ( ((RecursiveVar)parameterVars[i]).InScope((Element)parameters[i]) ); } else if (parameters[i] is EnumMember) { parameterVars[i] = new ElementReferenceVar(Parameters[i].Name, methodScope, methodNode, parameters[i]); } else { throw new NotImplementedException(); } } var returns = IndexedVar.AssignInternalVarExt(context.VarCollection, null, $"{methodNode.Name}: return", context.IsGlobal); returns.Type = Type; // Setup the continue skip array. IndexedVar continueSkipArray = IndexedVar.AssignInternalVar(context.VarCollection, null, $"{methodNode.Name} sca", context.IsGlobal); var stack = new MethodStack(this, parameterVars, context.ContinueSkip.GetSkipCount(), returns, continueSkipArray); // Add the method to the stack. context.MethodStackRecursive.Add(stack); Block.RelatedScopeGroup = methodScope; // Parse the method block context.ParseBlock(methodScope, methodScope, Block, true, returns); // No return value if the method is being used as an action. result = returns.GetVariable(); // Take the method out of scope. //Actions.AddRange(methodScope.RecursiveMethodStackPop()); methodScope.Out(context); // Setup the next continue skip. context.ContinueSkip.Setup(); context.ContinueSkip.SetSkipCount(Element.Part <V_LastOf>(continueSkipArray.GetVariable())); // Remove the last continue skip. context.Actions.AddRange( continueSkipArray.SetVariable( Element.Part <V_ArraySlice>( continueSkipArray.GetVariable(), new V_Number(0), Element.Part <V_CountOf>(continueSkipArray.GetVariable()) - 1 ) ) ); // Loop if the method goes any deeper by checking the length of the continue skip array. context.Actions.Add( Element.Part <A_LoopIf>( Element.Part <V_Compare>( Element.Part <V_CountOf>(continueSkipArray.GetVariable()), EnumData.GetEnumValue(Operators.NotEqual), new V_Number(0) ) ) ); // Reset the continue skip. context.ContinueSkip.ResetSkip(); context.Actions.AddRange(continueSkipArray.SetVariable(0)); // Remove the method from the stack. context.MethodStackRecursive.Remove(stack); } } return(result); }