#!/import/python-1.1/s41

import ilu, USENIX, USENIX__skel

# we need to hold onto objects until they are released
# by their users...
holdList = []
def hold(obj):
  global holdList
  holdList.append(obj)
  return obj

def CopyTape (oldtape):
	newtape = []
	for item in oldtape:
		newtape.append ({'kind': item['kind'], 'val': item['val']})
	return newtape

class Calculator_impl (USENIX__skel.Calculator):
	def __init__ (self):
		self.mem = None
		self.value = 0
		self.tape = []

	def Clear (self):
		self.tape.append({'kind': USENIX.OpType__Clear, 'val': None})
		self.value = 0

	def CurrentValue (self):
		return (float(self.value))

	def Add (self, value):
		self.tape.append({'kind': USENIX.OpType__Add, 'val': value})
		self.value = self.value + value

	def Subtract (self, value):
		self.tape.append({'kind': USENIX.OpType__Subtract, 'val': value})
		self.value = self.value - value

	def Multiply (self, value):
		self.tape.append({'kind': USENIX.OpType__Multiply, 'val': value})
		self.value = self.value * value

	def Divide (self, value):
		try:
			self.value = self.value / value
			self.tape.append({'kind': USENIX.OpType__Divide, 'val': value})
		except ZeroDivisionError:
			raise USENIX.ZeroDivisor

	def MemSet (self, value):
		self.tape.append({'kind': USENIX.OpType__MemSet, 'val': value})
		self.mem = value;

	def MemGet (self, value):
		if (self.mem == None):
			raise USENIX.NoValueInMemory
		return (self.mem)

	def MemAdd (self):
		if (self.mem == None):
			raise USENIX.NoValueInMemory
		self.tape.append({'kind': USENIX.OpType__MemAdd, 'val': None})
		self.value = self.value + self.mem
			
	def MemSubtract (self):
		if (self.mem == None):
			raise USENIX.NoValueInMemory
		self.tape.append({'kind': USENIX.OpType__MemSubtract, 'val': None})
		self.value = self.value - self.mem
			
	def MemMultiply (self):
		if (self.mem == None):
			raise USENIX.NoValueInMemory
		self.tape.append({'kind': USENIX.OpType__MemMultiply, 'val': None})
		self.value = self.value * self.mem
			
	def MemDivide (self):
		if (self.mem == None):
			raise USENIX.NoValueInMemory
		if (self.mem == 0):
			raise USENIX.ZeroDivisor
		self.tape.append({'kind': USENIX.OpType__MemDivide, 'val': None})
		self.value = self.value / self.mem
			
	def GetTape (self):
		return (CopyTape(self.tape))

class Factory_impl (USENIX__skel.Factory):
	def __init__ (self, server=None):
		self.IluInstHandle = "0"
		if server:
			self.IluServer = server
		else:
			self.IluServer = ilu.CreateServer("USENIX_Factory")

	def NewCalculator (self):
		newcalc = Calculator_impl()
		hold(newcalc)
		return newcalc

def main():
	the_factory = Factory_impl()
	the_factory.IluPublish()
	print the_factory.IluSBH()
	hold(the_factory)
	ilu.RunMainLoop()

main()
