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); }
public void appendEOF() { Token temp = new Token(TokenType.Token_EOF, ""); TokensList.Add(temp); }
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); }