figuring out: Output.printString('HELLO WORLD')

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

figuring out: Output.printString('HELLO WORLD')

froycard
This post was updated on .
Well, I am taking this course (NAND TO TETRIS II), and I am enjoying it, but I guess the Project 11, it is a very tough one, there is a lot of thing to be aware of in order to program a good VM compiler.

Anyway, I am stuck by implementing this line (this is just an example):

do Output.printString('HELLO WORLD\n')

(btw, I don't know if the \n -escape newline can be processed by the VM emulator)

If my compiler is about to parse and compile this line, I got this line from the XML compiling process:
<stringConstant> HELLO WORLD\n  </stringConstant>
so, I have reviewed the lessons, the book and the only thing I have so far found is this:

1. Construct a STRING by using the OS command:
       String.new(length)
2. Add each character to the string by using the OS command:
      String.appenChar(nextChar)

That's it...

My best guess out of this is to create a temporal variable where I saved the base address to the heap where the string (HELLO WORLD\n) will be saved, by using this command: temp = string.new(12)
then I am assuming I receive the base address from the above command (pop temp 0)
After this, I have to go into a WHILE loop to add each character from the string ('HELLO WORLD\n')
And then following this:
push temp 0
call Output.printString 1

.. I will print on the screen the famous phrase: HELLO WORLD

Maybe I am wrong about this procedure, but I like to know where I can find more info about this topic?

PS: Excuse my English anyway



Reply | Threaded
Open this post in threaded view
|

Re: figuring out: Output.printString(string)

cadet1620
Administrator
First, escape sequences are not supported in the Jack grammar.  You need to use Output.println() to display a newline.

There is a trick that lets you avoid using a temporary variable.

Go back to this post (where you caught my missing "constant" typos)

Because the String.new() constructor returns the 'this' for the new string on the stack, if you do not pop temp 0, the 'this' will be in the correct place to be the first argument to the String.append() call.

Because String.append() returns the 'this' that was passed to it, it can be repeatedly called without popping the return value or pushing 'this'.

Basically, this code just eliminates pairs of pop/push instructions that are popping a value off the stack and pushing the identical value back onto the stack.  Here's the code with those pops and pushes:
push 3
call String.new 1
pop temp 1          // temp 1 = string constant 'this'

push temp 1         // push 'this'
push constant 97
call String.append 1
pop temp 0          // throw away returned 'this'

...

push temp 1         // push 'this'
push constant 98
call String.append 1
pop temp 0          // throw away returned 'this'

push temp 1         // push 'this'
call Output.printString 1

--Mark