Beispiel #1
0
    public override void Interpret(Expression[] args, FunctionBlock block, Type contextType, string exprVal, out string newExprVal, out FunctionBlock newCurBlock, out Type newContextType, bool isLast)
    {
        if (ScriptEngine.AnalyzeDebug)
        {
            Debug.Log("fit scope");
        }
        IfStatement ifStatement = new IfStatement();
//		DeclareVariableStatement cmpStmt = new DeclareVariableStatement ();
//		ExprInter.CleanUpContextes.Add (cmpStmt);
//		cmpStmt.Name = "cmp" + DeclareVariableStatement.VariableId++;
//		cmpStmt.Type = Type;
        //cmpStmt.IsContext = true;
        string varName = block.FindStatement <DeclareVariableStatement> (v => v.IsContext).Name;
//		cmpStmt.InitExpression = String.Format ("{0}.GetComponent<{1}>()", varName, Type);
//		ifStatement.CheckExpression = String.Format ("{0} != null", cmpStmt.Name);
        FunctionBlock newBlock = new FunctionBlock(block, block.Method, block.Type);

        DeclareVariableStatement ifValue = new DeclareVariableStatement();

        ifValue.Name   = "ifResult" + DeclareVariableStatement.VariableId++;
        ifValue.IsTemp = true;
        ifValue.Type   = typeof(bool);
        block.Statements.Add(ifValue);
        ifStatement.CheckExpression = (ifValue.Name + " = ") + ExprInter.InterpretExpression(args [0], block).ExprString;

        ifStatement.TrueBlock = newBlock;
        //block.Statements.Add (cmpStmt);
        block.Statements.Add(ifStatement);
        newCurBlock    = newBlock;
        newExprVal     = exprVal;
        newContextType = contextType;
        if (isLast)
        {
            var res = block.FindStatement <DeclareVariableStatement> (v => v.IsResult);
            if (res != null)
            {
                res.Type           = typeof(List <>).MakeGenericType(contextType);
                res.InitExpression = String.Format("new {0}()", TypeName.NameOf(res.Type));
                newExprVal         = res.Name;
                newBlock.Statements.Add(String.Format("{0}.Add({1});", res.Name, varName));
            }
            else
            {
                newExprVal     = ifValue.Name;
                newContextType = typeof(bool);
            }
        }

        //ifStatement.CheckExpression = String.Format("{0}.GetComponen")
        //ifStatement.CheckExpression =
    }
Beispiel #2
0
    public override void Interpret(Expression[] args, FunctionBlock block, Type contextType, string exprVal, out string newExprVal, out FunctionBlock newCurBlock, out Type newContextType, bool isLast)
    {
        var thisVar = block.FindStatement <DeclareVariableStatement> (v => v.IsContext && !v.IsTemp);

        newExprVal     = thisVar.Name;
        newCurBlock    = block;
        newContextType = thisVar.Type;
    }
Beispiel #3
0
    public override void Interpret(Expression[] args, FunctionBlock block, Type contextType, string exprVal, out string newExprVal, out FunctionBlock newCurBlock, out Type newContextType, bool isLast)
    {
        var retVar = block.FindStatement <DeclareVariableStatement> (v => v.IsReturn);

        newExprVal = retVar.Name;
        block.Statements.Add(String.Format("{0} = true;", retVar.Name));
        newCurBlock    = block;
        newContextType = typeof(bool);
    }
Beispiel #4
0
    public Expr InterpretClosure(Expression expression, FunctionBlock block, Type closureType)
    {
        //Debug.LogFormat ("Interpret {0} as closure", expression);
        StringBuilder closureBuilder = new StringBuilder();
        var           methodInfo     = closureType.GetMethod("Invoke");
        var           args           = methodInfo.GetParameters();
        FunctionBlock lambdaBlock    = new FunctionBlock(block, block.Method, block.Type);

        if (args.Length > 0)
        {
            lambdaBlock.DefaultScope = args[0].Name;
        }
        else
        {
            lambdaBlock.DefaultScope = block.FindStatement <DeclareVariableStatement>(v => v.Type == typeof(GameObject) && v.IsContext && !v.IsTemp).Name;
        }
        closureBuilder.Append("(");
        DeclareVariableStatement lastArg = null;

        foreach (var param in args)
        {
            var argVar = new DeclareVariableStatement();
            lastArg      = argVar;
            argVar.Name  = param.Name;
            argVar.IsArg = true;
            argVar.Type  = param.ParameterType;
            lambdaBlock.Statements.Add(argVar);
            closureBuilder.Append(param.ParameterType).Append(" ").Append(param.Name).Append(",");
        }
        if (lastArg != null)
        {
            lastArg.IsContext = true;
        }
        if (closureBuilder [closureBuilder.Length - 1] == ',')
        {
            closureBuilder.Length -= 1;
        }
        closureBuilder.Append(")=>{");
        var internals = InterpretExpression(expression, lambdaBlock);

        foreach (var statement in lambdaBlock.Statements)
        {
            closureBuilder.Append(statement).Append(";").Append(Environment.NewLine);
        }
        if (methodInfo.ReturnType != null)
        {
            closureBuilder.Append("return ");
        }
        closureBuilder.Append(internals.ExprString).Append(";");
        closureBuilder.Append("}");

        return(new Expr()
        {
            ExprString = closureBuilder.ToString()
        });
        //return InterpretExpression (expression, block);
    }
