예제 #1
0
파일: Parser.cs 프로젝트: sameerms/compiler
        private Expression ParseExpression()
        {
            Expression curExpression;

            if (GetCurToken().Equals("print"))
            {
                Print print = new Print();

                NextToken();
                print._Expr = GetCurTokenAsLiteral();

                curExpression = print;
            }
            else if (GetCurToken().Equals("var"))
            {
                DeclareVar declareVar = new DeclareVar();

                NextToken();
                declareVar.Identifier = GetCurTokenAsString();

                NextToken();
                if (!Arithmetic.Colon.Equals(GetCurToken()))
                    throw new System.Exception("expected : after 'var ident'");

                NextToken();
                if (!(GetCurToken() is String))
                    throw new System.Exception("expected var type (integer, float)");
                else
                {
                    String curToken = GetCurTokenAsString();
                    if (curToken.Equals("array", StringComparison.InvariantCultureIgnoreCase))
                    {
                        NextToken();
                        if (!Arithmetic.OpenSquareBracket.Equals(GetCurToken()) )
                            throw new System.Exception("Invalid Array Declaration");

                        NextToken();
                        if (!(GetCurToken() is Int32))
                            throw new System.Exception("Invalid Array Declaration");

                        NextToken();
                        if (!Arithmetic.DoubleDots.Equals(GetCurToken()))
                            throw new System.Exception("Invalid Array Declaration");

                        NextToken();
                        if (!(GetCurToken() is Int32))
                            throw new System.Exception("Invalid Array Declaration");

                        NextToken();
                        if (!Arithmetic.CloseSquareBracket.Equals(GetCurToken()))
                            throw new System.Exception("Invalid Array Declaration");

                        NextToken();
                        if (!GetCurToken().Equals("of"))
                            throw new System.Exception("Invalid Array Declaration");
                        /*
                            Added Token array, Type String
                            Added Token OpenSquareBracket, Type Arithmetic
                            Added Token 1, Type Int32
                            Added Token DoubleDots, Type Arithmetic
                            Added Token 5, Type Int32
                            Added Token CloseSquareBracket, Type Arithmetic
                            Added Token of, Type String
                            Added Token integer, Type String
                        */
                        NextToken();
                        declareVar.IdentifierType = GetCurTokenAsString();
                        declareVar.IsArray = true;
                    }
                    else
                    {
                        declareVar.IdentifierType = curToken;
                    }
                }

                curExpression = declareVar;
            }
            else if (GetCurToken().Equals("read_int"))
            {
                ReadInt readInt = new ReadInt();

                NextToken();
                if (!(GetCurToken() is String))
                    throw new System.Exception("expected var name after read_int");
                else
                    readInt._Identifier = GetCurTokenAsString();

                curExpression = readInt;
            }
            else if (GetCurToken().Equals("for"))
            {
                ForLoop forLoop = new ForLoop();

                //Get For Identifier followed by :-
                NextToken();
                if (!(GetCurToken() is String))
                    throw new System.Exception("expected identifier after 'for'");
                else
                    forLoop._Identifier = (String)GetCurToken();

                NextToken();
                if (!Arithmetic.Colon.Equals(GetCurToken()))
                    throw new System.Exception("for missing ': after for'");

                NextToken();
                if (!Arithmetic.Equal.Equals(GetCurToken()))
                    throw new System.Exception("for missing '=' after for");

                //Get x to y
                NextToken();
                forLoop._From = GetCurTokenAsLiteral();

                NextToken();
                if (!GetCurToken().Equals("to"))
                    throw new System.Exception("expected 'to' after for");

                NextToken();
                forLoop._To = GetCurTokenAsLiteral();

                //Begin do, begin
                NextToken();
                if (!GetCurToken().Equals("do"))
                    throw new System.Exception("expected 'do' after from expression in for loop");

                NextToken();
                if (!GetCurToken().Equals("begin"))
                    throw new System.Exception("expected 'begin' in for loop");

                //Get For Loop Body
                NextToken();
                forLoop._Body = ParseExpression();

                //Todo: Parse STatement probly increements Token
                //Get For Loop end
                if (_index == _tokens.Count || !GetCurToken().Equals("end"))
                    throw new System.Exception("unterminated 'for' loop body");

                curExpression = forLoop;
            }
            else if (GetCurToken() is String)
            {
                Assign assign = new Assign();
                assign._Identifier = GetCurTokenAsString();

                NextToken();
                if (!Arithmetic.Equal.Equals(GetCurToken()))
                    throw new System.Exception("Invalid Array Assignment");

                assign._Expression = GetCurTokenAsLiteral();

                curExpression = assign;
            }
            else
            {
                throw new System.Exception("parse error at token " + _index + ": " + GetCurToken());
            }

            NextToken();
            //Check for Graceful end of Line
            if (!Arithmetic.Semi.Equals(GetCurToken()))
                throw new Exception("Unterminated Statement ");

            //Check for End of Program, If program has not ended yet, Recurse....
            NextToken();
            if (_index == _tokens.Count || GetCurToken().Equals("end"))
                return curExpression;
            else
                return new LinkedList(curExpression, ParseExpression());
        }
