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