protected ObjectDef EmitInvoke(ITree invokeExpressionNode, ITree atSignNode, ITree functionNode, ITree argsExpressionNode) { var functionName = functionNode.Text; ObjectDef invokeObjectDef; MethodBuilder methodBuilder; string invokeObjectName; if (invokeExpressionNode != null) { invokeObjectDef = EmitExpression(invokeExpressionNode); invokeObjectName = invokeObjectDef.Type.Name; } else { invokeObjectDef = new ArgObjectDef(CurrentTypeBuilder_, 0, "this"); invokeObjectName = CurrentTypeBuilder_.Name; } ObjectDef result; if (!Functions_.ContainsKey(invokeObjectName) || !Functions_[invokeObjectName].ContainsKey(functionName)) { CompilerErrors.Add(new UndefinedFunctionError(functionName, invokeObjectName, CompilerErrors.Count, functionNode.Line, functionNode.CharPositionInLine)); result = LocalObjectDef.AllocateLocal(typeof(object)); } else { methodBuilder = Functions_[invokeObjectName][functionName].MethodBuilder; var args = new List <ObjectDef>(); args.Add(invokeObjectDef); if (argsExpressionNode != null) { for (int i = 0; i < argsExpressionNode.ChildCount; i++) { var objectDef = EmitExpression(argsExpressionNode.GetChild(i)); args.Add(objectDef); } List <ArgObjectDef> args2 = new List <ArgObjectDef>(); foreach (var arg in Functions_[invokeObjectDef.Type.Name][functionName].Args) { args2.Add(arg.Value); } if (!CheckTypes(args, args2)) { var args2types = new List <Type>(); foreach (var arg in args2) { args2types.Add(arg.Type); } CompilerErrors.Add(new FunctionArgumentsError(functionName, args2types, CompilerErrors.Count, functionNode.Line, functionNode.CharPositionInLine)); } } foreach (var arg in args) { arg.Load(); } if (invokeExpressionNode == null) { CurrentILGenerator_.Emit(OpCodes.Call, methodBuilder); } else { CurrentILGenerator_.Emit(OpCodes.Callvirt, methodBuilder); } foreach (var arg in args) { arg.Remove(); } invokeObjectDef.Remove(); if (functionNode.Parent.Parent.Type == CoolGrammarLexer.Exprs && functionNode.Parent.ChildIndex != functionNode.Parent.Parent.ChildCount - 1) { CurrentILGenerator_.Emit(OpCodes.Pop); result = new ValueObjectDef(Functions_[invokeObjectDef.Type.Name][functionName].MethodBuilder.ReturnType, null); } else { result = LocalObjectDef.AllocateLocal(Functions_[invokeObjectDef.Type.Name][functionName].MethodBuilder.ReturnType); } } return(result); }
protected ObjectDef EmitInvoke(ITree invokeExpressionNode, ITree atSignNode, ITree functionNode, ITree argsExpressionNode) { var functionName = functionNode.Text; ObjectDef invokeObjectDef; MethodBuilder methodBuilder; string invokeObjectName; if (invokeExpressionNode != null) { invokeObjectDef = EmitExpression(invokeExpressionNode); invokeObjectName = invokeObjectDef.Type.Name; } else { invokeObjectDef = new ArgObjectDef(CurrentTypeBuilder_, 0, "this"); invokeObjectName = CurrentTypeBuilder_.Name; } ObjectDef result; if (!Functions_.ContainsKey(invokeObjectName) || !Functions_[invokeObjectName].ContainsKey(functionName)) { CompilerErrors.Add(new UndefinedFunctionError(functionName, invokeObjectName, CompilerErrors.Count, functionNode.Line, functionNode.CharPositionInLine)); result = LocalObjectDef.AllocateLocal(typeof(object)); } else { methodBuilder = Functions_[invokeObjectName][functionName].MethodBuilder; var args = new List<ObjectDef>(); args.Add(invokeObjectDef); if (argsExpressionNode != null) { for (int i = 0; i < argsExpressionNode.ChildCount; i++) { var objectDef = EmitExpression(argsExpressionNode.GetChild(i)); args.Add(objectDef); } List<ArgObjectDef> args2 = new List<ArgObjectDef>(); foreach (var arg in Functions_[invokeObjectDef.Type.Name][functionName].Args) args2.Add(arg.Value); if (!CheckTypes(args, args2)) { var args2types = new List<Type>(); foreach (var arg in args2) args2types.Add(arg.Type); CompilerErrors.Add(new FunctionArgumentsError(functionName, args2types, CompilerErrors.Count, functionNode.Line, functionNode.CharPositionInLine)); } } foreach (var arg in args) arg.Load(); if (invokeExpressionNode == null) CurrentILGenerator_.Emit(OpCodes.Call, methodBuilder); else CurrentILGenerator_.Emit(OpCodes.Callvirt, methodBuilder); foreach (var arg in args) arg.Remove(); invokeObjectDef.Remove(); if (functionNode.Parent.Parent.Type == CoolGrammarLexer.Exprs && functionNode.Parent.ChildIndex != functionNode.Parent.Parent.ChildCount - 1) { CurrentILGenerator_.Emit(OpCodes.Pop); result = new ValueObjectDef(Functions_[invokeObjectDef.Type.Name][functionName].MethodBuilder.ReturnType, null); } else result = LocalObjectDef.AllocateLocal(Functions_[invokeObjectDef.Type.Name][functionName].MethodBuilder.ReturnType); } return result; }
protected ObjectDef EmitSelf(ITree expressionNode) { var result = new ArgObjectDef(CurrentTypeBuilder_, 0, "this"); return(result); }
protected ObjectDef EmitSelf(ITree expressionNode) { var result = new ArgObjectDef(CurrentTypeBuilder_, 0, "this"); return result; }