Esempio n. 1
0
        /// <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 };
        }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
        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;
            }
        }