override public void GetSource(TranslateRule context, Element element, Location location) { IndexedVar supportedType = context.ParserData.ClassArray.CreateChild(null, Name + " root", new Element[] { element }, null); supportedType.Type = this; element.SupportedType = supportedType; }
override public Element Get(TranslateRule context, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters) { // Check the method stack if this method was already called. // Throw a syntax error if it was. if (context.MethodStackNotRecursive.Contains(this)) { throw new SyntaxErrorException("Recursion is not allowed in macros.", methodNode.Location); } context.MethodStackNotRecursive.Add(this); int actionCount = context.Actions.Count; ScopeGroup methodScope = scope.Root().Child(); for (int i = 0; i < parameters.Length; i++) { new ElementReferenceVar(Parameters[i].Name, methodScope, methodNode.Parameters[i], parameters[i]); } Element result = context.ParseExpression(methodScope, methodScope, Expression); methodScope.Out(context); context.MethodStackNotRecursive.Remove(this); if (context.Actions.Count > actionCount) { throw new SyntaxErrorException("Macro cannot result in any actions.", methodNode.Location); } return(result); }
public void Out(TranslateRule context) { if (!IsInScope) { throw new Exception("ScopeGroup is already out of scope."); } IsInScope = false; foreach (IScopeable var in InScope) { if (var is IndexedVar) { ((IndexedVar)var).OutOfScope(context); VarCollection.Free((IndexedVar)var); } } for (int i = 0; i < Children.Count; i++) { if (Children[0].IsInScope) { throw new Exception(); } } }
public SubroutineInfo(Subroutine routine, ReturnHandler returnHandler, TranslateRule rule, IndexReference[] parameterStores, IndexReference objectStore) { Subroutine = routine; ReturnHandler = returnHandler; Rule = rule; ParameterStores = parameterStores; ObjectStore = objectStore; }
public ActionSet(TranslateRule translate, DocRange genericErrorRange, List <IActionList> actions) { Translate = translate; IsGlobal = translate.IsGlobal; ActionList = translate.Actions; VarCollection = translate.DeltinScript.VarCollection; IndexAssigner = translate.DeltinScript.DefaultIndexAssigner; }
public Element Parse(TranslateRule context, bool needsToBeValue, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters) { Element result = Get(context, scope, methodNode, parameters); if (!needsToBeValue) { result = null; } return(result); }
public static void Delete(Element index, TranslateRule context) { context.Actions.AddRange( context.ParserData.ClassArray.SetVariable(new V_Null(), null, index) ); context.Actions.AddRange(context.ParserData.ClassIndexes.SetVariable( Element.Part <V_RemoveFromArray>( context.ParserData.ClassIndexes.GetVariable(), index ) )); }
override public void GetSource(TranslateRule context, Element element, Location location) { ElementOrigin origin = ElementOrigin.GetElementOrigin(element); if (origin == null) { throw new SyntaxErrorException("Could not get the type source.", location); } IndexedVar typeVar = origin.OriginVar(context.VarCollection, null, Name + " origin"); typeVar.Type = this; element.SupportedType = typeVar; }
public override void OutOfScope(TranslateRule context, Element targetPlayer = null) { Element get = base.Get(targetPlayer); context.Actions.AddRange(base.SetVariable( Element.Part <V_ArraySlice>( get, new V_Number(0), Element.Part <V_CountOf>(get) - 1 ), targetPlayer )); base.OutOfScope(context, targetPlayer); }
public SubroutineStack(DeltinScript deltinScript, string subroutineName, string ruleName) { _deltinScript = deltinScript; // Setup the subroutine element. Subroutine = deltinScript.SubroutineCollection.NewSubroutine(subroutineName); // Create the rule. Rule = new TranslateRule(deltinScript, subroutineName, Subroutine); // Setup the return handler. ReturnHandler = new ReturnHandler(Rule.ActionSet, subroutineName, true); ActionSet = Rule.ActionSet.New(ReturnHandler); AsyncLock(); }
// Sets up single-instance methods for methods with the 'rule' attribute. public void SetupSubroutine() { if (!IsSubroutine) { throw new Exception(Name + " does not have the subroutine attribute."); } // Setup the subroutine element. Subroutine subroutine = parseInfo.TranslateInfo.SubroutineCollection.NewSubroutine(Name); // Create the rule. TranslateRule subroutineRule = new TranslateRule(parseInfo.TranslateInfo, SubroutineName, subroutine); // Setup the return handler. ReturnHandler returnHandler = new ReturnHandler(subroutineRule.ActionSet, Name, multiplePaths); ActionSet actionSet = subroutineRule.ActionSet.New(returnHandler).New(subroutineRule.ActionSet.IndexAssigner.CreateContained()); // Get the variables that will be used to store the parameters. IndexReference[] parameterStores = new IndexReference[ParameterVars.Length]; for (int i = 0; i < ParameterVars.Length; i++) { parameterStores[i] = actionSet.IndexAssigner.Add(actionSet.VarCollection, ParameterVars[i], true, null, Attributes.Recursive) as IndexReference; } // If the subroutine is an object function inside a class, create a variable to store the class object. IndexReference objectStore = null; if (Attributes.ContainingType != null && !Static) { objectStore = actionSet.VarCollection.Assign("_" + Name + "_subroutineStore", true, true); Attributes.ContainingType.AddObjectVariablesToAssigner(objectStore.GetVariable(), actionSet.IndexAssigner); } // Set the subroutine info. subroutineInfo = new SubroutineInfo(subroutine, returnHandler, subroutineRule, parameterStores, objectStore); // Parse the block. block.Translate(actionSet); // Apply returns. returnHandler.ApplyReturnSkips(); // Add the subroutine. parseInfo.TranslateInfo.WorkshopRules.Add(subroutineRule.GetRule()); }
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); } } }
private ParsingData(string file, string content) { Rule initialGlobalValues = new Rule(Constants.INTERNAL_ELEMENT + "Initial Global Values"); Rule initialPlayerValues = new Rule(Constants.INTERNAL_ELEMENT + "Initial Player Values", RuleEvent.OngoingPlayer, Team.All, PlayerSelector.All); globalTranslate = new TranslateRule(initialGlobalValues, Root, this); playerTranslate = new TranslateRule(initialPlayerValues, Root, this); GetRulesets(content, file, true, null); VarCollection = new VarCollection(ReservedGlobalIDs.ToArray(), ReservedGlobalNames.ToArray(), ReservedPlayerIDs.ToArray(), ReservedPlayerNames.ToArray()); Root = new ScopeGroup(VarCollection); ClassIndexes = IndexedVar.AssignInternalVar(VarCollection, null, "_classIndexes", true); ClassArray = IndexedVar.AssignInternalVar(VarCollection, null, "_classArray", true); if (!Diagnostics.ContainsErrors()) { foreach (var ruleset in Rulesets) { GetObjects(ruleset.Value, ruleset.Key, globalTranslate, playerTranslate); } } foreach (var type in DefinedTypes) { try { type.RegisterParameters(this); } catch (SyntaxErrorException ex) { Diagnostics.Error(ex); } } foreach (var method in UserMethods) { try { method.RegisterParameters(this); } catch (SyntaxErrorException ex) { Diagnostics.Error(ex); } } if (!Diagnostics.ContainsErrors()) { // Parse the rules. Rules = new List <Rule>(); for (int i = 0; i < RuleNodes.Count; i++) { try { var result = TranslateRule.GetRule(RuleNodes[i], Root, this); Rules.Add(result); } catch (SyntaxErrorException ex) { Diagnostics.Error(ex); } } foreach (var definedVar in VarCollection.AllVars) { try { if (definedVar is IndexedVar && definedVar.IsDefinedVar && definedVar.Scope == Root) { Node value = ((IDefine)definedVar.Node).Value; if (value != null) { if (((IndexedVar)definedVar).IsGlobal) { globalTranslate.Actions.AddRange(((IndexedVar)definedVar).SetVariable(globalTranslate.ParseExpression(Root, Root, value))); } else { playerTranslate.Actions.AddRange(((IndexedVar)definedVar).SetVariable(playerTranslate.ParseExpression(Root, Root, value))); } } } } catch (SyntaxErrorException ex) { Diagnostics.Error(ex); } } globalTranslate.Finish(); playerTranslate.Finish(); // Add the player initial values rule if it was used. if (initialPlayerValues.Actions.Length > 0) { Rules.Insert(0, initialPlayerValues); } // Add the global initial values rule if it was used. if (initialGlobalValues.Actions.Length > 0) { Rules.Insert(0, initialGlobalValues); } foreach (Rule rule in AdditionalRules) { if (rule.Actions.Length > 0) { Rules.Add(rule); } } } Success = !Diagnostics.ContainsErrors(); }
void ToWorkshop(Func <VarCollection, Rule[]> addRules) { // Set up the variable collection. VarCollection.Setup(); // Set up initial global and player rules. InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal); InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer); WorkshopRules = new List <Rule>(); // Init called types. foreach (var type in Types.CalledTypes.Distinct()) { type.WorkshopInit(this); } // Assign variables at the rule-set level. foreach (var variable in rulesetVariables) { // Assign the variable an index. var assigner = DefaultIndexAssigner.Add(VarCollection, variable, true, null) as IndexReference; // Assigner will be non-null if it is an IndexReference. if (assigner != null) { DebugVariables.Add(variable, assigner); // Initial value. if (variable.InitialValue != null) { var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global); addToInitialRule.ActionSet.AddAction(assigner.SetVariable( (Element)variable.InitialValue.Parse(addToInitialRule.ActionSet) )); } } } // Setup single-instance methods. foreach (var method in subroutines) { method.SetupSubroutine(); } // Parse the rules. foreach (var rule in rules) { var translate = new TranslateRule(this, rule); Rule newRule = translate.GetRule(); WorkshopRules.Add(newRule); rule.ElementCountLens.RuleParsed(newRule); } // Add built-in rules. // Initial player if (InitialPlayer.Actions.Count > 0) { WorkshopRules.Insert(0, InitialPlayer.GetRule()); } // Initial global if (InitialGlobal.Actions.Count > 0) { WorkshopRules.Insert(0, InitialGlobal.GetRule()); } // Additional if (addRules != null) { WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null)); } // Order the workshop rules by priority. WorkshopRules = WorkshopRules.OrderBy(wr => wr.Priority).ToList(); // Get the final workshop string. WorkshopBuilder result = new WorkshopBuilder(Language); LanguageInfo.I18nWarningMessage(result, Language); // Get the custom game settings. if (Importer.MergedLobbySettings != null) { Ruleset settings = Ruleset.Parse(Importer.MergedLobbySettings); settings.ToWorkshop(result); result.AppendLine(); } // Get the variables. VarCollection.ToWorkshop(result); result.AppendLine(); // Print class identifiers. Types.PrintClassIdentifiers(result); // Get the subroutines. SubroutineCollection.ToWorkshop(result); // Get the rules. for (int i = 0; i < WorkshopRules.Count; i++) { WorkshopRules[i].ToWorkshop(result, OptimizeOutput); ElementCount += WorkshopRules[i].ElementCount(OptimizeOutput); if (i != WorkshopRules.Count - 1) { result.AppendLine(); } } WorkshopCode = result.ToString(); }
public static Rule GetRule(RuleNode ruleNode, ScopeGroup root, ParsingData parserData) { var result = new TranslateRule(ruleNode, root, parserData); return(result.Rule); }
public static void Delete(Element index, TranslateRule context) { context.Actions.AddRange(context.VarCollection.WorkshopArrayBuilder.SetVariable( new V_Null(), true, null, Variable.C, index )); }
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); }
// Sets up single-instance methods for methods with the 'rule' attribute. public void SetupSubroutine() { if (subroutineInfo != null || !IsSubroutine) { return; } // Setup the subroutine element. Subroutine subroutine = parseInfo.TranslateInfo.SubroutineCollection.NewSubroutine(Name); // Create the rule. TranslateRule subroutineRule = new TranslateRule(parseInfo.TranslateInfo, subroutine, SubroutineName, subroutineDefaultGlobal); // Setup the return handler. ReturnHandler returnHandler = new ReturnHandler(subroutineRule.ActionSet, Name, multiplePaths || Attributes.Virtual); ActionSet actionSet = subroutineRule.ActionSet.New(returnHandler).New(subroutineRule.ActionSet.IndexAssigner.CreateContained()); // Get the variables that will be used to store the parameters. IndexReference[] parameterStores = new IndexReference[ParameterVars.Length]; for (int i = 0; i < ParameterVars.Length; i++) { // Create the workshop variable the parameter will be stored as. IndexReference indexResult = actionSet.IndexAssigner.AddIndexReference(actionSet.VarCollection, ParameterVars[i], subroutineDefaultGlobal, Attributes.Recursive); parameterStores[i] = indexResult; // Assign virtual variables to the index reference. foreach (Var virtualParameterOption in VirtualVarGroup(i)) { actionSet.IndexAssigner.Add(virtualParameterOption, indexResult); } } // If the subroutine is an object function inside a class, create a variable to store the class object. IndexReference objectStore = null; if (Attributes.ContainingType != null && !Static) { objectStore = actionSet.VarCollection.Assign("_" + Name + "_subroutineStore", true, !Attributes.Recursive); // Set the objectStore as an empty array if the subroutine is recursive. if (Attributes.Recursive) { actionSet.InitialSet().AddAction(objectStore.SetVariable(new V_EmptyArray())); Attributes.ContainingType.AddObjectVariablesToAssigner(Element.Part <V_LastOf>(objectStore.GetVariable()), actionSet.IndexAssigner); actionSet = actionSet.New(Element.Part <V_LastOf>(objectStore.GetVariable())).PackThis(); } else { Attributes.ContainingType.AddObjectVariablesToAssigner(objectStore.GetVariable(), actionSet.IndexAssigner); actionSet = actionSet.New(objectStore.GetVariable()).PackThis(); } } // Set the subroutine info. subroutineInfo = new SubroutineInfo(subroutine, returnHandler, subroutineRule, parameterStores, objectStore); MethodBuilder builder = new MethodBuilder(this, actionSet, returnHandler); builder.BuilderSet = builder.BuilderSet.New(Attributes.Recursive); builder.ParseInner(); // Apply returns. returnHandler.ApplyReturnSkips(); // Pop object array and parameters if recursive. if (Attributes.Recursive) { if (objectStore != null) { actionSet.AddAction(objectStore.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.Part <V_CountOf>(objectStore.GetVariable()) - 1)); } RecursiveStack.PopParameterStacks(actionSet, ParameterVars); } // Add the subroutine. Rule translatedRule = subroutineRule.GetRule(); parseInfo.TranslateInfo.WorkshopRules.Add(translatedRule); var codeLens = new ElementCountCodeLens(DefinedAt.range, parseInfo.TranslateInfo.OptimizeOutput); parseInfo.Script.AddCodeLensRange(codeLens); codeLens.RuleParsed(translatedRule); }
protected void SetupNew(ScopeGroup getter, ScopeGroup scope, IndexedVar store, ScopeGroup typeScope, TranslateRule context, CreateObjectNode node) { // Set the default variables in the struct for (int i = 0; i < DefinedVars.Length; i++) { if (DefinedVars[i].Value != null) { context.Actions.AddRange( store.SetVariable(context.ParseExpression(typeScope, typeScope, DefinedVars[i].Value), null, new V_Number(i)) ); } } Constructor constructor = Constructors.FirstOrDefault(c => c.Parameters.Length == node.Parameters.Length); if (constructor == null && !(node.Parameters.Length == 0 && Constructors.Length == 0)) { throw SyntaxErrorException.NotAConstructor(TypeKind, Name, node.Parameters.Length, node.Location); } if (constructor != null) { ScopeGroup constructorScope = typeScope.Child(); IWorkshopTree[] parameters = context.ParseParameters( getter, scope, constructor.Parameters, node.Parameters, node.TypeName, node.Location ); context.AssignParameterVariables(constructorScope, constructor.Parameters, parameters, node); context.ParseBlock(typeScope, constructorScope, constructor.BlockNode, true, null); constructorScope.Out(context); } }
abstract public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context);
abstract public void GetSource(TranslateRule context, Element element, Location location);
public ParseExpressionTree(TranslateRule translator, ScopeGroup getter, ScopeGroup scope, Node root) { if (root is VariableNode) { VariableNode variableNode = (VariableNode)root; Var var = scope.GetVar(getter, ((VariableNode)root).Name, root.Location); ResultingVariable = var; //if (!ResultingVariable.Gettable()) throw SyntaxErrorException.CantReadVariable(ResultingVariable.Name, root.Location); if (ResultingVariable.Gettable()) { ResultingElement = var.GetVariable(); } VariableIndex = new Element[variableNode.Index.Length]; for (int i = 0; i < VariableIndex.Length; i++) { VariableIndex[i] = translator.ParseExpression(getter, scope, variableNode.Index[i]); } for (int i = 0; i < VariableIndex.Length; i++) { if (!ResultingVariable.Gettable()) { throw SyntaxErrorException.CantReadVariable(ResultingVariable.Name, root.Location); } ResultingElement = Element.Part <V_ValueInArray>(ResultingElement, VariableIndex[i]); } return; } if (root is ExpressionTreeNode == false) { throw new SyntaxErrorException("Error", root.Location); } List <Node> nodes = flatten((ExpressionTreeNode)root); ScopeGroup currentScope = scope; Element nodeResult = null; for (int index = 0; index < nodes.Count; index++) { if (nodes[index] is RootNode) { currentScope = translator.ParserData.Root; nodeResult = new V_Null(); } // If the node is a variable node, get the value. else if (nodes[index] is VariableNode) { VariableNode variableNode = (VariableNode)nodes[index]; Var var = currentScope.GetVar(getter, variableNode.Name, variableNode.Location); // If this is the last node, set the resulting var. if (index == nodes.Count - 1) { ResultingVariable = var; } // Get the variable index VariableIndex = new Element[variableNode.Index.Length]; for (int i = 0; i < VariableIndex.Length; i++) { VariableIndex[i] = translator.ParseExpression(getter, scope, variableNode.Index[i]); } // Set the nodeResult. nodeResult = var.GetVariable(Target); // Apply the index for (int i = 0; i < VariableIndex.Length; i++) { nodeResult = Element.Part <V_ValueInArray>(nodeResult, VariableIndex[i]); } } // If not, parse the node as an expression. else { nodeResult = translator.ParseExpression(getter, currentScope, nodes[index]); } // SupportedType will equal null if the element is not a defined type. if (nodeResult.SupportedType == null) { // If there is no supported type, assume the element or variable is containing a player. // Reset the scope. //currentScope = scope; currentScope = translator.ParserData.Root; // If this isn't the last node, set the target and reset the nodeResult. if (index < nodes.Count - 1) { Target = nodeResult; nodeResult = null; } } else { // Set the target scope to the type. currentScope = nodeResult.SupportedType.Type.GetRootScope(nodeResult, nodeResult.SupportedType, translator.ParserData, Target); } } ResultingElement = nodeResult; }
override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context) { context.ParserData.SetupClasses(); // Get the index to store the class. IndexedVar index = IndexedVar.AssignInternalVarExt(context.VarCollection, scope, "New " + Name + " class index", context.IsGlobal); // Assigns the index variable. Element takenIndexes = context.ParserData.ClassIndexes.GetVariable(); // Get an empty index in the class array to store the new class. Element firstFree = ( Element.Part <V_FirstOf>( Element.Part <V_FilteredArray>( // Sort the taken index array. Element.Part <V_SortedArray>(takenIndexes, new V_ArrayElement()), // Filter Element.Part <V_And>( // If the previous index was not taken, use that index. !(Element.Part <V_ArrayContains>( takenIndexes, new V_ArrayElement() - 1 )), // Make sure the index does not equal 0 so the resulting index is not -1. new V_Compare(new V_ArrayElement(), Operators.NotEqual, new V_Number(0)) ) ) ) - 1 // Subtract 1 to get the previous index ); // If the taken index array has 0 elements, just use the length of the class array subtracted by 1. firstFree = Element.TernaryConditional( new V_Compare(Element.Part <V_CountOf>(takenIndexes), Operators.NotEqual, new V_Number(0)), firstFree, Element.Part <V_CountOf>(context.ParserData.ClassArray.GetVariable()) - 1 ); context.Actions.AddRange(index.SetVariable(firstFree)); context.Actions.AddRange( index.SetVariable( Element.TernaryConditional( // If the index equals -1, use the length of the class array instead. new V_Compare(index.GetVariable(), Operators.Equal, new V_Number(-1)), Element.Part <V_CountOf>(context.ParserData.ClassArray.GetVariable()), index.GetVariable() ) ) ); // Add the selected index to the taken indexes array. context.Actions.AddRange( context.ParserData.ClassIndexes.SetVariable( Element.Part <V_Append>( context.ParserData.ClassIndexes.GetVariable(), index.GetVariable() ) ) ); // The direct reference to the class variable. IndexedVar store = context.ParserData.ClassArray.CreateChild(scope, Name + " root", new Element[] { index.GetVariable() }, null); store.Index[0].SupportedType = store; store.Type = this; ScopeGroup typeScope = GetRootScope(index.GetVariable(), store, context.ParserData); SetupNew(getter, scope, store, typeScope, context, node); return(index.GetVariable()); }
abstract public Element Get(TranslateRule context, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters);
void ToWorkshop(Func <VarCollection, Rule[]> addRules) { // Set up the variable collection. VarCollection.Setup(); WorkshopConverter = new ToWorkshop(this); // Set up initial global and player rules. InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal); InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer); WorkshopRules = new List <Rule>(); WorkshopConverter.InitStatic(); // Init called types. foreach (var workshopInit in _workshopInit) { workshopInit.WorkshopInit(this); } // Assign variables at the rule-set level. foreach (var variable in rulesetVariables) { var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global); // Assign the variable an index. IGettable value = variable .GetDefaultInstance(null) .GetAssigner(new(addToInitialRule.ActionSet)) .GetValue(new GettableAssignerValueInfo(addToInitialRule.ActionSet) { SetInitialValue = SetInitialValue.SetIfExists }); DefaultIndexAssigner.Add(variable, value); if (value is IndexReference indexReference) { DebugVariables.Add(variable, indexReference); } } // Parse the rules. foreach (var rule in rules) { var translate = new TranslateRule(this, rule); Rule newRule = GetRule(translate.GetRule()); WorkshopRules.Add(newRule); rule.ElementCountLens.RuleParsed(newRule); } // Add built-in rules. // Initial player if (InitialPlayer.Actions.Count > 0) { WorkshopRules.Insert(0, GetRule(InitialPlayer.GetRule())); } // Initial global if (InitialGlobal.Actions.Count > 0) { WorkshopRules.Insert(0, GetRule(InitialGlobal.GetRule())); } // Additional if (addRules != null) { WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null)); } // Complete portable functions WorkshopConverter.LambdaBuilder.Complete(); // Order the workshop rules by priority. WorkshopRules = WorkshopRules.OrderBy(wr => wr.Priority).ToList(); // Get the final workshop string. WorkshopBuilder result = new WorkshopBuilder(Language); LanguageInfo.I18nWarningMessage(result, Language); // Get the custom game settings. if (Importer.MergedLobbySettings != null) { Ruleset settings = Ruleset.Parse(Importer.MergedLobbySettings); settings.ToWorkshop(result); result.AppendLine(); } // Get the variables. VarCollection.ToWorkshop(result); result.AppendLine(); // Get the subroutines. SubroutineCollection.ToWorkshop(result); // Get the rules. for (int i = 0; i < WorkshopRules.Count; i++) { WorkshopRules[i].ToWorkshop(result); ElementCount += WorkshopRules[i].ElementCount(); if (i != WorkshopRules.Count - 1) { result.AppendLine(); } } WorkshopCode = result.GetResult(); }
void ToWorkshop(Func <VarCollection, Rule[]> addRules) { VarCollection.Setup(); InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal); InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer); WorkshopRules = new List <Rule>(); foreach (var variable in rulesetVariables) { // Assign the variable an index. DefaultIndexAssigner.Add(VarCollection, variable, true, null); var assigner = DefaultIndexAssigner[variable] as IndexReference; if (assigner != null && variable.InitialValue != null) { var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global); addToInitialRule.ActionSet.AddAction(assigner.SetVariable( (Element)variable.InitialValue.Parse(addToInitialRule.ActionSet) )); } } foreach (var rule in rules) { var translate = new TranslateRule(this, rule); WorkshopRules.Add(translate.GetRule()); } if (InitialPlayer.Actions.Count > 0) { WorkshopRules.Insert(0, InitialPlayer.GetRule()); } if (InitialGlobal.Actions.Count > 0) { WorkshopRules.Insert(0, InitialGlobal.GetRule()); } if (addRules != null) { WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null)); } // Get the final workshop string. StringBuilder result = new StringBuilder(); I18n.I18n.I18nWarningMessage(result, I18n.I18n.CurrentLanguage); // Get the variables. VarCollection.ToWorkshop(result, I18n.I18n.CurrentLanguage); result.AppendLine(); // Get the rules. foreach (var rule in WorkshopRules) { result.AppendLine(rule.ToWorkshop(I18n.I18n.CurrentLanguage)); } WorkshopCode = result.ToString(); }
void ToWorkshop(Func <VarCollection, Rule[]> addRules) { // Set up the variable collection. VarCollection.Setup(); // Set up initial global and player rules. InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal); InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer); WorkshopRules = new List <Rule>(); // Assign static variables. foreach (var type in types) { type.WorkshopInit(this); } // Assign variables at the rule-set level. foreach (var variable in rulesetVariables) { // Assign the variable an index. DefaultIndexAssigner.Add(VarCollection, variable, true, null); var assigner = DefaultIndexAssigner[variable] as IndexReference; if (assigner != null && variable.InitialValue != null) { var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global); addToInitialRule.ActionSet.AddAction(assigner.SetVariable( (Element)variable.InitialValue.Parse(addToInitialRule.ActionSet) )); } } // Setup single-instance methods. foreach (var method in subroutines) { method.SetupSubroutine(); } // Parse the rules. foreach (var rule in rules) { var translate = new TranslateRule(this, rule); WorkshopRules.Add(translate.GetRule()); } if (InitialPlayer.Actions.Count > 0) { WorkshopRules.Insert(0, InitialPlayer.GetRule()); } if (InitialGlobal.Actions.Count > 0) { WorkshopRules.Insert(0, InitialGlobal.GetRule()); } if (addRules != null) { WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null)); } // Order the workshop rules by priority. WorkshopRules = WorkshopRules.OrderBy(wr => wr.Priority).ToList(); // Get the final workshop string. WorkshopBuilder result = new WorkshopBuilder(Language); LanguageInfo.I18nWarningMessage(result, Language); // Get the custom game settings. if (MergedLobbySettings != null) { Ruleset settings = Ruleset.Parse(MergedLobbySettings); settings.ToWorkshop(result); result.AppendLine(); } // Get the variables. VarCollection.ToWorkshop(result); result.AppendLine(); // Get the subroutines. SubroutineCollection.ToWorkshop(result); // Get the rules. foreach (var rule in WorkshopRules) { result.AppendLine(rule.ToWorkshop(Language, OptimizeOutput)); } WorkshopCode = result.ToString(); }
override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context) { IndexedVar store = context.VarCollection.AssignVar(scope, Name + " store", context.IsGlobal, null); store.Type = this; ScopeGroup typeScope = GetRootScope(store, context.ParserData); SetupNew(getter, scope, store, typeScope, context, node); return(store.GetVariable()); }
override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context) { // Get the index to store the class. IndexedVar index = context.VarCollection.AssignVar(scope, "New " + Name + " class index", context.IsGlobal, null); // Assigns the index variable. // Get the index of the next free spot in the class array. context.Actions.AddRange( index.SetVariable( Element.Part <V_IndexOfArrayValue>( WorkshopArrayBuilder.GetVariable(true, null, Variable.C), new V_Null() ) ) ); // Set the index to the count of the class array if the index equals -1. context.Actions.AddRange( index.SetVariable( Element.TernaryConditional( new V_Compare(index.GetVariable(), Operators.Equal, new V_Number(-1)), Element.Part <V_CountOf>( WorkshopArrayBuilder.GetVariable(true, null, Variable.C) ), index.GetVariable() ) ) ); // The direct reference to the class variable. IndexedVar store = new IndexedVar( scope, Name + " root", true, Variable.C, new Element[] { index.GetVariable() }, context.VarCollection.WorkshopArrayBuilder, null ); store.Index[0].SupportedType = store; store.Type = this; ScopeGroup typeScope = GetRootScope(store, context.ParserData); SetupNew(getter, scope, store, typeScope, context, node); return(index.GetVariable()); }
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); } } } }