public override void Interpret(Operator op, FunctionBlock block) { if (ScriptEngine.AnalyzeDebug) { Debug.LogWarning("Context function " + op.Identifier); } if (exprInter == null) { exprInter = Engine.GetPlugin <ExpressionInterpreter> (); } var any = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; var sCtx = block.FindStatement <ContextStatement> (v => v.InterpretInContext(op, block) != null && (v.ContextVar.IsContext || v.ContextVar.IsArg)); var contextVar = sCtx != null ? sCtx.ContextVar : null; //var contextVar = block.FindStatement<DeclareVariableStatement> (v => ); StringBuilder argsBuilder = new StringBuilder(); // if (((op.Context is Expression) && op.Args.Count + 1 != argsDef.Length) || // ((op.Context is Context) && op.Args.Count != argsDef.Length)) // { // Debug.Log ("Wrong amount of arguments"); // return; // } for (int i = 0; i < op.Args.Count; i++) { if (argsDef [i].ParameterType.IsSubclassOf(typeof(Delegate))) { argsBuilder.Append(exprInter.InterpretClosure(op.Args [i], block, argsDef [i].ParameterType).ExprString).Append(","); } else if (argsDef [i].ParameterType == typeof(string)) { argsBuilder.Append('(').Append(exprInter.InterpretExpression(op.Args [i], block).ExprString).Append(')').Append(".ToString()").Append(","); } else { argsBuilder.Append('(').Append(argsDef [i].ParameterType).Append(')').Append('(').Append(exprInter.InterpretExpression(op.Args [i], block).ExprString).Append(')').Append(","); } } if (op.Context is Expression) { if (argsDef [argsDef.Length - 1].ParameterType.IsSubclassOf(typeof(Delegate))) { argsBuilder. Append('('). Append(argsDef [argsDef.Length - 1].ParameterType). Append(')'). Append('('). Append(exprInter.InterpretClosure(op.Context as Expression, block, argsDef [argsDef.Length - 1].ParameterType).ExprString). Append(')'); } else if (argsDef [argsDef.Length - 1].ParameterType == typeof(string)) { argsBuilder.Append('(').Append(exprInter.InterpretExpression(op.Context as Expression, block).ExprString).Append(')').Append(".ToString()"); } else { argsBuilder. Append('('). Append(argsDef [argsDef.Length - 1].ParameterType). Append(')'). Append('('). Append(exprInter.InterpretExpression(op.Context as Expression, block).ExprString). Append(')'); } if (contextVar == null) { block.Statements.Add(string.Format("root.{0}({1});", funcName, argsBuilder)); } else { block.Statements.Add(string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name)); } } else if (ctxInter != null) { if (op.Args.Count > 0) { argsBuilder.Length -= 1; } var ctx = op.Context as Context; FunctionBlock contextBlock = new FunctionBlock(block); block.Statements.Add(contextBlock); block = contextBlock; DeclareVariableStatement ctxVar = new DeclareVariableStatement(); ctxVar.Name = "FuncCtx" + DeclareVariableStatement.VariableId++; ctxVar.InitExpression = contextVar == null?string.Format("root.{0}({1});", funcName, argsBuilder) : string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name); ctxVar.Type = returnType; ctxVar.IsContext = true; ContextStatement stmt = new ContextStatement(); stmt.ContextVar = ctxVar; stmt.InterpretInContext = ctxInter.InterpretInContext; block.Statements.Add(ctxVar); block.Statements.Add(stmt); IfStatement isNotNull = new IfStatement(); isNotNull.CheckExpression = String.Format("{0} != null", ctxVar.Name); isNotNull.TrueBlock = new FunctionBlock(block); block.Statements.Add(isNotNull); block = isNotNull.TrueBlock; for (int i = 0; i < ctx.Entries.Count; i++) { ops.GetInterpreter(ctx.Entries [i] as Operator, block).Interpret(ctx.Entries [i] as Operator, block); } } else { //Func doesn't return a context, while maybe allows for either lambda as value or context addition var lastArg = argsDef.Length > 0 ? argsDef [argsDef.Length - 1] : null; if (lastArg != null) { if (typeof(Delegate).IsAssignableFrom(lastArg.ParameterType)) { Debug.Log("LAMBDA!"); //Interpret as lambda LambdaStatement lambda = new LambdaStatement(); lambda.DelegateType = lastArg.ParameterType; var method = lastArg.ParameterType.GetMethod("Invoke"); lambda.Params = method.GetParameters(); lambda.Name = "Lambda" + DeclareVariableStatement.VariableId++; block.Statements.Add(lambda); lambda.Block = new FunctionBlock(block); //DeclareVariableStatement lastVar = null; foreach (var param in lambda.Params) { var argVar = new DeclareVariableStatement(); // lastVar = argVar; argVar.Name = param.Name; argVar.IsArg = true; argVar.Type = param.ParameterType; lambda.Block.Statements.Add(argVar); } //if (lastVar != null) // lastVar.IsContext = true; var retType = lambda.DelegateType.GetMethod("Invoke").ReturnType; bool hasReturn = false; if (retType != null && retType != typeof(void)) { hasReturn = true; lambda.Block.Statements.Add(new DeclareVariableStatement() { Name = "return_value", InitExpression = string.Format("default({0})", retType), IsReturn = true, Type = retType }); } foreach (var entry in (op.Context as Context).Entries) { var subOp = entry as Operator; ops.GetInterpreter(subOp, lambda.Block).Interpret(subOp, lambda.Block); } if (hasReturn) { lambda.Block.Statements.Add("return return_value;"); } //Don't forget to call a function and add an arugment argsBuilder.Append(lambda.Name); if (contextVar == null) { block.Statements.Add(string.Format("root.{0}({1});", funcName, argsBuilder)); } else { block.Statements.Add(string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name)); } } else if (addContextInter != null) { //Interpret as new value DeclareVariableStatement newVar = new DeclareVariableStatement(); newVar.Name = "NewArg" + DeclareVariableStatement.VariableId++; newVar.IsContext = true; newVar.Type = lastArg.ParameterType; if (contextVar == null) { newVar.InitExpression = String.Format("root.AddComponent<{0}>()", newVar.Type); } else { newVar.InitExpression = String.Format("{0}.AddComponent<{0}>()", contextVar.Name, newVar.Type); } FunctionBlock contextBlock = new FunctionBlock(block); contextBlock.Statements.Add(newVar); addContextInter.Interpret(op, contextBlock); argsBuilder.Append(newVar.Name); if (contextVar == null) { contextBlock.Statements.Add(string.Format("root.{0}({1});", funcName, argsBuilder)); } else { contextBlock.Statements.Add(string.Format("{2}.{0}({1});", funcName, argsBuilder, contextVar.Name)); } block.Statements.Add(contextBlock); } } } }
public override void Interpret(Operator op, FunctionBlock block) { interpret = false; if (exprInter == null) { switches = Engine.GetPlugin <ContextSwitchesPlugin> (); ops = Engine.GetPlugin <EventFunctionOperators> (); exprInter = Engine.GetPlugin <ExpressionInterpreter> (); } var varName = op.Identifier as string; if (ScriptEngine.AnalyzeDebug) { Debug.Log(block); } var sCtx = block.FindStatement <ContextStatement> (v => v.InterpretInContext(op, block) != null && (v.ContextVar.IsContext || v.ContextVar.IsArg)); var context = sCtx != null ? sCtx.ContextVar : null; if (ScriptEngine.AnalyzeDebug) { Debug.LogFormat("FOUND COUNTEXT {0} for {1}", context, op.Identifier); } if (listT == null) { if (op.Context is Expression) { if (ScriptEngine.AnalyzeDebug) { Debug.Log("PROPERTY " + propName); } if (context == null) { block.Statements.Add(String.Format("root.{0} = ({2})({1});", propName, exprInter.InterpretExpression(op.Context as Expression, block, propType).ExprString, TypeName.NameOf(propType))); } else { block.Statements.Add(String.Format("{2}.{0} = ({3})({1});", propName, exprInter.InterpretExpression(op.Context as Expression, block, propType).ExprString, context.Name, TypeName.NameOf(propType))); } } else if (typeof(Delegate).IsAssignableFrom(propType)) { Debug.Log("LAMBDA!"); //Interpret as lambda LambdaStatement lambda = new LambdaStatement(); lambda.DelegateType = propType; var method = propType.GetMethod("Invoke"); lambda.Params = method.GetParameters(); lambda.Name = "Lambda" + DeclareVariableStatement.VariableId++; block.Statements.Add(lambda); lambda.Block = new FunctionBlock(block); //DeclareVariableStatement lastVar = null; foreach (var param in lambda.Params) { var argVar = new DeclareVariableStatement(); // lastVar = argVar; argVar.Name = param.Name; argVar.IsArg = true; argVar.Type = param.ParameterType; lambda.Block.Statements.Add(argVar); } //if (lastVar != null) // lastVar.IsContext = true; var retType = lambda.DelegateType.GetMethod("Invoke").ReturnType; bool hasReturn = false; if (retType != null && retType != typeof(void)) { hasReturn = true; lambda.Block.Statements.Add(new DeclareVariableStatement() { Name = "return_value", InitExpression = string.Format("default({0})", retType), IsReturn = true, Type = retType }); } foreach (var entry in (op.Context as Context).Entries) { var subOp = entry as Operator; ops.GetInterpreter(subOp, lambda.Block).Interpret(subOp, lambda.Block); } if (hasReturn) { lambda.Block.Statements.Add("return return_value;"); } if (context == null) { block.Statements.Add(String.Format("root.{0} = ({2})({1});", propName, lambda.Name, TypeName.NameOf(propType))); } else { block.Statements.Add(String.Format("{2}.{0} = ({3})({1});", propName, lambda.Name, context.Name, TypeName.NameOf(propType))); } } else { return; } } else { //Debug.Log ("list of" + listT); ForStatement statement = new ForStatement(); string listVarContent = context == null ? "root." + propName : context.Name + "." + propName; string listVarName = "list" + DeclareVariableStatement.VariableId++; DeclareVariableStatement listVar = new DeclareVariableStatement(); listVar.IsTemp = true; listVar.Name = listVarName; listVar.InitExpression = listVarContent; listVar.Type = propType; block.Statements.Add(listVar); string iterName = "i" + DeclareVariableStatement.VariableId++; statement.InsideExpr = String.Format("int {0} = 0; {1} != null && {0} < {1}.Count; {0}++", iterName, listVarName); FunctionBlock repeatBlock = new FunctionBlock(block, block.Method, block.Type); statement.RepeatBlock = repeatBlock; block.Statements.Add(statement); Operator listVarOp = new Operator(); DeclareVariableStatement iterVar = new DeclareVariableStatement(); iterVar.Name = "iter" + DeclareVariableStatement.VariableId++; iterVar.IsContext = true; iterVar.IsNew = true; iterVar.Type = listT; iterVar.IsListIter = true; iterVar.InitExpression = String.Format("{0}[{1}]", listVarName, iterName); statement.RepeatBlock.Statements.Add(iterVar); var inter = switches.GetInterByType(listT); //Debug.Log(inter); inter.Interpret(op, repeatBlock); } interpret = true; }