o
    hj                     @  s>   d Z ddlmZ ddlmZmZ G dd deZdd
dZdS )a  `#define` macro expansion.

Confirmed (reverse_engineering.md, batches 3 & 4): `#define`d constants
compile *identically* to writing the value directly, in every context
tested (plain assignment, function-call argument). So the simplest correct
implementation is textual substitution on the token stream before parsing:
delete the `#define` lines, and splice each macro's body tokens in wherever
its name is referenced.

This is a single, non-recursive substitution pass -- a macro's body isn't
itself re-expanded for other macro references. The manual's own examples
(`#define CommandID _GO + 5`) don't nest macros, and nothing in the
confirmed corpus does either, so this is left as a TODO rather than
speculatively implemented.
    )annotations   )Token	TokenTypec                   @  s   e Zd ZdS )PreprocessorErrorN)__name__
__module____qualname__ r
   r
   S/sessions/nice-awesome-ritchie/mnt/compiler/src/microbasic_compiler/preprocessor.pyr      s    r   tokenslist[Token]returnc           
      C  sX  i }g }d}t | }||k r| | }|jtjkru|jdkru|d |ks-| |d  jtjkr6td|j d| |d  j }g }|d }||k rn| | jtj	tj
fvrn|| |  |d7 }||k rn| | jtj	tj
fvsT|||< |}q
|| |d7 }||k s|s|S g }	|D ]}|jtjkr|j |v r|	||j   q|	| q|	S )Nr   z#definer   z/#define must be followed by a macro name (line )   )lentyper   KEYWORDvalueIDENTr   linelowerNEWLINEEOFappendextend)
r   macrosoutintoknamebodyjexpandedr
   r
   r   expand_macros   s@    
r%   N)r   r   r   r   )	__doc__
__future__r   r   r   r   	Exceptionr   r%   r
   r
   r
   r   <module>   s
    