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