1) There must always be a
comp component in every C-instruction. The presence of the
jump component is indicated by the ";". Similarly, the presence of the
dest component is indicated by the presence of the "=".
2a) /* */ comments are not valid syntax for Hack assembly language; you only need to deal with end-of-line comments that begin with "//". You may support /* */ comments if you wish, but they add a bit of work to the Parser.
An easy way to deal with blank lines or lines that only have a comment is to have your Parser module's commandType() return NO_COMMAND for those lines. Then your Pass1 and Pass2 main loops can simply ignore these lines.
2b)
Line numbers are irrelevant; what's important is the code address. The code address starts at 0 and is incremented for any line that generates code -- A_COMMAND and C_COMMAND only. The code address for labels is what you need to use as the value in A-commands.
Here's Max.asm showing line number, code address, and generated code (address and code in hexadecimal).
1 // This file is part of the materials accompanying the book
2 // "The Elements of Computing Systems" by Nisan and Schocken,
3 // MIT Press. Book site: www.idc.ac.il/tecs
4 // File name: projects/06/max/Max.asm
5
6 // Computes M[2] = max(M[0], M[1]) where M stands for RAM
7 0000 0000 @0
8 0001 FC10 D=M // D=first number
9 0002 0001 @1
10 0003 F4D0 D=D-M // D=first number - second number
11 0004 000A @OUTPUT_FIRST
12 0005 E301 D;JGT // if D>0 (first is greater) goto output_first
13 0006 0001 @1
14 0007 FC10 D=M // D=second number
15 0008 000C @OUTPUT_D
16 0009 EA87 0;JMP // goto output_d
17 000A (OUTPUT_FIRST)
18 000A 0000 @0
19 000B FC10 D=M // D=first number
20 000C (OUTPUT_D)
21 000C 0002 @2
22 000D E308 M=D // M[2]=D (greatest number)
23 000E (INFINITE_LOOP)
24 000E 000E @INFINITE_LOOP
25 000F EA87 0;JMP // infinite loop
--Mark