private TypeInfo BinaryOperatorVisit(BinaryOperator binaryOperator, MethodBuilder builder, Action <MethodBuilder> action, CodegenContext context) { Visit(binaryOperator.LeftOperand as dynamic, builder, context); var res = Visit(binaryOperator.RightOperand as dynamic, builder, context); action(builder); return(res); }
private TypeDescriptor TryToOverload(BinaryOperator node, TypeDescriptor leftType, TypeDescriptor rightType, Context context) { if (!leftType.IsObject || !operatorMethodsName.ContainsKey(node.Text)) { Log( String.Format("Оператор {0} не может применяться для типов {1} и {2}", node.Text, leftType.Type, rightType.Type), node); return(TypeDescriptor.Undefined); } var classType = leftType.Type as ClassType; var method = classType.GetMethod( operatorMethodsName[node.Text], new List <TypeInfo>() { rightType.Type }, false); if (method == null) { Log( String.Format("Оператор {0} не может применяться для типов {1} и {2}", node.Text, leftType.Type, rightType.Type), node); return(TypeDescriptor.Undefined); } var methodCallNode = new MethodCallNode( method.Name, node.LeftOperand, new List <BasicNode>() { node.RightOperand }); ReplaceNode(node.Parent as CommonTree, node.ChildIndex, methodCallNode); return(new TypeDescriptor(false, method.Ret, true)); }
private TypeDescriptor LogicOperator(BinaryOperator node, Context context) { var lOperand = Visit(node.LeftOperand as dynamic, context); var rOperand = Visit(node.RightOperand as dynamic, context); if (!TypeInfo.IsBool(lOperand.Type) || !TypeInfo.IsBool(rOperand.Type)) { return(TryToOverload(node, lOperand, rOperand, context)); } var type = Convert(lOperand.Type as SimpleType, rOperand.Type as SimpleType); if (!lOperand.Type.Equals(type)) { InsertCastNode(node, node.LeftOperand.ChildIndex, type); } if (!rOperand.Type.Equals(type)) { InsertCastNode(node, node.RightOperand.ChildIndex, type); } return(TypeDescriptor.Bool); }