Exemple #1
0
 protected override void VisitAndExpression(AndExpression expression)
 {
     CS.IndentInOut(
         "AndExpression",
         () =>
     {
         Locals.PeekPrep(Writer);
         VisitExpression(expression.Expression);
         CS.If(
             $"{Locals.Result}.IsSuccess",
             () =>
         {
             CS.Ln($"{Locals.Result} = Result.Success({Locals.Result}, {Cfg.CurName});");
         },
             () =>
         {
             CS.Ln($"{Locals.Result} = Result.Fail({Cfg.CurName});");
         });
     });
 }
        internal LLVMValueRef StartMethod(string pName, Syntax.MethodSyntax pNode)
        {
            var func = LLVM.GetNamedFunction(CurrentModule, pName);

            Debug.Assert(func.Pointer != IntPtr.Zero);
            Locals.AddScope();
            AddDebugScope(pNode.Span);

            //Emit body
            var body = LLVM.AppendBasicBlock(func, pName + "body");

            LLVM.PositionBuilderAtEnd(Builder, body);

            int start = 0;

            if (CurrentStruct != null)
            {
                start = 1;
                LLVMValueRef p = LLVM.GetParam(func, 0);
                LLVM.SetValueName(p, "self");
                Locals.DefineVariableInScope("self", LocalDefinition.CreateParameter(p, CurrentStruct));
                EmitDebugParameter("self", CurrentStruct, pNode.Span.Line, 0);
            }

            //Set parameter names and define in scope
            for (int i = 0; i < pNode.Parameters.Count; i++)
            {
                string       name = pNode.Parameters[i].Value;
                LLVMValueRef parm = LLVM.GetParam(func, (uint)(i + start));
                LLVM.SetValueName(parm, name);
                EmitDebugParameter(name, pNode.Parameters[i].Type, pNode.Span.Line, i + start);

                Debug.Assert(!Locals.IsVariableDefinedInScope(name), $"Parameter {name} already defined");
                Locals.DefineVariableInScope(name, LocalDefinition.CreateParameter(parm, pNode.Parameters[i].Type));
            }

            EmitFunctionDebugInfo(pNode, func);

            CurrentMethod = func;
            return(func);
        }
Exemple #3
0
        public bool LocalOrParent(string var)
        {
            if (Function)
            {
                return(Locals.ContainsKey(var));
            }

            var s = this;

            do
            {
                if (s.Locals.ContainsKey(var))
                {
                    return(true);
                }

                s = s.Parent;
            }while (s != null && !s.Function);

            return(false);
        }
        void EndMulti(ILGenerator il)
        {
            Debug.Assert(il != null);
            Debug.Assert(ArgsCount > 2);

            il_EmitSaveElem(il);

            for (int i = 0, j = ArgsCount - 1; i < ArgsCount; i++, j--)
            {
                var index = Locals.Pop();
                var array = Locals.Pop();
                var var   = ArgsLocs[j];

                // x += xstep;
                il.Emit(OpCodes.Ldloc, var);
                il.Emit(OpCodes.Ldloc, StepLocs.Pop());
                Generic.Operation(il, 1);
                il.Emit(OpCodes.Stloc, var);

                EmitLoopEnd(il, index, array);
            }
        }
Exemple #5
0
 public override Node AcceptTransformer(AbstractHirTransformer transformer, bool forceDefaultImpl)
 {
     if (forceDefaultImpl)
     {
         // todo. think about how to implement this without multiple clone operations
         var clause = base.AcceptTransformer(transformer, false);
         if (clause is Block && !(clause is Clause))
         {
             var visited = new Finally(clause);
             visited.Locals.SetElements(Locals.Select(loc => loc.DeepClone()));
             return(visited.HasProto(this));
         }
         else
         {
             return(clause.HasProto(this));
         }
     }
     else
     {
         return(transformer.TransformFinally(this).HasProto(this));
     }
 }
Exemple #6
0
 public override Node AcceptTransformer(AbstractHirTransformer transformer, bool forceDefaultImpl)
 {
     if (forceDefaultImpl)
     {
         // todo. think about how to implement this without multiple clone operations
         var clause = base.AcceptTransformer(transformer, false);
         if (clause is Block && !(clause is Clause))
         {
             var filter  = transformer.Transform(Filter).AssertCast <Lambda>();
             var visited = new Catch(ExceptionType, filter, clause);
             visited.Locals.SetElements(Locals.Select(loc => loc.DeepClone()));
             return(visited.HasProto(this));
         }
         else
         {
             return(clause.HasProto(this));
         }
     }
     else
     {
         return(transformer.TransformCatch(this).HasProto(this));
     }
 }
Exemple #7
0
        /// <summary>
        ///   Global distance D(X,Y) between two sequences of vectors.
        /// </summary>
        ///
        /// <param name="locals">The current thread local storage.</param>
        /// <param name="sequence1">A sequence of vectors.</param>
        /// <param name="sequence2">A sequence of vectors.</param>
        ///
        /// <returns>The global distance between X and Y.</returns>
        ///
        private double D(Locals locals, TInput[] sequence1, TInput[] sequence2)
        {
            // Get the number of vectors in each sequence. The vectors
            // have been projected, so the length is augmented by one.
            int vectorCount1 = sequence1.Length;
            int vectorCount2 = sequence2.Length;

            // Application of the Dynamic Time Warping
            // algorithm by using dynamic programming.
            if (locals.m < vectorCount2 || locals.n < vectorCount1)
            {
                locals.Create(vectorCount1, vectorCount2);
            }

            double[,] DTW = locals.DTW;

            for (int i = 0; i < sequence1.Length; i++)
            {
                for (int j = 0; j < sequence2.Length; j++)
                {
                    // Compute the distance between the sequences
                    double cost = distance.Distance(sequence1[i], sequence2[j]);

                    double insertion = DTW[i, j + 1];
                    double deletion  = DTW[i + 1, j];
                    double match     = DTW[i, j];

                    double min = (insertion < deletion
                        ? (insertion < match ? insertion : match)
                        : (deletion < match ? deletion : match));

                    DTW[i + 1, j + 1] = cost + min;
                }
            }

            return(DTW[vectorCount1, vectorCount2]); // return the minimum global distance
        }
 public void FinishMethod(LLVMValueRef pFunction)
 {
     RemoveDebugScope();
     Locals.RemoveScope();
     ValidateMethod(pFunction);
 }
Exemple #9
0
 public MethodBodySymbolContext WithLocal(ILocal local)
 => new MethodBodySymbolContext(SourceSymbolContext, Locals.Add(local), CurrentStatement);
Exemple #10
0
        /// <summary>
        ///   Global distance D(X,Y) between two sequences of vectors.
        /// </summary>
        /// 
        /// <param name="locals">The current thread local storage.</param>
        /// <param name="sequence1">A sequence of vectors.</param>
        /// <param name="sequence2">A sequence of vectors.</param>
        /// 
        /// <returns>The global distance between X and Y.</returns>
        /// 
        private unsafe double D(Locals locals, double[] sequence1, double[] sequence2)
        {
            // Get the number of vectors in each sequence. The vectors
            // have been projected, so the length is augmented by one.
            int vectorSize = length + 1;
            int vectorCount1 = sequence1.Length / vectorSize;
            int vectorCount2 = sequence2.Length / vectorSize;

            // Application of the Dynamic Time Warping
            // algorithm by using dynamic programming.
            if (locals.m < vectorCount2 || locals.n < vectorCount1)
                locals.Create(vectorCount1, vectorCount2);

            double[,] DTW = locals.DTW;


            fixed (double* start1 = sequence1)
            fixed (double* start2 = sequence2)
            {
                double* vector1 = start1;

                for (int i = 0; i < vectorCount1; i++, vector1 += vectorSize)
                {
                    double* vector2 = start2;

                    for (int j = 0; j < vectorCount2; j++, vector2 += vectorSize)
                    {
                        double prod = 0; // inner product 
                        for (int k = 0; k < vectorSize; k++)
                            prod += vector1[k] * vector2[k];

                        // Return the arc-cosine of the inner product
                        double cost = Math.Acos(prod > 1 ? 1 : (prod < -1 ? -1 : prod));

                        double insertion = DTW[i, j + 1];
                        double deletion = DTW[i + 1, j];
                        double match = DTW[i, j];

                        double min = (insertion < deletion
                            ? (insertion < match ? insertion : match)
                            : (deletion < match ? deletion : match));

                        DTW[i + 1, j + 1] = cost + min;
                    }
                }
            }

            return DTW[vectorCount1, vectorCount2]; // return the minimum global distance
        }
Exemple #11
0
 public override string ToString()
 {
     return("Locals: " + Locals.Count() + " Operands: " + OperandStack.Count());
 }
Exemple #12
0
 bool VariableNameInUse([NotNull] ZilAtom atom)
 {
     return(Locals.ContainsKey(atom) || TempLocalNames.Contains(atom) ||
            Globals.ContainsKey(atom) || SoftGlobals.ContainsKey(atom) ||
            Constants.ContainsKey(atom) || Objects.ContainsKey(atom) || Routines.ContainsKey(atom));
 }
