예제 #1
0
def program(env, p, heap = int( macros.HEAP_START ) ):

	if p == "End":
		return ( [], 0, heap )

	Tag = str( id( p ))
	for label in p:

		if label == "Print":
			exp = p[ label ][ 0 ]
			doc = [ "doc print " + str( exp )]
			(insts, heap, nextHeap) = expression( env, exp, heap )
			insts += macros.copy( heap, macros.OUTPUT_REG )
			( contInsts, resultLoc, nextHeap ) = program( env, p[ label ][ 1 ], nextHeap )
			return ( doc + insts + contInsts , resultLoc, nextHeap )

		if label == "Assign":
			a = p[ label ]
			varExp = a[ 1 ]
			varName = a[0][ "Variable"][ 0 ]
			if env.get( varName ) == None:
				heap = heap + 1
				varAddr = str( heap )
				env[ varName ] = varAddr
			else:
				varAddr = int( env[ varName ])
			(insts, resultAddr, nextHeap) = expression( env, varExp, heap )
			code = [ "doc assign "  + varName + str( varExp )]
			code += insts
			code += macros.copy( resultAddr, varAddr )
			(cont, resultAddr, nextHeap) = program( env, a[2], heap + 1 )
			return ( code + cont , resultAddr, nextHeap )

		if label == "Call":
			call = p[ label ]
			procName = call[0][ "Variable"][ 0 ]
			callCode = macros.call( procName, Tag)
			(rest_insts, rest_resultAddr, rest_nextHeap ) = program( env, call[ 1 ], heap )
			return ( callCode + rest_insts , rest_resultAddr, rest_nextHeap+1 )

		if label == "Procedure":
			proc = p[ label ]
			procName = proc[0][ "Variable"][ 0 ]
			(proc_insts, ignore, nextHeap ) = program( env, proc[ 1 ], heap )
			procCode = macros.procedure( procName, proc_insts )
			(rest_insts, rest_resultAddr, rest_nextHeap ) = program( env, proc[ 2 ], nextHeap )
			return ( procCode + rest_insts , rest_resultAddr, nextHeap+1 )

		if label == "If":
			ifs = p[ label ]
			
			(cond_insts, cond_resultAddr, cond_nextHeap ) = expression( env, ifs[ 0 ], heap )
			(ifTrue_insts, ifTrue_resultAddr, ifTrue_nextHeap ) = program( env, ifs[ 1 ], cond_nextHeap )
			(rest_insts, rest_resultAddr, rest_nextHeap ) = program( env, ifs[ 2 ], ifTrue_nextHeap )

			insts = [ 'doc ' + 'if (' + str( ifs[ 0 ]) + ' ... ']
			insts += cond_insts
			insts += macros.copy( cond_resultAddr, macros.ADD_RESULT )
			insts += [ 'branch ' + 'ifTrue_' + Tag + ' ' + macros.ADD_RESULT ]
			insts += [ 'goto ' + 'ifFalse_' + Tag ]
			insts += [ 'label ' + 'ifTrue_' + Tag ]
			insts += ifTrue_insts
			insts += [ 'label ' + 'ifFalse_' + Tag ]
			insts += rest_insts

			return ( insts, rest_resultAddr, rest_nextHeap + 1 )
예제 #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 )