private void EmitReadCall(CallStmt call) { var il = CurrentMethodIL; foreach (VariableExpr argument in call.Arguments) { il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine", Type.EmptyTypes)); if (argument.Type.SameAs(TypeInfo.BasicInt)) { il.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", new Type[] { typeof(string) })); } else if (argument.Type.SameAs(TypeInfo.BasicReal)) { il.Emit(OpCodes.Call, typeof(double).GetMethod("Parse", new Type[] { typeof(string) })); } else if (argument.Type.SameAs(TypeInfo.BasicBool)) { il.Emit(OpCodes.Call, typeof(bool).GetMethod("Parse", new Type[] { typeof(string) })); } var varSymbol = argument.VariableSymbol; if (varSymbol is GlobalSymbol) { var globalVar = varSymbol as GlobalSymbol; CurrentMethodIL.Emit(OpCodes.Stsfld, globalVar.CILField); } else if (varSymbol is VariableSymbol) { var localVar = varSymbol as VariableSymbol; CurrentMethodIL.Emit(OpCodes.Stloc, localVar.CILLocal); } } }
private void EmitPrintCall(CallStmt call) { var il = CurrentMethodIL; if (call.Arguments.Count > 0) { var paramsArr = il.DeclareLocal(typeof(object[])); il.Emit(OpCodes.Ldc_I4, call.Arguments.Count); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, paramsArr); int index = 0; foreach (var argument in call.Arguments) { il.Emit(OpCodes.Ldloc, paramsArr); il.Emit(OpCodes.Ldc_I4, index); Visit((dynamic)argument); il.Emit(OpCodes.Box, argument.Type.CILType); il.Emit(OpCodes.Stelem_Ref); index++; } il.Emit(OpCodes.Ldstr, " "); il.Emit(OpCodes.Ldloc, paramsArr); il.Emit(OpCodes.Call, typeof(string).GetMethod("Join", new Type[] { typeof(string), typeof(object[]) })); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); } else { il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", Type.EmptyTypes)); } }
private void Visit(CallStmt call) { var il = CurrentMethodIL; Symbol callee = call.DeclarationSymbol; if (callee.Predefined && callee.Name == "writeln") { EmitPrintCall(call); } else if (callee.Predefined && callee.Name == "read") { EmitReadCall(call); } else { foreach (var argument in call.Arguments) { Visit((dynamic)argument); } il.Emit(OpCodes.Call, call.DeclarationSymbol.CILMethod); if (!call.DeclarationSymbol.Type.SameAs(TypeInfo.BasicVoid)) { il.Emit(OpCodes.Pop); } } }
private CallStmt ParseCall() { Match(TokenType.Identifier); CallStmt call = new CallStmt(AcceptedToken); call.ProcedureId = AcceptedToken.Content; Match(TokenType.LParen); call.Arguments = ParseArguments(); Match(TokenType.RParen); return(call); }
private void Visit(CallStmt call) { var symbol = call.DeclarationSymbol; foreach (var freeSym in symbol.FreeVariables) { call.Arguments.Add(new VariableExpr(0, 0, freeSym.Name)); if (freeSym is VariableSymbol) { var varSym = freeSym as VariableSymbol; } } }
private void Visit(CallStmt callStmt) { Symbol callSymbol = Symbols.Lookup(callStmt.ProcedureId); if (callSymbol == null) { AddError(string.Format("Undeclared procedure '{0}'", callStmt.ProcedureId), callStmt); return; } if (!(callSymbol is FunctionSymbol) && !(callSymbol is ProcedureSymbol)) { AddError(string.Format("'{0}' is not defined as a function or a procedure", callStmt.ProcedureId), callStmt); return; } callStmt.DeclarationSymbol = callSymbol as CallableSymbol; CheckCallParameters(callStmt, callStmt.Arguments, callSymbol as CallableSymbol); }