Writing a primitive test first in Exupery

bryce at kampjes.demon.co.uk bryce at kampjes.demon.co.uk
Tue Jun 26 20:26:08 UTC 2007


Yakov Zaytsev writes:
 >  > Now look at IntermediateSimplifierTests>>testAtPrimitive. Use
 >  > this as an example to write a test for the "^ true" primitive.
 > 
 > IntermediateSimplifierTests >>testAtPrimitive
 > 	source := MedMethod
 > 				createIntermediate:
 > 					#((block 1  (primitive 60 Array block2 receiver arg1) ))
 > 				for: machine.			
 > 	mockEmitter expectEmission:
 > 		#((block1
 > 				(mov arg1 t1) "Index"
 > 				(mov receiver t2)	"receiver"
 > 				(addressOfIndexedElement t2 t1 block2))
 > 			(block2)).
 > 	...

What's literally happening in the test above is a method is created
from the first array literal by IntermediateCreator. A mock is set
up from the second array literal ("#((block1 ..."), the mock then
tests that Intermediate simplifier makes the corresponding calls to
(Mock)IntermediateEmitter.

The #expectEmission: really programs the mock to expect a series of
calls. #addressOfIndexedElement is a call to IntermediateEmitter, not
a piece of intermediate, IntermediateEmitter expands it into several
low level intermediate expressions.

The tests create both an input method using #createIntermediate:for:
and a mock that's responsible for most of the testing. Once both are
created then the IntermediateSimplifier is called. If it calls the
wrong method on IntermediateEmitter an assertion fails bringing up a
debugger. This makes it easy to write code during a failing test
in the debugger because chances are the method to change is in the
back trace.

 > 
 > It was discovered that createIntermediate:for: is connected with  
 > IntermediateCreator>>createBlock and friends... In order  
 > testTruePrimitive to be written, it's needed to be known how to write  
 > such arrays
 > 				#((block 1  (primitive 60 Array block2 receiver arg1) ))
 > 
 > Talking about MockIntermediateEmitter. Is this a pidgin assembler  
 > stateements
 > 				(mov arg1 t1) "Index"
 > 				(mov receiver t2)	"receiver"
 > 				(addressOfIndexedElement t2 t1 block2))
 > There's MockIntermediateEmitter>>addressOfIndexedElement:at:failTo:  
 > which probably is connected with
 > 				(addressOfIndexedElement t2 t1 block2))
 > ..but there's no something similar to mov...

Neither the input intermediate nor the output intermediate are
assembly. Both are register transfer languages. The output
intermediate (low level intermediate) is below assembly, it's
translated into assembly by the instruction selector. The instruction
selector matches patterns of low level intermediate to create a single
instruction.

To perform an addition and store the result in a register in low level
intermediate "(mov (add 10 20) resultRegister)" is used.

Bryce


More information about the Exupery mailing list