Beispiel #5
0
    public override void Interpret(Expression[] args, FunctionBlock block, Type contextType, string exprVal, out string newExprVal, out FunctionBlock newCurBlock, out Type newContextType, bool isLast)
    {
        Debug.Log("Has component scope");
        IfStatement ifStatement          = new IfStatement();
        DeclareVariableStatement cmpStmt = new DeclareVariableStatement();

        cmpStmt.IsTemp    = true;
        cmpStmt.IsContext = true;
        ExprInter.CleanUpContextes.Push(cmpStmt);
        cmpStmt.Name = "cmp" + DeclareVariableStatement.VariableId++;
        cmpStmt.Type = Type;
        //cmpStmt.IsContext = true;
        var ctxVar = block.FindStatement <DeclareVariableStatement> (v => v.IsContext);

        string varName = ctxVar == null ? "root" : ctxVar.Name;

        cmpStmt.InitExpression      = String.Format("({1}){0}.GetComponent(typeof({1}))", varName, Type);
        ifStatement.CheckExpression = String.Format("{0} != null", cmpStmt.Name);
        FunctionBlock newBlock = new FunctionBlock(block, block.Method, block.Type);

        ifStatement.TrueBlock = newBlock;
        block.Statements.Add(cmpStmt);
        block.Statements.Add(ifStatement);
        newCurBlock    = newBlock;
        newExprVal     = exprVal;
        newContextType = contextType;
        if (isLast)
        {
            var res = block.FindStatement <DeclareVariableStatement> (v => v.IsResult);
            res.Type           = typeof(List <>).MakeGenericType(contextType);
            res.InitExpression = String.Format("new {0}()", TypeName.NameOf(res.Type));
            newExprVal         = res.Name;
            newBlock.Statements.Add(String.Format("{0}.Add({1});", res.Name, varName));
        }

        //ifStatement.CheckExpression = String.Format("{0}.GetComponen")
        //ifStatement.CheckExpression =
    }
Beispiel #6
0
    public override void Interpret(Expression[] args, FunctionBlock block, Type contextType, string exprVal, out string newExprVal, out FunctionBlock newCurBlock, out Type newContextType, bool isLast)
    {
        string rootRef = null;

        if (args.Length == 2)
        {
            rootRef = block.FindStatement <DeclareVariableStatement>(v => v.IsContext && v.Type == typeof(GameObject)).Name;
        }
        else
        {
            rootRef = ExprInter.InterpretExpression(args[1], block).ExprString;
        }

        var metricName = args[0].ToString().ClearFromBraces().Trim(' ');
        var otherRef   = ExprInter.InterpretExpression(args.Length == 2 ? args[1] : args[2], block).ExprString;
        var varName    = "metrics" + DeclareVariableStatement.VariableId++;

        block.Statements.Add("var {1} = {0} != null?{0}.GetComponent<Metrics>():null;".Fmt(rootRef, varName));
        newExprVal     = "({0} != null? {0}.Weight(\"{1}\", {2}) : 0f)".Fmt(varName, metricName, otherRef);
        newContextType = typeof(float);
        newCurBlock    = block;
    }
Beispiel #7
0
 public override void Interpret(Operator op, FunctionBlock block)
 {
     if (exprInter == null)
     {
         exprInter = Engine.GetPlugin <ExpressionInterpreter>();
     }
     if (op.Args.Count > 0 && op.Args[0].Operands[0] is ExprAtom &&
         (op.Args[0].Operands[0] as ExprAtom).Content is Scope &&
         ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts.Count == 1)
     {
         var part = ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts[0];
         if (!(part is string))
         {
             Debug.Log("Wrong remove_from definition");
             return;
         }
         var listName = NameTranslator.CSharpNameFromScript(part as string);
         DeclareVariableStatement declareVar = block.FindStatement <DeclareVariableStatement>(v => v.IsContext && v.Type.GetProperty(listName) != null);
         //Debug.Log (declareVar.DebugString ());
         if (declareVar == null)
         {
             Debug.Log("remove_from operator can't find context variable");
         }
         else
         {
             if (op.Context is Expression)
             {
                 var exprValue = exprInter.InterpretExpression(op.Context as Expression, block);
                 //block = exprValue.NotNullBlock;
                 block.Statements.Add(String.Format("{0}.{1}.Remove({2});", declareVar.Name, listName, exprValue.ExprString));
             }
         }
     }
     else
     {
         Debug.Log("Wrong remove_from definition");
     }
 }
