예제 #1
0
        public bool BytecodeAnalysis()
        {
            BytecodeFounds    = new List <BytecodeFound>();
            OperationsName    = new OperationsName();
            ArgumentsList     = new List <Arguments>();
            LineArgumentsList = new List <int>();
            IdentLevel        = new Stack <int>();
            WhileLevel        = new Stack <int>();
            ForLevel          = new Stack <int>();

            var address = 0;

            LastLine = TokensList.Last();

            for (int line = 1; line <= LastLine.Line; line++)
            {
                foreach (var found in GetObjects(line))
                {
                    var bytecodeFound = new BytecodeFound
                    {
                        Line     = found.Line > 0 ? found.Line : line,
                        Address  = address,
                        OpName   = found.OpName,
                        Argument = found.Argument,
                        FriendlyInterpretation = found.FriendlyInterpretation
                    };

                    BytecodeFounds.Add(bytecodeFound);
                    address += 3;
                }
            }

            int setupLoopWhile = 0, setupLoopWhileAux = 0, setupLoopFor = 0, setupLoopForAux = 0;

            //Ajusta argumentos dos jumps
            var withoutArguments = BytecodeFounds.Where(x => x.Argument != null && x.Argument.Trim().Equals("")).ToList();

            if (withoutArguments != null)
            {
                withoutArguments.ForEach(argument =>
                {
                    var name = argument.OpName;

                    if (name.Contains("POP_JUMP") || name.Contains("JUMP"))
                    {
                        if (LineArgumentsList.Count > 0)
                        {
                            var line      = LineArgumentsList.First();
                            var firstChar = BytecodeFounds.Where(x => x.Line.Equals(line) && !x.OpName.Contains("JUMP")).FirstOrDefault();
                            if (firstChar != null)
                            {
                                if (firstChar.OpName.Contains("POP_BLOCK"))
                                {
                                    if (firstChar.OpName.Equals("POP_BLOCK_WHILE") && !setupLoopWhile.Equals(setupLoopWhileAux))
                                    {
                                        setupLoopWhileAux = setupLoopWhile;
                                        var popBlock      = BytecodeFounds.Where(x => x.OpName.Equals("POP_BLOCK_WHILE")).ElementAt(--WhileCounter);
                                        argument.Argument = popBlock.Address.ToString();
                                    }
                                    else if (firstChar.OpName.Equals("POP_BLOCK_FOR") && !setupLoopFor.Equals(setupLoopForAux))
                                    {
                                        setupLoopForAux   = setupLoopFor;
                                        var popBlock      = BytecodeFounds.Where(x => x.OpName.Equals("POP_BLOCK_FOR")).ElementAt(--ForCounter);
                                        argument.Argument = popBlock.Address.ToString();
                                    }
                                }

                                else if (name.Contains("POP_JUMP"))
                                {
                                    argument.Argument = firstChar.Address.ToString();
                                }
                                else if (name.Equals("JUMP_FORWARD"))
                                {
                                    argument.Argument = "0";
                                    argument.FriendlyInterpretation = "to " + firstChar.Address.ToString();
                                }
                            }

                            LineArgumentsList.RemoveAt(0);
                        }
                    }
                    else if (name.Equals("SETUP_LOOP_WHILE"))
                    {
                        argument.OpName = "SETUP_LOOP";
                        var popBlock    = BytecodeFounds.Where(x => x.OpName.Equals("POP_BLOCK_WHILE")).ElementAt(setupLoopWhile++);
                        argument.FriendlyInterpretation = "to " + (popBlock.Address).ToString(); //sempre no do pop block
                        argument.Argument = (popBlock.Address - 2).ToString();                   //sempre antes do jump_absolute
                    }
                    else if (name.Equals("SETUP_LOOP_FOR"))
                    {
                        argument.OpName = "SETUP_LOOP";
                        var popBlock    = BytecodeFounds.Where(x => x.OpName.Equals("POP_BLOCK_FOR")).ElementAt(setupLoopFor++);
                        argument.FriendlyInterpretation = "to " + (popBlock.Address).ToString(); //sempre no do pop block
                        argument.Argument = (popBlock.Address - 2).ToString();                   //sempre antes do jump_absolute
                    }
                    else if (name.Equals("FOR_ITER"))
                    {
                        var popBlock = BytecodeFounds.Where(x => x.OpName.Equals("POP_BLOCK_FOR")).ElementAt(setupLoopFor - 1);
                        argument.FriendlyInterpretation = "to " + (popBlock.Address).ToString(); //sempre no do pop block
                    }
                });
            }

            //ajusta os pop_block
            BytecodeFounds.Where(x => x.OpName.Contains("POP_BLOCK")).ToList().ForEach(popblock => popblock.OpName = "POP_BLOCK");

            //ajusta bloco do EOF
            if (BytecodeFounds.Where(x => x.Line.Equals(LastLine.Line)).Count().Equals(2))
            {
                BytecodeFounds.Where(x => x.Line.Equals(LastLine.Line)).ToList().ForEach(block => block.Line--);
            }

            return(true);
        }
예제 #2
0
        public void appendEOF()
        {
            Token temp = new Token(TokenType.Token_EOF, "");

            TokensList.Add(temp);
        }
