public static ParameterBase[] GetParameters(ParsingData parser, ParameterDefineNode[] defineNodes) { ParameterBase[] parameters = new ParameterBase[defineNodes.Length]; for (int i = 0; i < parameters.Length; i++) { EnumData enumData = null; DefinedType type = null; if (defineNodes[i].Type != null) { enumData = EnumData.GetEnum(defineNodes[i].Type); type = parser.GetDefinedType(defineNodes[i].Type, null); if (enumData == null && type == null) { throw SyntaxErrorException.NonexistentType(defineNodes[i].Type, defineNodes[i].Location); } } if (enumData != null) { parameters[i] = new EnumParameter(defineNodes[i].VariableName, enumData.Type); } else if (type != null) { parameters[i] = new TypeParameter(defineNodes[i].VariableName, type); } else { parameters[i] = new Parameter(defineNodes[i].VariableName, Elements.ValueType.Any, null); } } return(parameters); }
public ClassObjectResult CreateObject(ActionSet actionSet, string internalName) { var classReference = actionSet.VarCollection.Assign(internalName, actionSet.IsGlobal, true); DefinedType.GetClassIndex(classReference, actionSet, this); var classObject = ClassArray.CreateChild((Element)classReference.GetVariable()); return(new ClassObjectResult(classReference, classObject)); }
public DefinedType GetDefinedType(string name, Location location) { DefinedType type = DefinedTypes.FirstOrDefault(dt => dt.Name == name); if (type == null && location != null) { throw SyntaxErrorException.NonexistentType(name, location); } return(type); }
void Translate() { // Get the reserved variables and IDs foreach (ScriptFile script in ScriptFiles) { if (script.Context.reserved_global()?.reserved_list() != null) { foreach (var name in script.Context.reserved_global().reserved_list().PART()) { VarCollection.Reserve(name.GetText(), true); } foreach (var id in script.Context.reserved_global().reserved_list().NUMBER()) { VarCollection.Reserve(int.Parse(id.GetText()), true, null, null); } } if (script.Context.reserved_player()?.reserved_list() != null) { foreach (var name in script.Context.reserved_player().reserved_list().PART()) { VarCollection.Reserve(name.GetText(), false); } foreach (var id in script.Context.reserved_player().reserved_list().NUMBER()) { VarCollection.Reserve(int.Parse(id.GetText()), false, null, null); } } } // Get the enums foreach (ScriptFile script in ScriptFiles) { foreach (var enumContext in script.Context.enum_define()) { var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext); types.Add(newEnum); definedTypes.Add(newEnum); } } // Get the types foreach (ScriptFile script in ScriptFiles) { foreach (var typeContext in script.Context.type_define()) { var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext); types.Add(newType); definedTypes.Add(newType); } } // Get the methods and macros foreach (ScriptFile script in ScriptFiles) { // Get the methods. foreach (var methodContext in script.Context.define_method()) { var newMethod = new DefinedMethod(new ParseInfo(script, this), RulesetScope, RulesetScope, methodContext, null); } // Get the macros. foreach (var macroContext in script.Context.define_macro()) { GetMacro(new ParseInfo(script, this), RulesetScope, RulesetScope, macroContext); } } // Get the defined variables. foreach (ScriptFile script in ScriptFiles) { foreach (var varContext in script.Context.define()) { Var newVar = new RuleLevelVariable(RulesetScope, new DefineContextHandler(new ParseInfo(script, this), varContext)); rulesetVariables.Add(newVar); // Add the variable to the player variables scope if it is a player variable. if (newVar.VariableType == VariableType.Player) { PlayerVariableScope.CopyVariable(newVar); } } } foreach (var applyType in types) { if (applyType is ClassType classType) { classType.ResolveElements(); } } foreach (var apply in applyBlocks) { apply.SetupParameters(); } foreach (var apply in applyBlocks) { apply.SetupBlock(); } foreach (var apply in applyBlocks) { apply.CallInfo?.CheckRecursion(); } // Get the rules foreach (ScriptFile script in ScriptFiles) { foreach (var ruleContext in script.Context.ow_rule()) { rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext)); } } }
void Translate() { List <IApplyBlock> applyMethods = new List <IApplyBlock>(); // Get the reserved variables and IDs foreach (ScriptFile script in ScriptFiles) { if (script.Context.reserved_global()?.reserved_list() != null) { foreach (var name in script.Context.reserved_global().reserved_list().PART()) { VarCollection.Reserve(name.GetText(), true); } foreach (var id in script.Context.reserved_global().reserved_list().NUMBER()) { VarCollection.Reserve(int.Parse(id.GetText()), true, null, null); } } if (script.Context.reserved_player()?.reserved_list() != null) { foreach (var name in script.Context.reserved_player().reserved_list().PART()) { VarCollection.Reserve(name.GetText(), false); } foreach (var id in script.Context.reserved_player().reserved_list().NUMBER()) { VarCollection.Reserve(int.Parse(id.GetText()), false, null, null); } } } // Get the enums foreach (ScriptFile script in ScriptFiles) { foreach (var enumContext in script.Context.enum_define()) { var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext); types.Add(newEnum); definedTypes.Add(newEnum); } } // Get the types foreach (ScriptFile script in ScriptFiles) { foreach (var typeContext in script.Context.type_define()) { var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext, applyMethods); types.Add(newType); definedTypes.Add(newType); } } // Get the methods and macros foreach (ScriptFile script in ScriptFiles) { // Get the methods. foreach (var methodContext in script.Context.define_method()) { var newMethod = new DefinedMethod(new ParseInfo(script, this), RulesetScope, methodContext); applyMethods.Add(newMethod); //RulesetScope.AddMethod(newMethod, script.Diagnostics, DocRange.GetRange(methodContext.name)); } // Get the macros. foreach (var macroContext in script.Context.define_macro()) { GetMacro(new ParseInfo(script, this), RulesetScope, macroContext, applyMethods); } } // Get the defined variables. foreach (ScriptFile script in ScriptFiles) { foreach (var varContext in script.Context.define()) { var newVar = Var.CreateVarFromContext(VariableDefineType.RuleLevel, new ParseInfo(script, this), varContext); newVar.Finalize(RulesetScope); rulesetVariables.Add(newVar); // Add the variable to the player variables scope if it is a player variable. if (newVar.VariableType == VariableType.Player) { PlayerVariableScope.AddVariable(newVar, null, null); } } } foreach (var apply in applyMethods) { apply.SetupBlock(); } foreach (var apply in applyMethods) { apply.CallInfo.CheckRecursion(); } // Get the rules foreach (ScriptFile script in ScriptFiles) { foreach (var ruleContext in script.Context.ow_rule()) { rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext)); } } }
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); } } }
void Translate() { // Get the reserved variables and IDs // foreach (ScriptFile script in Importer.ScriptFiles) // { // if (script.Context.reserved_global()?.reserved_list() != null) // { // foreach (var name in script.Context.reserved_global().reserved_list().PART()) VarCollection.Reserve(name.GetText(), true); // foreach (var id in script.Context.reserved_global().reserved_list().NUMBER()) VarCollection.Reserve(int.Parse(id.GetText()), true, null, null); // } // if (script.Context.reserved_player()?.reserved_list() != null) // { // foreach (var name in script.Context.reserved_player().reserved_list().PART()) VarCollection.Reserve(name.GetText(), false); // foreach (var id in script.Context.reserved_player().reserved_list().NUMBER()) VarCollection.Reserve(int.Parse(id.GetText()), false, null, null); // } // } // Get the enums foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var enumContext in script.Context.Enums) { var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext); Types.AllTypes.Add(newEnum); Types.DefinedTypes.Add(newEnum); Types.CalledTypes.Add(newEnum); } } // Get the types foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var typeContext in script.Context.Classes) { var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext); Types.AllTypes.Add(newType); Types.DefinedTypes.Add(newType); Types.CalledTypes.Add(newType); } } // Get the declarations foreach (ScriptFile script in Importer.ScriptFiles) { ParseInfo parseInfo = new ParseInfo(script, this); // Get the functions. foreach (var declaration in script.Context.Declarations) { // Function if (declaration is FunctionContext function) { new DefinedMethod(parseInfo, RulesetScope, RulesetScope, function, null); } // Macro function else if (declaration is MacroFunctionContext macroFunction) { parseInfo.GetMacro(RulesetScope, RulesetScope, macroFunction); } // Macro var else if (declaration is MacroVarDeclaration macroVar) { parseInfo.GetMacro(RulesetScope, RulesetScope, macroVar); } // Variables else if (declaration is VariableDeclaration variable) { Var newVar = new RuleLevelVariable(RulesetScope, new DefineContextHandler(new ParseInfo(script, this), variable)); rulesetVariables.Add(newVar); // Add the variable to the player variables scope if it is a player variable. if (newVar.VariableType == VariableType.Player) { PlayerVariableScope.CopyVariable(newVar); } } } } foreach (var applyType in Types.AllTypes) { if (applyType is ClassType classType) { classType.ResolveElements(); } } foreach (var apply in _applyBlocks) { apply.SetupParameters(); } foreach (var apply in _applyBlocks) { apply.SetupBlock(); } foreach (var callInfo in _recursionCheck) { callInfo.CheckRecursion(); } // Get hooks foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var hookContext in script.Context.Hooks) { HookVar.GetHook(new ParseInfo(script, this), RulesetScope, hookContext); } } // Get the rules foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var ruleContext in script.Context.Rules) { rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext)); } } }
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); } } } }
public Element ParseExpression(ScopeGroup getter, ScopeGroup scope, Node expression) { switch (expression) { // Math and boolean operations. case OperationNode operationNode: { Element left = ParseExpression(getter, scope, operationNode.Left); Element right = ParseExpression(getter, scope, operationNode.Right); /* * if (Constants.BoolOperations.Contains(operationNode.Operation)) * { * if (left.ElementData.ValueType != Elements.ValueType.Any && left.ElementData.ValueType != Elements.ValueType.Boolean) * throw new SyntaxErrorException($"Expected boolean, got {left .ElementData.ValueType.ToString()} instead.", ((Node)operationNode.Left).Range); * * if (right.ElementData.ValueType != Elements.ValueType.Any && right.ElementData.ValueType != Elements.ValueType.Boolean) * throw new SyntaxErrorException($"Expected boolean, got {right.ElementData.ValueType.ToString()} instead.", ((Node)operationNode.Right).Range); * } */ switch (operationNode.Operation) { // Math: ^, *, %, /, +, - case "^": return(Element.Part <V_RaiseToPower>(left, right)); case "*": return(left * right); case "%": return(left % right); case "/": return(left / right); case "+": return(left + right); case "-": return(left - right); // BoolCompare: &&, || case "&&": return(Element.Part <V_And>(left, right)); case "||": return(Element.Part <V_Or>(left, right)); // Compare: <, <=, ==, >=, >, != case "<": return(left < right); case "<=": return(left <= right); case "==": return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.Equal), right)); case ">=": return(left >= right); case ">": return(left > right); case "!=": return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.NotEqual), right)); } throw new Exception($"Operation {operationNode.Operation} not implemented."); } // Number case NumberNode numberNode: return(numberNode.Value); // Bool case BooleanNode boolNode: if (boolNode.Value) { return(new V_True()); } else { return(new V_False()); } // Not operation case NotNode notNode: return(!(ParseExpression(getter, scope, notNode.Value))); case InvertNode invertNode: return(-ParseExpression(getter, scope, invertNode.Value)); // Strings case StringNode stringNode: Element[] stringFormat = new Element[stringNode.Format?.Length ?? 0]; for (int i = 0; i < stringFormat.Length; i++) { stringFormat[i] = ParseExpression(getter, scope, stringNode.Format[i]); } if (stringNode.Localized) { return(V_String.ParseString(stringNode.Location, stringNode.Value, stringFormat)); } else { return(V_CustomString.ParseString(stringNode.Location, stringNode.Value, stringFormat)); } // Null case NullNode nullNode: return(new V_Null()); // TODO check if groups need to be implemented here // Methods case MethodNode methodNode: return(ParseMethod(getter, scope, methodNode, true)); // Variable case VariableNode variableNode: Element[] index = new Element[variableNode.Index.Length]; for (int i = 0; i < index.Length; i++) { index[i] = ParseExpression(getter, scope, variableNode.Index[i]); } Var var = scope.GetVar(getter, variableNode.Name, variableNode.Location); if (!var.Gettable()) { throw SyntaxErrorException.VariableIsReadonly(var.Name, variableNode.Location); } Element result = var.GetVariable(); for (int i = 0; i < index.Length; i++) { result = Element.Part <V_ValueInArray>(result, index[i]); } return(result); // Get value in array case ValueInArrayNode viaNode: return(Element.Part <V_ValueInArray>(ParseExpression(getter, scope, viaNode.Value), ParseExpression(getter, scope, viaNode.Index))); // Create array case CreateArrayNode createArrayNode: { Element prev = null; Element current = null; for (int i = 0; i < createArrayNode.Values.Length; i++) { current = new V_Append() { ParameterValues = new IWorkshopTree[2] }; if (prev != null) { current.ParameterValues[0] = prev; } else { current.ParameterValues[0] = new V_EmptyArray(); } current.ParameterValues[1] = ParseExpression(getter, scope, createArrayNode.Values[i]); prev = current; } return(current ?? new V_EmptyArray()); } // Ternary Conditional (a ? b : c) case TernaryConditionalNode ternaryNode: return(Element.TernaryConditional ( ParseExpression(getter, scope, ternaryNode.Condition), ParseExpression(getter, scope, ternaryNode.Consequent), ParseExpression(getter, scope, ternaryNode.Alternative) )); // Enums case EnumNode enumNode: return(EnumData.ToElement(enumNode.EnumMember) ?? throw SyntaxErrorException.EnumCantBeValue(enumNode.Type, enumNode.Location)); // New object case CreateObjectNode createObjectNode: DefinedType typeData = ParserData.GetDefinedType(createObjectNode.TypeName, createObjectNode.Location); return(typeData.New(createObjectNode, getter, scope, this)); // Expression tree case ExpressionTreeNode expressionTree: return(new ParseExpressionTree(this, getter, scope, expressionTree).ResultingElement); // This case ThisNode thisNode: return(getter.GetThis(thisNode.Location)); // Type convert case TypeConvertNode typeConvertNode: DefinedType type = ParserData.GetDefinedType(typeConvertNode.Type, typeConvertNode.Location); Element element = ParseExpression(getter, scope, typeConvertNode.Expression); type.GetSource(this, element, typeConvertNode.Location); return(element); case RootNode rootNode: throw new SyntaxErrorException("'root' cannot be used like an expression.", rootNode.Location); } throw new Exception(); }