Exemple #13
0
        //This is an example of the implementation of the Parse method
        public override void Parse(TokensStack sTokens)
        {
            //We check that the first token is "function"
            Token tFunc = sTokens.Pop();

            if (!(tFunc is Statement) || ((Statement)tFunc).Name != "function")
            {
                throw new SyntaxErrorException("Expected function received: " + tFunc, tFunc);
            }
            //Now there should be the return type. We pop it from the stack, check for errors, and then set the field
            Token tType = sTokens.Pop();

            if (!(tType is VarType))
            {
                throw new SyntaxErrorException("Expected var type, received " + tType, tType);
            }
            ReturnType = VarDeclaration.GetVarType(tType);
            //Next is the function name
            Token tName = sTokens.Pop();

            if (!(tName is Identifier))
            {
                throw new SyntaxErrorException("Expected function name, received " + tType, tType);
            }
            Name = ((Identifier)tName).Name;

            //After the name there should be opening paranthesis for the arguments
            Token t = sTokens.Pop(); //(

            if (!(t is Parentheses) || ((Parentheses)t).Name != '(')
            {
                throw new SyntaxErrorException($"Expected a '(' but saw '{t}'", t);
            }

            //Now we extract the arguments from the stack until we see a closing parathesis
            while (sTokens.Count > 0 && !(sTokens.Peek() is Parentheses))//)
            {
                //For each argument there should be a type, and a name
                if (sTokens.Count < 3)
                {
                    throw new SyntaxErrorException("Early termination ", t);
                }
                Token          tArgType = sTokens.Pop();
                Token          tArgName = sTokens.Pop();
                VarDeclaration vc       = new VarDeclaration(tArgType, tArgName);
                Args.Add(vc);
                //If there is a comma, then there is another argument
                if (sTokens.Count > 0 && sTokens.Peek() is Separator) //,
                {
                    t = sTokens.Pop();
                    if (!(t is Separator) || ((Separator)t).Name != ',')
                    {
                        throw new SyntaxErrorException($"Expected a ',' but saw '{t}'", t);
                    }
                }
            }
            //Now we pop out the ) and the {. Note that you need to check that the stack contains the correct symbols here.
            t = sTokens.Pop();//)
            if (!(t is Parentheses) || ((Parentheses)t).Name != ')')
            {
                throw new SyntaxErrorException($"Expected a ')' but saw '{t}'", t);
            }
            t = sTokens.Pop();//{
            if (!(t is Parentheses) || ((Parentheses)t).Name != '{')
            {
                throw new SyntaxErrorException($"Expected a '{{' but saw '{t}'", t);
            }

            //Now we parse the list of local variable declarations
            while (sTokens.Count > 0 && (sTokens.Peek() is Statement) && (((Statement)sTokens.Peek()).Name == "var"))
            {
                VarDeclaration local = new VarDeclaration();
                //We call the Parse method of the VarDeclaration, which is responsible to parsing the elements of the variable declaration
                local.Parse(sTokens);
                Locals.Add(local);
            }

            //Now we parse the list of statements
            while (sTokens.Count > 0 && !(sTokens.Peek() is Parentheses))
            {
                //We create the correct Statement type (if, while, return, let) based on the top token in the stack
                StatetmentBase s = StatetmentBase.Create(sTokens.Peek());
                //And call the Parse method of the statement to parse the different parts of the statement
                s.Parse(sTokens);
                Body.Add(s);
            }

            bool hasReturn = false;

            if (Body.Count > 0)
            {
                StatetmentBase lastStatetment = Body[Body.Count - 1];
                Body.RemoveAt(Body.Count - 1);
                if (lastStatetment is ReturnStatement)
                {
                    Return    = (ReturnStatement)lastStatetment;
                    hasReturn = true;
                }
                else
                {
                    hasReturn = false;
                }
            }

            //Need to check here that the last statement is a return statement
            //Finally, the function should end with }
            Token tEnd = sTokens.Pop();//}

            if (!hasReturn)
            {
                throw new SyntaxErrorException("Missing a return statement.", tEnd);
            }
            if (!(tEnd is Parentheses) || ((Parentheses)tEnd).Name != '}')
            {
                throw new SyntaxErrorException($"Expected a '}}' but saw '{t}'", t);
            }
        }
        /// <summary>
        /// Compiles the statement, and returns wether or not control flow falls through to the next statement.
        /// </summary>
        public void CompileStatement(Statement s, bool markSource)
        {
            switch (s.StatementType)
            {
                case StatementType.Expression:
                    {
                        var e = s as Expression;
                        var pop = !e.ReturnType.IsVoid;
                        if (markSource)
                            MarkSource(e.Source);

                        CompileExpression(e, pop, false);
                    }
                    break;

                case StatementType.VariableDeclaration:
                    {
                        var ld = s as VariableDeclaration;
                        for (var var = ld.Variable; var != null; var = var.Next)
                        {
                            Locals.Add(var);
                            if (var.OptionalValue != null)
                            {
                                if (markSource)
                                    MarkSource(var.Source);
                                CompileExpression(var.OptionalValue);
                                Emit(Opcodes.StoreLocal, var);
                            }
                        }
                    }
                    break;

                case StatementType.FixedArrayDeclaration:
                    {
                        var ld = s as FixedArrayDeclaration;
                        Locals.Add(ld.Variable);

                        if (ld.OptionalInitializer != null)
                        {
                            for (int i = 0; i < ld.OptionalInitializer.Length; i++)
                            {
                                if (markSource)
                                    MarkSource(ld.OptionalInitializer[i].Source);
                                Emit(Opcodes.Constant, i);
                                CompileExpression(ld.OptionalInitializer[i]);
                                Emit(Opcodes.StoreArrayElement, ld.Variable);
                            }
                        }
                    }
                    break;

                case StatementType.Scope:
                    {
                        var sc = s as Scope;

                        foreach (var st in sc.Statements)
                        {
                            var scopeCall = st as CallMethod;
                            var markScopeCall = !(scopeCall?.Method != null && scopeCall.Method.IsGenerated);
                            CompileStatement(st, markSource && markScopeCall);
                        }

                        if (sc.Statements.Count == 0 && markSource)
                            MarkSource(sc.Source);
                    }
                    break;

                case StatementType.While:
                    {
                        var w = s as While;

                        var body = NewLabel();
                        var cond = NewLabel();
                        var after = NewLabel();
                        _breakLabels.Push(after);
                        _continueLabels.Push(cond);

                        if (w.DoWhile)
                        {
                            MarkLabel(body);
                            if (w.OptionalBody != null)
                                CompileStatement(w.OptionalBody, markSource);

                            MarkLabel(cond);
                            if (markSource)
                                MarkSource(w.Condition.Source);
                            CompileCondition(w.Condition, ConditionSequence.FalseFollows, body, after);
                        }
                        else
                        {
                            MarkLabel(cond);
                            if (markSource)
                                MarkSource(w.Condition.Source);
                            CompileCondition(w.Condition, ConditionSequence.TrueFollows, body, after);

                            MarkLabel(body);
                            if (w.OptionalBody != null)
                                CompileStatement(w.OptionalBody, markSource);

                            Branch(Opcodes.Br, cond);
                        }

                        _breakLabels.Pop();
                        _continueLabels.Pop();

                        MarkLabel(after);
                    }
                    break;

                case StatementType.For:
                    {
                        var f = s as For;
                        var body = NewLabel();
                        var inc = NewLabel();
                        var cond = NewLabel();
                        var after = NewLabel();

                        _breakLabels.Push(after);
                        _continueLabels.Push(inc);

                        if (f.OptionalInitializer != null)
                            CompileStatement(f.OptionalInitializer, markSource);

                        Branch(Opcodes.Br, cond);

                        MarkLabel(body);
                        if (f.OptionalBody != null)
                            CompileStatement(f.OptionalBody, markSource);

                        MarkLabel(inc);
                        if (f.OptionalIncrement != null)
                        {
                            if (markSource)
                                MarkSource(f.OptionalIncrement.Source);
                            CompileExpression(f.OptionalIncrement, true);
                        }

                        MarkLabel(cond);
                        if (f.OptionalCondition != null)
                        {
                            if (markSource)
                                MarkSource(f.OptionalCondition.Source);
                            CompileCondition(f.OptionalCondition, ConditionSequence.FalseFollows, body, after);
                        }
                        else
                        {
                            Branch(Opcodes.Br, body);
                        }

                        _breakLabels.Pop();
                        _continueLabels.Pop();

                        MarkLabel(after);
                    }
                    break;

                case StatementType.IfElse:
                    {
                        var ife = s as IfElse;
                        if (markSource)
                            MarkSource(ife.Condition.Source);
                        var cond = CompileCondition(ife.Condition, ConditionSequence.TrueFollows);

                        MarkLabel(cond.TrueLabel);
                        if (ife.OptionalIfBody != null)
                            CompileStatement(ife.OptionalIfBody, markSource);

                        if (ife.OptionalElseBody != null)
                        {
                            var after = NewLabel();
                            Branch(Opcodes.Br, after);

                            MarkLabel(cond.FalseLabel);
                            CompileStatement(ife.OptionalElseBody, markSource);

                            MarkLabel(after);
                        }
                        else
                        {
                            MarkLabel(cond.FalseLabel);
                        }
                    }
                    break;

                case StatementType.Return:
                    {
                        var r = s as Return;
                        if (r.Value != null)
                        {
                            if (markSource)
                                MarkSource(r.Value.Source);
                            CompileExpression(r.Value);
                            Return(r.Value.ReturnType);
                        }
                        else
                        {
                            if (markSource)
                                MarkSource(s.Source);
                            Return(null);
                        }
                    }
                    break;

                case StatementType.Break:
                    {
                        if (_breakLabels.Count == 0)
                            throw new FatalException(s.Source, ErrorCode.E0015, "Invalid break");

                        if (markSource)
                            MarkSource(s.Source);
                        Branch(Opcodes.Br, _breakLabels.Peek());
                    }
                    break;

                case StatementType.Continue:
                    {
                        if (_continueLabels.Count == 0)
                            throw new FatalException(s.Source, ErrorCode.E0016, "Invalid continue");

                        if (markSource)
                            MarkSource(s.Source);
                        Branch(Opcodes.Br, _continueLabels.Peek());
                    }
                    break;

                case StatementType.TryCatchFinally:
                    {
                        var tc = s as TryCatchFinally;

                        _tryCatchStack.Add(tc);

                        Emit(Opcodes.BeginExceptionBlock);
                        CompileStatement(tc.TryBody, markSource);

                        foreach (var c in tc.CatchBlocks)
                        {
                            Emit(Opcodes.BeginCatchBlock, c.Exception.ValueType);

                            if (markSource)
                                MarkSource(c.Body.Source);
                            Locals.Add(c.Exception);
                            Emit(Opcodes.StoreLocal, c.Exception);
                            CompileStatement(c.Body, markSource);
                        }

                        _tryCatchStack.RemoveLast();

                        // TODO: finally-clause goes here (_AFTER_ "POP"!)

                        if (tc.OptionalFinallyBody != null)
                        {
                            Emit(Opcodes.BeginFinallyBlock);
                            if (markSource)
                                MarkSource(tc.OptionalFinallyBody.Source);
                            CompileStatement(tc.OptionalFinallyBody, markSource);
                        }

                        Emit(Opcodes.EndExceptionBlock);
                    }
                    break;

                case StatementType.Switch:
                    {
                        var sw = s as Switch;
                        if (markSource)
                            MarkSource(sw.ControlVariable.Source);
                        CompileExpression(sw.ControlVariable);
                        var temp = StoreTempDontDup(sw.ControlVariable.ReturnType);

                        var after = NewLabel();

                        Label defaultLabel = null;
                        _breakLabels.Push(after);

                        var caseLabels = new Label[sw.Cases.Length];

                        for (var i = 0; i < sw.Cases.Length; i++)
                            caseLabels[i] = NewLabel();

                        for (var i = 0; i < sw.Cases.Length; i++)
                        {
                            for (int v = 0; v < sw.Cases[i].Values.Length; v++)
                            {
                                CompileExpression(sw.Cases[i].Values[v]);
                                LoadTemp(temp);
                                Branch(Opcodes.BrEq, caseLabels[i]);
                            }

                            if (sw.Cases[i].HasDefault)
                            {
                                defaultLabel = caseLabels[i];
                            }
                        }

                        Branch(Opcodes.Br, defaultLabel ?? after);

                        for (var i = 0; i < sw.Cases.Length; i++)
                        {
                            MarkLabel(caseLabels[i]);
                            CompileStatement(sw.Cases[i].Scope, markSource);
                            Branch(Opcodes.Br, after);
                        }

                        _breakLabels.Pop();
                        MarkLabel(after);
                    }
                    break;

                case StatementType.Throw:
                    {
                        var t = s as Throw;
                        if (markSource)
                            MarkSource(t.Source);
                        CompileExpression(t.Exception);
                        Emit(Opcodes.Throw);
                        if (markSource)
                            MarkSource(t.Source);
                    }
                    break;

                case StatementType.Draw:
                case StatementType.DrawDispose:
                    break;

                default:
                    throw new FatalException(s.Source, ErrorCode.I0017, "Statement type not supported in bytecode backend: " + s.StatementType);
            }
        }