예제 #3
0
        private List <BytecodeFound> GetObjects(int line)
        {
            var  tokens = TokensList.FindAll(x => x.Line.Equals(line));
            var  list   = new List <BytecodeFound>();
            bool hasPlaceJumpForward = false;
            int  index = 0;

            while (tokens[index].Token.Equals("TOKEN.INDENT"))
            {
                index++;
                IdentLevel.Push(line);
                if (tokens[index].Token.Equals("TOKEN.ELSE"))
                {
                    return(list);
                }
            }
            while (tokens[index].Token.Equals("TOKEN.DEDENT"))
            {
                index++;
                if (IdentLevel.Count > 0)
                {
                    IdentLevel.Pop();
                }

                string nextToken;
                if (line + 1 <= LastLine.Line)
                {
                    if ((nextToken = TokensList.FindAll(x => x.Line.Equals(line + 1)).FirstOrDefault().Token.ToString()) != null)
                    {
                        if (nextToken.Equals("TOKEN.DEDENT") && IdentLevel.Count > 0)
                        {
                            IdentLevel.Pop();
                        }
                    }
                }

                if (tokens[index].Token.Equals("TOKEN.ELSE") || tokens[index].Token.Equals("TOKEN.DEF"))
                {
                    return(list);
                }

                int actualLine = tokens[index].Line;
                InsertIntoLineArgumentsList(actualLine, IdentLevel.Count);

                if (tokens[index].Token.Equals("TOKEN.IF") || tokens[index].Token.Equals("TOKEN.ELIF"))
                {
                    InsertIntoLineArgumentsList(actualLine, IdentLevel.Count, tokens[index].Token);
                    if (!hasPlaceJumpForward)
                    {
                        list.Add(new BytecodeFound
                        {
                            OpName   = "JUMP_FORWARD",
                            Argument = ""
                        });

                        hasPlaceJumpForward = true;
                    }
                    else
                    {
                        list.Add(new BytecodeFound
                        {
                            OpName   = "JUMP_ABSOLUTE",
                            Argument = ""
                        });
                    }
                }
                else if (WhileLevel.Count > 0 && WhileLevel.Count != WhileCounter)
                {
                    InsertIntoLineArgumentsList(actualLine, IdentLevel.Count);

                    if (WhileLevel.Count == 1)
                    {
                        list.Add(new BytecodeFound
                        {
                            OpName   = "JUMP_ABSOLUTE",
                            Argument = "",
                            Line     = line - 1
                        });
                    }

                    list.Add(new BytecodeFound
                    {
                        OpName = "POP_BLOCK_WHILE",
                        Line   = line - 1
                    });

                    WhileLevel.Pop();
                    WhileCounter++;
                }
                else if (ForLevel.Count > 0 && ForLevel.Count != ForCounter)
                {
                    InsertIntoLineArgumentsList(actualLine, IdentLevel.Count);

                    if (ForLevel.Count == 1)
                    {
                        list.Add(new BytecodeFound
                        {
                            OpName   = "JUMP_ABSOLUTE",
                            Argument = "",
                            Line     = line - 1
                        });
                    }

                    list.Add(new BytecodeFound
                    {
                        OpName = "POP_BLOCK_FOR",
                        Line   = line - 1
                    });

                    ForLevel.Pop();
                    ForCounter++;
                }
                else if (!tokens[index].Token.Equals("TOKEN.DEDENT") && !tokens[index].Token.Equals("TOKEN.EOF"))
                {
                    InsertIntoLineArgumentsList(actualLine, IdentLevel.Count);
                    list.Add(new BytecodeFound
                    {
                        OpName   = "JUMP_FORWARD",
                        Argument = ""
                    });
                }
                else if (!tokens[index - 1].Token.Equals("TOKEN.DEDENT") && !tokens[index].Token.Equals("TOKEN.EOF"))
                {
                    InsertIntoLineArgumentsList(actualLine, IdentLevel.Count);
                    list.Add(new BytecodeFound
                    {
                        OpName   = "JUMP_ABSOLUTE",
                        Argument = ""
                    });
                }
            }
            if (tokens[index].Token.Equals("TOKEN.ELSE") || tokens[index].Token.Equals("TOKEN.DEF"))
            {
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.ID") && tokens[index + 1].Token.Equals("TOKEN.IGUAL"))
            {
                IsAssign(tokens, index).ForEach(bytecode => list.Add(bytecode));
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.IF") || tokens[index].Token.Equals("TOKEN.ELIF"))
            {
                IsIf(tokens).ForEach(bytecode => list.Add(bytecode));
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.WHILE"))
            {
                IsWhile(tokens, index).ForEach(bytecode => list.Add(bytecode));
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.FOR"))
            {
                IsFor(tokens, index).ForEach(bytecode => list.Add(bytecode));
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.ID") && tokens[index + 1].Token.Equals("TOKEN.PARENTESES_ESQUERDO"))
            {
                IsFunction(tokens, index).ForEach(bytecode => list.Add(bytecode));
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.RETURN"))
            {
                IsReturn(tokens, index).ForEach(bytecode => list.Add(bytecode));
                return(list);
            }
            else if (tokens[index].Token.Equals("TOKEN.EOF"))
            {
                var endProgram = new BytecodeFound()
                {
                    Argument = "0",
                    OpName   = "LOAD_CONST",
                    FriendlyInterpretation = "None"
                };

                list.Add(endProgram);
                OperationsName.OperationsNameList.TryGetValue(tokens[index].Token, out string opName);
                list.Add(CreateBytecodeFoundObject(opName));
                return(list);
            }

            return(list);
        }