[squeak-dev] Failing Decompiler tests - how to fix?

Frank Shearar frank.shearar at angband.za.org
Tue Dec 21 11:07:31 UTC 2010


One of the failing Decompiler tests is when we check 
MethodPragmaTest>>testCompileCharacter:

testCompileCharacter
	self assertPragma: 'foo: $a' givesKeyword: #foo: arguments: #( $a ).
	self assertPragma: 'foo: $ ' givesKeyword: #foo: arguments: #( $  ).

As bytecodes, this method looks like this:

37 <70> self
38 <21> pushConstant: 'foo: $a'
39 <22> pushConstant: #foo:
40 <23> pushConstant: #($a)
41 <83 60> send: assertPragma:givesKeyword:arguments:
43 <87> pop
44 <70> self
45 <24> pushConstant: 'foo: $ '
46 <22> pushConstant: #foo:
47 <25> pushConstant: {Character space}
48 <83 60> send: assertPragma:givesKeyword:arguments:
50 <87> pop
51 <78> returnSelf

And when decompiled, we have:

testCompileCharacter
	self
		assertPragma: 'foo: $a'
		givesKeyword: #foo:
		arguments: #($a ).
	self
		assertPragma: 'foo: $ '
		givesKeyword: #foo:
		arguments: ((Array new: 1) at: 1 put: Character space; yourself)

Notice that the literal #( $  ) has expanded into an Array declaration etc.

When we compile this decompiled string, we end up with the rather different

	self
	pushConstant: ''foo: $a''
	pushConstant: #foo:
	pushConstant: #($a)
	send: #assertPragma:givesKeyword:arguments: (3 args)
	pop
	self
	pushConstant: ''foo: $ ''
	pushConstant: #foo:
	pushLit: Array
	pushConstant: 1
	send: #new: (1 arg)
	dup
	pushConstant: 1
	pushLit: Character
	send: #space (0 args)
	send: #at:put: (2 args)
	pop
	send: #yourself (0 args)
	send: #assertPragma:givesKeyword:arguments: (3 args)
	pop
	returnSelf

The decompiler turns that pushConstant: into a whole bunch of stuff 
because it interprets #( $  ) as (Array new: 1) at: 1 put: Character 
space; yourself.

(The same thing happens for SyntaxMorph>>replaceSel:menuItem: and 
SyntaxMorph>>replaceKeyWord:menuItem. It looks like $  is being 
interpreted as Character space, and then decompiled to pushLit: 
Character send: #space.)

That's all fine, but what happens is that when you compile the 
decompiled method (and then decompile _that_ method), you can't have the 
newly-decompiled method match the original decompiled method. The parse 
tree are different: where the original has a LiteralNode, the new 
version has a CascadeNode.

frank



More information about the Squeak-dev mailing list