internal static CompilerException AppendCodeInfo(CompilerException exc, CodePositionInfo codePosInfo)
        {
            exc.LineNumber   = codePosInfo.LineNumber;
            exc.ColumnNumber = codePosInfo.LineNumber;
            exc.Code         = codePosInfo.Code;
            exc.ModuleName   = codePosInfo.ModuleName;

            return(exc);
        }
예제 #2
0
            private void UnwindOperators()
            {
                while (_operators.Count > 0)
                {
                    var oper = PopOperator();
                    if (oper == Token.OpenPar)
                    {
                        throw CompilerException.ExpressionSyntax();
                    }

                    AddCommandForToken(oper);
                }
            }
예제 #3
0
 internal static CompilerException AppendCodeInfo(CompilerException exc, CodePositionInfo codePosInfo)
 {
     AppendCodeInfo(exc, codePosInfo.LineNumber, codePosInfo.Code);
     return(exc);
 }
예제 #4
0
 internal static CompilerException AppendCodeInfo(CompilerException exc, int line, string codeString)
 {
     exc.LineNumber = line;
     exc.Code       = codeString;
     return(exc);
 }
예제 #5
0
 private void AppendCodeInfo(int line, CompilerException exc)
 {
     var cp = new CodePositionInfo();
     cp.LineNumber = line;
     cp.Code = _parser.GetCodeLine(line);
     CompilerException.AppendCodeInfo(exc, cp);
 }
예제 #6
0
        private void BuildSingleMethod()
        {
            if (_lastExtractedLexem.Token == Token.Procedure)
            {
                PushStructureToken(Token.EndProcedure);
                _isFunctionProcessed = false;
                NextToken();
            }
            else if (_lastExtractedLexem.Token == Token.Function)
            {
                PushStructureToken(Token.EndFunction);
                _isFunctionProcessed = true;
                NextToken();
            }
            else
            {
                throw CompilerException.UnexpectedOperation();
            }

            #region Method signature
            // сигнатура
            if (!IsUserSymbol(ref _lastExtractedLexem))
            {
                throw CompilerException.IdentifierExpected();
            }

            int definitionLine = _parser.CurrentLine;
            MethodInfo method = new MethodInfo();
            method.Name = _lastExtractedLexem.Content;
            method.IsFunction = _isFunctionProcessed;

            NextToken();
            if (_lastExtractedLexem.Token != Token.OpenPar)
            {
                throw CompilerException.TokenExpected(Token.OpenPar);
            }
            #endregion

            NextToken();

            #region Parameters list
            var paramsList = new List<ParameterDefinition>();
            var methodCtx = new SymbolScope();

            while (_lastExtractedLexem.Token != Token.ClosePar)
            {
                var param = new ParameterDefinition();
                string name;

                if (_lastExtractedLexem.Token == Token.ByValParam)
                {
                    param.IsByValue = true;
                    NextToken();
                    if (IsUserSymbol(ref _lastExtractedLexem))
                    {
                        name = _lastExtractedLexem.Content;
                    }
                    else
                    {
                        throw CompilerException.IdentifierExpected();
                    }
                }
                else if (IsUserSymbol(ref _lastExtractedLexem))
                {
                    param.IsByValue = false;
                    name = _lastExtractedLexem.Content;
                }
                else
                {
                    throw CompilerException.UnexpectedOperation();
                }

                NextToken();
                if (_lastExtractedLexem.Token == Token.Equal)
                {
                    param.HasDefaultValue = true;
                    NextToken();
                    if (IsLiteral(ref _lastExtractedLexem))
                    {
                        var cd = CreateConstDefinition(ref _lastExtractedLexem);
                        var num = GetConstNumber(ref cd);
                        param.DefaultValueIndex = num;
                        NextToken();
                    }
                    else
                    {
                        throw CompilerException.UnexpectedOperation();
                    }
                }

                if (_lastExtractedLexem.Token == Token.Comma || _lastExtractedLexem.Token == Token.ClosePar)
                {
                    paramsList.Add(param);
                    methodCtx.DefineVariable(name);

                    if(_lastExtractedLexem.Token != Token.ClosePar)
                        NextToken();
                }
                else
                {
                    throw CompilerException.UnexpectedOperation();
                }
            }

            method.Params = paramsList.ToArray();

            #endregion

            NextToken();
            bool isExportedMethod = false;
            if (_lastExtractedLexem.Token == Token.Export)
            {
                isExportedMethod = true;
                NextToken();
            }

            #region Body
            // тело
            var entryPoint = _module.Code.Count;

            try
            {
                _ctx.PushScope(methodCtx);
                DispatchMethodBody();
            }
            finally
            {
                _ctx.PopScope();
            }
            var pop = PopStructureToken();

            var descriptor = new MethodDescriptor();
            descriptor.EntryPoint = entryPoint;
            descriptor.Signature = method;
            descriptor.VariableFrameSize = methodCtx.VariableCount;
            SymbolBinding binding;
            try
            {
                binding = _ctx.DefineMethod(method);
            }
            catch (CompilerException)
            {
                var exc = new CompilerException("Метод с таким именем уже определен: " + method.Name);
                exc.LineNumber = definitionLine;
                exc.Code = _parser.GetCodeLine(exc.LineNumber);
                throw exc;
            }
            _module.MethodRefs.Add(binding);
            _module.Methods.Add(descriptor);

            if (isExportedMethod)
            {
                _module.ExportedMethods.Add(new ExportedSymbol()
                {
                    SymbolicName = method.Name,
                    Index = binding.CodeIndex
                });
            }

            #endregion

            NextToken();
        }
예제 #7
0
 internal static CompilerException AppendCodeInfo(CompilerException exc, CodePositionInfo codePosInfo)
 {
     AppendCodeInfo(exc, codePosInfo.LineNumber, codePosInfo.Code);
     return exc;
 }
