/// <summary> /// Performs the code parsing, asynchronously. /// </summary> /// <returns></returns> public async Task<CompilationResult> DoAnalysisAsync(string outputFilePath) { string programName = null; try { await Task.Factory.StartNew(StartAnalysis); } catch (CompilationException ex) { int column = _lexical.Position.Column - _token.Lexeme.Length; if (_position.HasValue) { return new CompilationResult { Error = new CompilationError(_position.Value, ex.Message) }; } return new CompilationResult { Error = new CompilationError(_lexical.Position, ex.Message) }; } finally { _expressionAnalyzer = null; programName = _symbolTable.GetProgramName(); _symbolTable.Clear(); _funcInfo = null; _level = 0; } await _codeGenerator.SaveToFileAsync(outputFilePath); return new CompilationResult { Error = null, ProgramName = programName }; }
private void AnalyzeFuncDcl() { _isAnalyzingFunction = true; NextToken(); if (_token.Symbol != Symbols.SIdentificador) { RaiseUnexpectedTokenError("identificador"); } var item = _symbolTable.Search(_token.Lexeme); if (item != null) { RaiseDoubleError(Symbols.SFuncao); } var funcItem = new FunctionItem { Lexeme = _token.Lexeme, Level = _level, Label = _codeGenerator.GetStringLabelFor(_lastLabel) }; _funcInfo = new FunctionInfo { Name = _token.Lexeme }; _rootNode = new SyntaxTreeNode { Value = _token.Symbol }; _currentNode = _rootNode; _codeGenerator.GenerateLabel(_lastLabel); _level++; NextToken(); if (_token.Symbol != Symbols.SDoisPontos) { RaiseUnexpectedTokenError("\":\""); } NextToken(); if (_token.Symbol != Symbols.SInteiro && _token.Symbol != Symbols.SBooleano) { RaiseUnexpectedTokenError("\"inteiro\" ou \"booleano\""); } var type = _token.Symbol == Symbols.SInteiro ? ItemType.Integer : ItemType.Boolean; funcItem.Type = type; _symbolTable.Insert(funcItem); NextToken(); if (_token.Symbol != Symbols.SPontoVirgula) { RaiseMissingSemicolonError(); } AnalyzeBlock(true); if (!FunctionHelper.AllPathsReturns(_rootNode)) { RaiseMissingFunctionReturn(); } _symbolTable.CleanUpToLevel(_level); _level--; _rootNode = _currentNode = null; _funcInfo = null; }
private void AnalyzeBlock(bool isFunction = false) { uint totalVars; NextToken(); totalVars = AnalyzeVarsDcl(); if (totalVars > 0) { if (isFunction) { _funcInfo.VarsCount = totalVars; _funcInfo.FirstVarAddress = totalVars == 0 ? 0 : _allocBase; } _codeGenerator.GenerateInstruction(ALLOC, _allocBase, totalVars); _allocBase += totalVars; } _lastLabel++; if (isFunction) { //Saves the current values //We'll need this values saved in case a function has other functions inside it var rootNode = _rootNode; var funcInfo = _funcInfo; var currentNode = _currentNode; AnalyzeSubRoutines(); _rootNode = rootNode; _funcInfo = funcInfo; _currentNode = currentNode; } else { AnalyzeSubRoutines(); } AnalyzeCommands(true); if (totalVars > 0) { _allocBase -= totalVars; if (!isFunction) { _codeGenerator.GenerateInstruction(DALLOC, _allocBase, totalVars); } _memory -= totalVars; } }