Beispiel #1
0
        public bool CallInitializer(CodeScopeNode Scope, ref int Index, CodeString Code)
        {
            var FS         = Scope.FunctionScope;
            var Structured = FS.Parent as StructuredScope;
            var Type       = Structured.StructuredType;
            var Class      = Type as ClassType;

            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            ExpressionNode SizeN;

            if (FS.ObjectSize == null)
            {
                SizeN = Plugin.NewNode(Constants.GetIntValue(Scope, Class.InstanceSize, Code, true));
                if (SizeN == null)
                {
                    return(false);
                }
            }
            else
            {
                SizeN = FS.ObjectSize.Copy(Plugin, Mode: BeginEndMode.None);
                if (SizeN == null)
                {
                    return(false);
                }
            }

            return(CallInitializer(Scope, ref Index, Plugin, SizeN, Code));
        }
Beispiel #2
0
        bool CallInitializerWithoutCmp(CodeScopeNode Scope, ref int Index, PluginRoot Plugin, ExpressionNode Size, CodeString Code)
        {
            var Self = Scope.FunctionScope.SelfVariable;

            if (!AllocateObject(Scope, ref Index, Self, Size, Plugin, Code))
            {
                return(false);
            }

            var StructuredType = Scope.StructuredScope.StructuredType;
            var ObjectType     = Identifiers.GetByFullNameFast <ClassType>(Scope.GlobalContainer, "System.Object");

            if (Identifiers.IsSubtypeOrEquivalent(StructuredType, ObjectType))
            {
                if (!SetFunctionTable(Scope, ref Index, Self, Code))
                {
                    return(false);
                }
                if (!SetTypePointer(Scope, ref Index, Self, Code))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #3
0
        bool LeaveTryBlock(CodeScopeNode Scope, CodeString Code)
        {
            var Global = Scope.State.GlobalContainer;
            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var Func = Identifiers.GetByFullNameFast <Function>(Global, "Internals.LeaveTryBlock");

            if (Func == null)
            {
                return(false);
            }

            var Node = Expressions.Call(Code, Plugin, Func);

            if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
            {
                return(false);
            }

            var Command = new Command(Scope, Code, CommandType.Expression);

            Command.Expressions = new List <ExpressionNode>()
            {
                Node
            };
            Scope.Children.Add(Command);
            return(ProcessContainer(Command));
        }
Beispiel #4
0
        private bool SetTypePointer(CodeScopeNode Scope, ref int Index, SelfVariable Self, CodeString Code)
        {
            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var Value = Plugin.NewNode(new DataPointerNode(Code, Self.TypeOfSelf));

            if (Value == null)
            {
                return(false);
            }

            var Assignment = Expressions.SetValue(Self, "_objTypePointer", Value, Plugin, Code, true);

            if (Assignment == null)
            {
                return(false);
            }

            var Command = new Command(Scope, Code, CommandType.Expression);

            Command.Expressions = new List <ExpressionNode>()
            {
                Assignment
            };
            Scope.Children.Insert(Index, Command);
            Index++;

            return(ProcessContainer(Command));
        }
Beispiel #5
0
        bool SetFinallyReturn(CodeScopeNode Scope, ExpressionNode Value, CodeString Code)
        {
            var FS     = Scope.FunctionScope;
            var FSData = FS.Data.Get <NCFuncScopeData>();

            if (!CreateFinallyReturn(FS))
            {
                return(false);
            }

            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var Node = Expressions.SetValue(FSData.FinallyReturn, Value, Plugin, Code, true);

            if (Node == null)
            {
                return(false);
            }

            var Comm = new Command(Scope, Code, CommandType.Expression);

            Comm.Expressions = new List <ExpressionNode>()
            {
                Node
            };
            Scope.Children.Add(Comm);
            return(ProcessContainer(Comm));
        }
Beispiel #6
0
        CodeScopeNode CreateScopeForCommand(Command Command)
        {
            var Scope = new CodeScopeNode(Command.Parent, Command.Code);

            Command.Parent.ReplaceChild(Command, Scope);
            CopyIdentifiers(Scope, Command);
            return(Scope);
        }
Beispiel #7
0
        bool AddFreeScopes(CodeScopeNode Scope, int Count, CodeString Code)
        {
            for (var i = 0; i < Count; i++)
            {
                Scope.Children.Add(new CodeScopeNode(Scope, Code));
            }

            return(true);
        }
Beispiel #8
0
        bool FinallyRethrow(Command Command, CodeScopeNode Scope, CodeString Code)
        {
            var CatchVar = GetCatchVariable(Command);

            if (CatchVar == null)
            {
                return(false);
            }

            var Plugin = Command.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var Cmp_Dst = Plugin.NewNode(new IdExpressionNode(CatchVar, Code));
            var Cmp_Src = Plugin.NewNode(Constants.GetNullValue(Command, Code));

            if (Cmp_Dst == null || Cmp_Src == null)
            {
                return(false);
            }

            var Cmp_Ch   = new ExpressionNode[] { Cmp_Dst, Cmp_Src };
            var Cmp_Node = Plugin.NewNode(new OpExpressionNode(Operator.Inequality, Cmp_Ch, Code));

            if (Cmp_Node == null || Plugin.End(ref Cmp_Node) == PluginResult.Failed)
            {
                return(false);
            }

            var Cmp_If = new Command(Scope, Code, CommandType.If);

            Cmp_If.Expressions = new List <ExpressionNode>()
            {
                Cmp_Node
            };
            Scope.Children.Add(Cmp_If);

            var Then = new Command(Cmp_If, Code, CommandType.Rethrow);

            Cmp_If.Children.Add(Then);

            if (!ProcessContainer(Then))
            {
                return(false);
            }
            if (!ProcessContainer(Cmp_If))
            {
                return(false);
            }
            return(true);
        }
Beispiel #9
0
        bool CallInitializerWithCmp(CodeScopeNode Scope, ref int Index, PluginRoot Plugin, ExpressionNode Size, CodeString Code)
        {
            var CondComm = new Command(Scope, Code, CommandType.If);

            Scope.Children.Insert(Index, CondComm);
            Index++;

            var ThenScope = new CodeScopeNode(CondComm, new CodeString());

            CondComm.Children = new List <IdContainer>()
            {
                ThenScope
            };

            var CmpPlugin = ThenScope.GetPlugin();

            if (!CmpPlugin.Begin())
            {
                return(false);
            }

            var FS   = Scope.FunctionScope;
            var Self = CmpPlugin.NewNode(new IdExpressionNode(FS.SelfVariable, Code));
            var Null = CmpPlugin.NewNode(Constants.GetNullValue(Scope, Code));

            if (Self == null || Null == null)
            {
                return(false);
            }

            var CmpCh   = new ExpressionNode[] { Self, Null };
            var CmpNode = CmpPlugin.NewNode(new OpExpressionNode(Operator.RefEquality, CmpCh, Code));

            if (CmpNode == null || (CmpNode = CmpPlugin.End(CmpNode)) == null)
            {
                return(false);
            }
            CondComm.Expressions = new List <ExpressionNode>()
            {
                CmpNode
            };

            var NewIndex = ThenScope.Children.Count;

            if (!CallInitializerWithoutCmp(ThenScope, ref NewIndex, Plugin, Size, Code))
            {
                return(false);
            }
            if (!ProcessContainer(ThenScope))
            {
                return(false);
            }
            return(ProcessContainer(CondComm));
        }
Beispiel #10
0
        bool CreateJump(CodeScopeNode Scope, string Label, CodeString Code)
        {
            var Comm = CreateJump((IdContainer)Scope, Label, Code);

            if (Comm == null)
            {
                return(false);
            }

            Scope.Children.Add(Comm);
            return(ProcessContainer(Comm));
        }
Beispiel #11
0
        bool EnterTryBlock(CodeScopeNode Scope, int Index, CodeString Code, Identifier CatchVariable, int Label)
        {
            var FScope = Scope.FunctionScope;

            FScope.NeverSkippedLabels.Add(Label);

            var Global = Scope.State.GlobalContainer;
            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var CatchVarNode = Plugin.NewNode(new IdExpressionNode(CatchVariable, Code));

            if (CatchVarNode == null)
            {
                return(false);
            }

            var Ch = new ExpressionNode[] { CatchVarNode };

            CatchVarNode = Plugin.NewNode(new OpExpressionNode(Operator.Address, Ch, Code));
            var JumpTo = Plugin.NewNode(new LabelExpressionNode(Code, "_" + Label.ToString()));
            var Func   = Identifiers.GetByFullNameFast <Function>(Global, "Internals.EnterTryBlock");

            if (Func == null || CatchVarNode == null || JumpTo == null)
            {
                return(false);
            }

            var Node = Expressions.Call(Code, Plugin, Func, CatchVarNode, JumpTo);

            if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
            {
                return(false);
            }

            var Command = new Command(Plugin.Container, Code, CommandType.Expression);

            Command.Expressions = new List <ExpressionNode>()
            {
                Node
            };
            Scope.Children.Insert(0, Command);
            return(ProcessContainer(Command));
        }
Beispiel #12
0
        private bool SetFunctionTable(CodeScopeNode Scope, ref int Index, SelfVariable Self, CodeString Code)
        {
            var Class  = Self.TypeOfSelf.UnderlyingClassOrRealId as ClassType;
            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            ExpressionNode Value;

            if (Class.HasFunctionTable)
            {
                Value = Plugin.NewNode(new LabelExpressionNode(Code, Class.FunctionTableLabel));
                if (Value == null)
                {
                    return(false);
                }
            }
            else
            {
                Value = Constants.GetNullValue(Scope, Code);
                if (Value == null)
                {
                    return(false);
                }
            }

            var Assignment = Expressions.SetValue(Self, "_objFunctionTable", Value, Plugin, Code, true);

            if (Assignment == null)
            {
                return(false);
            }

            var Command = new Command(Scope, Code, CommandType.Expression);

            Command.Expressions = new List <ExpressionNode>()
            {
                Assignment
            };
            Scope.Children.Insert(Index, Command);
            Index++;

            return(ProcessContainer(Command));
        }
Beispiel #13
0
        bool CallInitializer(CodeScopeNode Scope, ref int Index, PluginRoot Plugin,
                             ExpressionNode Size, CodeString Code)
        {
            var FS         = Scope.FunctionScope;
            var Structured = FS.Parent as StructuredScope;
            var Type       = Structured.StructuredType;

            var FType       = Scope.FunctionScope.Function.Children[0];
            var NoCondition = FType.Children[0].RealId is VoidType;

            if (NoCondition)
            {
                return(CallInitializerWithoutCmp(Scope, ref Index, Plugin, Size, Code));
            }
            else
            {
                return(CallInitializerWithCmp(Scope, ref Index, Plugin, Size, Code));
            }
        }
Beispiel #14
0
        bool SetFinallyJump(Command TryComm, CodeScopeNode Scope, string Label, CodeString Code)
        {
            var NCData = TryComm.Data.GetOrCreate <NCCommandData>();

            if (!CreateFinallyJump(TryComm, Code))
            {
                return(false);
            }

            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var Dst = Plugin.NewNode(new IdExpressionNode(NCData.FinallyJump, Code));
            var Src = Plugin.NewNode(new LabelExpressionNode(Code, Label));

            if (Dst == null || Src == null)
            {
                return(false);
            }

            var Ch   = new ExpressionNode[] { Dst, Src };
            var Node = Plugin.NewNode(new OpExpressionNode(Operator.Assignment, Ch, Code));

            if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
            {
                return(false);
            }

            var Command = new Command(Scope, Code, CommandType.Expression);

            Command.Expressions = new List <ExpressionNode>()
            {
                Node
            };
            Scope.Children.Add(Command);
            return(ProcessContainer(Command));
        }
Beispiel #15
0
        public ExprRecResult Recognize(CodeString Code, PluginRoot Plugin, ref ExpressionNode Out)
        {
            var Result = Code.StartsWith(Operators, Skip, new IdCharCheck(true));

            if (Result.Position != -1)
            {
                var State = Plugin.State;
                var Right = Code.Substring(Result.String.Length).Trim();
                Right = Right.TrimOneBracket(SkippingHandlers);

                if (Right.Length == 0)
                {
                    State.Messages.Add(MessageId.DeficientExpr, Code);
                    return(ExprRecResult.Failed);
                }

                var Scope = new CodeScopeNode(Plugin.Container, Right);
                if (!Scope.ProcessCode())
                {
                    return(ExprRecResult.Failed);
                }

                var List   = Scope.GetContainerId("retvar", x => x is LocalVariable);
                var RetVar = Identifiers.SelectIdentifier(State, List, Code) as LocalVariable;
                if (RetVar == null)
                {
                    return(ExprRecResult.Failed);
                }

                Out = new ScopeExpressionNode(Scope, Code)
                {
                    ReturnVar = RetVar,
                };

                return(ExprRecResult.Succeeded);
            }

            return(ExprRecResult.Unknown);
        }
Beispiel #16
0
        private bool AllocateObject(CodeScopeNode Scope, ref int Index, SelfVariable Self, ExpressionNode Size, PluginRoot Plugin, CodeString Code)
        {
            var TypeMngrPlugin = Plugin.GetPlugin <TypeMngrPlugin>();

            TypeMngrPlugin.Flags |= TypeMngrPluginFlags.NoWarningOnCastingToSameType;
            TypeMngrPlugin.Flags |= TypeMngrPluginFlags.EnableReadonlyWriting;

            var Func = Identifiers.GetByFullNameFast <Function>(Scope.State, "Internals.ObjectHelper.Allocate");

            if (Func == null)
            {
                return(false);
            }

            var FuncNode = Plugin.NewNode(new IdExpressionNode(Func, Code));

            if (Func == null)
            {
                return(false);
            }

            var FuncType  = Func.Children[0] as TypeOfFunction;
            var SizeParam = FuncType.Children[1] as FunctionParameter;

            if (Size.Type == null || !Size.Type.IsEquivalent(SizeParam.TypeOfSelf))
            {
                Size = Expressions.Convert(Size, SizeParam.TypeOfSelf, Plugin, Code);
                if (Size == null)
                {
                    return(false);
                }
            }

            var CallCh = new ExpressionNode[] { FuncNode, Size };
            var Call   = Plugin.NewNode(new OpExpressionNode(Operator.Call, CallCh, Code));

            if (Call == null)
            {
                return(false);
            }

            var Node = Expressions.Reinterpret(Call, Self.TypeOfSelf, Plugin, Code);

            if (Node == null)
            {
                return(false);
            }

            var FS         = Scope.FunctionScope;
            var Assignment = Expressions.SetValue(FS.SelfVariable, Node, Plugin, Code, true);

            if (Assignment == null)
            {
                return(false);
            }

            var Command = new Command(Scope, Code, CommandType.Expression);

            Command.Expressions = new List <ExpressionNode>()
            {
                Assignment
            };
            Scope.Children.Insert(Index, Command);
            Index++;

            return(ProcessContainer(Command));
        }
Beispiel #17
0
        bool FinallyJump(CodeScopeNode Scope, Identifier JumpTo, CodeString Code)
        {
            var Plugin = Scope.GetPlugin();

            if (!Plugin.Begin())
            {
                return(false);
            }

            var Cmp_IdNode = Plugin.NewNode(new IdExpressionNode(JumpTo, Code));
            var Cmp_Null   = Plugin.NewNode(Constants.GetNullValue(Scope, Code));

            if (Cmp_IdNode == null || Cmp_Null == null)
            {
                return(false);
            }

            var Cmp_Ch   = new ExpressionNode[] { Cmp_IdNode, Cmp_Null };
            var Cmp_Node = Plugin.NewNode(new OpExpressionNode(Operator.Inequality, Cmp_Ch, Code));

            if (Cmp_Node == null || Plugin.End(ref Cmp_Node) == PluginResult.Failed)
            {
                return(false);
            }

            var Cmp_If = new Command(Scope, Code, CommandType.If);

            Cmp_If.Expressions = new List <ExpressionNode>()
            {
                Cmp_Node
            };
            Scope.Children.Add(Cmp_If);

            if (!Plugin.Begin())
            {
                return(false);
            }
            var Then_Node = Plugin.NewNode(new IdExpressionNode(JumpTo, Code));

            if (Then_Node == null || Plugin.End(ref Then_Node) == PluginResult.Failed)
            {
                return(false);
            }

            var Then_Jump = CreateJump(Cmp_If, Then_Node, Code);

            if (Then_Jump == null)
            {
                return(false);
            }

            Cmp_If.Children.Add(Then_Jump);
            if (!ProcessContainer(Then_Jump))
            {
                return(false);
            }
            if (!ProcessContainer(Cmp_If))
            {
                return(false);
            }
            return(true);
        }
Beispiel #18
0
 bool SetFinallyJump(Command TryComm, CodeScopeNode Scope, int Label, CodeString Code)
 {
     Scope.FunctionScope.NeverSkippedLabels.Add(Label);
     return(SetFinallyJump(TryComm, Scope, "_" + Label, Code));
 }
Beispiel #19
0
        public IdContainer ExtractCommand(Command Command, NCExpressionRunBefores[] RunBefores)
        {
            var State = Command.State;
            var Code  = Command.Code;

            if (Command.Type == CommandType.For)
            {
                var Scope = CreateScopeForCommand(Command);
                if (Command.Expressions[0] != null)
                {
                    var Init = new Command(Scope, Code, CommandType.Expression);
                    Init.Expressions = new List <ExpressionNode>()
                    {
                        Command.Expressions[0]
                    };
                    Scope.Children.Add(Init);
                    if (!ProcessContainer(Init))
                    {
                        return(null);
                    }
                }

                var While = new Command(Scope, Code, CommandType.While);
                While.Expressions = new List <ExpressionNode>()
                {
                    Command.Expressions[1]
                };
                Scope.Children.Add(While);

                var WhileScope = new CodeScopeNode(While, Code);
                While.Children.Add(WhileScope);
                WhileScope.Children.Add(Command.Children[0]);
                Command.Children[0].Parent = WhileScope;

                var Loop = new Command(WhileScope, Code, CommandType.Expression);
                Loop.Expressions = new List <ExpressionNode>()
                {
                    Command.Expressions[2]
                };
                WhileScope.Children.Add(Loop);
                if (!ProcessContainer(Loop))
                {
                    return(null);
                }

                if (!ProcessContainer(WhileScope))
                {
                    return(null);
                }
                if (!ProcessContainer(While))
                {
                    return(null);
                }
                if (!ProcessContainer(Scope))
                {
                    return(null);
                }
                return(Scope);
            }

            else if (Command.Type == CommandType.While || Command.Type == CommandType.DoWhile)
            {
                var Cycle = new Command(Command.Parent, Code, CommandType.Cycle);
                Command.Parent.ReplaceChild(Command, Cycle);
                CopyIdentifiers(Cycle, Command);

                var CycleScope = new CodeScopeNode(Cycle, Code);
                Cycle.Children.Add(CycleScope);

                var If = new Command(CycleScope, Code, CommandType.If);
                CycleScope.Children.Add(If);

                var Condition = NCExpressions.Negate(If.GetPlugin(), Command.Expressions[0], Code);
                If.Expressions = new List <ExpressionNode>()
                {
                    Condition
                };
                if (Condition == null)
                {
                    return(null);
                }

                var Then = new Command(If, Code, CommandType.Break);
                Then.Label = Cycle.BreakLabel;
                If.Children.Add(Then);

                if (!ProcessContainer(Then))
                {
                    return(null);
                }
                if (!ProcessContainer(If))
                {
                    return(null);
                }

                if (Command.Type == CommandType.While)
                {
                    CycleScope.Children.Add(Command.Children[0]);
                }
                else
                {
                    CycleScope.Children.Insert(0, Command.Children[0]);
                }
                Command.Children[0].Parent = CycleScope;

                if (!ProcessContainer(CycleScope))
                {
                    return(null);
                }
                if (!ProcessContainer(Cycle))
                {
                    return(null);
                }
                return(Cycle);
            }

            else if (Command.Type == CommandType.If)
            {
                var Scope = CreateScopeForCommand(Command);
                if (Command.Expressions.Count == 1)
                {
                    var FreeScopeCount = RunBefores[0].NeededRunBefores.Length;
                    if (!AddFreeScopes(Scope, FreeScopeCount, Code))
                    {
                        return(null);
                    }

                    Scope.Children.Add(Command);
                    Command.Parent = Scope;

                    if (!ProcessContainer(Command, true))
                    {
                        return(null);
                    }
                }
                else
                {
                    var Label     = State.AutoLabel;
                    var LabelComm = new Command(Scope, Code, CommandType.Label);
                    LabelComm.Label = Label;

                    for (var i = 0; i < Command.Expressions.Count; i++)
                    {
                        var If = new Command(Scope, Code, CommandType.If);
                        If.Expressions = new List <ExpressionNode>()
                        {
                            Command.Expressions[i]
                        };
                        Scope.Children.Add(If);

                        if (i == Command.Expressions.Count - 1)
                        {
                            If.Children.Add(Command.Children[i]);
                            Command.Children[i].Parent = If;

                            for (var j = i + 1; j < Command.Children.Count; j++)
                            {
                                If.Children.Add(Command.Children[j]);
                                Command.Children[j].Parent = If;
                            }
                        }
                        else
                        {
                            var ThenScope = new CodeScopeNode(If, Code);
                            If.Children.Add(ThenScope);

                            ThenScope.Children.Add(Command.Children[i]);
                            Command.Children[i].Parent = ThenScope;

                            var Goto = new Command(ThenScope, Code, CommandType.Goto);
                            Goto.JumpTo = LabelComm;
                            Goto.Label  = Label;
                            ThenScope.Children.Add(Goto);

                            if (!ProcessContainer(Goto))
                            {
                                return(null);
                            }
                            if (!ProcessContainer(ThenScope))
                            {
                                return(null);
                            }
                        }

                        if (!ProcessContainer(If))
                        {
                            return(null);
                        }
                    }

                    Scope.Children.Add(LabelComm);

                    if (!ProcessContainer(LabelComm))
                    {
                        return(null);
                    }
                }

                if (!ProcessContainer(Scope))
                {
                    return(null);
                }
                return(Scope);
            }

            else
            {
                if (RunBefores.Length != 1)
                {
                    throw new ApplicationException();
                }

                var Scope          = CreateScopeForCommand(Command);
                var FreeScopeCount = RunBefores[0].NeededRunBefores.Length;
                if (!AddFreeScopes(Scope, FreeScopeCount, Code))
                {
                    return(null);
                }

                Scope.Children.Add(Command);
                Command.Parent = Scope;

                if (!ProcessContainer(Command, true))
                {
                    return(null);
                }
                if (!ProcessContainer(Scope))
                {
                    return(null);
                }
                return(Scope);
            }
        }
Beispiel #20
0
        IdContainer ProcessCommand(Command Command, bool NoExtract = false)
        {
            var State           = Command.State;
            var GlobalContainer = State.GlobalContainer;
            var Code            = Command.Code;

            if (!NoExtract && Command.Expressions != null && Command.Expressions.Count > 0)
            {
                var RunBefores = NCExpressions.GetCommandRunBefores(Command);
                if (!RunBefores.TrueForAll(x => x.NeededRunBefores.Length == 0))
                {
                    return(ExtractCommand(Command, RunBefores));
                }
            }

            if (Command.Type == CommandType.Try)
            {
                var NCData = Command.Data.GetOrCreate <NCCommandData>();
                if (NCData.FinallyJump != null && !InitializeFinallyJump(Command, Code))
                {
                    return(null);
                }

                var TryScope = Command.Children[0] as CodeScopeNode;
                var CatchVar = GetCatchVariable(Command);
                if (CatchVar == null)
                {
                    return(null);
                }

                var Pos = NCData.FinallyJump != null ? 1 : 0;
                if (!EnterTryBlock(TryScope, Pos, Code, CatchVar, Command.CatchLabel))
                {
                    return(null);
                }

                if (!LeaveTryBlock(TryScope, Code))
                {
                    return(null);
                }

                if (Command.CatchScope == null)
                {
                    if (!FinallyRethrow(Command, Command.FinallyScope, Code))
                    {
                        return(null);
                    }
                }

                if (Command.FinallyScope != null && NCData.FinallyJump != null)
                {
                    if (!FinallyJump(Command.FinallyScope, NCData.FinallyJump, Command.Code))
                    {
                        return(null);
                    }
                }
            }

            else if (Command.Type == CommandType.Throw || Command.Type == CommandType.Rethrow)
            {
                var NewPlugin = Command.GetPlugin();
                if (!NewPlugin.Begin())
                {
                    return(null);
                }

                ExpressionNode Node;
                if (Command.Expressions != null && Command.Expressions.Count > 0)
                {
                    Node = Command.Expressions[0];
                }
                else
                {
                    var TryComm  = Command.GetParent(CommandType.Try);
                    var CatchVar = GetCatchVariable(TryComm);

                    Node = NewPlugin.NewNode(new IdExpressionNode(CatchVar, Command.Code));
                    if (Node == null)
                    {
                        return(null);
                    }

                    Command.Expressions = new List <ExpressionNode>()
                    {
                        null
                    };
                }

                Node = NCExpressions.Throw(NewPlugin, Node, Code);
                if (Node == null)
                {
                    return(null);
                }

                Command.Expressions[0] = Node;
                Command.Type           = CommandType.Expression;
            }

            else if (Commands.IsJumpCommand(Command.Type))
            {
                var TryComms = new AutoAllocatedList <Command>();
                Command.ForEachJumpedOver <Command>(x =>
                {
                    if (x.Type == CommandType.Try && x.FinallyScope != null)
                    {
                        TryComms.Add(x);
                    }
                });

                if (TryComms.Count > 0)
                {
                    var NewScope = new CodeScopeNode(Command.Parent, Code);
                    Command.Parent.ReplaceChild(Command, NewScope);

                    var LastLabel = Command.Label;
                    if (Command.Type == CommandType.Return)
                    {
                        if (!SetFinallyReturn(NewScope, Command.Expressions[0], Code))
                        {
                            return(null);
                        }

                        var FS     = Command.FunctionScope;
                        var FSData = FS.Data.Get <NCFuncScopeData>();
                        LastLabel = FSData.FinallyReturnLabel;
                    }

                    for (var i = 0; i < TryComms.Count - 1; i++)
                    {
                        var Label = TryComms[i + 1].FinallyLabel;
                        if (!SetFinallyJump(TryComms[i], NewScope, Label, Code))
                        {
                            return(null);
                        }
                    }

                    var Last = TryComms[TryComms.Count - 1];
                    if (!SetFinallyJump(Last, NewScope, LastLabel, Code))
                    {
                        return(null);
                    }
                    if (!CreateJump(NewScope, TryComms[0].FinallyLabel, Code))
                    {
                        return(null);
                    }
                    Command.FunctionScope.NeverSkippedLabels.Add(Command.Label);
                    return(NewScope);
                }
            }

            return(Command);
        }
Beispiel #21
0
 bool CreateJump(CodeScopeNode Scope, int Label, CodeString Code)
 {
     Scope.FunctionScope.NeverSkippedLabels.Add(Label);
     return(CreateJump(Scope, "_" + Label, Code));
 }