/// <summary> /// Faz a leitura do código e retorna um hash com as variáveis que existem no mesmo /// </summary> /// <param name="File"></param> /// <returns></returns> private Dictionary <string, Variable> GetVariables(string[] File) { Dictionary <string, Variable> variables = new Dictionary <string, Variable>(); LexicAnalizer.Analize(File); Token token = null; do { token = LexicAnalizer.NextToken(); if (token != null) { if (token.Type == TokenType.VARIABLE) { string variableName = token.Value; if (!variables.ContainsKey(variableName)) { variables.Add(variableName, new Variable(variableName)); } } } } while (token != null); return(variables); }
/// <summary> /// Para calcular expressões sem parênteses e sem variáveis /// </summary> /// <param name="expression"></param> /// <returns></returns> public int CalculateExpression(string expression) { LexicAnalizer lexic = new LexicAnalizer(); lexic.Analize(new string[] { expression }); int result = 0; Token token = null; //Primeiro deve vir um número token = lexic.NextToken(); result = int.Parse(token.Value); do { token = lexic.NextToken(); if (token != null) { string mathOperator = token.Value; token = lexic.NextToken(); int nextValue = int.Parse(token.Value); switch (mathOperator) { case "+": result += nextValue; break; case "-": result -= nextValue; break; case "*": result *= nextValue; break; case "/": result /= nextValue; break; } } } while (token != null); return(result); }
public string[] CalculateExpressionVariable(string expression, Dictionary <string, Variable> variables) { //Não é aceitável ter RND com variável List <string> commands = new List <string>(); String commandCache = null; bool hasParenthesis = expression.Contains('('); if (hasParenthesis) { //Remove todos os parênteses colocando a expressão na forma que deve acontecer expression = AdjustParenthesis(expression); } LexicAnalizer lexic = new LexicAnalizer(); lexic.Analize(new string[] { expression }); bool hasVariables = lexic.HasVariable(); string hexValue; string hexValue2; if (hasVariables) { Token token = null; do { token = lexic.NextToken(); if (token != null) { switch (token.Type) { case TokenType.VALUE: { IntToHexa(int.Parse(token.Value), out hexValue, out hexValue2); commands.Add("LDI"); commands.Add(hexValue); commands.Add(hexValue2); if (commandCache != null) { commands.Add(commandCache); commandCache = null; } } break; case TokenType.VARIABLE: { Variable variable = variables[token.Value]; IntToHexa(variable.CodePosition, out hexValue, out hexValue2); commands.Add("LOD"); commands.Add(hexValue); commands.Add(hexValue2); if (commandCache != null) { commands.Add(commandCache); commandCache = null; } } break; case TokenType.MATH_OPERATOR: { string command = ""; switch (token.Value) { case "+": command = "ADD"; break; case "-": command = "MIN"; break; case "*": command = "TIM"; break; case "/": command = "DIV"; break; } commandCache = command; } break; } } } while (token != null); } else { int result = CalculateExpression(expression); IntToHexa(result, out hexValue, out hexValue2); commands.Add("LDI"); commands.Add(hexValue); commands.Add(hexValue2); } return(commands.ToArray()); }
/// <summary> /// Busca as linhas que correspondem aos input do código /// </summary> /// <param name="variables"></param> /// <param name="File"></param> /// <returns></returns> private string[] GetInputs(Dictionary <string, Variable> variables, string[] File) { //Utiliza um analisador léxico próprio para a expressão, para não confundir os tokens LexicAnalizer lexic = new LexicAnalizer(); lexic.Analize(File); List <string> inputList = new List <string>(); Token token = null; Variable variable = null; bool nextToken = true; string hexValue; string hexValue2; do { if (nextToken) { token = lexic.NextToken(); nextToken = false; } if (token != null) { if (token.Type == TokenType.RESERVED_WORD) { if (token.Value.Equals("INPUT")) { //Pega a primeira variável token = lexic.NextToken(); variable = variables[token.Value]; IntToHexa(variable.CodePosition, out hexValue, out hexValue2); inputList.Add(hexValue); inputList.Add(hexValue2); token = lexic.NextToken(); //Procura por uma lista de inputs if (token != null) { while (token != null && token.Type == TokenType.SEPARATOR) { token = lexic.NextToken(); variable = variables[token.Value]; IntToHexa(variable.CodePosition, out hexValue, out hexValue2); inputList.Add(hexValue); inputList.Add(hexValue2); token = lexic.NextToken(); } } } else { nextToken = true; } } else { nextToken = true; } } } while (token != null); return(inputList.ToArray()); }
private string[] ReadLine(Dictionary <string, Variable> variables, Dictionary <int, int> lineNumber, string line, int offset) { //Importante: A leitura dos hexadecimais é feita da esquerda para a direita List <string> code = new List <string>(); if (line == null || line.Equals("")) { return(new string[] { }); } LexicAnalizer localLexic = new LexicAnalizer(); localLexic.Analize(new string[] { line }); Token token = localLexic.NextToken(); string hexValue; string hexValue2; //Expressão começou com um identificador de linha if (token.Type == TokenType.VALUE) { int number = int.Parse(token.Value); if (!lineNumber.ContainsKey(number)) { lineNumber[number] = offset; } token = localLexic.NextToken(); } switch (token.Value) { case "GOTO": { string expression = line.Substring(line.IndexOf("GOTO") + 4); string[] commands = CalculateExpressionVariable(expression, variables); int jmpNumber = lineNumber[int.Parse(commands[1])] + 1; IntToHexa(jmpNumber, out hexValue, out hexValue2); code.Add("JMP"); code.Add(hexValue); code.Add(hexValue2); } break; case "LET": { token = localLexic.NextToken(); Variable variable = variables[token.Value]; string expression = line.Substring(line.IndexOf("=") + 2); string[] commands = CalculateExpressionVariable(expression, variables); code.AddRange(commands); int address = variable.CodePosition; IntToHexa(address, out hexValue, out hexValue2); code.Add("STO"); code.Add(hexValue); code.Add(hexValue2); } break; case "PRINT": { string[] printCode = null; do { token = localLexic.NextToken(); if (token != null) { if (token.Type == TokenType.STRING) { printCode = PrintString(token.Value); } else { #region Print de Expressão string expression = ""; do { expression = token.Value + " "; token = localLexic.NextToken(); } while (token != null && token.Type != TokenType.SEPARATOR && !token.Value.Equals(",")); printCode = CalculateExpressionVariable(expression, variables); #endregion } code.AddRange(printCode); code.Add("OUT"); } } while (token != null); } break; case "REM": { token = localLexic.NextToken(); string[] printCode = PrintString(token.Value); code.AddRange(printCode); } break; case "RETURN": { code.Add("STOP"); } break; case "IF": { string firstExp = ""; string compareExp = ""; #region Carrega o valor da primeira expressão token = localLexic.NextToken(); do { firstExp += token.Value + " "; token = localLexic.NextToken(); } while (token.Type != TokenType.RELATIONAL_OPERATOR); string[] firstCode = CalculateExpressionVariable(firstExp, variables); code.AddRange(firstCode); #endregion //Busca o comparador da expressão do IF string comparator = GetComparator(token); #region Carrega o valor da segunda expressão token = localLexic.NextToken(); do { compareExp += token.Value + " "; token = localLexic.NextToken(); } while (token.Type != TokenType.RESERVED_WORD); string[] compareCode = CalculateExpressionVariable(compareExp, variables); code.AddRange(compareCode); #endregion code.Add(comparator); //Carrega o valor do THEN string thenExpression = line.Substring(line.IndexOf("THEN") + 5); string[] thenCode = ReadLine(variables, lineNumber, thenExpression, offset); int actualNumberOfAddresses = code.Count; int numberOfAddresses = thenCode.Length; //+1 para pular a linha do JF //+1 para a próxima expressão depois do IF int jumpTo = offset + actualNumberOfAddresses + numberOfAddresses + 4; IntToHexa(jumpTo, out hexValue, out hexValue2); code.Add("JF"); code.Add(hexValue); code.Add(hexValue2); for (int i = 0; i < thenCode.Length; i++) { /*Atualiza os endereços JF dos IF aninhados * para o valor do JF relativo ao IF mais externo*/ if (thenCode[i].Contains("JF")) { thenCode[i] = "JF"; thenCode[i + 1] = hexValue; thenCode[i + 2] = hexValue2; break; } } code.AddRange(thenCode); } break; } return(code.ToArray()); }