Math.init() can't be called?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Math.init() can't be called?

throwinshapes
I'm just starting on project 12. Following the suggestion from the book, I am trying to build an array within the Math.init() function. However, I can't seem to figure out how to get Math.init() to run.

If I try to call Math.init(), the online compiler errors out stating 'Math' doesn't have a subroutine called 'init', even if I try to call it within Math.jack. Is this some issue with trying to override the built in implementation? If I look into the MathTest folder, none of those files call Math.init()...
Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

pm100
Math.init is called by system.init. you don't need to call it
Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

throwinshapes
This post was updated on .
I thought that would be the case initially, but if I insert a simple "do Output.printInt(0);" into Math.init(), I don't get any display.

This is being run in a folder with just Math.jack and a Main.jack. There is no Sys.jack, so the I am not overriding the built in implementation of Sys.

EDIT: This is interesting, the above was on the online IDE. On the Windows VM Emulator, I can see Math.init() being called, but the Output.printInit() causes an error "The built-in implementation of printInt caused an exception: java.lang.NullPointerException"
Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

dolomiti7
The convention of the Hack system is that the bootstrap calls Sys.init() and Sys.init calls the init() functions of all static OS classes. Which means, at the point when Sys.init is called, none of the OS classes that require initialization is ready to go. I.e. if you would put a call to Output.printString inside Sys.init before Output.init was called, it will fail.

Now think about the dependencies of the different OS classes. In order to calculate (shift) the character bitmaps, the Output class may require multiplication - which may only work properly once Math has been initialized. And for sure it requires to allocate Memory to store the charset which requires Memory to be initialized. If Math.init() is using lookup tables, it needs to reserve memory as well - which again will only work properly once Memory has been initialized. Thus, the order of initialization is relevant. If you follow the above logic, it is not possible to place calls to Output inside Math.init or Memory.init. Therefore the typical order of initialization is Memory, Math, Output, Screen, Keyboard.

Having said that, the actual reaction of an emulator may vary. The Java based tools have internal replacements for all OS routines which will be loaded if the respective VM file of the OS wasn't found. I am not sure about the exact implementation, but depending on which VM files you put into the folder, it may or may not work to place calls to Output inside Math.init. Because of the above reasons, it is generally not a good idea though. If you want to debug Math.init, the better approach is to execute the program step by step in the VM emulator. Additionally, you could temporarily place Memory.poke statements to write debug information somewhere into the upper part of the memory (i.e. 16000, or 2000 assuming that the stack will never go that high).

Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

throwinshapes
That makes complete sense now. Thanks for the detailed response!
Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

throwinshapes
I think I still have a problem though - I'd like to include a helper function in Math.jack, that does the lookup for if a bit in a given position is one (used in multiply).

If I try to include a new function in Math.jack, I get an error in the online compiler "Class Math doesn't contain a subroutine isBitOne". I have attempted to define this helper function in Math.jack, as "function boolean isBitOne(int x, int i)". It feels like the online compiler is not recognizing that I am trying to overwrite the built-in implementation.
Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

dolomiti7
This seems to be a bug(or features?) in the web-ide. Though the web-based tools are the right way to go, I still feel that the new tools have been published prematurely. The compiler seems to rely on the API of the internal built-in routines for OS classes, and ignores whatever additional functions have been implemented in the class. If you rename your class (and all internal and external references) to Math2 instead of Math, it should work.

In the Java-based tools it should work without problems.

I did a quick test, and even trying to call Memory.init or Math.init from Sys.init resulted in an error message.  I'll raise a ticket about this.
Reply | Threaded
Open this post in threaded view
|

Re: Math.init() can't be called?

throwinshapes
Thanks, right. If I compile and run locally it works fine. But that's on my own compiler.

It's been a lot of switching back and forth online/local:
-The above issue on the online compiler
-The online VM emulator doesn't always update when browsing local files
-The offline VM emulator doesn't ignore whitespace correctly
-I have not been able to get the supplied offline compiler running on my machine.