Beispiel #8
0
    public override void Interpret(Expression[] args, FunctionBlock block, Type contextType, string exprVal, out string newExprVal, out FunctionBlock newCurBlock, out Type newContextType, bool isLast)
    {
        var varName   = ((args [0].Operands [0] as ExprAtom).Content as Scope).Parts [0] as string;
        var valueExpr = args [1];
        var exprData  = Engine.GetPlugin <ExpressionInterpreter> ().InterpretExpression(valueExpr, block);

        newExprVal     = exprVal;
        newCurBlock    = block;
        newContextType = contextType;
//		if (exprData.Type != typeof(bool))
//			block.Statements.Add ("return false;");
//		block.Statements.Add (String.Format ("return {0};", exprData.ExprString));
        var declVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == varName && v.Type == exprData.Type);

        if (declVar != null)
        {
            Debug.Log("Adds set value");
            block.Statements.Add(String.Format("{0} = {1};", varName, exprData.ExprString));
        }
        else
        {
            Debug.LogErrorFormat("Unable to find var {0} in {1} of {2}", varName, block.Method, block.Type);
        }
    }
Beispiel #9
0
    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;
    }
    public override void Interpret(Operator op, FunctionBlock block)
    {
        base.Interpret(op, block);
        if (interpret)
        {
            if (ScriptEngine.AnalyzeDebug)
            {
                Debug.LogFormat("Property {0} was interpreted by ContextPropertyInterpreter {1} already", op, propName);
            }
            return;
        }
        if (!(op.Context is Context))
        {
            if (ScriptEngine.AnalyzeDebug)
            {
                Debug.LogFormat("Property context switch {0} has no context", op);
            }
            return;
        }
        if (ops == null)
        {
            ops = Engine.GetPlugin <EventFunctionOperators> ();
        }
        var varName = op.Identifier as string;

        FunctionBlock contextBlock = new FunctionBlock(block, block.Method, block.Type);

        block.Statements.Add(contextBlock);
        DeclareVariableStatement declareVar = new DeclareVariableStatement();

        declareVar.Type      = propType;
        declareVar.Name      = "subContext" + DeclareVariableStatement.VariableId++;
        declareVar.IsContext = true;

        DeclareVariableStatement contextVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == varName);

        if (contextVar == null)
        {
            var sCtx = block.FindStatement <ContextStatement> (v => v.InterpretInContext(op, block) != null && v.ContextVar.IsContext);
            contextVar = sCtx != null ? sCtx.ContextVar : null;
        }

        if (contextVar == null)
        {
            declareVar.InitExpression = String.Format("root.{0}", propName);
        }
        else
        {
            declareVar.InitExpression = String.Format("{1}.{0}", propName, contextVar.Name);
        }
        contextBlock.Statements.Add(declareVar);
        contextBlock.Statements.Add(new ContextStatement()
        {
            ContextVar         = declareVar,
            InterpretInContext = InterpretInContext
        });
        IfStatement isNotNull = new IfStatement();

        isNotNull.CheckExpression = String.Format("{0} != null", declareVar.Name);
        isNotNull.TrueBlock       = new FunctionBlock(contextBlock);
        contextBlock.Statements.Add(isNotNull);
        contextBlock = isNotNull.TrueBlock;
        foreach (var entry in (op.Context as Context).Entries)
        {
            //Debug.LogFormat("Interpreting {0} as part of {1} context", (entry as Operator).Identifier, op.Identifier);
            var subOp = entry as Operator;
            if (subOp == null)
            {
                continue;
            }
            FunctionOperatorInterpreter opInter = null;
            if ((opInter = ops.GetInterpreter(subOp, contextBlock)) == null)
            {
                if (!contextSwitches.TryGetValue(subOp.Identifier as string, out opInter))
                {
                    if (!functions.TryGetValue(subOp.Identifier as string, out opInter))
                    {
                        if (!properties.TryGetValue(subOp.Identifier as string, out opInter))
                        {
                            //Debug.LogFormat ("Can't interpret context operator {1} in {0}", block.Method.Name, subOp.Identifier);
                            continue;
                        }
                    }
                }
            }
            opInter.Interpret(subOp, 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))
            {
                return;
            }
            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).ExprString, TypeName.NameOf(propType)));
            }
            else
            {
                block.Statements.Add(String.Format("{2}.{0} = ({3})({1});", propName, exprInter.InterpretExpression(op.Context as Expression, block).ExprString, context.Name, TypeName.NameOf(propType)));
            }
        }
        else
        {
            Debug.Log("list of" + listT);
            ForStatement statement   = new ForStatement();
            string       listVarName = context == null ? "root." + propName : context.Name + "." + propName;
            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 listVar = new DeclareVariableStatement();
            listVar.Name           = "iter" + DeclareVariableStatement.VariableId++;
            listVar.IsContext      = true;
            listVar.IsNew          = true;
            listVar.Type           = listT;
            listVar.InitExpression = String.Format("{0}[{1}]", listVarName, iterName);

            statement.RepeatBlock.Statements.Add(listVar);
            var inter = switches.GetInterByType(listT);
            //Debug.Log(inter);
            inter.Interpret(op, repeatBlock);
        }
        interpret = true;
    }
    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)
    {
        if (ops == null)
        {
            ops = Engine.GetPlugin <EventFunctionOperators> ();
        }
        FunctionBlock contextBlock = new FunctionBlock(block, block.Method, block.Type);

        block.Statements.Add(contextBlock);
        DeclareVariableStatement addVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == op.Identifier as string);
        bool setContext = false;

        if (addVar != null && !addVar.IsContext)
        {
            setContext = addVar.IsContext = true;
        }
        if (addVar == null)
        {
            addVar = block.FindStatement <DeclareVariableStatement> (v => v.IsContext && v.Type == contextType);
        }
        //TODO: probably will fail
        DeclareVariableStatement contextVar = contextType == typeof(GameObject)? addVar : block.FindStatement <DeclareVariableStatement> (v => v.IsContext && v.Type == typeof(GameObject) && v != addVar);
        DeclareVariableStatement declareVar = null;

        if (addVar == null)
        {
            declareVar           = new DeclareVariableStatement();
            declareVar.Type      = contextType;
            declareVar.Name      = "subContext" + DeclareVariableStatement.VariableId++;
            declareVar.IsContext = true;

            if (contextVar == null)
            {
                declareVar.InitExpression = String.Format("({0})root.GetComponent(typeof({0}))", contextType);
            }
            else
            {
                declareVar.InitExpression = String.Format("({0}){1}.GetComponent(typeof({0}))", contextType, contextVar.Name);
            }
            contextBlock.Statements.Add(declareVar);
        }
        else
        {
            declareVar = addVar;
        }

        contextBlock.Statements.Add(new ContextStatement()
        {
            ContextVar         = declareVar,
            InterpretInContext = InterpretInContext
        });
        IfStatement isNotNull = new IfStatement();

        isNotNull.CheckExpression = String.Format("{0} != null", declareVar.Name);
        isNotNull.TrueBlock       = new FunctionBlock(contextBlock);
        contextBlock.Statements.Add(isNotNull);
        contextBlock = isNotNull.TrueBlock;
        contextBlock.Statements.Add(new DeclareVariableStatement()
        {
            Name = declareVar.Name, IsArg = true, IsContext = true, Type = declareVar.Type
        });
        foreach (var entry in (op.Context as Context).Entries)
        {
            var subOp = entry as Operator;
            if (subOp == null)
            {
                continue;
            }
            FunctionOperatorInterpreter opInter = null;

            if ((opInter = ops.GetInterpreter(subOp, contextBlock)) == null)
            {
                if (!contextSwitches.TryGetValue(subOp.Identifier as string, out opInter))
                {
                    if (!functions.TryGetValue(subOp.Identifier as string, out opInter))
                    {
                        if (!properties.TryGetValue(subOp.Identifier as string, out opInter))
                        {
                            Debug.LogWarningFormat("Can't interpret context operator {1} in {0}", block.Method.Name, subOp.Identifier);
                            continue;
                        }
                    }
                }
            }
            if (ScriptEngine.AnalyzeDebug)
            {
                Debug.LogFormat("Interpret {0} via {1}", subOp.Identifier, opInter);
            }
            opInter.Interpret(subOp, contextBlock);
        }

        if (setContext)
        {
            addVar.IsContext = false;
        }
    }
