anchor.diff:          |   '\r'    // Macintosh
           |   '\n'    // Unix
           )
  -        { self.newline(); }
  +        { $newline; }
       ;
   
   // Single-line comments
   SL_COMMENT
   	:	"#"
   		(~('\n'|'\r'))* ('\n'|'\r'('\n')?)?
  -		{$setType(Token.SKIP); newline();}
  +		{ $newline; $setType(SKIP); }
   	;
   
   // multiple-line comments
  
positive.code: 
  
  
  BINARY: '0' ('b'|'B') ('0'|'1')*;
  HEXADECIMAL: '0' ('x'|'X') ('0'..'9'|'a'..'f'|'A'..'F')*;
  OCTAL: '0' ('0'..'9')*;
  DECIMAL: '1'..'9' ('0'..'9')*;
  
negative.code: 	k = 3;
  }
  
  start returns [res]
  		{ insns = [] }
  	:
  		( s=statement
  			{ insns.extend(s) } 
  		)* EOF
  		{ res = self.factory.make("Module(insns)", insns = insns) }
  	;
  
  statement returns [res]
  	: lbls=labels isns=tail EOL
  		{
              res = []
              res.extend(lbls)
              res.extend(isns)
  		}
   	;
  
  labels returns [res]
  	: (symbol COLON) => (lbl=symbol COLON^ lbls=labels)
  		{
              res = [self.factory.make("Label(lbl)", lbl=lbl)]
              res.extend(lbls)
          }
  	| /* no label */
  		{ res = [] }
  	;
  
  tail returns [res]
  	: /* empty statement */
  		{ res = [] }
  	| DIRECTIVE^ (~EOL)*
  		{ res = [] }
  	| insn=prefixed_instruction
  		{ res = [insn] }
  	;
  
  prefixed_instruction returns [res]
  	: (instruction) => insn=instruction
  		{ res = insn }
  	| INSTRUCTION insn=instruction
  		{ res = insn }
  	;
  
  instruction returns [res]
  		{ operands = [] }
  	: opcode:INSTRUCTION^ (o=operand { operands.append(o) } (COMMA! o=operand  { operands.append(o) })* )?
  		{
              res = self.factory.make("Assembly(opcode, operands)", opcode=opcode.getText().upper(), operands=operands)
  		}
  	;
   
  operand returns [res]
  	: o=register
  		{ res = o }
  	| o=immediate
  		{ res = o }
  	| o=memory
  		{ res = o }
  	;
  
  immediate returns [ret]
  	: DOLLAR^ c=constant
  		{ ret = c }
  	;
  
  register returns [ret]
  	: PERCENTAGE^ reg=symbol
  		{ ret = self.factory.make("Register(reg)", reg=reg) }
  	;
  
  memory returns [ret]
  	: disp=constant 
  		(
  		{ ret = self.factory.make("Address()") }
  		| LPAR! (base=register)? (COMMA! (index=register)? (COMMA! (scale=integer)? )? )? RPAR!
  		{ ret = self.factory.make("Address()") }
  		)
  	| LPAR! (base=register)? (COMMA! (index=register)? (COMMA! (scale=integer)? )? )? RPAR!
  		{ ret = self.factory.make("Address()") }
  	;
  
  constant returns [ret] 
  	: sym=symbol
  		{ ret = self.factory.make("Symbol(sym)", sym=sym) }
  	| value=integer
  		{ ret = self.factory.make("Constant(value)", value=value) }
  	;
  
  symbol returns [name]
  	: 
  		( d:DIRECTIVE 
  			{ name = d.getText() }
  		| i:INSTRUCTION
  			{ name = i.getText() }
  		)
  	;
  
  integer returns [value]
  	:
  		( b:BINARY
  			{ value = int(b.getText()[2:], 2) }
  		| o:OCTAL 
  			{ value = int(o.getText(), 8) }
  		| d:DECIMAL
  			{ value = int(d.getText()) }
  		| h:HEXADECIMAL
  			{ value = int(h.getText()[2:], 16) }
  		| MINUS^ i=integer
  			{ value = -i }
  		) 
  	;
  