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()); }
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())); } }
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); } }