예제 #2
0
        private Expression ParseExpression()
        {
            Expression curExpression;

            if (GetCurToken().Equals("print"))
            {
                Print print = new Print();

                NextToken();
                print._Expr = GetCurTokenAsLiteral();

                curExpression = print;
            }
            else if (GetCurToken().Equals("var"))
            {
                DeclareVar declareVar = new DeclareVar();

                NextToken();
                declareVar.Identifier = GetCurTokenAsString();

                NextToken();
                if (!Arithmetic.Colon.Equals(GetCurToken()))
                {
                    throw new System.Exception("expected : after 'var ident'");
                }

                NextToken();
                if (!(GetCurToken() is String))
                {
                    throw new System.Exception("expected var type (integer, float)");
                }
                else
                {
                    String curToken = GetCurTokenAsString();
                    if (curToken.Equals("array", StringComparison.InvariantCultureIgnoreCase))
                    {
                        NextToken();
                        if (!Arithmetic.OpenSquareBracket.Equals(GetCurToken()))
                        {
                            throw new System.Exception("Invalid Array Declaration");
                        }

                        NextToken();
                        if (!(GetCurToken() is Int32))
                        {
                            throw new System.Exception("Invalid Array Declaration");
                        }

                        NextToken();
                        if (!Arithmetic.DoubleDots.Equals(GetCurToken()))
                        {
                            throw new System.Exception("Invalid Array Declaration");
                        }

                        NextToken();
                        if (!(GetCurToken() is Int32))
                        {
                            throw new System.Exception("Invalid Array Declaration");
                        }

                        NextToken();
                        if (!Arithmetic.CloseSquareBracket.Equals(GetCurToken()))
                        {
                            throw new System.Exception("Invalid Array Declaration");
                        }

                        NextToken();
                        if (!GetCurToken().Equals("of"))
                        {
                            throw new System.Exception("Invalid Array Declaration");
                        }

                        /*
                         *  Added Token array, Type String
                         *  Added Token OpenSquareBracket, Type Arithmetic
                         *  Added Token 1, Type Int32
                         *  Added Token DoubleDots, Type Arithmetic
                         *  Added Token 5, Type Int32
                         *  Added Token CloseSquareBracket, Type Arithmetic
                         *  Added Token of, Type String
                         *  Added Token integer, Type String
                         */
                        NextToken();
                        declareVar.IdentifierType = GetCurTokenAsString();
                        declareVar.IsArray        = true;
                    }
                    else
                    {
                        declareVar.IdentifierType = curToken;
                    }
                }

                curExpression = declareVar;
            }
            else if (GetCurToken().Equals("read_int"))
            {
                ReadInt readInt = new ReadInt();

                NextToken();
                if (!(GetCurToken() is String))
                {
                    throw new System.Exception("expected var name after read_int");
                }
                else
                {
                    readInt._Identifier = GetCurTokenAsString();
                }

                curExpression = readInt;
            }
            else if (GetCurToken().Equals("for"))
            {
                ForLoop forLoop = new ForLoop();

                //Get For Identifier followed by :-
                NextToken();
                if (!(GetCurToken() is String))
                {
                    throw new System.Exception("expected identifier after 'for'");
                }
                else
                {
                    forLoop._Identifier = (String)GetCurToken();
                }

                NextToken();
                if (!Arithmetic.Colon.Equals(GetCurToken()))
                {
                    throw new System.Exception("for missing ': after for'");
                }

                NextToken();
                if (!Arithmetic.Equal.Equals(GetCurToken()))
                {
                    throw new System.Exception("for missing '=' after for");
                }

                //Get x to y
                NextToken();
                forLoop._From = GetCurTokenAsLiteral();

                NextToken();
                if (!GetCurToken().Equals("to"))
                {
                    throw new System.Exception("expected 'to' after for");
                }

                NextToken();
                forLoop._To = GetCurTokenAsLiteral();

                //Begin do, begin
                NextToken();
                if (!GetCurToken().Equals("do"))
                {
                    throw new System.Exception("expected 'do' after from expression in for loop");
                }

                NextToken();
                if (!GetCurToken().Equals("begin"))
                {
                    throw new System.Exception("expected 'begin' in for loop");
                }

                //Get For Loop Body
                NextToken();
                forLoop._Body = ParseExpression();

                //Todo: Parse STatement probly increements Token
                //Get For Loop end
                if (_index == _tokens.Count || !GetCurToken().Equals("end"))
                {
                    throw new System.Exception("unterminated 'for' loop body");
                }

                curExpression = forLoop;
            }
            else if (GetCurToken() is String)
            {
                Assign assign = new Assign();
                assign._Identifier = GetCurTokenAsString();

                NextToken();
                if (!Arithmetic.Equal.Equals(GetCurToken()))
                {
                    throw new System.Exception("Invalid Array Assignment");
                }

                assign._Expression = GetCurTokenAsLiteral();

                curExpression = assign;
            }
            else
            {
                throw new System.Exception("parse error at token " + _index + ": " + GetCurToken());
            }

            NextToken();
            //Check for Graceful end of Line
            if (!Arithmetic.Semi.Equals(GetCurToken()))
            {
                throw new Exception("Unterminated Statement ");
            }

            //Check for End of Program, If program has not ended yet, Recurse....
            NextToken();
            if (_index == _tokens.Count || GetCurToken().Equals("end"))
            {
                return(curExpression);
            }
            else
            {
                return(new LinkedList(curExpression, ParseExpression()));
            }
        }
