Exemple #1
0
def formula(env, f, heap = int( macros.HEAP_START ) ):
	tag = str( id( f ))
	if type(f) == Leaf:
		if f == 'True':
			# Find a new memory address on the heap.
			heap = heap + 1
			# Generate instruction to store the integer representing True on the heap.
			inst = 'set ' + str(heap) + ' 1'
			# Return the instruction list and top of the heap.
			return ([inst], heap,  heap + 1 )

		if f == 'False':
			# Find a new memory address on the heap.
			heap = heap + 1
			# Generate instruction to store the integer representing False on the heap.
			inst = 'set ' + str(heap) + ' 0'
			# Return the instruction list and top of the heap.
			return ([inst], heap, heap + 1)

	if type(f) == Node:
		for label in f:
			children = f[label]

			if label == "Variable":
				varName = children[ 0 ]
				varAddr = env[ varName ]
				instsVar = [ 'doc  value of ' + varName + ' addr = ' + str( varAddr )]
				instsVar += macros.copy( varAddr, heap )

				return ( instsVar, heap, heap + 1)



			if label == 'Not':
				# Compile the subtree f to obtain the list of
				# instructions that computes the value represented
				# by f.
				f = children[0]
				(insts, heap, nextHeap) = formula( env, f, heap )
				# Generate more instructions to change the memory
				# location in accordance with the definition of the
				# Not operation.
				instsNot = \
					["branch setZero" + tag + " " + str(heap),\
					"set " + str(heap) + " 1",\
					"goto finish" + tag,\
					"label setZero" + tag,\
					"set " + str(heap) + " 0",\
					"label finish" + tag\
					]
				return (insts + instsNot, heap, heap+1)

			if label == 'Or':
				# Compile the two subtrees and get the instructions
				# lists as well as the addresses in which the results
				# of computing the two subtrees would be stored if someone
				# were to run those machine instructions.
				f1 = children[0]
				f2 = children[1]
				(insts1, leftResult, nextHeap) = formula( env, f1, heap )
				(insts2, rightResult, nextHeap) = formula( env, f2, nextHeap )
				# Increment the heap counter so we store the
				# result of computing Or in a new location.
				heap4 = nextHeap + 1
				# Add instructions that compute the result of the
				# Or operation.

				instsOr = macros.add( leftResult, rightResult, macros.ADD_RESULT )

				instsOr += [\
					"branch setOne" + tag + " 0",\
					"goto finish" + tag,\
					"label setOne" + tag,\
					"set " + macros.ADD_RESULT + " 1",\
					"label finish" + tag,\
					]
				instsOr += macros.copy( "0", str( heap4 ) )
				return (insts1 + insts2 + instsOr, heap4, heap4+1)

			if label == 'And':
				# adding left and right results: true == 1 and false == 0
				# false + false == 0  : and -> 0
				# false + true == 1 : and -> 0
				# true + false == 1 : and -> 0
				# true + true == 2 : and -> 1

				# so 0->0, 1->0, 2->1
				# we generate 

				# goto zero
				# goto zero
				# goto one

				# and we jump based on the result of adding the children of And

				# Compile the two subtrees and get the instructions
				# lists as well as the addresses in which the results
				# of computing the two subtrees would be stored if someone
				# were to run those machine instructions.
				f1 = children[0]
				f2 = children[1]
				(insts1, leftResult, nextHeap) = formula( env, f1, heap )
				(insts2, rightResult, nextHeap) = formula( env,f2, nextHeap )
				# Increment the heap counter so we store the
				# result of computing And in a new location.
				heap4 = nextHeap + 1
				heap5 = heap4 + 1
				# Add instructions that compute the result of the
				# Or operation.

				instsAnd = macros.add( leftResult, rightResult, heap4 )
				instsAnd += macros.relativeJump( heap4 )

				instsAnd += [\
					"goto zero" + tag,\
					"goto zero" + tag,\
					"goto one" + tag,\
					"label zero" + tag,\
					"set " + macros.ADD_RESULT + " 0",\
					"goto finish" + tag,\
					"label one" + tag,\
					"set " + macros.ADD_RESULT + " 1",\
					"label finish" + tag,\
					]
				instsAnd += macros.copy( "0", str( heap5 ) )
				return (insts1 + insts2 + instsAnd, heap5, heap5 + 1)
Exemple #2
0
def macroTests():

	testRelJump = '''
	set 200 0
	set 100 3
	''' + toStr( macros.relativeJump( 100 ) ) + '''
	set 200 1
	goto finish
	set 200 2
	goto finish
	set 200 3
	goto finish
	label finish
	assert 200 2
	'''
	test( testRelJump )


	testCopy = '''
	set 100 1
	''' + toStr( macros.copy( 100, 200 ) ) + '''
	assert 200 1
	'''
	test( testCopy )

	testAdd = '''
	set 100 1000
	set 101 2000
	''' + toStr( macros.add( 100, 101, 102 ) ) + '''
	assert 102 3000
	'''

	test( testAdd )

	testIncr = '''
	set 100 2000
	set 200 2000
	''' + toStr( macros.incrementBy( 100, 1 ) ) + '''
	''' + toStr( macros.incrementBy( 200, -1 ) ) + '''
	assert 100 2001
	assert 200 1999
	'''
	test( testIncr )

	testDeref = '''
	set 100 200
	set 200 1000
	set 300 0 
	''' + toStr( macros.deref( 100, 300 ) ) + '''
	assert 300 1000
	'''
	test( testDeref )

	testIndirectSet = '''
	set 100 101
	set 101 1000
	set 200 201
	set 201 0
	''' + toStr( macros.indirectSet( 100, 200 ) ) + '''
	assert 201 1000
	'''
	test( testIndirectSet )

	testIndirectSetLiteral = '''
	set 100 200
	set 200 0
	''' + toStr( macros.indirectSetLiteral( 100, 123 ) ) + '''
	assert 200 123
	'''
	test( testIndirectSet )

	testIndirectIncrement = '''
	set 100 101
	set 101 1000
	''' + toStr( macros.indirectIncrement( 100, 50 ) ) + '''
	assert 101 1050
	'''
	test( testIndirectIncrement )


	testIndirectIncrement = '''
	set 100 101
	set 101 1000
	''' + toStr( macros.indirectIncrement( 100, 50 ) ) + '''
	assert 101 1050
	'''
	test( testIndirectIncrement )

	testStack = '''
	set 100 2222
	set 200 0
	''' + toStr( macros.push( 100 ) ) + '''
	assert -1 2222
	''' + toStr( macros.pop( 200 ) ) + '''
	doc assert 200 2222
	''' + toStr( macros.pushLiteral( 10 ) ) + '''
	assert -1 10
	'''+ toStr( macros.pushLiteral( 4 ) ) + '''
	assert -2 4
	'''+ toStr( macros.pop( 100 ) ) + '''
	assert 100 4
	'''+ toStr( macros.pop( 200 ) ) + '''
	assert 200 10
	'''
	test( testStack )

	pcall = '''
	''' + toStr( macros.procedure( "foo", [ 'set 300 1 ', 'set 301 2'])) + '''
	''' + toStr( macros.call( "foo", "blah" ) ) + '''
	assert 300 1
	assert 301 2
	'''
	test( pcall )