예제 #8
0
 internal static CompilerException AppendCodeInfo(CompilerException exc, int line, string codeString)
 {
     exc.LineNumber = line;
     exc.Code = codeString;
     return exc;
 }
예제 #9
0
            public void Build(Token stopToken)
            {
                const int STATE_UNDEF             = 0;
                const int STATE_OPERAND_EXPECTED  = 1;
                const int STATE_FUNC_WAIT         = 2;
                const int STATE_OPERATOR_EXPECTED = 3;

                _operators = new Stack <Token>();

                int    currentState      = STATE_UNDEF;
                string waitingIdentifier = null;
                int    parCount          = 0;

                while (true)
                {
                    bool success = false;

                    if (_compiler._lastExtractedLexem.Token == stopToken)
                    {
                        if (currentState == STATE_FUNC_WAIT)
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                        }
                        else if (currentState != STATE_OPERATOR_EXPECTED)
                        {
                            throw CompilerException.ExpressionSyntax();
                        }
                        break;
                    }

                    switch (currentState)
                    {
                    case STATE_UNDEF:
                    case STATE_OPERAND_EXPECTED:
                        if (_compiler.IsLiteral(ref _compiler._lastExtractedLexem))
                        {
                            _compiler.BuildPushConstant();
                            currentState = STATE_OPERATOR_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Type == LexemType.Identifier)
                        {
                            if (_compiler._lastExtractedLexem.Token == Token.NotAToken)
                            {
                                waitingIdentifier = _compiler._lastExtractedLexem.Content;
                                currentState      = STATE_FUNC_WAIT;
                                success           = true;
                            }
                            else if (LanguageDef.IsBuiltInFunction(_compiler._lastExtractedLexem.Token))
                            {
                                _compiler.BuildBuiltinFunction();
                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else if (_compiler._lastExtractedLexem.Token == Token.NewObject)
                            {
                                _compiler.BuildNewObjectCreation();
                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else
                            {
                                throw CompilerException.TokenExpected(stopToken);
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Minus)
                        {
                            PushOperator(Token.UnaryMinus);
                            currentState = STATE_OPERAND_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.OpenPar)
                        {
                            PushOperator(Token.OpenPar);
                            parCount++;
                            currentState = STATE_UNDEF;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Not)
                        {
                            PushOperator(Token.Not);
                            currentState = STATE_OPERAND_EXPECTED;
                            success      = true;
                        }

                        break;

                    case STATE_FUNC_WAIT:
                        if (_compiler._lastExtractedLexem.Token == Token.OpenPar)
                        {
                            _compiler.BuildFunctionCall(waitingIdentifier);
                            if (_compiler._lastExtractedLexem.Token == Token.ClosePar)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else if (_compiler._lastExtractedLexem.Type == LexemType.Operator)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                continue;
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.OpenBracket)
                        {
                            _compiler.BuildIndexedAccess(waitingIdentifier);
                            currentState = STATE_OPERATOR_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Dot)
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                            int identifier;
                            _compiler.BuildResolveChain(out identifier);
                            _compiler.ProcessResolvedItem(identifier, stopToken);

                            if (_compiler._lastExtractedLexem.Type == LexemType.Operator || _compiler._lastExtractedLexem.Token == stopToken)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                continue;
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Type == LexemType.Operator && IsBinaryOperator(_compiler._lastExtractedLexem.Token))
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                            currentState = STATE_OPERATOR_EXPECTED;
                            continue;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.ClosePar)
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                            currentState = STATE_OPERATOR_EXPECTED;
                            continue;
                        }

                        break;

                    case STATE_OPERATOR_EXPECTED:
                        if (_compiler._lastExtractedLexem.Type == LexemType.Operator && IsBinaryOperator(_compiler._lastExtractedLexem.Token))
                        {
                            ProcessExpressionOperator();
                            currentState = STATE_OPERAND_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.ClosePar)
                        {
                            Token current;
                            parCount--;
                            if (parCount < 0)
                            {
                                UnwindOperators();
                                var cp = new CodePositionInfo();
                                cp.LineNumber = _compiler._parser.CurrentLine;
                                cp.Code       = _compiler._parser.GetCodeLine(cp.LineNumber);
                                throw new ExtraClosedParenthesis(cp);
                            }

                            if (_operators.Count > 0)
                            {
                                while ((current = PopOperator()) != Token.OpenPar)
                                {
                                    AddCommandForToken(current);
                                    if (_operators.Count == 0)
                                    {
                                        throw CompilerException.TokenExpected(Token.OpenPar);
                                    }
                                }

                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else
                            {
                                throw CompilerException.TokenExpected(Token.OpenPar);
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.OpenBracket)
                        {
                            _compiler.NextToken();
                            _compiler.BuildExpression(Token.CloseBracket);
                            _compiler.AddCommand(OperationCode.PushIndexed, 0);
                            currentState = STATE_OPERATOR_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Dot)
                        {
                            int identifier;
                            _compiler.BuildResolveChain(out identifier);
                            _compiler.ProcessResolvedItem(identifier, stopToken);

                            if (_compiler._lastExtractedLexem.Type == LexemType.Operator || _compiler._lastExtractedLexem.Token == stopToken)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                continue;
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token != stopToken)
                        {
                            throw CompilerException.TokenExpected(stopToken);
                        }
                        break;
                    }

                    if (success)
                    {
                        if (_compiler._lastExtractedLexem.Token != stopToken)
                        {
                            _compiler.NextToken();
                        }
                    }
                    else
                    {
                        throw CompilerException.ExpressionSyntax();
                    }
                }

                UnwindOperators();
            }