Beispiel #14
0
    public FunctionOperatorInterpreter GetInterpreter(Operator op, FunctionBlock block)
    {
        FunctionOperatorInterpreter inter = null;

        if (op.Identifier as string == null)
        {
            exprInter.TransformScopedOperator(op, block);
            if (ScriptEngine.AnalyzeDebug)
            {
                Debug.Log("Transformed op " + op.ToString());
            }
        }
        interpreters.TryGetValue(op.Identifier as string, out inter);

        if (inter == null)
        {
            var customVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == (op.Identifier as string));
            if (customVar == null)
            {
                foreach (var interPair in interpreters)
                {
                    if (interPair.Value.Match(op, block))
                    {
                        return(interPair.Value);
                    }
                }
                var context = block.FindStatement <ContextStatement> (c => (inter = c.InterpretInContext(op, block)) != null);
                if (ScriptEngine.AnalyzeDebug)
                {
                    if (context != null)
                    {
                        Debug.LogFormat("{0} is not an operator of context, found one {1}", op.Identifier, context.ContextVar);
                    }
                    else
                    {
                        Debug.LogWarningFormat("{0} is not an operator of context, not found one", op.Identifier);
                    }
                }

//				if (context != null)
//					inter = context.InterpretInContext (op, block);
                if (inter == null && op.Context is Expression)
                {
                    VarDeclareInterpreter declInter = new VarDeclareInterpreter();
                    declInter.Inter = exprInter;
                    inter           = declInter;
                }
            }
            else
            {
                if (op.Context is Expression)
                {
                    VarAssignInterpreter varInter = new VarAssignInterpreter();
                    varInter.Var   = customVar;
                    varInter.Inter = exprInter;
                    inter          = varInter;
                }
                else
                {
                    inter = switches.GetInterByType(customVar.Type);
                }
                //if(op.Context is Expression)
            }
        }

        if (ScriptEngine.AnalyzeDebug)
        {
            Debug.LogFormat("{0} - {1}", op, inter);
        }
        return(inter);
    }
    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(InternalDSL.Operator op, FunctionBlock block)
    {
        if (ops == null)
        {
            ctxs      = Engine.GetPlugin <ContextSwitchesPlugin> ();
            ops       = Engine.GetPlugin <EventFunctionOperators> ();
            exprInter = Engine.GetPlugin <ExpressionInterpreter> ();
        }
        if (op.Args.Count > 0)
        {
            var varName = ((op.Args [0].Operands [0] as ExprAtom).Content as Scope).Parts [0] as string;
            if (op.Context is Expression)
            {
                //cache(some_name) = expression
//				var varDecl = block.FindStatement<DeclareVariableStatement> (v => v.Name == varName);
//				varDecl.IsArg = true;

                var exprValue = exprInter.InterpretExpression(op.Context as Expression, block);
                Debug.Log(exprValue.ExprString);
                var field = new CodeMemberField(exprValue.Type, varName);
                field.UserData.Add("type", exprValue.Type);
                block.Type.Members.Add(field);
                block.Statements.Add(String.Format("{0} = {1};", varName, exprValue.ExprString));
                block.Statements.Add(new DeclareVariableStatement()
                {
                    Name = varName, IsArg = true, Type = exprValue.Type
                });
                //var varDecl = block.FindStatement<DeclareVariableStatement> (v => v.Name == varName);
            }
            else
            {
                //cache(some_name, scope) = { ... }
                var exprValue = exprInter.InterpretExpression(op.Args [1], block);
                var field     = new CodeMemberField(exprValue.Type, varName);
                field.UserData.Add("type", exprValue.Type);
                block.Type.Members.Add(field);
                DeclareVariableStatement cachedVar = new DeclareVariableStatement();
                cachedVar.Name      = varName;
                cachedVar.IsContext = true;
                cachedVar.Type      = exprValue.Type;
                cachedVar.IsArg     = true;
                block.Statements.Add(cachedVar);
                block.Statements.Add(String.Format("{0} = {1};", varName, exprValue.ExprString));
                block.Statements.Add(new DeclareVariableStatement()
                {
                    Name = varName, IsArg = true, Type = exprValue.Type
                });
                var inter = ctxs.GetInterByType(exprValue.Type);
                inter.Interpret(op, block);
            }
        }
        else
        {
            //cache = some_name

            var varName = (((op.Context as Expression).Operands [0] as ExprAtom).Content as Scope).Parts [0] as string;
            var varDecl = block.FindStatement <DeclareVariableStatement> (v => v.Name == varName);
            //varDecl.IsArg = true;
            varDecl.IsDeclaration = false;

            var field = new CodeMemberField(varDecl.Type, varDecl.Name);
            field.UserData.Add("type", varDecl.Type);
            block.Type.Members.Add(field);
            //block.Statements.Add (String.Format ("this.{0} = {0};", varName));
        }

        //new CodeMemberField()
        //block.Type.Members.Add ();
    }
    public override void Interpret(Operator op, FunctionBlock block)
    {
        if (ops == null)
        {
            ops      = Engine.GetPlugin <EventFunctionOperators> ();
            switches = Engine.GetPlugin <ContextSwitchesPlugin> ();
            var cmps = Engine.FindTypesCastableTo <MonoBehaviour> ();
            foreach (var cmp in cmps)
            {
                components.Add(NameTranslator.ScriptNameFromCSharp(cmp.Name), cmp);
            }
        }
        //add = cmp_type - no args, context is Expression
        //add(var) = cmp_type - 1 arg, context is Expression
        //add(cmp_type) = { ... } - 1 arg, context is Context
        //add(var, cmp_type) = { ... } - 2 args, context is Context
        DeclareVariableStatement cmpVar     = null;
        DeclareVariableStatement contextVar = block.FindStatement <DeclareVariableStatement> (v => (v.IsContext | v.IsArg) && v.Type == typeof(GameObject));
        string ctxVar      = contextVar == null ? "root" : contextVar.Name;
        string cmpTypeName = null;

        try
        {
            if (op.Args.Count == 0)
            {
                var expr = op.Context as Expression;
                if (expr != null)
                {
                    var cmpType = (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0] as string;
                    block.Statements.Add(string.Format("{0}.AddComponent<{1}>();", ctxVar, components[cmpType]));
                }
            }
            else if (op.Args.Count == 1)
            {
                var ctx  = op.Context as Context;
                var expr = op.Context as Expression;
                if (expr != null)
                {
                    cmpTypeName = (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0] as string;
                    var varName = ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts[0] as string;
                    var cmpType = components[cmpTypeName];
                    cmpVar = new DeclareVariableStatement();
                    cmpVar.InitExpression = string.Format("{0}.AddComponent<{1}>();", ctxVar, cmpType);
                    cmpVar.Type           = cmpType;
                    cmpVar.Name           = varName;
                    cmpVar.IsNew          = true;
                    cmpVar.IsContext      = true;
                    block.Statements.Add(cmpVar);
                }
                else if (ctx != null)
                {
                    cmpTypeName = ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts[0] as string;
                    var cmpType = components[cmpTypeName];
                    cmpVar = new DeclareVariableStatement();
                    cmpVar.InitExpression = string.Format("{0}.AddComponent<{1}>();", ctxVar, cmpType);
                    cmpVar.Type           = cmpType;
                    cmpVar.IsContext      = true;
                    cmpVar.IsNew          = true;
                    cmpVar.Name           = "ContextVar" + DeclareVariableStatement.VariableId++;
                    block.Statements.Add(cmpVar);
                    switches.GetInterByType(cmpType).Interpret(op, block);
                }
            }
            else if (op.Args.Count == 2)
            {
                var ctx = op.Context as Context;
                if (ctx != null)
                {
                    cmpTypeName = ((op.Args[1].Operands[0] as ExprAtom).Content as Scope).Parts[0] as string;
                    var varName = ((op.Args[0].Operands[0] as ExprAtom).Content as Scope).Parts[0] as string;
                    var cmpType = components[cmpTypeName];
                    cmpVar = new DeclareVariableStatement();
                    cmpVar.InitExpression = string.Format("{0}.AddComponent<{1}>();", ctxVar, cmpType);
                    cmpVar.Type           = cmpType;
                    cmpVar.IsContext      = true;
                    cmpVar.IsNew          = true;
                    cmpVar.Name           = varName;
                    block.Statements.Add(cmpVar);
                    switches.GetInterByType(cmpType).Interpret(op, block);
                }
            }


            var entVar = block.FindStatement <DeclareVariableStatement>(v => v.ctxEntity == ctxVar && v.Type == typeof(Entity));
            if (entVar == null)
            {
                entVar           = new DeclareVariableStatement();
                entVar.Name      = "EntVar" + DeclareVariableStatement.VariableId++;
                entVar.Type      = typeof(Entity);
                entVar.ctxEntity = ctxVar;

                entVar.InitExpression = String.Format("(Entity){0}.GetComponent(typeof(Entity));", ctxVar);
                block.Statements.Add(entVar);
                var updateSt = new StatementStringContainer(String.Format("if({0} != null) {0}.ComponentAdded();", entVar.Name));
                entVar.Cnt = updateSt;
                block.Statements.Add(updateSt);
            }
            else
            {
                var updateSt = new StatementStringContainer(entVar.Cnt.Data);
                entVar.Cnt.Data = "";
                entVar.Cnt      = updateSt;
                block.Statements.Add(updateSt);
            }

            if (cmpVar != null)
            {
                cmpVar.IsContext = false;
            }
        }
        catch (KeyNotFoundException e)
        {
            Debug.LogErrorFormat("Can't create {0} in {1}", cmpTypeName, op);
        }
    }
