//
//  EXPUnaryOp.m
//  Expression
//
//  Created by Ashley on 28/02/2006.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "EXPExpression.h"
#import "EXPConstant.h"
#import "EXPUnaryOp.h"
#import "EXPVirtualMachine.h"
//#import "EXPAssemblerConstants.h"
#import "EXPError.h"

static int _numEXPUnaryOps = 0;

@implementation EXPUnaryOp

+ (int) numEXPUnaryOps
{
	return _numEXPUnaryOps;
}

- (id) initOp:(id)name withLeft:(id)left
{
	[super init];
	_name = [name retain];
	[self setLeft:left];
	[self storeIndices];
	_numEXPUnaryOps++;
	return self;
}

- (void) setLeft:(id)left
{
	[left retain];
	[_left release];
	_left = left;
	[self storeIndices];
}

- (id) left
{
	return _left;
}

- (void) storeIndices
{
	EXPExpression *left = [self left];
	NSArray *indices = [[NSArray alloc] initWithArray:[left indices]];
	[self setIndices:indices];
	[indices release];
}

- (NSString *)elementType
{
	return @"unaryop";
}

- (void) coerceLeft:(EXPExpressionType)newType
{
	EXPExpression *exp = [self left];
	if ([[exp elementType] isEqualToString:@"constant"]) {
		EXPConstant *left = (EXPConstant *)exp;
		[left setExpressionType:newType];
	} else {
		NSString *opName;
		if (newType==doubleType) {
			opName = @"float";
		} else {
			opName = @"int";
		}
		EXPUnaryOp *doubleOp = [[EXPUnaryOp alloc] initOp:opName withLeft:exp];
		[doubleOp setExpressionType:doubleType];
		[self setLeft:doubleOp];
		[doubleOp release];
	}
}

- (id) name
{
	return _name;
}

- (NSString *)description
{
	return [NSString stringWithFormat:@"%@(%@)", [self name], [[self left] description]];
}

/*- (BOOL) compile:(EXPVirtualMachine *)machine error:(EXPError *)err
{
	EXPExpression *left = [self left];
	BOOL success =[left compile:machine error:err];
	[machine putOpcode:NEGA mode:FLTPOINT];
	return success;
} */

- (double) result
{
	return -[_left result];
}

- (void) dump
{
	[super dump];
	[[self left] dump];
}

- (void) dealloc
{
//	printf("EXPUnaryOp - (void)dealloc\n");
	[_left release];
	[_name release];
	_numEXPUnaryOps--;
	[super dealloc];
}

@end

/*@implementation EXPUnaryNot

- (NSString *)description
{
	return [NSString stringWithFormat:@"!(%@)", [[self left] description]];
}

- (double) result
{
	return ![[self left] result];
}

@end

@implementation EXPUnaryPostIncrement

- (NSString *)description
{
	return [NSString stringWithFormat:@"%@++", [[self left] description]];
}

@end

@implementation EXPUnaryPreIncrement

- (NSString *)description
{
	return [NSString stringWithFormat:@"++%@", [[self left] description]];
}

@end */