parallaxinc / OpenSpin

Spin/PASM compiler for the Parallax Propeller.
56 stars 19 forks source link

#define vs Newton and Schroedinger and his cat (Milton) #37

Open drawkula opened 7 years ago

drawkula commented 7 years ago

Newton has no cat (subobject):

$ cat Newton.spin 
#ifdef X
#warning X defined
#endif

#ifndef X
#warning X not defined
#endif

pub Newton

Compiling without defining X looks ok:

$ /opt/openspin/bin/openspin Newton.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Newton.spin
Newton.spin:6: warning: #warn:  X not defined
Done.
Program size is 28 bytes

Compiling with -D(-efining) X and with and without -a(-lternative preprocesor) looks ok too...

$ /opt/openspin/bin/openspin -D X Newton.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Newton.spin
Newton.spin:2: warning: #warn:  X defined
Done.
Program size is 28 bytes
$ /opt/openspin/bin/openspin -a -D X Newton.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Newton.spin
Newton.spin:2: warning: #warn:  X defined
Done.
Program size is 28 bytes

Now adding -u(-ncertainty):

$ /opt/openspin/bin/openspin -u -D X Newton.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Newton.spin
Newton.spin:2: warning: #warn:  X defined
Newton.spin:6: warning: #warn:  X not defined
Done.
Unused Method Elimination:
Nothing removed.
--------------------------
Program size is 28 bytes
$ /opt/openspin/bin/openspin -u -a -D X Newton.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Newton.spin
Newton.spin:2: warning: #warn:  X defined
Newton.spin:6: warning: #warn:  X not defined
Done.
Unused Method Elimination:
Nothing removed.
--------------------------
Program size is 28 bytes

But now for something not really completely different:

Schroedinger has a cat (subobject):

$ cat Schroedinger.spin 
#ifdef X
#warning X defined
#endif

#ifndef X
#warning X not defined
#endif

obj

  cat : "Milton"

pub Schroedinger
$ cat Milton.spin 
#ifdef X
#warning X defined
#endif

#ifndef X
#warning X not defined
#endif

pub Milton

Compiling without a define and without -u(-ncertainty):

$ /opt/openspin/bin/openspin Schroedinger.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Schroedinger.spin
Schroedinger.spin:6: warning: #warn:  X not defined
|-Milton.spin
Milton.spin:6: warning: #warn:  X not defined
Schroedinger.spin:6: warning: #warn:  X not defined
Done.
Program size is 44 bytes

Compiling with defining X and not using -u(-ncertainty):

$ /opt/openspin/bin/openspin -D X Schroedinger.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Schroedinger.spin
Schroedinger.spin:2: warning: #warn:  X defined
|-Milton.spin
Milton.spin:6: warning: #warn:  X not defined
Schroedinger.spin:6: warning: #warn:  X not defined
Done.
Program size is 44 bytes
$ /opt/openspin/bin/openspin -a -D X Schroedinger.spin 
Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.80 Compiled on Aug 15 2017 15:07:36
Compiling...
Schroedinger.spin
Schroedinger.spin:2: warning: #warn:  X defined
|-Milton.spin
Milton.spin:6: warning: #warn:  X not defined
Schroedinger.spin:6: warning: #warn:  X not defined
Done.
Program size is 44 bytes

This is confusing enough, so adding -u(-ncertainty) is not needed to make my head spin...

Meow!

Can please someone explain this to me without using quantum physics?

reltham commented 7 years ago

The first issue, when using the -u option, is because the compiler is compiling the code a second time when doing unused method removal, and it looks like it's not setting up the preprocessor correctly the second time. The second issue is showing a couple things, the first one is that child objects are not getting the preprocessor defines setup for their compile, and second parent objects get their first pass compile step redone after their child objects are compiled and it's not setting up the preprocessor properly when doing that. To have it only show the messages once per object instance, I'll need to add a "silent" mode for the second compiles of the same object instance.

Thanks for reporting this.

maccasoft commented 7 years ago

Looks like I have encountered the same issue, here: http://forums.parallax.com/discussion/167622/weird-issue-with-openspin-preprocessor

Examining the source code, seems that the definitions are cleared after each file is processed when calling pp_finish in GetPASCIISource so any included object will clear all definitions. The proposed patch removes the call to pp_clear_define_state from pp_finish which is called after each file is processed so the definitions are not cleared and adds a call to pp_clear_define_state to ShutdownCompiler to clear the memory. Any definition added by sub-objects are already cleared with a call to pp_restore_define_state in CompileRecursively so they will not be propagated to upper objects.

I think that a more correct patch should change pp_run to immediately return the text buffer and leave pp_finish at the end of the whole compile process, as the name implies.

issue-37-preprocessor.patch.txt

reltham commented 6 years ago

@maccasoft I have applied your proposed patch. This at least fixes the main bug here.

When using -u, there will still be double messages because it compiles twice.

Changing from bug to enhancement, since the bug should be fixed, and all that remains is cosmetic enhancement.