Exemple #1
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()));
            }
        }
Exemple #2
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);
            }
        }