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()));
    }
Exemplo n.º 2
0
    public override void Interpret(Script script)
    {
        MaxProgress = script.Entries.Count;
        for (int i = 0; i < script.Entries.Count; i++)
        {
            if (!Engine.Working)
            {
                Thread.CurrentThread.Abort();
            }
            CurProgress = i;
            var entry = script.Entries[i];
            CodeTypeDeclaration codeType = new CodeTypeDeclaration();
            //codeType.CustomAttributes.
            codeType.BaseTypes.Add(new CodeTypeReference(typeof(Metric)));
            codeType.Name = entry.Identifier as string;
            codeTypes.Add(codeType);

            if (ScriptEngine.AnalyzeDebug)
            {
                Debug.LogWarning((entry.Identifier as string).ToUpper());
            }

            var ctx = entry.Context as Context;
            if (ctx == null)
            {
                continue;
            }
            var scopeMethod               = typeof(Metric).GetMethod("RootFilter");
            var otherScopeMethod          = typeof(Metric).GetMethod("OtherFilter");
            var valueMethod               = typeof(Metric).GetMethod("Value");
            CodeAttributeDeclaration attr = new CodeAttributeDeclaration("MetricAttribute");
            codeType.CustomAttributes.Add(attr);
            CodeAttributeArgument weightArg = new CodeAttributeArgument("Weight", new CodeSnippetExpression("1"));
            attr.Arguments.Add(weightArg);
            FunctionBlock dependenciesBlock = new FunctionBlock(null, null, codeType);
            List <string> deps = new List <string>();
            for (int j = 0; j < ctx.Entries.Count; j++)
            {
                var op = ctx.Entries[j] as Operator;
                if (op == null)
                {
                    continue;
                }
                if (op.Identifier as string == "weight")
                {
                    weightArg.Value = new CodeSnippetExpression((op.Context as InternalDSL.Expression).Operands[0].ToString());
                }
                else if (op.Identifier as string == "category")
                {
                    var cat  = (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0].ToString();
                    var type = Engine.FindType("ScriptedTypes." + cat);
                    if (type != null)
                    {
                        var props = type.GetProperties();
                        codeType.BaseTypes.Add(type);

                        foreach (var propInfo in props)
                        {
                            var prop = new CodeMemberProperty();
                            prop.HasGet = true;
                            prop.HasSet = true;
                            prop.Name   = propInfo.Name;
                            prop.Type   = new CodeTypeReference(propInfo.PropertyType);
                            var fieldName = NameTranslator.ScriptNameFromCSharp(prop.Name);
                            prop.GetStatements.Add(new CodeSnippetStatement(String.Format("return {0}; ", fieldName)));
                            prop.SetStatements.Add(new CodeSnippetStatement(String.Format("{0} = value; ", fieldName)));
                            prop.PrivateImplementationType = new CodeTypeReference(type);
                            if (!codeType.UserData.Contains(fieldName))
                            {
                                var field = new CodeMemberField();
                                field.Name = fieldName;
                                field.Type = new CodeTypeReference(propInfo.PropertyType);
                                codeType.Members.Add(field);
                                codeType.UserData.Add(fieldName, field);
                                field.UserData.Add("type", propInfo.PropertyType);
                            }
                            codeType.Members.Add(prop);
                        }
                    }
                    else
                    {
                        if (!cNamespace.UserData.Contains(cat))
                        {
                            CodeTypeDeclaration catInterface = new CodeTypeDeclaration(cat);
                            catInterface.IsInterface = true;
                            cNamespace.Types.Add(catInterface);
                            cNamespace.UserData.Add(cat, catInterface);
                        }
                        codeType.BaseTypes.Add(cat);
                    }
                }
                else if (op.Identifier as string == "scope")
                {
                    //It's a filter function
                    //					Debug.Log (op.Context.GetType ());
                    if (ScriptEngine.AnalyzeDebug)
                    {
                        Debug.Log((op.Context as Expression).Operands[0].GetType());
                    }

                    (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true");
                    DeclareVariableStatement retVal = new DeclareVariableStatement();
                    retVal.IsReturn       = true;
                    retVal.Name           = "applicable";
                    retVal.Type           = typeof(bool);
                    retVal.InitExpression = "false";

                    CreateEventFunction("RootFilter", op.Context, codeType, scopeMethod, false, retVal);
                    //CreateFilterFunction (op.Context as Expression, codeType);
                }
                else if (op.Identifier as string == "other_scope")
                {
                    //It's a filter function
                    //					Debug.Log (op.Context.GetType ());
                    if (ScriptEngine.AnalyzeDebug)
                    {
                        Debug.Log((op.Context as Expression).Operands[0].GetType());
                    }

                    (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true");
                    DeclareVariableStatement retVal = new DeclareVariableStatement();
                    retVal.IsReturn       = true;
                    retVal.Name           = "applicable";
                    retVal.Type           = typeof(bool);
                    retVal.InitExpression = "false";
                    //Debug.Log(otherScopeMethod);
                    CreateEventFunction("OtherFilter", op.Context, codeType, otherScopeMethod, false, retVal);
                    //CreateFilterFunction (op.Context as Expression, codeType);
                }
                else if (op.Identifier as string == "value")
                {
                    DeclareVariableStatement utVal = new DeclareVariableStatement();
                    utVal.IsReturn       = true;
                    utVal.Name           = "val";
                    utVal.Type           = typeof(float);
                    utVal.InitExpression = "0";
                    CreateEventFunction(op.Identifier as string, op.Context, codeType, valueMethod, false, utVal);
                }

                else
                {
                    //No idea
                }
            }
            if (deps.Count > 0)
            {
                CodeMemberMethod getDepsOverride = new CodeMemberMethod();
                getDepsOverride.ReturnType = new CodeTypeReference(typeof(List <Dependency>));
                getDepsOverride.Name       = "GetDependencies";
                getDepsOverride.Attributes = MemberAttributes.Public | MemberAttributes.Override;
                codeType.Members.Add(getDepsOverride);
                string listName = "list" + DeclareVariableStatement.VariableId++;
                string listOp   = String.Format("var {0} = new System.Collections.Generic.List<Dependency>({1});", listName, deps.Count);
                dependenciesBlock.Statements.Add(listOp);
                var addToListBlock = new FunctionBlock(dependenciesBlock);
                foreach (var newDep in deps)
                {
                    addToListBlock.Statements.Add(String.Format("{0}.Add({1});", listName, newDep));
                }
                dependenciesBlock.Statements.Add(addToListBlock);
                dependenciesBlock.Statements.Add(String.Format("return {0};", listName));
                getDepsOverride.Statements.Add(new CodeSnippetStatement(dependenciesBlock.ToString()));
            }
            CodeMemberMethod initOverrideMethod = new CodeMemberMethod();
            initOverrideMethod.Name       = "Init";
            initOverrideMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            codeType.Members.Add(initOverrideMethod);
            builder.Length = 0;
            builder.Append("base.Init();").AppendLine();
            foreach (var member in codeType.Members)
            {
                var field = member as CodeMemberField;
                if (field != null)
                {
                    builder.Append("this.").Append(field.Name).Append(" = ").Append("default(").Append((field.UserData["type"] as Type).FullName).Append(");").AppendLine();
                }
            }
            initOverrideMethod.Statements.Add(new CodeSnippetStatement(builder.ToString()));
        }
        CurProgress = MaxProgress;
        foreach (var type in codeTypes)
        {
            cNamespace.Types.Add(type);
        }

        CSharpCodeProvider   provider = new CSharpCodeProvider();
        CodeGeneratorOptions options  = new CodeGeneratorOptions();
        var writer = new StringWriter();

        provider.GenerateCodeFromNamespace(cNamespace, writer, options);
        Engine.GetPlugin <ScriptCompiler>().AddSource(writer.ToString());
    }
Exemplo n.º 3
0
    public override void Interpret(Script script)
    {
        MaxProgress = script.Entries.Count;
        for (int i = 0; i < script.Entries.Count; i++)
        {
            if (!Engine.Working)
            {
                Thread.CurrentThread.Abort();
            }
            CurProgress = i;
            var entry = script.Entries [i];
            CodeTypeDeclaration codeType = new CodeTypeDeclaration();
            //codeType.CustomAttributes.
            codeType.BaseTypes.Add(new CodeTypeReference(typeof(EventAction)));
            codeType.Name = entry.Identifier as string;
            codeTypes.Add(codeType);

            if (ScriptEngine.AnalyzeDebug)
            {
                Debug.LogWarning((entry.Identifier as string).ToUpper());
            }

            var ctx = entry.Context as Context;
            if (ctx == null)
            {
                continue;
            }
            var actionMethod = typeof(EventAction).GetMethod("Action");
            var utMethod     = typeof(EventAction).GetMethod("Utility");
            var scopeMethod  = typeof(EventAction).GetMethod("Filter");
            var interMethod  = typeof(EventAction).GetMethod("Interaction");
            CodeAttributeDeclaration attr = new CodeAttributeDeclaration("EventActionAttribute");
            codeType.CustomAttributes.Add(attr);
            CodeAttributeArgument maxArg         = new CodeAttributeArgument("ShouldHaveMaxUtility", new CodeSnippetExpression("false"));
            CodeAttributeArgument onceArg        = new CodeAttributeArgument("OncePerObject", new CodeSnippetExpression("false"));
            CodeAttributeArgument oncePerTurnArg = new CodeAttributeArgument("OncePerTurn", new CodeSnippetExpression("false"));
            CodeAttributeArgument aiActionArg    = new CodeAttributeArgument("IsAIAction", new CodeSnippetExpression("false"));
            CodeAttributeArgument interactionArg = new CodeAttributeArgument("IsInteraction", new CodeSnippetExpression("false"));
            CodeAttributeArgument tooltipArg     = new CodeAttributeArgument("Tooltip", new CodeSnippetExpression("\"\""));
            CodeAttributeArgument onceInCategory = new CodeAttributeArgument("OnceInCategory", new CodeSnippetExpression("false"));
            attr.Arguments.Add(maxArg);
            attr.Arguments.Add(onceArg);
            attr.Arguments.Add(oncePerTurnArg);
            attr.Arguments.Add(aiActionArg);
            attr.Arguments.Add(tooltipArg);
            attr.Arguments.Add(onceInCategory);
            attr.Arguments.Add(interactionArg);
            FunctionBlock dependenciesBlock = new FunctionBlock(null, null, codeType);
            List <string> deps = new List <string>();
            for (int j = 0; j < ctx.Entries.Count; j++)
            {
                var op = ctx.Entries [j] as Operator;
                if (op == null)
                {
                    continue;
                }
                if (op.Identifier as string == "tooltip")
                {
                    tooltipArg.Value = new CodeSnippetExpression((op.Context as InternalDSL.Expression).Operands[0].ToString());
                }
                else if (op.Identifier as string == "ai_action")
                {
                    aiActionArg.Value = new CodeSnippetExpression("true");
                }
                else if (op.Identifier as string == "once_per_category")
                {
                    onceInCategory.Value = new CodeSnippetExpression("true");
                }
                else if (op.Identifier as string == "only_max_utility")
                {
                    maxArg.Value = new CodeSnippetExpression((op.Context as InternalDSL.Expression).Operands[0].ToString());
                }
                else if (op.Identifier as string == "category")
                {
                    var cat  = (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0].ToString();
                    var type = Engine.FindType("ScriptedTypes." + cat);
                    if (type == null)
                    {
                        type = Engine.FindType(NameTranslator.CSharpNameFromScript(cat));
                    }
                    if (type != null)
                    {
                        var props = type.GetProperties();
                        codeType.BaseTypes.Add(type);

                        foreach (var propInfo in props)
                        {
                            var prop = new CodeMemberProperty();
                            prop.HasGet = true;
                            prop.HasSet = true;
                            prop.Name   = propInfo.Name;
                            prop.Type   = new CodeTypeReference(propInfo.PropertyType);
                            var fieldName = NameTranslator.ScriptNameFromCSharp(prop.Name);
                            prop.GetStatements.Add(new CodeSnippetStatement(String.Format("return {0}; ", fieldName)));
                            prop.SetStatements.Add(new CodeSnippetStatement(String.Format("{0} = value; ", fieldName)));
                            prop.PrivateImplementationType = new CodeTypeReference(type);
                            if (!codeType.UserData.Contains(fieldName))
                            {
                                var field = new CodeMemberField();
                                field.Name = fieldName;
                                field.Type = new CodeTypeReference(propInfo.PropertyType);
                                codeType.Members.Add(field);
                                codeType.UserData.Add(fieldName, field);
                                field.UserData.Add("type", propInfo.PropertyType);
                            }
                            codeType.Members.Add(prop);
                        }
                    }
                    else
                    {
                        if (!cNamespace.UserData.Contains(cat))
                        {
                            CodeTypeDeclaration catInterface = new CodeTypeDeclaration(cat);
                            catInterface.IsInterface = true;
                            cNamespace.Types.Add(catInterface);
                            cNamespace.UserData.Add(cat, catInterface);
                        }
                        codeType.BaseTypes.Add(cat);
                    }
                }
                else if (op.Identifier as string == "once_per_object")
                {
                    onceArg.Value = new CodeSnippetExpression("true");
                }
                else if (op.Identifier as string == "once_per_turn")
                {
                    oncePerTurnArg.Value = new CodeSnippetExpression("true");
                }
                else if (op.Identifier as string == "scope")
                {
                    //It's a filter function
                    //					Debug.Log (op.Context.GetType ());
                    if (ScriptEngine.AnalyzeDebug)
                    {
                        Debug.Log((op.Context as Expression).Operands[0].GetType());
                    }

                    (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true");
                    DeclareVariableStatement retVal = new DeclareVariableStatement();
                    retVal.IsReturn       = true;
                    retVal.Name           = "applicable";
                    retVal.Type           = typeof(bool);
                    retVal.InitExpression = "false";

                    CreateEventFunction("Filter", op.Context, codeType, scopeMethod, false, retVal);
                    //CreateFilterFunction (op.Context as Expression, codeType);
                }
                else if (op.Identifier as string == "interaction")
                {
                    //It's a filter function
                    //					Debug.Log (op.Context.GetType ());
                    if (ScriptEngine.AnalyzeDebug)
                    {
                        Debug.Log((op.Context as Expression).Operands[0].GetType());
                    }

                    (((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts.Add("true");
                    DeclareVariableStatement retVal = new DeclareVariableStatement();
                    retVal.IsReturn       = true;
                    retVal.Name           = "applicable";
                    retVal.Type           = typeof(bool);
                    retVal.InitExpression = "false";

                    CreateEventFunction("Interaction", op.Context, codeType, interMethod, false, retVal);
                    interactionArg.Value = new CodeSnippetExpression("true");
                    //CreateFilterFunction (op.Context as Expression, codeType);

                    var type  = typeof(EventInteraction);
                    var props = type.GetProperties();
                    codeType.BaseTypes.Add(type);

                    foreach (var propInfo in props)
                    {
                        var prop = new CodeMemberProperty();
                        prop.HasGet = true;
                        prop.HasSet = true;
                        prop.Name   = propInfo.Name;
                        prop.Type   = new CodeTypeReference(propInfo.PropertyType);
                        var fieldName = NameTranslator.ScriptNameFromCSharp(prop.Name);
                        prop.GetStatements.Add(new CodeSnippetStatement(String.Format("return {0}; ", fieldName)));
                        prop.SetStatements.Add(new CodeSnippetStatement(String.Format("{0} = value; ", fieldName)));
                        prop.PrivateImplementationType = new CodeTypeReference(type);
                        if (!codeType.UserData.Contains(fieldName))
                        {
                            var field = new CodeMemberField();
                            field.Name = fieldName;
                            field.Type = new CodeTypeReference(propInfo.PropertyType);
                            codeType.Members.Add(field);
                            codeType.UserData.Add(fieldName, field);
                            field.UserData.Add("type", propInfo.PropertyType);
                        }
                        codeType.Members.Add(prop);
                    }
                }
                else if (op.Identifier as string == "action")
                {
                    //It's an action function
                    CreateEventFunction(op.Identifier as string, op.Context, codeType, actionMethod, true);
                }
                else if (op.Identifier as string == "utility")
                {
                    DeclareVariableStatement utVal = new DeclareVariableStatement();
                    utVal.IsReturn       = true;
                    utVal.Name           = "ut";
                    utVal.Type           = typeof(float);
                    utVal.InitExpression = "0";
                    CreateEventFunction(op.Identifier as string, op.Context, codeType, utMethod, false, utVal);
                }
                else if (op.Identifier as string == "depends")
                {
                    //Debug.Log(op);
                    //Debug.Log(((op.Context as Expression).Operands[0] as ExprAtom).Content.GetType().Name);
                    var        ctor            = ((((op.Context as Expression).Operands[0] as ExprAtom).Content as Scope).Parts[0] as FunctionCall);
                    var        type            = Engine.FindType(NameTranslator.CSharpNameFromScript(ctor.Name));
                    MethodInfo initMethod      = type.GetMethod("Init");
                    var        args            = initMethod.GetParameters();
                    bool       hasInteractable = false;
                    bool       hasInitiator    = false;
                    foreach (var param in args)
                    {
                        if (param.Name == "interactable")
                        {
                            hasInteractable = true;
                        }
                        else if (param.Name == "initiator")
                        {
                            hasInitiator = true;
                        }
                    }
                    builder.Length = 0;
                    builder.Append("new ");
                    builder.Append(type.FullName);
                    builder.Append("().Init");
                    builder.Append("(");
                    if (hasInteractable)
                    {
                        builder.Append("this.root");
                        builder.Append(",");
                    }
                    if (hasInitiator)
                    {
                        builder.Append("this.initiator");
                        builder.Append(",");
                    }

                    foreach (var funcArg in ctor.Args)
                    {
                        builder.Append(exprInter.InterpretExpression(funcArg, dependenciesBlock).ExprString);
                        builder.Append(",");
                    }
                    if (builder[builder.Length - 1] == ',')
                    {
                        builder.Length = builder.Length - 1;
                    }
                    builder.Append(")");
                    deps.Add(builder.ToString());
                }
                else
                {
                    //No idea
                }
            }
            if (deps.Count > 0)
            {
                CodeMemberMethod getDepsOverride = new CodeMemberMethod();
                getDepsOverride.ReturnType = new CodeTypeReference(typeof(List <Dependency>));
                getDepsOverride.Name       = "GetDependencies";
                getDepsOverride.Attributes = MemberAttributes.Public | MemberAttributes.Override;
                codeType.Members.Add(getDepsOverride);
                string listName = "list" + DeclareVariableStatement.VariableId++;
                string listOp   = String.Format("var {0} = new System.Collections.Generic.List<Dependency>({1});", listName, deps.Count);
                dependenciesBlock.Statements.Add(listOp);
                var addToListBlock = new FunctionBlock(dependenciesBlock);
                foreach (var newDep in deps)
                {
                    addToListBlock.Statements.Add(String.Format("{0}.Add({1});", listName, newDep));
                }
                dependenciesBlock.Statements.Add(addToListBlock);
                dependenciesBlock.Statements.Add(String.Format("return {0};", listName));
                getDepsOverride.Statements.Add(new CodeSnippetStatement(dependenciesBlock.ToString()));
            }
            CodeMemberMethod initOverrideMethod = new CodeMemberMethod();
            initOverrideMethod.Name       = "Init";
            initOverrideMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            codeType.Members.Add(initOverrideMethod);
            builder.Length = 0;
            builder.Append("base.Init();").AppendLine();
            foreach (var member in codeType.Members)
            {
                var field = member as CodeMemberField;
                if (field != null)
                {
                    builder.Append("this.").Append(field.Name).Append(" = ").Append("default(").Append((field.UserData["type"] as Type).FullName).Append(");").AppendLine();
                }
            }
            initOverrideMethod.Statements.Add(new CodeSnippetStatement(builder.ToString()));
        }
        CurProgress = MaxProgress;
        foreach (var type in codeTypes)
        {
            cNamespace.Types.Add(type);
        }

        CSharpCodeProvider   provider = new CSharpCodeProvider();
        CodeGeneratorOptions options  = new CodeGeneratorOptions();
        var writer = new StringWriter();

        provider.GenerateCodeFromNamespace(cNamespace, writer, options);
        Engine.GetPlugin <ScriptCompiler> ().AddSource(writer.ToString());
    }
Exemplo n.º 4
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 == null)
                {
                    Debug.LogErrorFormat("Context type is null, {0}, \r\n {1}", operand, block.ToString());
                }
                if (contextType.IsGenericType && contextType.GetGenericTypeDefinition() == typeof(List <>))
                {
                    if (firstTimeList)
                    {
                        CleanUpContextes.Push(resultVar);
                        resultVar.IsTemp = true;
                        resultVar.Name   = "result" + DeclareVariableStatement.VariableId++;
                        block.Statements [insertResultIndex] = resultVar;
                        resultVar.IsHidden = false;
                        resultVar.IsResult = true;

                        //resultList.Type = contextType;
                        //exprIsResultVar = true;
                        firstTimeList = false;
                    }
                    Debug.Log("scope list " + scope [i]);
                    DeclareVariableStatement declVar = new DeclareVariableStatement();
                    CleanUpContextes.Push(declVar);
                    declVar.IsTemp = true;
                    declVar.Name   = "list" + DeclareVariableStatement.VariableId++;
                    declVar.Type   = contextType;
                    if (exprBuilder [exprBuilder.Length - 1] == '.')
                    {
                        exprBuilder.Length -= 1;
                    }
                    if (hasSign)
                    {
                        declVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1);
                        exprBuilder.Length     = 1;
                        //exprBuilder.Append (declVar.Name).Append ('.');
                    }
                    else
                    {
                        declVar.InitExpression = exprBuilder.ToString();
                        exprBuilder.Length     = 0;
                        //exprBuilder.Append (declVar.Name).Append ('.');
                    }
                    curBlock.Statements.Add(declVar);
                    ForStatement forStatement = new ForStatement();
                    forStatement.RepeatBlock = new FunctionBlock(block, block.Method, block.Type);
                    var repeatContext = new DeclareVariableStatement();
                    repeatContext.IsTemp = true;
                    CleanUpContextes.Push(repeatContext);
                    forStatement.RepeatBlock.Statements.Add(repeatContext);
                    curBlock.Statements.Add(forStatement);
                    curBlock = forStatement.RepeatBlock;
                    var iterName = "i" + DeclareVariableStatement.VariableId++;
                    forStatement.InsideExpr = String.Format(@"int {0} = 0; {0} < {1}.Count; {0}++", iterName, declVar.Name);

                    contextType                  = contextType.GetGenericArguments() [0];
                    repeatContext.Name           = "SubContext" + DeclareVariableStatement.VariableId++;
                    repeatContext.Type           = contextType;
                    repeatContext.IsContext      = true;
                    repeatContext.InitExpression = String.Format(@"{0}[{1}]", declVar.Name, iterName);
                }
                bool isFunc = false;
                if (scope [i] is FunctionCall || scope [i] is string)
                {
//					var callOp = ProcessOperand (scope [i], block);
                    Expression[] callArgs = defaultArgsList;
                    string       callName = null;
                    var          call     = scope [i] as FunctionCall;
                    if (call != null)
                    {
                        callName = call.Name;
                        callArgs = call.Args;
                    }
                    else
                    {
                        callName = scope [i] as string;
                    }
                    if (scopeInterpreters.ContainsKey(callName))
                    {
                        var    interpreter = scopeInterpreters [callName];
                        string outExpr     = null;
                        interpreter.Interpret(callArgs, curBlock, contextType, exprBuilder.ToString(), out outExpr, out curBlock, out contextType, i == scope.Count - 1);
                        if (hasSign)
                        {
                            exprBuilder.Length = 1;
                            exprBuilder.Append(outExpr).Append('.');
                        }
                        else
                        {
                            exprBuilder.Length = 0;
                            exprBuilder.Append(outExpr).Append('.');
                        }
                        isFunc = true;
                    }
                    else
                    {
                        var methodName = NameTranslator.CSharpNameFromScript(callName);
                        var method     = contextType.GetMethod(methodName);
                        if (i == 0 && method == null)
                        {
                            var otherContext = block.FindStatement <DeclareVariableStatement> (v => (v.IsContext || v.IsArg) && (method = v.Type.GetMethod(methodName, any)) != null);
                            if (otherContext != null)
                            {
                                exprBuilder.Length = hasSign ? 1 : 0;
                                if (ScriptEngine.AnalyzeDebug)
                                {
                                    Debug.LogWarning("OTHER CONTEXT" + otherContext.DebugString());
                                }
                                exprBuilder.Append(otherContext.Name).Append('.');
                                contextType = otherContext.Type;
                            }
                            else
                            {
                                if (ScriptEngine.AnalyzeDebug)
                                {
                                    Debug.LogWarning("Can't find context for method " + methodName);
                                }
                                block.FindStatement <DeclareVariableStatement> (v => {
                                    if (ScriptEngine.AnalyzeDebug)
                                    {
                                        Debug.LogFormat("{0} {1} {3}                  ||||{2}", v.Name, v.Type, IfStatement.AntiMergeValue++, v.IsContext || v.IsArg);
                                    }
                                    return(false);
                                });
                            }
                        }
                        if (method == null)
                        {
                            if (ScriptEngine.AnalyzeDebug)
                            {
                                Debug.LogFormat("Can't find method {0} in {1}", NameTranslator.CSharpNameFromScript(callName), contextType);
                            }
                        }
                        else
                        {
                            exprBuilder.Append(method.Name).Append("(");
                            var argsDef = method.GetParameters();
                            if (callArgs != null)
                            {
                                for (int j = 0; j < callArgs.Length; j++)
                                {
                                    try
                                    {
                                        if (argsDef[j].ParameterType.IsSubclassOf(typeof(Delegate)))
                                        {
                                            exprBuilder.Append(InterpretClosure(callArgs[j], curBlock, argsDef[j].ParameterType).ExprString).Append(",");
                                        }
                                        else if (argsDef[j].ParameterType == typeof(System.Type))
                                        {
                                            exprBuilder.Append("typeof(ScriptedTypes.").
                                            Append(callArgs[j].ToString().ClearFromBraces()).Append(")").Append(",");
                                        }
                                        else
                                        {
                                            exprBuilder.Append(InterpretExpression(callArgs[j], curBlock).ExprString).Append(",");
                                        }
                                    }
                                    catch (IndexOutOfRangeException e)
                                    {
                                        Debug.Log(e);
                                        Debug.LogErrorFormat("Index out of range {0} in args of {1}. Script: {2}, Args count: {3}", j, method.Name, operand, argsDef.Length);
                                    }
                                }
                                if (callArgs.Length > 0)
                                {
                                    exprBuilder.Length -= 1;
                                }
                            }

                            exprBuilder.Append(")");
                            contextType = method.ReturnType;


                            var declVar = new DeclareVariableStatement();
                            CleanUpContextes.Push(declVar);
                            declVar.IsTemp    = true;
                            declVar.Name      = "prop" + DeclareVariableStatement.VariableId++;
                            declVar.IsContext = true;
                            if (exprBuilder.Length > 0 && exprBuilder [exprBuilder.Length - 1] == '.')
                            {
                                exprBuilder.Length -= 1;
                            }
                            if (hasSign)
                            {
                                declVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1);
                                exprBuilder.Length     = 1;
                                exprBuilder.Append(declVar.Name).Append('.');
                            }
                            else
                            {
                                declVar.InitExpression = exprBuilder.ToString();
                                exprBuilder.Length     = 0;
                                exprBuilder.Append(declVar.Name).Append('.');
                            }
                            declVar.Type = contextType;
                            curBlock.Statements.Add(declVar);
                            if (contextType.IsClass)
                            {
                                IfStatement ifSt = new IfStatement();
                                ifSt.CheckExpression = String.Format("{0} != null", declVar.Name);
                                ifSt.TrueBlock       = new FunctionBlock(curBlock);
                                curBlock.Statements.Add(ifSt);
                                curBlock = ifSt.TrueBlock;
                            }
                            else if (contextType == typeof(bool))
                            {
                                IfStatement ifSt = new IfStatement();
                                ifSt.CheckExpression = String.Format("{0} != false", declVar.Name);
                                ifSt.TrueBlock       = new FunctionBlock(curBlock);
                                curBlock.Statements.Add(ifSt);
                                curBlock = ifSt.TrueBlock;
                            }
                            isFunc = true;
                        }
                    }
                }
                if (!isFunc)
                {
                    var scopeStr = scope[i] as string;
                    if (scopeStr == null)
                    {
                        Debug.LogErrorFormat("{0} can't be casted to string", scope[i]);
                    }

                    var propName = NameTranslator.CSharpNameFromScript(scopeStr);

                    var prop = contextType.GetProperty(propName);

                    if (i == 0 && prop == null)
                    {
                        var customVar = block.FindStatement <DeclareVariableStatement> (v => v.Name == scope [i] as string);
                        if (ScriptEngine.CompileDebug)
                        {
                            Debug.LogFormat("{0} - {1} custom var", scope[i], customVar);
                        }
                        if (customVar == null)
                        {
                            var otherContext = block.FindStatement <DeclareVariableStatement> (v => {
                                //Debug.LogWarning (v.Type);
                                //Debug.Log (v.IsContext || v.IsArg);
                                //var props = v.Type.GetProperties (any);
                                //foreach (var allProp in props)
                                //	Debug.Log (allProp.Name);
                                return((v.IsContext || v.IsArg) && (prop = v.Type.GetProperty(propName, any)) != null);
                            });
                            if (otherContext != null)
                            {
                                exprBuilder.Length = hasSign ? 1 : 0;

                                exprBuilder.Append(otherContext.Name).Append('.');
                                contextType = otherContext.Type;
                                if (contextType.IsClass && !prop.GetGetMethod().IsStatic)
                                {
                                    IfStatement ifSt = new IfStatement();
                                    ifSt.CheckExpression = String.Format("{0} != null", otherContext.Name);
                                    ifSt.TrueBlock       = new FunctionBlock(curBlock);
                                    curBlock.Statements.Add(ifSt);
                                    curBlock = ifSt.TrueBlock;
                                }
                            }
                            else
                            if (ScriptEngine.AnalyzeDebug)
                            {
                                Debug.LogWarning("Can't find context for property " + propName);
                            }
                        }
                        else
                        {
                            exprBuilder.Length = hasSign ? 1 : 0;
                            exprBuilder.Append(customVar.Name).Append('.');
                            contextType = customVar.Type;
                            if (contextType.IsClass && !prop.GetGetMethod().IsStatic)
                            {
                                IfStatement ifSt = new IfStatement();
                                ifSt.CheckExpression = String.Format("{0} != null", customVar.Name);
                                ifSt.TrueBlock       = new FunctionBlock(curBlock);
                                curBlock.Statements.Add(ifSt);
                                curBlock = ifSt.TrueBlock;
                            }
                        }
                    }
                    if (ScriptEngine.AnalyzeDebug)
                    {
                        Debug.LogWarning(prop);
                    }
                    if (prop == null && components.ContainsKey(scope [i] as string))
                    {
                        var    type           = components [scope [i] as string];
                        string storedFromName = null;
                        if (hasSign)
                        {
                            storedFromName = exprBuilder.ToString(1, exprBuilder.Length - 1);
                        }
                        else
                        {
                            storedFromName = exprBuilder.ToString();
                        }
                        if (ScriptEngine.AnalyzeDebug)
                        {
                            Debug.LogWarning("Component found " + type);
                        }
                        var storedVar = curBlock.FindStatement <DeclareVariableStatement> (v => v.Type == type && v.storedOf != null && storedFromName == v.storedOf);
                        var prevType  = contextType;
                        contextType = type;
                        if (storedVar == null)
                        {
                            storedVar = new DeclareVariableStatement();
                            CleanUpContextes.Push(storedVar);
                            storedVar.IsTemp    = true;
                            storedVar.IsContext = true;
                            storedVar.Name      = "StoredVariable" + DeclareVariableStatement.VariableId++;
                            storedVar.Type      = type;

                            storedVar.storedOf = hasSign ? exprBuilder.ToString(1, exprBuilder.Length) : exprBuilder.ToString(0, exprBuilder.Length);
                            if (prevType != typeof(GameObject) && !typeof(MonoBehaviour).IsAssignableFrom(prevType))
                            {
                                exprBuilder.Length = hasSign ? 1 : 0;
                                var ctx = block.FindStatement <DeclareVariableStatement>(
                                    v => v.IsContext && (v.Type == typeof(GameObject) || typeof(MonoBehaviour).IsAssignableFrom(v.Type))
                                    ).Name;
                                if (ctx == null)
                                {
                                    ctx = block.DefaultScope;
                                }
                                exprBuilder.Append(ctx).Append('.');
                            }

                            curBlock.Statements.Add(storedVar);
                            exprBuilder.Append(String.Format("GetComponent(typeof({0})))", type));
                            exprBuilder.Insert(0, String.Format("(({0})", type));
                            if (hasSign)
                            {
                                storedVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1);
                                exprBuilder.Length       = 1;
                                exprBuilder.Append(storedVar.Name).Append('.');
                            }
                            else
                            {
                                storedVar.InitExpression = exprBuilder.ToString();
                                exprBuilder.Length       = 0;
                                exprBuilder.Append(storedVar.Name).Append('.');
                            }
                        }
                        if (hasSign)
                        {
                            exprBuilder.Length = 1;
                            exprBuilder.Append(storedVar.Name).Append('.');
                        }
                        else
                        {
                            exprBuilder.Length = 0;
                            exprBuilder.Append(storedVar.Name).Append('.');
                        }

                        if (contextType.IsClass)
                        {
                            IfStatement ifSt = new IfStatement();
                            ifSt.CheckExpression = String.Format("{0} != null", storedVar.Name);
                            ifSt.TrueBlock       = new FunctionBlock(curBlock);
                            curBlock.Statements.Add(ifSt);
                            curBlock = ifSt.TrueBlock;
                        }
                    }
                    else if (scopeInterpreters.ContainsKey(scope [i] as string))
                    {
                        var    interpreter = scopeInterpreters [scope [i] as string];
                        string outExpr     = null;
                        interpreter.Interpret(null, curBlock, contextType, exprBuilder.ToString(), out outExpr, out curBlock, out contextType, i == scope.Count - 1);
                        if (hasSign)
                        {
                            exprBuilder.Length = 1;
                            exprBuilder.Append(outExpr).Append('.');
                        }
                        else
                        {
                            exprBuilder.Length = 0;
                            exprBuilder.Append(outExpr).Append('.');
                        }
                    }
                    else if (prop == null && scope.Count == 1)
                    {
                        if (ScriptEngine.AnalyzeDebug)
                        {
                            Debug.LogWarningFormat("Can't find {0} in {1}, interpreting as a string", propName, contextType);
                        }
                        contextType        = typeof(string);
                        exprBuilder.Length = 0;
                        exprBuilder.Append("\"").Append(scope [i]).Append("\"");
                        break;
                    }
                    else if (prop == null)
                    {
                        Debug.LogWarningFormat("Can't find {0} in {1}", propName, contextType);
                        break;
                    }
                    else
                    {
                        contextType = prop.PropertyType;
                        exprBuilder.Append(propName).Append('.');
                        var declVar = new DeclareVariableStatement();
                        CleanUpContextes.Push(declVar);
                        declVar.IsTemp    = true;
                        declVar.IsContext = true;
                        declVar.Name      = "prop" + DeclareVariableStatement.VariableId++;
                        if (exprBuilder.Length > 0 && exprBuilder [exprBuilder.Length - 1] == '.')
                        {
                            exprBuilder.Length -= 1;
                        }
                        if (hasSign)
                        {
                            declVar.InitExpression = exprBuilder.ToString(1, exprBuilder.Length - 1);
                            exprBuilder.Length     = 1;
                            exprBuilder.Append(declVar.Name).Append('.');
                        }
                        else
                        {
                            declVar.InitExpression = exprBuilder.ToString();
                            exprBuilder.Length     = 0;
                            exprBuilder.Append(declVar.Name).Append('.');
                        }
                        declVar.Type = contextType;
                        curBlock.Statements.Add(declVar);
                        if (contextType.IsClass)
                        {
                            IfStatement ifSt = new IfStatement();
                            ifSt.CheckExpression = String.Format("{0} != null", declVar.Name);
                            ifSt.TrueBlock       = new FunctionBlock(curBlock);
                            curBlock.Statements.Add(ifSt);
                            curBlock = ifSt.TrueBlock;
                        }
                    }
                }
            }
            returnExpr.Type = contextType;
            var res = resultVar;
            if (!res.IsHidden)
            {
                var list   = curBlock.FindStatement <DeclareVariableStatement> (v => v.Type != null && v.Type.IsGenericType && v.Type.GetGenericTypeDefinition() == typeof(List <>));
                var lasVar = curBlock.FindStatement <DeclareVariableStatement> (v => v.IsContext);
                if (list != null && !firstTimeList)
                {
                    curBlock.Statements.Add(String.Format(@"{0}.Add({1});", res.Name, lasVar.Name));
                    res.Type           = typeof(List <>).MakeGenericType(lasVar.Type);
                    res.InitExpression = String.Format("new {0}();", TypeName.NameOf(res.Type));
                }
                else
                {
                    res.Type = lasVar.Type;
                    curBlock.Statements.Add(String.Format(@"{0} = {1};", res.Name, lasVar.Name));
                }
                if (hasSign)
                {
                    exprBuilder.Length = 1;
                    exprBuilder.Append(res.Name).Append('.');
                }
                else
                {
                    exprBuilder.Length = 0;
                    exprBuilder.Append(res.Name).Append('.');
                }

                returnExpr.Type = res.Type;
            }

            if (!res.IsHidden && res.Type != null)
            {
                var resType = res.Type;
                res.IsResult = false;
                Debug.Log(isInsideBoolean);
                if (isInsideBoolean && resType.IsGenericType && resType.GetGenericTypeDefinition() == typeof(List <>))
                {
                    exprBuilder.Append(String.Format(" != null ? {0}.Count : 0", exprBuilder));
                }
            }
            if (exprBuilder.Length > 0 && exprBuilder [exprBuilder.Length - 1] == '.')
            {
                exprBuilder.Length -= 1;
            }
            if (res.IsHidden)
            {
                resultVar.Name                       = "OperandVar" + DeclareVariableStatement.VariableId++;
                resultVar.Type                       = contextType;
                resultVar.InitExpression             = string.Format("default({0})", TypeName.NameOf(contextType));
                resultVar.IsHidden                   = false;
                block.Statements [insertResultIndex] = resultVar;
                curBlock.Statements.Add(String.Format("{0} = {1};", resultVar.Name, exprBuilder));
                exprBuilder.Length = hasSign ? 1 : 0;
                var resType = res.Type;
                if (isInsideBoolean && resType.IsGenericType && resType.GetGenericTypeDefinition() == typeof(List <>))
                {
                    exprBuilder.Append(String.Format("{0} != null ? {0}.Count : 0", resultVar.Name));
                }
                else
                {
                    exprBuilder.Append(resultVar.Name);
                }
            }
        }
        else if (operand is FunctionCall)
        {
//			var call = operand as FunctionCall;
//			for (int i = 0; i < call.Args.Length; i++)
//			{
//
//			}
        }
        else if (operand is Expression)
        {
            var ex = InterpretExpression(operand as Expression, block, false, isInsideBoolean);
            exprBuilder.Append(ex.ExprString);
            returnExpr.Type = ex.Type;
        }
        else
        {
            returnExpr.Type = operand.GetType();
            if (operand is bool)
            {
                exprBuilder.Append((bool)operand ? "true" : "false");
            }
            else
            {
                exprBuilder.Append(operand);
            }
            if (operand is float)
            {
                exprBuilder.Append('f');
            }
        }
        string head = String.Format("{0}(", signChar);

        exprBuilder.Insert(0, head).Append(')');
        returnExpr.ExprString = exprBuilder.ToString();
        return(returnExpr);
    }