예제 #3
0
        private void GenerateStatement(Expression pStatement, Type pExpectedType)
        {
            if (pStatement is DeclareVar)
            {
                DeclareVar curStmnt = (DeclareVar)pStatement;

                DeclareSymbolInTable(curStmnt.Identifier, curStmnt.GetSystemType());
            }
            else if (pStatement is ReadInt)
            {
                ReadInt curStmnt = (ReadInt)pStatement;

                _ilGenerator.Emit(Emit.OpCodes.Call, GetMSILMethod("ReadLine", typeof(String)));
                _ilGenerator.Emit(Emit.OpCodes.Call, GetMSILMethod("Parse", typeof(Int32)));

                ValidateSymbolType(curStmnt._Identifier, typeof(Int32));
                _ilGenerator.Emit(Emit.OpCodes.Stloc, GetValueFromSymbolTable(curStmnt._Identifier, -1));
            }
            else if (pStatement is StringLiteral)
            {
                StringLiteral curStmnt = (StringLiteral)pStatement;

                _ilGenerator.Emit(Emit.OpCodes.Ldstr, curStmnt._Value);

                if (pExpectedType != typeof(String))
                {
                    throw new Exception("can't coerce a " + typeof(Int32).Name + " to a " + pExpectedType.Name);
                }
            }
            else if (pStatement is IntLiteral)
            {
                IntLiteral curStmnt = (IntLiteral)pStatement;

                //Sample ASM:   IL_0001:  ldc.i4.3 (pushes 3 onto stack)
                _ilGenerator.Emit(Emit.OpCodes.Ldc_I4, curStmnt._Value);

                //Casting Possibility
                if (pExpectedType != typeof(Int32))
                {
                    if (pExpectedType == typeof(String))
                    {
                        _ilGenerator.Emit(Emit.OpCodes.Box, typeof(Int32));
                        _ilGenerator.Emit(Emit.OpCodes.Callvirt, GetMSILMethod("toString", null));
                    }
                    else
                    {
                        throw new Exception("can't coerce a " + typeof(Int32).Name + " to a " + pExpectedType.Name);
                    }
                }
            }
            else if (pStatement is Variable)
            {
                Variable curStmnt = (Variable)pStatement;

                _ilGenerator.Emit(Emit.OpCodes.Ldloc, GetValueFromSymbolTable(curStmnt._Identifier, -1));
                if (pExpectedType != TypeOfExpression(pStatement))
                {
                    if (TypeOfExpression(pStatement) == typeof(Int32) && pExpectedType == typeof(String))
                    {
                        _ilGenerator.Emit(Emit.OpCodes.Box, typeof(Int32));
                        _ilGenerator.Emit(Emit.OpCodes.Callvirt, GetMSILMethod("toString", null));
                    }
                    else
                    {
                        throw new Exception("can't coerce a " + TypeOfExpression(pStatement).Name +
                                            " to a " + pExpectedType.Name);
                    }
                }
            }
            else if (pStatement is LinkedList)
            {
                LinkedList seq = (LinkedList)pStatement;

                GenerateStatement(seq.First, null);
                GenerateStatement(seq.Second, null);
            }
            else if (pStatement is Assign)
            {
                //retrieve info about variable, including address, type
                //LHS addrs <--addr;
                //LHS type <-- type;
                //getToken();
                //match(TK_ASSIGN);

                //a = b+c;
                //push b
                //push c
                //add
                //pop a


                Assign curStmnt = (Assign)pStatement;

                GenerateStatement(curStmnt._Expression, TypeOfExpression(curStmnt._Expression));

                //ValidateSymbolType(curStmnt._Identifier, TypeOfExpression(curStmnt._Expression));
                //Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0.
                _ilGenerator.Emit(Emit.OpCodes.Stloc, GetValueFromSymbolTable(curStmnt._Identifier, -1));
            }
            else if (pStatement is Print)
            {
                Print curStmnt = (Print)pStatement;

                GenerateStatement(curStmnt._Expr, TypeOfExpression(curStmnt._Expr));
                _ilGenerator.Emit(Emit.OpCodes.Call, GetMSILMethod("Print", TypeOfExpression(curStmnt._Expr)));
            }
            else if (pStatement is ForLoop)
            {
                ForLoop curStmnt = (ForLoop)pStatement;

                Assign assign = new Assign(curStmnt._Identifier, curStmnt._From, -1);
                GenerateStatement(assign, null);

                // jump to the test
                Emit.Label test = _ilGenerator.DefineLabel();
                Emit.Label body = _ilGenerator.DefineLabel();

                _ilGenerator.Emit(Emit.OpCodes.Br, test);
                _ilGenerator.MarkLabel(body);

                GenerateStatement(curStmnt._Body, null);

                // to (increment the value of x)
                _ilGenerator.Emit(Emit.OpCodes.Ldloc, GetValueFromSymbolTable(curStmnt._Identifier, -1));
                _ilGenerator.Emit(Emit.OpCodes.Ldc_I4, 1);
                _ilGenerator.Emit(Emit.OpCodes.Add);

                ValidateSymbolType(curStmnt._Identifier, typeof(Int32));
                _ilGenerator.Emit(Emit.OpCodes.Stloc, GetValueFromSymbolTable(curStmnt._Identifier, -1));

                _ilGenerator.MarkLabel(test);
                _ilGenerator.Emit(Emit.OpCodes.Ldloc, GetValueFromSymbolTable(curStmnt._Identifier, -1));
                GenerateStatement(curStmnt._To, typeof(Int32));

                _ilGenerator.Emit(Emit.OpCodes.Blt, body);
            }
            else
            {
                throw new Exception("don't know how to generate a " + pStatement.GetType().Name);
            }
        }