Exemple #15
0
 public string GetStringText(string key)
 {
     return(Locals.Find(s => s [0] == key)[(int)CurrentLocal]);
 }
Exemple #16
0
 public Iter(Expression init, Block body)
     : base(NodeType.Iter, init, body ?? new Block())
 {
     Locals.Add(new Local("$el", null));
 }
Exemple #17
0
        public void CompileExpression(Expression e, bool pop = false, bool addressMode = false, Condition cond = null)
        {
            switch (e.ExpressionType)
            {
            case ExpressionType.NoOp:
                break;

            case ExpressionType.AddressOf:
                CompileExpression((e as AddressOf).Operand, pop, true);
                break;

            case ExpressionType.Constant:
            {
                if (cond != null && !cond.Handled)
                {
                    if ((bool)e.ConstantValue)
                    {
                        cond.CanSkipFalse = true;

                        if (cond.Sequence != ConditionSequence.TrueFollows)
                        {
                            Branch(Opcodes.Br, cond.TrueLabel ?? (cond.TrueLabel = NewLabel()));
                        }
                    }
                    else
                    {
                        cond.CanSkipTrue = true;

                        if (cond.Sequence != ConditionSequence.FalseFollows)
                        {
                            Branch(Opcodes.Br, cond.FalseLabel ?? (cond.FalseLabel = NewLabel()));
                        }
                    }

                    cond.Handled = true;
                }
                else if (!pop)
                {
                    if (e.ConstantValue != null)
                    {
                        Emit(Opcodes.Constant, e.ConstantValue);
                    }
                    else if (!e.ReturnType.IsReferenceType || e.ReturnType.IsGenericType)
                    {
                        Emit(Opcodes.DefaultInit, e.ReturnType);
                    }
                    else
                    {
                        Emit(Opcodes.Null);
                    }

                    if (addressMode)
                    {
                        CreateIndirection(e.ReturnType);
                    }
                }
            }
            break;

            case ExpressionType.Default:
            {
                if (cond != null && !cond.Handled)
                {
                    Branch(Opcodes.Br, cond.FalseLabel);
                    cond.Handled = true;
                }
                else if (!pop)
                {
                    Emit(Opcodes.DefaultInit, e.ReturnType);

                    if (addressMode)
                    {
                        CreateIndirection(e.ReturnType);
                    }
                }
            }
            break;

            case ExpressionType.TypeOf:
            {
                if (!pop)
                {
                    Emit(Opcodes.TypeOf, (e as TypeOf).Type);
                }
            }
            break;

            case ExpressionType.This:
            {
                if (pop)
                {
                    return;
                }
                Emit(Opcodes.This);

                if (!addressMode && Function.DeclaringType.IsValueType)
                {
                    Emit(Opcodes.LoadObj, Function.DeclaringType);
                }
            }
            break;

            case ExpressionType.Base:
            {
                if (pop)
                {
                    return;
                }
                Emit(Opcodes.This);

                if (!Function.DeclaringType.IsValueType)
                {
                    return;
                }

                Emit(Opcodes.LoadObj, Function.DeclaringType);
                Emit(Opcodes.Box, Function.DeclaringType);
            }
            break;

            case ExpressionType.SequenceOp:
            {
                var s = e as SequenceOp;
                CompileExpression(s.Left, !s.Left.ReturnType.IsVoid);
                CompileExpression(s.Right, pop, addressMode);
            }
            break;

            case ExpressionType.IsOp:
            {
                var s = e as IsOp;
                CompileExpression(s.Operand, pop);

                if (pop)
                {
                    break;
                }
                if (s.Operand.ReturnType.IsGenericParameter)
                {
                    Emit(Opcodes.Box, s.Operand.ReturnType);
                }

                Emit(Opcodes.AsClass, s.TestType);
                Emit(Opcodes.Null);
                Emit(Opcodes.Neq);

                if (addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.AsOp:
            {
                var s = e as AsOp;
                CompileExpression(s.Operand, pop);

                if (pop)
                {
                    break;
                }
                if (s.Operand.ReturnType.IsGenericParameter)
                {
                    Emit(Opcodes.Box, s.Operand.ReturnType);
                }

                Emit(Opcodes.AsClass, s.ReturnType);

                if (s.ReturnType.IsGenericParameter)
                {
                    Emit(Opcodes.UnboxAny, s.ReturnType);
                }
                if (addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.LoadLocal:
            {
                var s = e as LoadLocal;
                if (pop)
                {
                    break;
                }

                Emit(addressMode
                                ? Opcodes.LoadLocalAddress
                                : Opcodes.LoadLocal,
                     s.Variable);
            }
            break;

            case ExpressionType.LoadField:
            {
                var s = e as LoadField;

                if (s.Object != null)
                {
                    CompileExpression(s.Object, false, addressMode && s.Object is This);

                    if (pop)
                    {
                        Pop();
                    }
                    else
                    {
                        Emit(addressMode
                                        ? Opcodes.LoadFieldAddress
                                        : Opcodes.LoadField,
                             s.Field);
                    }
                }
                else
                {
                    if (!pop)
                    {
                        Emit(addressMode
                                        ? Opcodes.LoadStaticFieldAddress
                                        : Opcodes.LoadStaticfield,
                             s.Field);
                    }
                }
            }
            break;

            case ExpressionType.LoadElement:
            {
                var s = e as LoadElement;
                CompileExpression(s.Array, pop);
                CompileExpression(s.Index, pop);

                if (pop)
                {
                    return;
                }

                Emit(addressMode
                                ? Opcodes.LoadArrayElementAddress
                                : Opcodes.LoadArrayElement,
                     s.Array.ReturnType.ElementType);
            }
            break;

            case ExpressionType.LoadArgument:
            {
                if (pop)
                {
                    return;
                }
                var s        = e as LoadArgument;
                var paramRef = s.Parameter.IsReference;

                if (paramRef)
                {
                    if (addressMode)
                    {
                        Emit(Opcodes.LoadArg, s.Index);
                    }
                    else
                    {
                        Emit(Opcodes.LoadArg, s.Index);
                        Emit(Opcodes.LoadObj, s.Parameter.Type);
                    }
                }
                else
                {
                    Emit(addressMode
                                    ? Opcodes.LoadArgAddress
                                    : Opcodes.LoadArg,
                         s.Index);
                }
            }
            break;

            case ExpressionType.StoreLocal:
            {
                var s = e as StoreLocal;

                // TODO: This is a workaround for bug in sub ctor calls, remove this later
                if (!Locals.Contains(s.Variable))
                {
                    Locals.Add(s.Variable);
                }

                CompileExpression(s.Value);
                if (!pop)
                {
                    Emit(Opcodes.Dup);
                }
                Emit(Opcodes.StoreLocal, s.Variable);
            }
            break;

            case ExpressionType.StoreArgument:
            {
                var s = e as StoreArgument;

                if (s.Parameter.IsReference)
                {
                    Emit(Opcodes.LoadArg, s.Index);         // Loads the pointer from a out/ref argument
                    CompileExpression(s.Value);
                    var temp = StoreTemp(s.Value.ReturnType, pop);
                    Emit(Opcodes.StoreObj, s.Value.ReturnType);
                    LoadTemp(temp);
                }
                else
                {
                    CompileExpression(s.Value);
                    var temp = StoreTemp(s.Value.ReturnType, pop);
                    Emit(Opcodes.StoreArg, s.Index);
                    LoadTemp(temp);
                }

                if (!pop && addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.StoreField:
            {
                var s = e as StoreField;

                if (s.Object != null)
                {
                    CompileObject(s.Object, s.Field);
                    CompileExpression(s.Value);

                    var temp = StoreTemp(s.Value.ReturnType, pop);
                    Emit(Opcodes.StoreField, s.Field);
                    LoadTemp(temp);
                }
                else
                {
                    CompileExpression(s.Value);

                    var temp = StoreTemp(s.Value.ReturnType, pop);
                    Emit(Opcodes.StoreStaticField, s.Field);
                    LoadTemp(temp);
                }

                if (!pop & addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.StoreThis:
            {
                var s = e as StoreThis;

                Emit(Opcodes.This);

                if (!pop & addressMode)
                {
                    Emit(Opcodes.Dup);
                }

                CompileExpression(s.Value);
                Emit(Opcodes.StoreObj, s.Value.ReturnType);
            }
            break;

            case ExpressionType.StoreElement:
            {
                var s = e as StoreElement;

                CompileExpression(s.Array);
                CompileExpression(s.Index);
                CompileExpression(s.Value);

                var temp = StoreTemp(s.Value.ReturnType, pop);
                Emit(Opcodes.StoreArrayElement, s.Value.ReturnType);
                LoadTemp(temp);

                if (!pop & addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.SetProperty:
            {
                var s = e as SetProperty;
                CompileObject(s.Object, s.Property);

                foreach (var arg in s.Arguments)
                {
                    CompileExpression(arg);
                }

                CompileExpression(s.Value);

                var temp = StoreTemp(s.Value.ReturnType, pop);

                Call(s.Object, s.Property.SetMethod);

                LoadTemp(temp);

                if (!pop & addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.GetProperty:
            {
                var s = e as GetProperty;
                CompileObject(s.Object, s.Property);

                foreach (var arg in s.Arguments)
                {
                    CompileExpression(arg);
                }

                if (s.Property.DeclaringType.IsArray && s.Property.Parameters.Length == 0 && s.Property.UnoName == "Length")
                {
                    Emit(Opcodes.LoadArrayLength);
                }
                else
                {
                    Call(s.Object, s.Property.GetMethod);
                }

                if (pop)
                {
                    Pop();
                }
                else if (addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.AddListener:
            {
                var s = e as AddListener;
                CompileObject(s.Object, s.Event);
                CompileExpression(s.Listener);
                Call(s.Object, s.Event.AddMethod);
            }
            break;

            case ExpressionType.RemoveListener:
            {
                var s = e as RemoveListener;
                CompileObject(s.Object, s.Event);
                CompileExpression(s.Listener);
                Call(s.Object, s.Event.RemoveMethod);
            }
            break;

            case ExpressionType.ReferenceOp:
            {
                var s = e as ReferenceOp;

                CompileExpression(s.Left);

                if (s.Left.ReturnType.IsGenericParameter)
                {
                    Emit(Opcodes.Box, s.Left.ReturnType);
                }

                CompileExpression(s.Right);

                if (s.Right.ReturnType.IsGenericParameter)
                {
                    Emit(Opcodes.Box, s.Right.ReturnType);
                }

                if (cond != null && !cond.Handled)
                {
                    if (s.EqualityType == EqualityType.NotEqual)
                    {
                        Branch(Opcodes.BrNeq, cond.TrueLabel ?? (cond.TrueLabel = NewLabel()));
                        Branch(Opcodes.Br, cond.FalseLabel ?? (cond.FalseLabel = NewLabel()));
                    }
                    else
                    {
                        Branch(Opcodes.BrEq, cond.TrueLabel ?? (cond.TrueLabel = NewLabel()));
                        Branch(Opcodes.Br, cond.FalseLabel ?? (cond.FalseLabel = NewLabel()));
                    }

                    cond.Handled = true;
                    return;
                }

                Emit(s.EqualityType == EqualityType.NotEqual
                                ? Opcodes.Neq
                                : Opcodes.Eq);

                if (pop)
                {
                    Pop();
                }
                else if (addressMode)
                {
                    CreateIndirection(e.ReturnType);
                }
            }
            break;

            case ExpressionType.BranchOp:
            {
                var s = e as BranchOp;

                if (s.BranchType == BranchType.And)
                {
                    if (cond != null && !cond.Handled)
                    {
                        var brtrue = NewLabel();
                        CompileCondition(s.Left, ConditionSequence.TrueFollows, brtrue, cond.FalseLabel ?? (cond.FalseLabel = NewLabel()));

                        MarkLabel(brtrue);
                        CompileCondition(s.Right, ConditionSequence.NoneFollows, cond.TrueLabel ?? (cond.TrueLabel = NewLabel()), cond.FalseLabel ?? (cond.FalseLabel = NewLabel()));

                        cond.Handled = true;
                    }
                    else
                    {
                        var c = CompileCondition(s.Left, ConditionSequence.TrueFollows);

                        var brafter = NewLabel();

                        MarkLabel(c.TrueLabel);
                        CompileExpression(s.Right);
                        Branch(Opcodes.Br, brafter);

                        MarkLabel(c.FalseLabel);
                        Emit(Opcodes.Constant, false);

                        MarkLabel(brafter);
                    }
                }
                else
                {
                    if (cond != null && !cond.Handled)
                    {
                        var brfalse = NewLabel();
                        CompileCondition(s.Left, ConditionSequence.FalseFollows, cond.TrueLabel ?? (cond.TrueLabel = NewLabel()), brfalse);

                        MarkLabel(brfalse);
                        CompileCondition(s.Right, ConditionSequence.NoneFollows, cond.TrueLabel ?? (cond.TrueLabel = NewLabel()), cond.FalseLabel ?? (cond.FalseLabel = NewLabel()));

                        cond.Handled = true;
                    }
                    else
                    {
                        var c = CompileCondition(s.Left, ConditionSequence.TrueFollows);

                        var brafter = NewLabel();

                        MarkLabel(c.TrueLabel);
                        Emit(Opcodes.Constant, true);
                        Branch(Opcodes.Br, brafter);

                        MarkLabel(c.FalseLabel);
                        CompileExpression(s.Right);

                        MarkLabel(brafter);
                    }
                }
            }
            break;

            case ExpressionType.ConditionalOp:
            {
                var s       = e as ConditionalOp;
                var brtrue  = NewLabel();
                var brfalse = NewLabel();
                var brafter = NewLabel();
                var cc      = CompileCondition(s.Condition, ConditionSequence.TrueFollows, brtrue, brfalse);

                if (!cc.CanSkipTrue)
                {
                    MarkLabel(brtrue);
                    CompileExpression(s.True, pop, addressMode);
                    Branch(Opcodes.Br, brafter);
                }

                if (!cc.CanSkipFalse)
                {
                    MarkLabel(brfalse);
                    CompileExpression(s.False, pop, addressMode);
                }

                MarkLabel(brafter);
            }
            break;

            case ExpressionType.NullOp:
            {
                var s       = e as NullOp;
                var brnull  = NewLabel();
                var brafter = NewLabel();

                CompileExpression(s.Left);
                Emit(Opcodes.Dup);

                if (s.Left.ReturnType.IsGenericParameter)
                {
                    Emit(Opcodes.Box, s.Left.ReturnType);
                }

                Branch(Opcodes.BrNotNull, brafter);

                MarkLabel(brnull);
                Emit(Opcodes.Pop);
                CompileExpression(s.Right);

                MarkLabel(brafter);

                if (pop)
                {
                    Pop();
                }
            }
            break;

            case ExpressionType.CallCast:
            {
                var s = e as CallCast;
                CompileExpression(s.Operand);

                // TODO: Many casts are NOOP - i.e. byte -> char, char -> int
                switch (s.Operand.ReturnType.BuiltinType)
                {
                case BuiltinType.Char:
                case BuiltinType.Byte:
                case BuiltinType.SByte:
                case BuiltinType.UShort:
                case BuiltinType.Short:
                case BuiltinType.UInt:
                case BuiltinType.Int:
                case BuiltinType.ULong:
                case BuiltinType.Long:
                case BuiltinType.Float:
                case BuiltinType.Double:
                    switch (s.ReturnType.BuiltinType)
                    {
                    case BuiltinType.Char: Emit(Opcodes.ConvChar); break;

                    case BuiltinType.Byte: Emit(Opcodes.ConvByte); break;

                    case BuiltinType.SByte: Emit(Opcodes.ConvSByte); break;

                    case BuiltinType.UShort: Emit(Opcodes.ConvUShort); break;

                    case BuiltinType.Short: Emit(Opcodes.ConvShort); break;

                    case BuiltinType.UInt: Emit(Opcodes.ConvUInt); break;

                    case BuiltinType.Int: Emit(Opcodes.ConvInt); break;

                    case BuiltinType.ULong: Emit(Opcodes.ConvULong); break;

                    case BuiltinType.Long: Emit(s.Operand.ReturnType.IsUnsignedType ? Opcodes.ConvULong : Opcodes.ConvLong); break;

                    case BuiltinType.Float: Emit(Opcodes.ConvFloat); break;

                    case BuiltinType.Double: Emit(Opcodes.ConvDouble); break;

                    default: Call(null, s.Cast); break;
                    }

                    break;

                default:
                    Call(null, s.Cast);
                    break;
                }

                if (pop)
                {
                    Pop();
                }
                else if (addressMode)
                {
                    CreateIndirection(s.ReturnType);
                }
            }
            break;

            case ExpressionType.CallConstructor:
            {
                var s = e as CallConstructor;

                Emit(Opcodes.This);

                for (int i = 0; i < s.Arguments.Length; i++)
                {
                    CompileExpression(s.Arguments[i]);
                }

                Call(null, s.Constructor);
            }
            break;

            case ExpressionType.CallMethod:
            {
                var s = e as CallMethod;
                CompileObject(s.Object, s.Method);

                for (int i = 0; i < s.Arguments.Length; i++)
                {
                    CompileExpression(s.Arguments[i]);
                }

                Call(s.Object, s.Method);

                if (!s.ReturnType.IsVoid)
                {
                    if (pop)
                    {
                        Pop();
                    }
                    else if (addressMode)
                    {
                        CreateIndirection(s.ReturnType);
                    }
                }
            }
            break;

            case ExpressionType.CallDelegate:
            {
                var s = e as CallDelegate;
                CompileExpression(s.Object);

                foreach (var arg in s.Arguments)
                {
                    CompileExpression(arg);
                }

                Emit(Opcodes.CallDelegate, s.Object.ReturnType);

                if (!s.ReturnType.IsVoid)
                {
                    if (pop)
                    {
                        Pop();
                    }
                    else if (addressMode)
                    {
                        CreateIndirection(s.ReturnType);
                    }
                }
            }
            break;

            case ExpressionType.CallBinOp:
            {
                CompileBinOp(e as CallBinOp, pop, cond);
                if (addressMode)
                {
                    CreateIndirection(e.ReturnType);
                }
            }
            break;

            case ExpressionType.CallUnOp:
            {
                CompileUnOp(e as CallUnOp, pop);
                if (addressMode)
                {
                    CreateIndirection(e.ReturnType);
                }
            }
            break;

            case ExpressionType.CastOp:
            {
                var s = e as CastOp;
                CompileExpression(s.Operand);

                if (s.ReturnType.IsReferenceType && !s.ReturnType.IsGenericParameter)
                {
                    if (s.Operand.ReturnType.IsValueType || s.Operand.ReturnType.IsGenericParameter)
                    {
                        Emit(Opcodes.Box, s.Operand.ReturnType);
                    }
                    else
                    {
                        Emit(Opcodes.CastClass, s.ReturnType);
                    }

                    if (pop)
                    {
                        Pop();
                    }
                }
                else if (s.Operand.ReturnType.IsReferenceType && !s.Operand.ReturnType.IsGenericParameter)
                {
                    if (s.ReturnType.IsValueType)
                    {
                        Emit(Opcodes.Unbox, s.ReturnType);
                        Emit(Opcodes.LoadObj, s.ReturnType);

                        if (pop)
                        {
                            Pop();
                        }
                        else if (addressMode)
                        {
                            CreateIndirection(e.ReturnType);
                        }
                    }
                    else if (s.ReturnType.IsGenericParameter)
                    {
                        Emit(Opcodes.UnboxAny, s.ReturnType);

                        if (pop)
                        {
                            Pop();
                        }
                        else if (addressMode)
                        {
                            CreateIndirection(e.ReturnType);
                        }
                    }
                    else
                    {
                        Emit(Opcodes.CastClass, s.ReturnType);
                        if (pop)
                        {
                            Pop();
                        }
                    }
                }
                else
                {
                    if (addressMode && !pop)
                    {
                        CreateIndirection(s.ReturnType);
                    }
                }
            }
            break;

            case ExpressionType.NewObject:
            {
                var s = e as NewObject;
                foreach (var arg in s.Arguments)
                {
                    CompileExpression(arg);
                }

                Emit(Opcodes.NewObject, s.Constructor);

                if (pop)
                {
                    Pop();
                }
                else if (s.ReturnType.IsValueType && addressMode)
                {
                    CreateIndirection(e.ReturnType);
                }
            }
            break;

            case ExpressionType.NewDelegate:
            {
                var s = e as NewDelegate;

                if (s.Object != null)
                {
                    CompileExpression(s.Object);
                }
                else
                {
                    Emit(Opcodes.Null);
                }

                if (s.Object == null ||
                    s.Object is Base)
                {
                    Emit(Opcodes.LoadFunction, s.Method);
                }
                else
                {
                    Emit(Opcodes.Dup);
                    Emit(Opcodes.LoadFunctionVirtual, s.Method);
                }

                Emit(Opcodes.NewDelegate, s.ReturnType);
            }
            break;

            case ExpressionType.NewArray:
            {
                var s = e as NewArray;

                if (s.Size != null)
                {
                    CompileExpression(s.Size);
                }
                else
                {
                    Emit(Opcodes.Constant, s.Initializers.Length);
                }

                Emit(Opcodes.NewArray, ((RefArrayType)s.ReturnType).ElementType);

                if (s.Initializers != null)
                {
                    for (int i = 0; i < s.Initializers.Length; i++)
                    {
                        Emit(Opcodes.Dup);
                        Emit(Opcodes.Constant, i);
                        CompileExpression(s.Initializers[i]);
                        Emit(Opcodes.StoreArrayElement, s.Initializers[i].ReturnType);
                    }
                }

                if (pop)
                {
                    Pop();
                }
            }
            break;

            case ExpressionType.FixOp:
                CompileFixOp(e as FixOp, pop, addressMode);
                break;

            case ExpressionType.Swizzle:
            {
                var sw = e as Swizzle;

                CompileExpression(sw.Object);
                var temp = StoreTemp(sw.Object.ReturnType, false);

                foreach (var f in sw.Fields)
                {
                    LoadTemp(temp);
                    Emit(Opcodes.LoadField, f);
                }

                Emit(Opcodes.NewObject, sw.Constructor);

                if (pop)
                {
                    Pop();
                }
                else if (sw.ReturnType.IsValueType && addressMode)
                {
                    CreateIndirection(e.ReturnType);
                }
            }
            break;

            // Shader expression types must be handled to be able to use the bytecode backend for control flow validation of shaders,
            // as well as generating bytecode/assembly shaders
            case ExpressionType.RuntimeConst:
            {
                var s = e as RuntimeConst;
                Emit(Opcodes.GetShaderConst, s.State.RuntimeConstants[s.Index]);
            }
            break;

            case ExpressionType.LoadUniform:
            {
                var s = e as LoadUniform;
                Emit(Opcodes.LoadShaderUniform, s.State.Uniforms[s.Index]);
            }
            break;

            case ExpressionType.LoadPixelSampler:
            {
                var s = e as LoadPixelSampler;
                Emit(Opcodes.LoadShaderPixelSampler, s.State.PixelSamplers[s.Index]);
            }
            break;

            case ExpressionType.LoadVarying:
            {
                var s = e as LoadVarying;
                Emit(Opcodes.LoadShaderVarying, s.State.Varyings[s.Index]);
            }
            break;

            case ExpressionType.LoadVertexAttrib:
            {
                var s = e as LoadVertexAttrib;
                Emit(Opcodes.LoadShaderVarying, s.State.VertexAttributes[s.Index]);
            }
            break;

            case ExpressionType.CallShader:
            {
                var s = e as CallShader;

                for (int i = 0; i < s.Arguments.Length; i++)
                {
                    CompileExpression(s.Arguments[i]);
                }

                Call(null, s.Function);

                if (!s.ReturnType.IsVoid)
                {
                    if (pop)
                    {
                        Pop();
                    }
                    else if (addressMode)
                    {
                        CreateIndirection(s.ReturnType);
                    }
                }
            }
            break;

            case ExpressionType.LoadPtr:
            {
                var s = e as LoadPtr;
                CompileExpression(s.Argument, pop, addressMode, cond);
            }
            break;

            default:
                throw new Exception("<" + e.ExpressionType + "> is not supported in bytecode backend - at " + e.Source);
            }
        }
Exemple #18
0
 public bool DoesIdentifierExist(string iden)
 => Locals.ContainsKey(iden) ||
 Outer.DoesIdentifierExist(iden);
Exemple #19
0
 public MethodBodySymbolContext WithScope(IMethod method)
 => new MethodBodySymbolContext(SourceSymbolContext.WithScope(method), Locals.AddRange(method.ParameterLocals), CurrentStatement);
Exemple #20
0
 public Using(Expression init, Block body)
     : base(NodeType.Using, init, body ?? new Block())
 {
     Locals.Add(new Local("$res", null));
 }
Exemple #21
0
        public void Start(int ticks)
        {
            Application.targetFrameRate = ticks <= 0 ? 10 : ticks;
            if (IsStarted)
            {
                LogStartedError();
                return;
            }
            else
            {
            }

            Tester = Tester.Instance;
            Tester.Init(new TesterBaseApp());

            AssertFrameworkInit(int.MaxValue);
            AssertFrameworkInit(0);

            Notificater = NotificatonsInt.Instance.Notificater; //new Notifications<int>();//新建消息中心
            ABs         = new AssetBundles();                   //新建资源包管理器
            Servers     = new Servers();                        //新建服务容器管理器
            DataWarehouse datas = new DataWarehouse();          //新建数据管理器

            AssetsPooling = new AssetsPooling();                //新建场景资源对象池
            ECSContext    = new ShipDockComponentContext        //新建 ECS 组件上下文
            {
                FrameTimeInScene = (int)(Time.deltaTime * UpdatesCacher.UPDATE_CACHER_TIME_SCALE)
            };
            StateMachines = new StateMachines//新建有限状态机管理器
            {
                FSMFrameUpdater   = OnFSMFrameUpdater,
                StateFrameUpdater = OnStateFrameUpdater
            };
            Effects             = new Effects();            //新建特效管理器
            Locals              = new Locals();             //新建本地化管理器
            PerspectivesInputer = new PerspectiveInputer(); //新建透视物体交互器
            AppModulars         = new DecorativeModulars(); //新建装饰模块管理器
            Configs             = new ConfigHelper();       //新建配置管理器

            #region 向定制框架中填充框架功能单元
            Framework framework = Framework.Instance;
            FrameworkUnits = new IFrameworkUnit[]
            {
                framework.CreateUnitByBridge(Framework.UNIT_DATA, datas),
                framework.CreateUnitByBridge(Framework.UNIT_AB, ABs),
                framework.CreateUnitByBridge(Framework.UNIT_MODULARS, AppModulars),
                framework.CreateUnitByBridge(Framework.UNIT_ECS, ECSContext),
                framework.CreateUnitByBridge(Framework.UNIT_IOC, Servers),
                framework.CreateUnitByBridge(Framework.UNIT_CONFIG, Configs),
                framework.CreateUnitByBridge(Framework.UNIT_UI, UIs),
                framework.CreateUnitByBridge(Framework.UNIT_FSM, StateMachines),
            };
            framework.LoadUnit(FrameworkUnits);
            #endregion

            mFSMUpdaters   = new KeyValueList <IStateMachine, IUpdate>();
            mStateUpdaters = new KeyValueList <IState, IUpdate>();
            TicksUpdater   = new TicksUpdater(Application.targetFrameRate);//新建客户端心跳帧更新器

            AssertFrameworkInit(1);
            AssertFrameworkInit(2);

            IsStarted = true;
            mAppStarted?.Invoke();
            mAppStarted = default;

            ShipDockConsts.NOTICE_SCENE_UPDATE_READY.Add(OnSceneUpdateReady);
            UpdatesComponent?.Init();

            ShipDockConsts.NOTICE_APPLICATION_STARTUP.Broadcast();//框架启动完成
            AssertFrameworkInit(3);
        }
Exemple #22
0
        private Type EmitAssignment(CodeExpression Left, CodeExpression Right, bool ForceTypes)
        {
            Depth++;
            Debug("Emitting assignment expression");
            Type Generated = typeof(void);

            if (Left is CodeVariableReferenceExpression)
            {
                // local IL variables generated by parser
                var Reference = Left as CodeVariableReferenceExpression;

                LocalBuilder Var;
                if (Locals.ContainsKey(Reference.VariableName))
                {
                    Var = Locals[Reference.VariableName];
                }
                else
                {
                    Var = Generator.DeclareLocal(typeof(int));
                    Locals.Add(Reference.VariableName, Var);
                }

                EmitExpression(Right, ForceTypes);
                Generator.Emit(OpCodes.Stloc, Var);
                Generator.Emit(OpCodes.Pop);
            }
            else if (Left is CodeArrayIndexerExpression)
            {
                var index = (CodeArrayIndexerExpression)Left;

                Generator.Emit(OpCodes.Ldloc, VarsProperty);

                EmitExpression(index.Indices[0]);
                Type resultType = EmitExpression(Right, ForceTypes);
                if (resultType.IsValueType)
                {
                    Generator.Emit(OpCodes.Box, resultType);
                }

                Generator.Emit(OpCodes.Callvirt, SetVariable);

                Generated = typeof(object);
            }
            else if (Left is CodePropertyReferenceExpression)
            {
                var prop = (CodePropertyReferenceExpression)Left;

                // HACK: property set method target
                var info = typeof(Rusty.Core).GetProperty(prop.PropertyName);

                if (Mirror != null)
                {
                    info = Mirror.GrabProperty(info);
                }

                var set = info == null ? null : info.GetSetMethod();

                if (set == null)
                {
                    Generator.Emit(OpCodes.Ldnull);
                }
                else
                {
                    EmitExpression(Right);
                    Generator.Emit(OpCodes.Dup);
                    Generator.Emit(OpCodes.Call, set);
                }

                Generated = typeof(object);
            }
            else
            {
                throw new CompileException(Left, "Left hand is unassignable");
            }

            Depth--;

            return(Generated);
        }
Exemple #23
0
 private (int idx, VeinArgumentRef arg)? getLocal(FieldName @ref)
 {
     var(key, value) = Locals
                       .FirstOrDefault(x
                                       => x.Value.Name.Equals(@ref.Name, StringComparison.CurrentCultureIgnoreCase));
     return(value != null ? (key, value) : default);
Exemple #24
0
        public override void Parse(TokensStack sTokens)
        {
            /*
             * Function Type ID( args ){
             * varDec*
             * Statments*
             * Return Statment
             * }
             *
             * check more errors
             */
            Token t;

            StackIsNotEmpty(sTokens);
            Token tFunc = sTokens.Pop();

            if (!(tFunc is Statement) || ((Statement)tFunc).Name != "function")
            {
                throw new SyntaxErrorException("Expected function received: " + tFunc, tFunc);
            }
            StackIsNotEmpty(sTokens);
            Token tType = sTokens.Pop();

            if (!(tType is VarType))
            {
                throw new SyntaxErrorException("Expected var type, received " + tType, tType);
            }
            ReturnType = VarDeclaration.GetVarType(tType);
            StackIsNotEmpty(sTokens);
            Token tName = sTokens.Pop();

            if (!(tName is Identifier))
            {
                throw new SyntaxErrorException("Expected function name, received " + tType, tType);
            }
            Name = ((Identifier)tName).Name;
            StackIsNotEmpty(sTokens);
            if (sTokens.Peek() is Parentheses && sTokens.Peek().ToString() == "(")
            {
                t = sTokens.Pop(); //(
            }
            else
            {
                throw new SyntaxErrorException("Expected ( Parentheses received: " + sTokens.Peek().ToString(), sTokens.Peek());
            }
            StackIsNotEmpty(sTokens);
            while (sTokens.Count > 0 && !(sTokens.Peek() is Parentheses))
            {
                if (sTokens.Count < 3)
                {
                    throw new SyntaxErrorException("Early termination ", t);
                }
                Token          tArgType = sTokens.Pop();
                Token          tArgName = sTokens.Pop();
                VarDeclaration vc       = new VarDeclaration(tArgType, tArgName);
                Args.Add(vc);
                if (sTokens.Count > 0 && sTokens.Peek() is Separator)//,
                {
                    sTokens.Pop();
                }
            }
            StackIsNotEmpty(sTokens);
            if (sTokens.Peek() is Parentheses && sTokens.Peek().ToString() == ")")
            {
                t = sTokens.Pop(); //)
            }
            else
            {
                throw new SyntaxErrorException("Expected ) Parentheses received: " + sTokens.Peek().ToString(), sTokens.Peek());
            }
            StackIsNotEmpty(sTokens);
            if (sTokens.Peek() is Parentheses && sTokens.Peek().ToString() == "{")
            {
                t = sTokens.Pop(); //{
            }
            else
            {
                throw new SyntaxErrorException("Expected { Parentheses received: " + sTokens.Peek().ToString(), sTokens.Peek());
            }
            StackIsNotEmpty(sTokens);
            while (sTokens.Count > 0 && (sTokens.Peek() is Statement) && (((Statement)sTokens.Peek()).Name == "var"))
            {
                VarDeclaration local = new VarDeclaration();
                local.Parse(sTokens);
                Locals.Add(local);
            }
            StackIsNotEmpty(sTokens);
            while (sTokens.Count > 0 && !(sTokens.Peek() is Parentheses))
            {
                StatetmentBase s = StatetmentBase.Create(sTokens.Peek());
                s.Parse(sTokens);
                Body.Add(s);
            }
            StackIsNotEmpty(sTokens);
            if (sTokens.Peek() is Parentheses && sTokens.Peek().ToString() == "}")
            {
                t = sTokens.Pop(); //}
            }
            else
            {
                throw new SyntaxErrorException("Expected } Parentheses received: " + sTokens.Peek().ToString(), sTokens.Peek());
            }
        }
Exemple #25
0
        /// <summary>
        /// Updates our entries in the dictionary. To be immediately visible as soon as
        /// the _items.CanCommit() passes, we add ourselves into the dict straight away,
        /// and in a side effect we remove unnecessary entries, or, on rollback, undo
        /// the early additions.
        /// </summary>
        void UpdateEntries()
        {
            Shield.Enlist(this, false, true);
            var l = new Locals();

            var oldItems = _items.GetOldValue();
            var newItems = _items.Value;
            l.PreAdd = newItems == null ? null :
                (oldItems != null ? newItems.Except(oldItems).ToList() : newItems.ToList());
            l.CommitRemove = oldItems == null ? null :
                (newItems != null ? oldItems.Except(newItems).ToList() : oldItems.ToList());
            try { }
            finally
            {
                _locals.Value = l;
                var newArray = new[] { this };
                // early adding
                if (l.PreAdd != null)
                    foreach (var newKey in l.PreAdd)
                    {
                        lock (Context)
                            Context.AddOrUpdate(newKey,
                                k => newArray,
                                (k, existing) => existing.Concat(newArray).ToArray());
                    }
            }
        }
Exemple #26
0
        public override void Parse(TokensStack sTokens)
        {
            Token tFunc = sTokens.Pop();

            if (!(tFunc is Statement) || ((Statement)tFunc).Name != "function")
            {
                throw new SyntaxErrorException("Expected function received: " + tFunc, tFunc);
            }
            Token tType = sTokens.Pop();

            if (!(tType is VarType))
            {
                throw new SyntaxErrorException("Expected var type, received " + tType, tType);
            }
            ReturnType = VarDeclaration.GetVarType(tType);
            Token tName = sTokens.Pop();

            if (!(tName is Identifier))
            {
                throw new SyntaxErrorException("Expected function name, received " + tType, tType);
            }
            Name = ((Identifier)tName).Name;

            Token t = sTokens.Pop();                                      //(

            while (sTokens.Count > 0 && !(sTokens.Peek() is Parentheses)) //)
            {
                if (sTokens.Count < 3)
                {
                    throw new SyntaxErrorException("Early termination ", t);
                }
                Token          tArgType = sTokens.Pop();
                Token          tArgName = sTokens.Pop();
                VarDeclaration vc       = new VarDeclaration(tArgType, tArgName);
                Args.Add(vc);
                if (sTokens.Count > 0 && sTokens.Peek() is Separator)//,
                {
                    sTokens.Pop();
                }
            }
            t = sTokens.Pop(); //)
            t = sTokens.Pop(); //{
            while (sTokens.Count > 0 && (sTokens.Peek() is Statement) && (((Statement)sTokens.Peek()).Name == "var"))
            {
                VarDeclaration local = new VarDeclaration();
                local.Parse(sTokens);
                Locals.Add(local);
            }
            while (sTokens.Count > 0 && !(sTokens.Peek() is Parentheses))
            {
                StatetmentBase s = StatetmentBase.Create(sTokens.Peek());
                s.Parse(sTokens);
                Body.Add(s);
            }
            if (sTokens.Count == 0)
            {
                throw new SyntaxErrorException("Early termination ", t);
            }
            Token tEnd = sTokens.Pop();//}

            if (!(tEnd is Parentheses) || ((Parentheses)tEnd).Name != '}')
            {
                throw new SyntaxErrorException("Expected }, received", tEnd);
            }
        }
Exemple #27
0
        void BuildRoutine([NotNull] ZilRoutine routine, [NotNull] IRoutineBuilder rb, bool entryPoint, bool traceRoutines)
        {
            // give the user a chance to rewrite the routine
            routine = MaybeRewriteRoutine(Context, routine);

            // set up arguments and locals
            ClearLocalsAndBlocks();

            if (Context.TraceRoutines)
            {
                rb.EmitPrint("[" + routine.Name, false);
            }

            DefineLocalsFromArgSpec();

            if (Context.TraceRoutines)
            {
                rb.EmitPrint("]\n", false);
            }

            // define a block for the routine
            Blocks.Clear();
            Blocks.Push(new Block
            {
                Name        = routine.ActivationAtom,
                AgainLabel  = rb.RoutineStart,
                ReturnLabel = null,
                Flags       = BlockFlags.None
            });

            // generate code for routine body
            int i = 1;

            foreach (var stmt in routine.Body)
            {
                // only want the result of the last statement
                // and we never want results in the entry routine, since it can't return
                CompileStmt(rb, stmt, !entryPoint && i == routine.BodyLength);
                i++;
            }

            // the entry point has to quit instead of returning
            if (entryPoint)
            {
                rb.EmitQuit();
            }

            // clean up
            WarnAboutUnusedLocals();
            ClearLocalsAndBlocks();

            // helpers
            void DefineLocalsFromArgSpec()
            {
                foreach (var arg in routine.ArgSpec)
                {
                    var originalArgName = arg.Atom;
                    var uniqueArgName   = MakeUniqueVariableName(originalArgName);

                    if (uniqueArgName != originalArgName)
                    {
                        /* When a parameter has to be renamed because of a conflict, use TempLocalNames
                         * to reserve the new name so we don't collide with it later. For example:
                         *
                         *   <GLOBAL FOO <>>
                         *   <ROUTINE BLAH (FOO)
                         *     <PROG ((FOO)) ...>>
                         *
                         * We rename the local variable to FOO?1 to avoid shadowing the global.
                         * Now the temporary variable bound by the PROG has to be FOO?2.
                         * ZIL code only sees the name FOO: the local is shadowed inside the PROG,
                         * and the global can always be accessed with SETG and GVAL.
                         */
                        TempLocalNames.Add(uniqueArgName);
                    }

                    var lb = MakeLocalBuilder(arg, uniqueArgName.Text);

                    if (traceRoutines && arg.Type == ArgItem.ArgType.Required)
                    {
                        // TODO: print OPT parameters when tracing routine execution too
                        rb.EmitPrint(" " + originalArgName + "=", false);
                        rb.EmitPrint(PrintOp.Number, lb);
                    }

                    var lbr = new LocalBindingRecord(arg.Type.ToLocalBindingType(), routine.SourceLine, originalArgName.Text, lb);
                    Locals.Add(originalArgName, lbr);
                    AllLocalBindingRecords.Add(lbr);

                    SetOrEmitDefaultValue(lb, arg);
                }
            }

            ILocalBuilder MakeLocalBuilder(ArgItem arg, string uniqueArgName)
            {
                ILocalBuilder lb;

                switch (arg.Type)
                {
                case ArgItem.ArgType.Required:
                    try
                    {
                        lb = rb.DefineRequiredParameter(uniqueArgName);
                    }
                    catch (InvalidOperationException)
                    {
                        throw new CompilerError(
                                  CompilerMessages.Expression_Needs_Temporary_Variables_Not_Allowed_Here);
                    }
                    break;

                case ArgItem.ArgType.Optional:
                    lb = rb.DefineOptionalParameter(uniqueArgName);
                    break;

                case ArgItem.ArgType.Auxiliary:
                    lb = rb.DefineLocal(uniqueArgName);
                    break;

                default:
                    throw UnhandledCaseException.FromEnum(arg.Type);
                }

                return(lb);
            }

            void SetOrEmitDefaultValue(ILocalBuilder lb, ArgItem arg)
            {
                if (arg.DefaultValue == null)
                {
                    return;
                }

                Debug.Assert(arg.Type == ArgItem.ArgType.Optional || arg.Type == ArgItem.ArgType.Auxiliary);

                // setting any default value counts as a write
                MarkVariableAsWritten(lb);

                lb.DefaultValue = CompileConstant(arg.DefaultValue);
                if (lb.DefaultValue != null)
                {
                    return;
                }

                ILabel nextLabel = null;

                // ReSharper disable once SwitchStatementMissingSomeCases
                switch (arg.Type)
                {
                case ArgItem.ArgType.Optional when !rb.HasArgCount:
                    // not a constant
                    throw new CompilerError(routine.SourceLine,
                                            CompilerMessages.Optional_Args_With_Nonconstant_Defaults_Not_Supported_For_This_Target);

                case ArgItem.ArgType.Optional:
                    nextLabel = rb.DefineLabel();
                    rb.Branch(Condition.ArgProvided, lb, null, nextLabel, true);
                    goto default;

                default:
                    var val = CompileAsOperand(rb, arg.DefaultValue, routine.SourceLine, lb);
                    if (val != lb)
                    {
                        rb.EmitStore(lb, val);
                    }
                    break;
                }

                if (nextLabel != null)
                {
                    rb.MarkLabel(nextLabel);
                }
            }

            void WarnAboutUnusedLocals()
            {
                foreach (var lbr in AllLocalBindingRecords)
                {
                    if (lbr.IsEverRead || lbr.IsEverWritten)
                    {
                        continue;
                    }

                    if (lbr.Type == LocalBindingType.CompilerTemporary)
                    {
                        continue;
                    }

                    //XXX not sure about this
                    if (lbr.Type == LocalBindingType.RoutineRequired)
                    {
                        continue;
                    }

                    var warning = new CompilerError(
                        lbr.Definition,
                        CompilerMessages.Local_Variable_0_Is_Never_Used,
                        lbr.BoundName);

                    Context.HandleError(warning);
                }
            }
        }
 public GameController(Locals locals, Players players, Pokedexes pokedexes)
 {
     Locals    = locals;
     Players   = players;
     Pokedexes = pokedexes;
 }
Exemple #29
0
        internal BinaryMethod ToBinary()
        {
            // 检查每个BB最后是不是br
            foreach (BasicBlock basicBlock in BasicBlocks)
            {
                foreach (Instruction inst in basicBlock.Instructions)
                {
                    if ((inst.IsBranch && inst != basicBlock.Instructions.Last.Value) ||
                        (!inst.IsBranch && inst == basicBlock.Instructions.Last.Value))
                    {
                        throw new XiVMError($"Basic Block is not ended with br");
                    }
                }
            }

            // 遍历各个BasicBlock的指令,将带label的指令转换为正确的displacement
            int offset = 0;

            foreach (BasicBlock bb in BasicBlocks)
            {
                // 计算每个BasicBlock在函数中的offset
                bb.Offset     = offset;
                bb.InstLength = 0;
                foreach (Instruction inst in bb.Instructions)
                {
                    bb.InstLength += 1;
                    if (inst.Params != null)
                    {
                        bb.InstLength += inst.Params.Length;
                    }
                }
                offset += bb.InstLength;
            }
            foreach (BasicBlock bb in BasicBlocks)
            {
                if (bb.Instructions.Last.Value.OpCode == InstructionType.JMP)
                {
                    // offset是目的地的地址
                    BitConverter.TryWriteBytes(bb.Instructions.Last.Value.Params,
                                               bb.JmpTargets[0].Offset);
                }
                else if (bb.Instructions.Last.Value.OpCode == InstructionType.JCOND)
                {
                    // offset是目的地的地址
                    BitConverter.TryWriteBytes(new Span <byte>(bb.Instructions.Last.Value.Params, 0, sizeof(int)),
                                               bb.JmpTargets[0].Offset);
                    BitConverter.TryWriteBytes(new Span <byte>(bb.Instructions.Last.Value.Params, sizeof(int), sizeof(int)),
                                               bb.JmpTargets[1].Offset);
                }
            }

            // 拼接每个BB的指令生成最终指令
            Stream instStream = new MemoryStream();

            foreach (Instruction inst in BasicBlocks.SelectMany(b => b.Instructions))
            {
                instStream.WriteByte((byte)inst.OpCode);
                instStream.Write(inst.Params);
            }

            BinaryMethod ret = new BinaryMethod
            {
                Instructions = new byte[instStream.Length]
            };

            instStream.Seek(0, SeekOrigin.Begin);
            instStream.Read(ret.Instructions);

            // 局部变量信息
            ret.LocalDescriptorIndex = Locals.Select(v => Parent.Parent.StringPool.TryAdd(v.Type.GetDescriptor())).ToArray();

            return(ret);
        }
Exemple #30
0
 public void AddVariable(string name, object value)
 {
     LocalNames.Add(name);
     Locals.Add(value);
 }
Exemple #31
0
 /// <summary>
 /// Check if a specific string is a local value to this context
 /// </summary>
 /// <param name="name">variable name</param>
 /// <returns></returns>
 public bool CheckLocal(string name)
 {
     return(Locals.ContainsKey(name));
 }
Exemple #32
0
        internal void CompileCondition([NotNull] IRoutineBuilder rb, [NotNull] ZilObject expr, [NotNull] ISourceLine src,
                                       [NotNull] ILabel label, bool polarity)
        {
            expr = expr.Unwrap(Context);
            var type = expr.StdTypeAtom;

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (type)
            {
            case StdAtom.FALSE:
                if (polarity == false)
                {
                    rb.Branch(label);
                }
                return;

            case StdAtom.ATOM:
                var atom = (ZilAtom)expr;
                if (atom.StdAtom != StdAtom.T && atom.StdAtom != StdAtom.ELSE)
                {
                    // could be a missing , or . before variable name
                    var warning = new CompilerError(src, CompilerMessages.Bare_Atom_0_Treated_As_True_Here, expr);

                    if (Locals.ContainsKey(atom) || Globals.ContainsKey(atom))
                    {
                        warning = warning.Combine(new CompilerError(src, CompilerMessages.Did_You_Mean_The_Variable));
                    }

                    Context.HandleError(warning);
                }

                if (polarity)
                {
                    rb.Branch(label);
                }
                return;

            case StdAtom.FIX:
                bool nonzero = ((ZilFix)expr).Value != 0;
                if (polarity == nonzero)
                {
                    rb.Branch(label);
                }
                return;

            case StdAtom.FORM:
                // handled below
                break;

            default:
                Context.HandleError(new CompilerError(expr.SourceLine ?? src, CompilerMessages.Expressions_Of_This_Type_Cannot_Be_Compiled));
                return;
            }

            // it's a FORM
            var form = (ZilForm)expr;

            if (!(form.First is ZilAtom head))
            {
                Context.HandleError(new CompilerError(form, CompilerMessages.FORM_Must_Start_With_An_Atom));
                return;
            }

            // check for standard built-ins
            // prefer the predicate version, then value, value+predicate, void
            // (value+predicate is hard to clean up)
            var zversion = Context.ZEnvironment.ZVersion;
            var argCount = form.Count() - 1;

            if (ZBuiltins.IsBuiltinPredCall(head.Text, zversion, argCount))
            {
                ZBuiltins.CompilePredCall(head.Text, this, rb, form, label, polarity);
                return;
            }
            if (ZBuiltins.IsBuiltinValueCall(head.Text, zversion, argCount))
            {
                var result = ZBuiltins.CompileValueCall(head.Text, this, rb, form, rb.Stack);
                BranchIfNonZero(result);
                return;
            }
            if (ZBuiltins.IsBuiltinValuePredCall(head.Text, zversion, argCount))
            {
                if (rb.CleanStack)
                {
                    /* wasting the branch and checking the result with ZERO? is more efficient
                     * than using the branch and having to clean the result off the stack */
                    var noBranch = rb.DefineLabel();
                    ZBuiltins.CompileValuePredCall(head.Text, this, rb, form, rb.Stack, noBranch, true);
                    rb.MarkLabel(noBranch);
                    rb.BranchIfZero(rb.Stack, label, !polarity);
                }
                else
                {
                    ZBuiltins.CompileValuePredCall(head.Text, this, rb, form, rb.Stack, label, polarity);
                }
                return;
            }
            if (ZBuiltins.IsBuiltinVoidCall(head.Text, zversion, argCount))
            {
                ZBuiltins.CompileVoidCall(head.Text, this, rb, form);

                // void calls return true
                if (polarity)
                {
                    rb.Branch(label);
                }
                return;
            }

            // special cases
            var op1 = CompileAsOperand(rb, form, form.SourceLine);

            BranchIfNonZero(op1);

            void BranchIfNonZero(IOperand operand)
            {
                if (operand is INumericOperand numericResult)
                {
                    if (numericResult.Value != 0 == polarity)
                    {
                        rb.Branch(label);
                    }
                }
                else
                {
                    rb.BranchIfZero(operand, label, !polarity);
                }
            }
        }