void CreateEventFunction(string name, object context, CodeTypeDeclaration codeType, MethodInfo baseMethod, params object[] initStatements) { CodeMemberMethod method = new CodeMemberMethod(); method.Name = NameTranslator.CSharpNameFromScript(name); method.Attributes = MemberAttributes.Override | MemberAttributes.Public; method.ReturnType = new CodeTypeReference(baseMethod.ReturnType); var args = baseMethod.GetParameters(); FunctionBlock block = new FunctionBlock(null, method, codeType); block.Statements.Add("var root = this.root;"); //block.Statements.Add ("UnityEngine.Debug.Log(root.ToString() + IfStatement.AntiMergeValue++);"); var externVar = new DeclareVariableStatement() { Name = "External", IsArg = true, Type = Engine.GetType("External") }; block.Statements.Add(externVar); block.Statements.Add(new ContextStatement() { ContextVar = externVar, InterpretInContext = Engine.GetPlugin <ExternalFunctionsPlugin>().Ctx.InterpretInContext }); foreach (var initStmt in initStatements) { block.Statements.Add(initStmt); } //bool hasRoot = false; foreach (var arg in args) { //if (arg.Name == "root") // hasRoot = true; method.Parameters.Add(new CodeParameterDeclarationExpression(arg.ParameterType, arg.Name)); var paramVar = new DeclareVariableStatement(); paramVar.Name = arg.Name; paramVar.Type = arg.ParameterType; paramVar.IsArg = true; block.Statements.Add(paramVar); } var rootVar = new DeclareVariableStatement(); rootVar.Name = "root"; rootVar.Type = typeof(GameObject); rootVar.IsArg = true; block.Statements.Add(rootVar); foreach (var member in codeType.Members) { var field = member as CodeMemberField; if (field != null) { var cachedVar = new DeclareVariableStatement(); cachedVar.Name = field.Name; cachedVar.Type = field.UserData ["type"] as Type; cachedVar.IsArg = true; block.Statements.Add(cachedVar); } } //if (!hasRoot) //{ // Debug.LogFormat ("Method {0} in {1} has no root arg", baseMethod.Name, codeType.Name); // return; //} codeType.Members.Add(method); var table = context as Context; if (table != null) { foreach (var entry in table.Entries) { Operator op = entry as Operator; var inter = functionOperators.GetInterpreter(op, block); if (inter == null) { Debug.LogFormat("Can't find interpreter for operator {0} in {1} of {2}", op.Identifier, baseMethod.Name, codeType.Name); continue; } inter.Interpret(op, block); } var retVal = block.FindStatement <DeclareVariableStatement> (v => v.IsReturn); if (retVal != null) { block.Statements.Add(String.Format("return {0};", retVal.Name)); } } else { var expr = context as Expression; var retVal = block.FindStatement <DeclareVariableStatement> (v => v.IsReturn); //retVal.IsArg = true; block.Statements.Add(String.Format("return ({1}){0};", exprInter.InterpretExpression(expr, block).ExprString, TypeName.NameOf(retVal.Type))); } method.Statements.Add(new CodeSnippetStatement(block.ToString())); }
public override void Interpret(Script script) { MaxProgress = script.Entries.Count; for (int i = 0; i < script.Entries.Count; i++) { if (!Engine.Working) { Thread.CurrentThread.Abort(); } CurProgress = i; var entry = script.Entries[i]; CodeTypeDeclaration codeType = new CodeTypeDeclaration(); //codeType.CustomAttributes. codeType.BaseTypes.Add(new CodeTypeReference(typeof(Metric))); codeType.Name = entry.Identifier as string; codeTypes.Add(codeType); if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning((entry.Identifier as string).ToUpper()); } var ctx = entry.Context as Context; if (ctx == null) { continue; } var scopeMethod = typeof(Metric).GetMethod("RootFilter"); var otherScopeMethod = typeof(Metric).GetMethod("OtherFilter"); var valueMethod = typeof(Metric).GetMethod("Value"); CodeAttributeDeclaration attr = new CodeAttributeDeclaration("MetricAttribute"); codeType.CustomAttributes.Add(attr); CodeAttributeArgument weightArg = new CodeAttributeArgument("Weight", new CodeSnippetExpression("1")); attr.Arguments.Add(weightArg); FunctionBlock dependenciesBlock = new FunctionBlock(null, null, codeType); List <string> deps = new List <string>(); for (int j = 0; j < ctx.Entries.Count; j++) { var op = ctx.Entries[j] as Operator; if (op == null) { continue; } if (op.Identifier as string == "weight") { weightArg.Value = new CodeSnippetExpression((op.Context as InternalDSL.Expression).Operands[0].ToString()); } else if (op.Identifier as string == "category") { var cat = (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0].ToString(); var type = Engine.FindType("ScriptedTypes." + cat); if (type != null) { var props = type.GetProperties(); codeType.BaseTypes.Add(type); foreach (var propInfo in props) { var prop = new CodeMemberProperty(); prop.HasGet = true; prop.HasSet = true; prop.Name = propInfo.Name; prop.Type = new CodeTypeReference(propInfo.PropertyType); var fieldName = NameTranslator.ScriptNameFromCSharp(prop.Name); prop.GetStatements.Add(new CodeSnippetStatement(String.Format("return {0}; ", fieldName))); prop.SetStatements.Add(new CodeSnippetStatement(String.Format("{0} = value; ", fieldName))); prop.PrivateImplementationType = new CodeTypeReference(type); if (!codeType.UserData.Contains(fieldName)) { var field = new CodeMemberField(); field.Name = fieldName; field.Type = new CodeTypeReference(propInfo.PropertyType); codeType.Members.Add(field); codeType.UserData.Add(fieldName, field); field.UserData.Add("type", propInfo.PropertyType); } codeType.Members.Add(prop); } } else { if (!cNamespace.UserData.Contains(cat)) { CodeTypeDeclaration catInterface = new CodeTypeDeclaration(cat); catInterface.IsInterface = true; cNamespace.Types.Add(catInterface); cNamespace.UserData.Add(cat, catInterface); } codeType.BaseTypes.Add(cat); } } else if (op.Identifier as string == "scope") { //It's a filter function // Debug.Log (op.Context.GetType ()); if (ScriptEngine.AnalyzeDebug) { Debug.Log((op.Context as Expression).Operands[0].GetType()); } (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true"); DeclareVariableStatement retVal = new DeclareVariableStatement(); retVal.IsReturn = true; retVal.Name = "applicable"; retVal.Type = typeof(bool); retVal.InitExpression = "false"; CreateEventFunction("RootFilter", op.Context, codeType, scopeMethod, false, retVal); //CreateFilterFunction (op.Context as Expression, codeType); } else if (op.Identifier as string == "other_scope") { //It's a filter function // Debug.Log (op.Context.GetType ()); if (ScriptEngine.AnalyzeDebug) { Debug.Log((op.Context as Expression).Operands[0].GetType()); } (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true"); DeclareVariableStatement retVal = new DeclareVariableStatement(); retVal.IsReturn = true; retVal.Name = "applicable"; retVal.Type = typeof(bool); retVal.InitExpression = "false"; //Debug.Log(otherScopeMethod); CreateEventFunction("OtherFilter", op.Context, codeType, otherScopeMethod, false, retVal); //CreateFilterFunction (op.Context as Expression, codeType); } else if (op.Identifier as string == "value") { DeclareVariableStatement utVal = new DeclareVariableStatement(); utVal.IsReturn = true; utVal.Name = "val"; utVal.Type = typeof(float); utVal.InitExpression = "0"; CreateEventFunction(op.Identifier as string, op.Context, codeType, valueMethod, false, utVal); } else { //No idea } } if (deps.Count > 0) { CodeMemberMethod getDepsOverride = new CodeMemberMethod(); getDepsOverride.ReturnType = new CodeTypeReference(typeof(List <Dependency>)); getDepsOverride.Name = "GetDependencies"; getDepsOverride.Attributes = MemberAttributes.Public | MemberAttributes.Override; codeType.Members.Add(getDepsOverride); string listName = "list" + DeclareVariableStatement.VariableId++; string listOp = String.Format("var {0} = new System.Collections.Generic.List<Dependency>({1});", listName, deps.Count); dependenciesBlock.Statements.Add(listOp); var addToListBlock = new FunctionBlock(dependenciesBlock); foreach (var newDep in deps) { addToListBlock.Statements.Add(String.Format("{0}.Add({1});", listName, newDep)); } dependenciesBlock.Statements.Add(addToListBlock); dependenciesBlock.Statements.Add(String.Format("return {0};", listName)); getDepsOverride.Statements.Add(new CodeSnippetStatement(dependenciesBlock.ToString())); } CodeMemberMethod initOverrideMethod = new CodeMemberMethod(); initOverrideMethod.Name = "Init"; initOverrideMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; codeType.Members.Add(initOverrideMethod); builder.Length = 0; builder.Append("base.Init();").AppendLine(); foreach (var member in codeType.Members) { var field = member as CodeMemberField; if (field != null) { builder.Append("this.").Append(field.Name).Append(" = ").Append("default(").Append((field.UserData["type"] as Type).FullName).Append(");").AppendLine(); } } initOverrideMethod.Statements.Add(new CodeSnippetStatement(builder.ToString())); } CurProgress = MaxProgress; foreach (var type in codeTypes) { cNamespace.Types.Add(type); } CSharpCodeProvider provider = new CSharpCodeProvider(); CodeGeneratorOptions options = new CodeGeneratorOptions(); var writer = new StringWriter(); provider.GenerateCodeFromNamespace(cNamespace, writer, options); Engine.GetPlugin <ScriptCompiler>().AddSource(writer.ToString()); }
public override void Interpret(Script script) { MaxProgress = script.Entries.Count; for (int i = 0; i < script.Entries.Count; i++) { if (!Engine.Working) { Thread.CurrentThread.Abort(); } CurProgress = i; var entry = script.Entries [i]; CodeTypeDeclaration codeType = new CodeTypeDeclaration(); //codeType.CustomAttributes. codeType.BaseTypes.Add(new CodeTypeReference(typeof(EventAction))); codeType.Name = entry.Identifier as string; codeTypes.Add(codeType); if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning((entry.Identifier as string).ToUpper()); } var ctx = entry.Context as Context; if (ctx == null) { continue; } var actionMethod = typeof(EventAction).GetMethod("Action"); var utMethod = typeof(EventAction).GetMethod("Utility"); var scopeMethod = typeof(EventAction).GetMethod("Filter"); var interMethod = typeof(EventAction).GetMethod("Interaction"); CodeAttributeDeclaration attr = new CodeAttributeDeclaration("EventActionAttribute"); codeType.CustomAttributes.Add(attr); CodeAttributeArgument maxArg = new CodeAttributeArgument("ShouldHaveMaxUtility", new CodeSnippetExpression("false")); CodeAttributeArgument onceArg = new CodeAttributeArgument("OncePerObject", new CodeSnippetExpression("false")); CodeAttributeArgument oncePerTurnArg = new CodeAttributeArgument("OncePerTurn", new CodeSnippetExpression("false")); CodeAttributeArgument aiActionArg = new CodeAttributeArgument("IsAIAction", new CodeSnippetExpression("false")); CodeAttributeArgument interactionArg = new CodeAttributeArgument("IsInteraction", new CodeSnippetExpression("false")); CodeAttributeArgument tooltipArg = new CodeAttributeArgument("Tooltip", new CodeSnippetExpression("\"\"")); CodeAttributeArgument onceInCategory = new CodeAttributeArgument("OnceInCategory", new CodeSnippetExpression("false")); attr.Arguments.Add(maxArg); attr.Arguments.Add(onceArg); attr.Arguments.Add(oncePerTurnArg); attr.Arguments.Add(aiActionArg); attr.Arguments.Add(tooltipArg); attr.Arguments.Add(onceInCategory); attr.Arguments.Add(interactionArg); FunctionBlock dependenciesBlock = new FunctionBlock(null, null, codeType); List <string> deps = new List <string>(); for (int j = 0; j < ctx.Entries.Count; j++) { var op = ctx.Entries [j] as Operator; if (op == null) { continue; } if (op.Identifier as string == "tooltip") { tooltipArg.Value = new CodeSnippetExpression((op.Context as InternalDSL.Expression).Operands[0].ToString()); } else if (op.Identifier as string == "ai_action") { aiActionArg.Value = new CodeSnippetExpression("true"); } else if (op.Identifier as string == "once_per_category") { onceInCategory.Value = new CodeSnippetExpression("true"); } else if (op.Identifier as string == "only_max_utility") { maxArg.Value = new CodeSnippetExpression((op.Context as InternalDSL.Expression).Operands[0].ToString()); } else if (op.Identifier as string == "category") { var cat = (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0].ToString(); var type = Engine.FindType("ScriptedTypes." + cat); if (type == null) { type = Engine.FindType(NameTranslator.CSharpNameFromScript(cat)); } if (type != null) { var props = type.GetProperties(); codeType.BaseTypes.Add(type); foreach (var propInfo in props) { var prop = new CodeMemberProperty(); prop.HasGet = true; prop.HasSet = true; prop.Name = propInfo.Name; prop.Type = new CodeTypeReference(propInfo.PropertyType); var fieldName = NameTranslator.ScriptNameFromCSharp(prop.Name); prop.GetStatements.Add(new CodeSnippetStatement(String.Format("return {0}; ", fieldName))); prop.SetStatements.Add(new CodeSnippetStatement(String.Format("{0} = value; ", fieldName))); prop.PrivateImplementationType = new CodeTypeReference(type); if (!codeType.UserData.Contains(fieldName)) { var field = new CodeMemberField(); field.Name = fieldName; field.Type = new CodeTypeReference(propInfo.PropertyType); codeType.Members.Add(field); codeType.UserData.Add(fieldName, field); field.UserData.Add("type", propInfo.PropertyType); } codeType.Members.Add(prop); } } else { if (!cNamespace.UserData.Contains(cat)) { CodeTypeDeclaration catInterface = new CodeTypeDeclaration(cat); catInterface.IsInterface = true; cNamespace.Types.Add(catInterface); cNamespace.UserData.Add(cat, catInterface); } codeType.BaseTypes.Add(cat); } } else if (op.Identifier as string == "once_per_object") { onceArg.Value = new CodeSnippetExpression("true"); } else if (op.Identifier as string == "once_per_turn") { oncePerTurnArg.Value = new CodeSnippetExpression("true"); } else if (op.Identifier as string == "scope") { //It's a filter function // Debug.Log (op.Context.GetType ()); if (ScriptEngine.AnalyzeDebug) { Debug.Log((op.Context as Expression).Operands[0].GetType()); } (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true"); DeclareVariableStatement retVal = new DeclareVariableStatement(); retVal.IsReturn = true; retVal.Name = "applicable"; retVal.Type = typeof(bool); retVal.InitExpression = "false"; CreateEventFunction("Filter", op.Context, codeType, scopeMethod, false, retVal); //CreateFilterFunction (op.Context as Expression, codeType); } else if (op.Identifier as string == "interaction") { //It's a filter function // Debug.Log (op.Context.GetType ()); if (ScriptEngine.AnalyzeDebug) { Debug.Log((op.Context as Expression).Operands[0].GetType()); } (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true"); DeclareVariableStatement retVal = new DeclareVariableStatement(); retVal.IsReturn = true; retVal.Name = "applicable"; retVal.Type = typeof(bool); retVal.InitExpression = "false"; CreateEventFunction("Interaction", op.Context, codeType, interMethod, false, retVal); interactionArg.Value = new CodeSnippetExpression("true"); //CreateFilterFunction (op.Context as Expression, codeType); var type = typeof(EventInteraction); var props = type.GetProperties(); codeType.BaseTypes.Add(type); foreach (var propInfo in props) { var prop = new CodeMemberProperty(); prop.HasGet = true; prop.HasSet = true; prop.Name = propInfo.Name; prop.Type = new CodeTypeReference(propInfo.PropertyType); var fieldName = NameTranslator.ScriptNameFromCSharp(prop.Name); prop.GetStatements.Add(new CodeSnippetStatement(String.Format("return {0}; ", fieldName))); prop.SetStatements.Add(new CodeSnippetStatement(String.Format("{0} = value; ", fieldName))); prop.PrivateImplementationType = new CodeTypeReference(type); if (!codeType.UserData.Contains(fieldName)) { var field = new CodeMemberField(); field.Name = fieldName; field.Type = new CodeTypeReference(propInfo.PropertyType); codeType.Members.Add(field); codeType.UserData.Add(fieldName, field); field.UserData.Add("type", propInfo.PropertyType); } codeType.Members.Add(prop); } } else if (op.Identifier as string == "action") { //It's an action function CreateEventFunction(op.Identifier as string, op.Context, codeType, actionMethod, true); } else if (op.Identifier as string == "utility") { DeclareVariableStatement utVal = new DeclareVariableStatement(); utVal.IsReturn = true; utVal.Name = "ut"; utVal.Type = typeof(float); utVal.InitExpression = "0"; CreateEventFunction(op.Identifier as string, op.Context, codeType, utMethod, false, utVal); } else if (op.Identifier as string == "depends") { //Debug.Log(op); //Debug.Log(((op.Context as Expression).Operands[0] as ExprAtom).Content.GetType().Name); var ctor = ((((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0] as FunctionCall); var type = Engine.FindType(NameTranslator.CSharpNameFromScript(ctor.Name)); MethodInfo initMethod = type.GetMethod("Init"); var args = initMethod.GetParameters(); bool hasInteractable = false; bool hasInitiator = false; foreach (var param in args) { if (param.Name == "interactable") { hasInteractable = true; } else if (param.Name == "initiator") { hasInitiator = true; } } builder.Length = 0; builder.Append("new "); builder.Append(type.FullName); builder.Append("().Init"); builder.Append("("); if (hasInteractable) { builder.Append("this.root"); builder.Append(","); } if (hasInitiator) { builder.Append("this.initiator"); builder.Append(","); } foreach (var funcArg in ctor.Args) { builder.Append(exprInter.InterpretExpression(funcArg, dependenciesBlock).ExprString); builder.Append(","); } if (builder[builder.Length - 1] == ',') { builder.Length = builder.Length - 1; } builder.Append(")"); deps.Add(builder.ToString()); } else { //No idea } } if (deps.Count > 0) { CodeMemberMethod getDepsOverride = new CodeMemberMethod(); getDepsOverride.ReturnType = new CodeTypeReference(typeof(List <Dependency>)); getDepsOverride.Name = "GetDependencies"; getDepsOverride.Attributes = MemberAttributes.Public | MemberAttributes.Override; codeType.Members.Add(getDepsOverride); string listName = "list" + DeclareVariableStatement.VariableId++; string listOp = String.Format("var {0} = new System.Collections.Generic.List<Dependency>({1});", listName, deps.Count); dependenciesBlock.Statements.Add(listOp); var addToListBlock = new FunctionBlock(dependenciesBlock); foreach (var newDep in deps) { addToListBlock.Statements.Add(String.Format("{0}.Add({1});", listName, newDep)); } dependenciesBlock.Statements.Add(addToListBlock); dependenciesBlock.Statements.Add(String.Format("return {0};", listName)); getDepsOverride.Statements.Add(new CodeSnippetStatement(dependenciesBlock.ToString())); } CodeMemberMethod initOverrideMethod = new CodeMemberMethod(); initOverrideMethod.Name = "Init"; initOverrideMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; codeType.Members.Add(initOverrideMethod); builder.Length = 0; builder.Append("base.Init();").AppendLine(); foreach (var member in codeType.Members) { var field = member as CodeMemberField; if (field != null) { builder.Append("this.").Append(field.Name).Append(" = ").Append("default(").Append((field.UserData["type"] as Type).FullName).Append(");").AppendLine(); } } initOverrideMethod.Statements.Add(new CodeSnippetStatement(builder.ToString())); } CurProgress = MaxProgress; foreach (var type in codeTypes) { cNamespace.Types.Add(type); } CSharpCodeProvider provider = new CSharpCodeProvider(); CodeGeneratorOptions options = new CodeGeneratorOptions(); var writer = new StringWriter(); provider.GenerateCodeFromNamespace(cNamespace, writer, options); Engine.GetPlugin <ScriptCompiler> ().AddSource(writer.ToString()); }
public Expr ProcessOperand(object operand, FunctionBlock block, bool isInsideBoolean = false) { Expr returnExpr = new Expr(); StringBuilder exprBuilder = new StringBuilder(); bool hasSign = false; DeclareVariableStatement resultVar = new DeclareVariableStatement(); resultVar.IsHidden = true; int insertResultIndex = block.Statements.Count; block.Statements.Add(""); char signChar = ' '; if (operand is ExprAtom) { if ((operand as ExprAtom).Op == ExprAtom.UnaryOp.Inverse) { signChar = '!'; } else if ((operand as ExprAtom).Op == ExprAtom.UnaryOp.Not) { signChar = '-'; } operand = (operand as ExprAtom).Content; } BindingFlags any = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public; if (operand is Scope) { //bool exprIsResultVar = false; var scope = (operand as Scope).Parts; bool contextVariable = true; var contextVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == scope [0] as string); if (contextVariable = (contextVar == null)) { contextVar = block.FindStatement <DeclareVariableStatement> (v => v.IsContext); } if (ScriptEngine.AnalyzeDebug) { Debug.LogWarningFormat("S_CTX {0} {1}", contextVar, operand); } string contextName = null; //!contextVariable ? "root" : contextVar.Name; Type contextType = null; //!contextVariable ? typeof(GameObject) : contextVar.Type; if (contextVar == null) { contextName = block.DefaultScope; contextType = typeof(GameObject); } else { contextName = contextVar.Name; contextType = contextVar.Type; } exprBuilder.Append(contextName).Append("."); bool firstTimeList = true; FunctionBlock curBlock = block; for (int i = contextVariable ? 0 : 1; i < scope.Count; i++) { if (ScriptEngine.AnalyzeDebug) { Debug.LogWarningFormat("scope part {0} {1} {2}", scope [i], contextType.IsGenericType, contextType.IsGenericType ? (contextType.GetGenericTypeDefinition() == typeof(List <>)).ToString() : ""); } if (contextType == null) { Debug.LogErrorFormat("Context type is null, {0}, \r\n {1}", operand, block.ToString()); } if (contextType.IsGenericType && contextType.GetGenericTypeDefinition() == typeof(List <>)) { if (firstTimeList) { CleanUpContextes.Push(resultVar); resultVar.IsTemp = true; resultVar.Name = "result" + DeclareVariableStatement.VariableId++; block.Statements [insertResultIndex] = resultVar; resultVar.IsHidden = false; resultVar.IsResult = true; //resultList.Type = contextType; //exprIsResultVar = true; firstTimeList = false; } Debug.Log("scope list " + scope [i]); DeclareVariableStatement declVar = new DeclareVariableStatement(); CleanUpContextes.Push(declVar); declVar.IsTemp = true; declVar.Name = "list" + DeclareVariableStatement.VariableId++; declVar.Type = contextType; if (exprBuilder [exprBuilder.Length - 1] == '.') { exprBuilder.Length -= 1; } if (hasSign) { declVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1); exprBuilder.Length = 1; //exprBuilder.Append (declVar.Name).Append ('.'); } else { declVar.InitExpression = exprBuilder.ToString(); exprBuilder.Length = 0; //exprBuilder.Append (declVar.Name).Append ('.'); } curBlock.Statements.Add(declVar); ForStatement forStatement = new ForStatement(); forStatement.RepeatBlock = new FunctionBlock(block, block.Method, block.Type); var repeatContext = new DeclareVariableStatement(); repeatContext.IsTemp = true; CleanUpContextes.Push(repeatContext); forStatement.RepeatBlock.Statements.Add(repeatContext); curBlock.Statements.Add(forStatement); curBlock = forStatement.RepeatBlock; var iterName = "i" + DeclareVariableStatement.VariableId++; forStatement.InsideExpr = String.Format(@"int {0} = 0; {0} < {1}.Count; {0}++", iterName, declVar.Name); contextType = contextType.GetGenericArguments() [0]; repeatContext.Name = "SubContext" + DeclareVariableStatement.VariableId++; repeatContext.Type = contextType; repeatContext.IsContext = true; repeatContext.InitExpression = String.Format(@"{0}[{1}]", declVar.Name, iterName); } bool isFunc = false; if (scope [i] is FunctionCall || scope [i] is string) { // var callOp = ProcessOperand (scope [i], block); Expression[] callArgs = defaultArgsList; string callName = null; var call = scope [i] as FunctionCall; if (call != null) { callName = call.Name; callArgs = call.Args; } else { callName = scope [i] as string; } if (scopeInterpreters.ContainsKey(callName)) { var interpreter = scopeInterpreters [callName]; string outExpr = null; interpreter.Interpret(callArgs, curBlock, contextType, exprBuilder.ToString(), out outExpr, out curBlock, out contextType, i == scope.Count - 1); if (hasSign) { exprBuilder.Length = 1; exprBuilder.Append(outExpr).Append('.'); } else { exprBuilder.Length = 0; exprBuilder.Append(outExpr).Append('.'); } isFunc = true; } else { var methodName = NameTranslator.CSharpNameFromScript(callName); var method = contextType.GetMethod(methodName); if (i == 0 && method == null) { var otherContext = block.FindStatement <DeclareVariableStatement> (v => (v.IsContext || v.IsArg) && (method = v.Type.GetMethod(methodName, any)) != null); if (otherContext != null) { exprBuilder.Length = hasSign ? 1 : 0; if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning("OTHER CONTEXT" + otherContext.DebugString()); } exprBuilder.Append(otherContext.Name).Append('.'); contextType = otherContext.Type; } else { if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning("Can't find context for method " + methodName); } block.FindStatement <DeclareVariableStatement> (v => { if (ScriptEngine.AnalyzeDebug) { Debug.LogFormat("{0} {1} {3} ||||{2}", v.Name, v.Type, IfStatement.AntiMergeValue++, v.IsContext || v.IsArg); } return(false); }); } } if (method == null) { if (ScriptEngine.AnalyzeDebug) { Debug.LogFormat("Can't find method {0} in {1}", NameTranslator.CSharpNameFromScript(callName), contextType); } } else { exprBuilder.Append(method.Name).Append("("); var argsDef = method.GetParameters(); if (callArgs != null) { for (int j = 0; j < callArgs.Length; j++) { try { if (argsDef[j].ParameterType.IsSubclassOf(typeof(Delegate))) { exprBuilder.Append(InterpretClosure(callArgs[j], curBlock, argsDef[j].ParameterType).ExprString).Append(","); } else if (argsDef[j].ParameterType == typeof(System.Type)) { exprBuilder.Append("typeof(ScriptedTypes."). Append(callArgs[j].ToString().ClearFromBraces()).Append(")").Append(","); } else { exprBuilder.Append(InterpretExpression(callArgs[j], curBlock).ExprString).Append(","); } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.LogErrorFormat("Index out of range {0} in args of {1}. Script: {2}, Args count: {3}", j, method.Name, operand, argsDef.Length); } } if (callArgs.Length > 0) { exprBuilder.Length -= 1; } } exprBuilder.Append(")"); contextType = method.ReturnType; var declVar = new DeclareVariableStatement(); CleanUpContextes.Push(declVar); declVar.IsTemp = true; declVar.Name = "prop" + DeclareVariableStatement.VariableId++; declVar.IsContext = true; if (exprBuilder.Length > 0 && exprBuilder [exprBuilder.Length - 1] == '.') { exprBuilder.Length -= 1; } if (hasSign) { declVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1); exprBuilder.Length = 1; exprBuilder.Append(declVar.Name).Append('.'); } else { declVar.InitExpression = exprBuilder.ToString(); exprBuilder.Length = 0; exprBuilder.Append(declVar.Name).Append('.'); } declVar.Type = contextType; curBlock.Statements.Add(declVar); if (contextType.IsClass) { IfStatement ifSt = new IfStatement(); ifSt.CheckExpression = String.Format("{0} != null", declVar.Name); ifSt.TrueBlock = new FunctionBlock(curBlock); curBlock.Statements.Add(ifSt); curBlock = ifSt.TrueBlock; } else if (contextType == typeof(bool)) { IfStatement ifSt = new IfStatement(); ifSt.CheckExpression = String.Format("{0} != false", declVar.Name); ifSt.TrueBlock = new FunctionBlock(curBlock); curBlock.Statements.Add(ifSt); curBlock = ifSt.TrueBlock; } isFunc = true; } } } if (!isFunc) { var scopeStr = scope[i] as string; if (scopeStr == null) { Debug.LogErrorFormat("{0} can't be casted to string", scope[i]); } var propName = NameTranslator.CSharpNameFromScript(scopeStr); var prop = contextType.GetProperty(propName); if (i == 0 && prop == null) { var customVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == scope [i] as string); if (ScriptEngine.CompileDebug) { Debug.LogFormat("{0} - {1} custom var", scope[i], customVar); } if (customVar == null) { var otherContext = block.FindStatement <DeclareVariableStatement> (v => { //Debug.LogWarning (v.Type); //Debug.Log (v.IsContext || v.IsArg); //var props = v.Type.GetProperties (any); //foreach (var allProp in props) // Debug.Log (allProp.Name); return((v.IsContext || v.IsArg) && (prop = v.Type.GetProperty(propName, any)) != null); }); if (otherContext != null) { exprBuilder.Length = hasSign ? 1 : 0; exprBuilder.Append(otherContext.Name).Append('.'); contextType = otherContext.Type; if (contextType.IsClass && !prop.GetGetMethod().IsStatic) { IfStatement ifSt = new IfStatement(); ifSt.CheckExpression = String.Format("{0} != null", otherContext.Name); ifSt.TrueBlock = new FunctionBlock(curBlock); curBlock.Statements.Add(ifSt); curBlock = ifSt.TrueBlock; } } else if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning("Can't find context for property " + propName); } } else { exprBuilder.Length = hasSign ? 1 : 0; exprBuilder.Append(customVar.Name).Append('.'); contextType = customVar.Type; if (contextType.IsClass && !prop.GetGetMethod().IsStatic) { IfStatement ifSt = new IfStatement(); ifSt.CheckExpression = String.Format("{0} != null", customVar.Name); ifSt.TrueBlock = new FunctionBlock(curBlock); curBlock.Statements.Add(ifSt); curBlock = ifSt.TrueBlock; } } } if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning(prop); } if (prop == null && components.ContainsKey(scope [i] as string)) { var type = components [scope [i] as string]; string storedFromName = null; if (hasSign) { storedFromName = exprBuilder.ToString(1, exprBuilder.Length - 1); } else { storedFromName = exprBuilder.ToString(); } if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning("Component found " + type); } var storedVar = curBlock.FindStatement <DeclareVariableStatement> (v => v.Type == type && v.storedOf != null && storedFromName == v.storedOf); var prevType = contextType; contextType = type; if (storedVar == null) { storedVar = new DeclareVariableStatement(); CleanUpContextes.Push(storedVar); storedVar.IsTemp = true; storedVar.IsContext = true; storedVar.Name = "StoredVariable" + DeclareVariableStatement.VariableId++; storedVar.Type = type; storedVar.storedOf = hasSign ? exprBuilder.ToString(1, exprBuilder.Length) : exprBuilder.ToString(0, exprBuilder.Length); if (prevType != typeof(GameObject) && !typeof(MonoBehaviour).IsAssignableFrom(prevType)) { exprBuilder.Length = hasSign ? 1 : 0; var ctx = block.FindStatement <DeclareVariableStatement>( v => v.IsContext && (v.Type == typeof(GameObject) || typeof(MonoBehaviour).IsAssignableFrom(v.Type)) ).Name; if (ctx == null) { ctx = block.DefaultScope; } exprBuilder.Append(ctx).Append('.'); } curBlock.Statements.Add(storedVar); exprBuilder.Append(String.Format("GetComponent(typeof({0})))", type)); exprBuilder.Insert(0, String.Format("(({0})", type)); if (hasSign) { storedVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1); exprBuilder.Length = 1; exprBuilder.Append(storedVar.Name).Append('.'); } else { storedVar.InitExpression = exprBuilder.ToString(); exprBuilder.Length = 0; exprBuilder.Append(storedVar.Name).Append('.'); } } if (hasSign) { exprBuilder.Length = 1; exprBuilder.Append(storedVar.Name).Append('.'); } else { exprBuilder.Length = 0; exprBuilder.Append(storedVar.Name).Append('.'); } if (contextType.IsClass) { IfStatement ifSt = new IfStatement(); ifSt.CheckExpression = String.Format("{0} != null", storedVar.Name); ifSt.TrueBlock = new FunctionBlock(curBlock); curBlock.Statements.Add(ifSt); curBlock = ifSt.TrueBlock; } } else if (scopeInterpreters.ContainsKey(scope [i] as string)) { var interpreter = scopeInterpreters [scope [i] as string]; string outExpr = null; interpreter.Interpret(null, curBlock, contextType, exprBuilder.ToString(), out outExpr, out curBlock, out contextType, i == scope.Count - 1); if (hasSign) { exprBuilder.Length = 1; exprBuilder.Append(outExpr).Append('.'); } else { exprBuilder.Length = 0; exprBuilder.Append(outExpr).Append('.'); } } else if (prop == null && scope.Count == 1) { if (ScriptEngine.AnalyzeDebug) { Debug.LogWarningFormat("Can't find {0} in {1}, interpreting as a string", propName, contextType); } contextType = typeof(string); exprBuilder.Length = 0; exprBuilder.Append("\"").Append(scope [i]).Append("\""); break; } else if (prop == null) { Debug.LogWarningFormat("Can't find {0} in {1}", propName, contextType); break; } else { contextType = prop.PropertyType; exprBuilder.Append(propName).Append('.'); var declVar = new DeclareVariableStatement(); CleanUpContextes.Push(declVar); declVar.IsTemp = true; declVar.IsContext = true; declVar.Name = "prop" + DeclareVariableStatement.VariableId++; if (exprBuilder.Length > 0 && exprBuilder [exprBuilder.Length - 1] == '.') { exprBuilder.Length -= 1; } if (hasSign) { declVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1); exprBuilder.Length = 1; exprBuilder.Append(declVar.Name).Append('.'); } else { declVar.InitExpression = exprBuilder.ToString(); exprBuilder.Length = 0; exprBuilder.Append(declVar.Name).Append('.'); } declVar.Type = contextType; curBlock.Statements.Add(declVar); if (contextType.IsClass) { IfStatement ifSt = new IfStatement(); ifSt.CheckExpression = String.Format("{0} != null", declVar.Name); ifSt.TrueBlock = new FunctionBlock(curBlock); curBlock.Statements.Add(ifSt); curBlock = ifSt.TrueBlock; } } } } returnExpr.Type = contextType; var res = resultVar; if (!res.IsHidden) { var list = curBlock.FindStatement <DeclareVariableStatement> (v => v.Type != null && v.Type.IsGenericType && v.Type.GetGenericTypeDefinition() == typeof(List <>)); var lasVar = curBlock.FindStatement <DeclareVariableStatement> (v => v.IsContext); if (list != null && !firstTimeList) { curBlock.Statements.Add(String.Format(@"{0}.Add({1});", res.Name, lasVar.Name)); res.Type = typeof(List <>).MakeGenericType(lasVar.Type); res.InitExpression = String.Format("new {0}();", TypeName.NameOf(res.Type)); } else { res.Type = lasVar.Type; curBlock.Statements.Add(String.Format(@"{0} = {1};", res.Name, lasVar.Name)); } if (hasSign) { exprBuilder.Length = 1; exprBuilder.Append(res.Name).Append('.'); } else { exprBuilder.Length = 0; exprBuilder.Append(res.Name).Append('.'); } returnExpr.Type = res.Type; } if (!res.IsHidden && res.Type != null) { var resType = res.Type; res.IsResult = false; Debug.Log(isInsideBoolean); if (isInsideBoolean && resType.IsGenericType && resType.GetGenericTypeDefinition() == typeof(List <>)) { exprBuilder.Append(String.Format(" != null ? {0}.Count : 0", exprBuilder)); } } if (exprBuilder.Length > 0 && exprBuilder [exprBuilder.Length - 1] == '.') { exprBuilder.Length -= 1; } if (res.IsHidden) { resultVar.Name = "OperandVar" + DeclareVariableStatement.VariableId++; resultVar.Type = contextType; resultVar.InitExpression = string.Format("default({0})", TypeName.NameOf(contextType)); resultVar.IsHidden = false; block.Statements [insertResultIndex] = resultVar; curBlock.Statements.Add(String.Format("{0} = {1};", resultVar.Name, exprBuilder)); exprBuilder.Length = hasSign ? 1 : 0; var resType = res.Type; if (isInsideBoolean && resType.IsGenericType && resType.GetGenericTypeDefinition() == typeof(List <>)) { exprBuilder.Append(String.Format("{0} != null ? {0}.Count : 0", resultVar.Name)); } else { exprBuilder.Append(resultVar.Name); } } } else if (operand is FunctionCall) { // var call = operand as FunctionCall; // for (int i = 0; i < call.Args.Length; i++) // { // // } } else if (operand is Expression) { var ex = InterpretExpression(operand as Expression, block, false, isInsideBoolean); exprBuilder.Append(ex.ExprString); returnExpr.Type = ex.Type; } else { returnExpr.Type = operand.GetType(); if (operand is bool) { exprBuilder.Append((bool)operand ? "true" : "false"); } else { exprBuilder.Append(operand); } if (operand is float) { exprBuilder.Append('f'); } } string head = String.Format("{0}(", signChar); exprBuilder.Insert(0, head).Append(')'); returnExpr.ExprString = exprBuilder.ToString(); return(returnExpr); }