Beispiel #18
0
    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.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 {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++)
                                {
                                    if (argsDef [j].ParameterType.IsSubclassOf(typeof(Delegate)))
                                    {
                                        exprBuilder.Append(InterpretClosure(callArgs [j], curBlock, argsDef [j].ParameterType).ExprString).Append(",");
                                    }
                                    else
                                    {
                                        exprBuilder.Append(InterpretExpression(callArgs [j], curBlock).ExprString).Append(",");
                                    }
                                }
                                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;
                            }
                            isFunc = true;
                        }
                    }
                }
                if (!isFunc)
                {
                    var propName = NameTranslator.CSharpNameFromScript(scope [i] as string);

                    var prop = contextType.GetProperty(propName);

                    if (i == 0 && prop == null)
                    {
                        var customVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == scope [i] as string);
                        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);

                        contextType = type;
                        if (storedVar == null)
                        {
                            storedVar = new DeclareVariableStatement();
                            CleanUpContextes.Push(storedVar);
                            storedVar.IsTemp    = true;
                            storedVar.IsContext = true;
                            curBlock.Statements.Add(storedVar);                             //block.FindStatement<DeclareVariableStatement> (v => !v.IsContext && v.Type == type);
                            storedVar.Name = "StoredVariable" + DeclareVariableStatement.VariableId++;
                            storedVar.Type = type;

                            storedVar.storedOf = hasSign ? exprBuilder.ToString(1, exprBuilder.Length) : exprBuilder.ToString(0, exprBuilder.Length);
                            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);
    }
