public override AstNode Visit(UnaryOperation node) { // Remove the nop expression. if(node.GetOperation() == UnaryOperation.OpNop) return node.GetExpression(); // Process the base expression. Expression expr = node.GetExpression(); expr = (Expression)expr.Accept(this); node.SetExpression(expr); // Get the node type. IChelaType nodeType = node.GetNodeType(); if(!nodeType.IsConstant()) return node; // Perform the base coercion. ConstantValue baseConstant = (ConstantValue)expr.GetNodeValue(); IChelaType baseType = expr.GetNodeType(); IChelaType baseCoercion = node.GetCoercionType(); if(baseType != baseCoercion) baseConstant = baseConstant.Cast(baseCoercion); // Perform the constant operation. ConstantValue res = null; switch(node.GetOperation()) { case UnaryOperation.OpNop: res = baseConstant; break; case UnaryOperation.OpNeg: res = -baseConstant; break; case UnaryOperation.OpNot: res = !baseConstant; break; case UnaryOperation.OpBitNot: res = ~baseConstant; break; } return res.ToAstNode(node.GetPosition()); }
public override AstNode Visit(UnaryOperation node) { // Visit recursively. node.GetExpression().Accept(this); return node; }
public override AstNode Visit(UnaryOperation node) { // Begin the node. builder.BeginNode(node); // Evaluate first the expression. Expression expr = node.GetExpression(); expr.Accept(this); // Perform coercion. IChelaType exprType = expr.GetNodeType(); IChelaType coercionType = node.GetCoercionType(); if(exprType != coercionType) Cast(node, expr.GetNodeValue(), exprType, coercionType); // Perform the operation. switch(node.GetOperation()) { case UnaryOperation.OpNop: // Do nothing. break; case UnaryOperation.OpNeg: builder.CreateNeg(); break; case UnaryOperation.OpNot: case UnaryOperation.OpBitNot: builder.CreateNot(); break; } return builder.EndNode(); }
public override AstNode Visit(UnaryOperation node) { // Get the expression. Expression expr = node.GetExpression(); // Visit the expression. expr.Accept(this); // Get the expression type. IChelaType type = expr.GetNodeType(); // Dereference the type. type = DeReferenceType(type); node.SetCoercionType(type); // De-const the type. type = DeConstType(type); // Validate the expression type. switch(node.GetOperation()) { case UnaryOperation.OpNop: break; case UnaryOperation.OpNeg: if(!type.IsNumber()) Error(node, "expected numeric expression."); // Use signed integer when negating. if(type.IsInteger() && !type.IsPlaceHolderType()) { IntegerType intType = (IntegerType)type; intType = intType.GetSignedVersion(); if(node.GetCoercionType().IsConstant()) node.SetCoercionType(ConstantType.Create(intType)); else node.SetCoercionType(intType); } break; case UnaryOperation.OpNot: if(type != ChelaType.GetBoolType()) Error(node, "expected boolean expression."); break; case UnaryOperation.OpBitNot: if(!type.IsInteger()) Error(node, "expected integer expression."); break; default: Error(node, "Compiler bug, unknown unary operation."); break; } // Set the node type. node.SetNodeType(node.GetCoercionType()); return node; }