Beispiel #19
0
    public override void Interpret(Operator op, FunctionBlock block)
    {
        if (exprInter == null)
        {
            exprInter = Engine.GetPlugin <ExpressionInterpreter>();
        }

        block.Method.ReturnType = new CodeTypeReference(typeof(IEnumerator));
        block.Method.Attributes = MemberAttributes.Public;
        block.Method.Name       = "ActionCoroutine";
        if (!block.Method.UserData.Contains("has_transformed_action"))
        {
            var newActionMethod = new CodeMemberMethod();
            newActionMethod.Name       = "Action";
            newActionMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            newActionMethod.Statements.Add(new CodeSnippetStatement("Coroutine = ActionCoroutine(); state = ActionState.Started;"));
            block.Type.Members.Add(newActionMethod);
            block.Method.UserData.Add("has_transformed_action", "has_transformed_action");
        }

        var contextVar = block.FindStatement <DeclareVariableStatement>(v => (v.IsContext) && v.Type == typeof(Actor));

        if (contextVar == null)
        {
            contextVar = block.FindStatement <DeclareVariableStatement>(v => (v.IsContext) && v.Type == typeof(GameObject));
        }
        int aId = 0;

        if (op.Args.Count == 1)
        {
            if (op.Context is Expression)
            {
                //do(interaction_type) = target
                var interTypeArg = op.Args[0].ToString().ClearFromBraces();
                var targetArg    = exprInter.InterpretExpression(op.Context as Expression, block);
                aId = DeclareVariableStatement.VariableId++;
                block.Statements.Add(String.Format("var a{0} = Actions.Instance.GetAction(typeof(ScriptedTypes.{1}));", aId, interTypeArg));
                block.Statements.Add(String.Format("a{0}.Init();", aId));
                block.Statements.Add(String.Format("(a{0} as EventInteraction).Initiator = {1};", aId, (contextVar.Type == typeof(GameObject)? contextVar.Name : (contextVar.Name + ".gameObject"))));
                if (targetArg.Type == typeof(GameObject))
                {
                    block.Statements.Add(String.Format("a{0}.Root = {1};", aId, targetArg.ExprString));
                }
                else
                {
                    block.Statements.Add(String.Format("a{0}.Root = {1}.gameObject;", aId, targetArg.ExprString));
                }
                block.Statements.Add(String.Format("UnityEngine.Debug.Log(a{0}.Root);", aId));
                block.Statements.Add(String.Format("UnityEngine.Debug.Log((a{0} as EventInteraction).Initiator);", aId));
                if (contextVar.Type == typeof(GameObject))
                {
                    block.Statements.Add(String.Format("({0}.GetComponent(typeof(Actor)) as Actor).Act(a{1});", contextVar.Name, aId));
                }
                else
                {
                    block.Statements.Add(String.Format("{0}.Act(a{1});", contextVar.Name, aId));
                }
            }
            else
            {
                //do(interaction_type) = { target = some_object some_argument = some_value }
                var interTypeArg = op.Args[0].ToString().ClearFromBraces();
                aId = DeclareVariableStatement.VariableId++;
                block.Statements.Add(String.Format("var a{0} = Actions.Instance.GetAction(typeof(ScriptedTypes.{1}));", aId, interTypeArg));
                block.Statements.Add(String.Format("a{0}.Init();", aId));
                block.Statements.Add(String.Format("(a{0} as EventInteraction).Initiator = {1};", aId, (contextVar.Type == typeof(GameObject) ? contextVar.Name : (contextVar.Name + ".gameObject"))));
                var type  = Engine.FindType(interTypeArg);
                var props = type.GetProperties();
                propsDict.Clear();
                foreach (var prop in props)
                {
                    propsDict.Add(NameTranslator.ScriptNameFromCSharp(prop.Name), prop);
                }
                foreach (var subOpObject in (op.Context as Context).Entries)
                {
                    PropertyInfo prop;
                    var          subOp = subOpObject as Operator;
                    if (subOp.Identifier as string == "target")
                    {
                        var targetArg = exprInter.InterpretExpression(subOp.Context as Expression, block);
                        if (targetArg.Type == typeof(GameObject))
                        {
                            block.Statements.Add(String.Format("a{0}.Root = {1};", aId, targetArg.ExprString));
                        }
                        else
                        {
                            block.Statements.Add(String.Format("a{0}.Root = {1}.gameObject;", aId, targetArg.ExprString));
                        }
                    }
                    else if (propsDict.TryGetValue(subOp.Identifier as string, out prop))
                    {
                        var propArg = exprInter.InterpretExpression(subOp.Context as Expression, block).ExprString;
                        block.Statements.Add(String.Format("(a{0} as EventInteraction).{1} = ({3}){2};", aId, prop.Name, propArg, prop.PropertyType));
                    }
                }
                var propExpr = exprInter.InterpretExpression(op.Args[0], block).ExprString;
                //block.Statements.Add(String.Format("(a{0} as ScriptedTypes.{1}).{2} = ({4}){3}", aId, interTypeArg, prop.Name, propExpr));
                if (contextVar.Type == typeof(GameObject))
                {
                    block.Statements.Add(String.Format("({0}.GetComponent(typeof(Actor)) as Actor).Act(a{1});", contextVar.Name, aId));
                }
                else
                {
                    block.Statements.Add(String.Format("{0}.Act(a{1});", contextVar.Name, aId));
                }
            }
        }
        else if (op.Args.Count == 2)
        {
            //do(interaction_type, possible_one_argument) = target
            var interTypeArg = op.Args[0].ToString().ClearFromBraces();
            var targetArg    = exprInter.InterpretExpression(op.Context as Expression, block);
            aId = DeclareVariableStatement.VariableId++;
            block.Statements.Add(String.Format("var a{0} = Actions.Instance.GetAction(typeof(ScriptedTypes.{1}));", aId, interTypeArg));
            block.Statements.Add(String.Format("a{0}.Init();", aId));
            var type  = Engine.FindType(interTypeArg);
            var props = type.GetProperties();
            if (ScriptEngine.AnalyzeDebug)
            {
                if (props.Length != 1)
                {
                    Debug.LogErrorFormat("Wrong number of properties for DO statement in ", block.Type.Name);
                }
            }
            var prop     = props[0];
            var propExpr = exprInter.InterpretExpression(op.Args[0], block).ExprString;
            block.Statements.Add(String.Format("(a{0} as EventInteraction).Initiator = {1};", aId, (contextVar.Type == typeof(GameObject) ? contextVar.Name : (contextVar.Name + ".gameObject"))));
            if (targetArg.Type == typeof(GameObject))
            {
                block.Statements.Add(String.Format("a{0}.Root = {1};", aId, targetArg.ExprString));
            }
            else
            {
                block.Statements.Add(String.Format("a{0}.Root = {1}.gameObject;", aId, targetArg.ExprString));
            }
            block.Statements.Add(String.Format("(a{0} as ScriptedTypes.{1}).{2} = {3}", aId, interTypeArg, prop.Name, propExpr));
            if (contextVar.Type == typeof(GameObject))
            {
                block.Statements.Add(String.Format("({0}.GetComponent(typeof(Actor)) as Actor).Act(a{1});", contextVar.Name, aId));
            }
            else
            {
                block.Statements.Add(String.Format("{0}.Act(a{1});", contextVar.Name, aId));
            }
        }
        string operatorString = null;


        if (operatorString != null)
        {
            block.Statements.Add(operatorString);
        }
        var waitString = string.Format("while(a{0}.State != EventAction.ActionState.Finished){{ if(a{0}.State == EventAction.ActionState.Failed) {{ this.state = EventAction.ActionState.Failed; yield break; }} yield return null; }}",
                                       aId);

        block.Statements.Add(waitString);
    }