o
    bßgj  ã                   @  sr   d Z ddlmZ ddlmZmZmZmZmZ G dd„ de	ƒZ
ddd	d
dddddddœ
ZG dd„ dƒZddd„ZdS )a2  Lexer for MicroBasic source (.mb files).

Handles:
  - comments: ' to end of line
  - numbers: decimal (120), hex (0xA1), binary (0b101)
  - strings: "..." with \-escapes and \xHH hex escapes
  - identifiers / keywords (case-insensitive)
  - labels: identifier at start of line followed by ':'
  - operators, per tokens.MULTI_CHAR_OPERATORS / SINGLE_CHAR_OPERATORS
  - significant newlines (MicroBasic statements are one-per-line)

This does not yet resolve #define macro substitution -- that belongs in a
preprocessing pass ahead of the parser. Left as a TODO.
é    )Úannotationsé   )ÚKEYWORDSÚMULTI_CHAR_OPERATORSÚSINGLE_CHAR_OPERATORSÚTokenÚ	TokenTypec                      s   e Zd Zd‡ fdd„Z‡  ZS )	ÚLexErrorÚmessageÚstrÚlineÚintÚcolc                   s.   t ƒ  |› d|› d|› d¡ || _|| _d S )Nz (line z, col ú))ÚsuperÚ__init__r   r   )Úselfr
   r   r   ©Ú	__class__© úL/sessions/nice-awesome-ritchie/mnt/compiler/src/microbasic_compiler/lexer.pyr      s   
zLexError.__init__)r
   r   r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__r   Ú__classcell__r   r   r   r   r	      s    r	   ú'ú"ú úúúÚ
úú	ú)
r   r   ú\ÚaÚbÚfÚnÚrÚtÚvc                   @  s^   e Zd Zddd„Zddd„Zd d!dd„Zd"dd„Zd#dd„Zd$dd„Zd$dd„Z	d%dd„Z
dS )&ÚLexerÚsourcer   c                 C  s"   || _ d| _d| _d| _d| _d S )Nr   r   T)ÚsrcÚposr   r   Ú_at_line_start)r   r.   r   r   r   r   1   s
   
zLexer.__init__Úreturnúlist[Token]c                 C  s,   g }	 |   ¡ }| |¡ |jtjkr	 |S q©N)Ú_next_tokenÚappendÚtyper   ÚEOF)r   ÚtokensÚtokr   r   r   Útokenize8   s   
ûzLexer.tokenizer   Úoffsetr   c                 C  s&   | j | }|t| jƒk r| j| S dS )NÚ )r0   Úlenr/   )r   r<   Úir   r   r   Ú_peekC   s   
zLexer._peekc                 C  sL   | j | j }|  jd7  _|dkr|  jd7  _d| _|S |  jd7  _|S )Nr   r!   )r/   r0   r   r   )r   Úchr   r   r   Ú_advanceG   s   ÿzLexer._advancer   c                 C  sZ  	 |   ¡ dv r|  ¡  |   ¡ dv s|   ¡ dkr0|   ¡ r/|   ¡ dkr/|  ¡  |   ¡ r/|   ¡ dks!q 	 |   ¡ s?ttjd| j| jƒS | j| j}}|   ¡ }|dkr]|  ¡  d| _ttjd||ƒS | j}d| _| 	¡ rm|  
||¡S |dkrw|  ||¡S | ¡ s|dkr†|  |||¡S |d	kr‘|  |||¡S |d
kr¡|  ¡  ttjd
||ƒS |dkr±|  ¡  ttjd||ƒS |dkrÁ|  ¡  ttjd||ƒS |dkrÑ|  ¡  ttjd||ƒS |dkrá|  ¡  ttjd||ƒS |dkrñ|  ¡  ttjd||ƒS tD ]}| j || j¡r|D ]}|  ¡  q ttj|||ƒ  S qó|tv r$|  ¡  ttj|||ƒS td|›||ƒ‚)NT)ú r#   r"   r   r!   r=   Fr   Ú_ú#ú(r   ú[ú]ú,ú:zUnexpected character )r@   rB   r   r   r8   r   r   r1   ÚNEWLINEÚisdigitÚ_read_numberÚ_read_stringÚisalphaÚ_read_identifierÚLPARENÚRPARENÚLBRACKETÚRBRACKETÚCOMMAÚCOLONr   r/   Ú
startswithr0   ÚOPr   r	   )r   r   r   rA   Úat_line_startÚoprD   r   r   r   r5   Q   sp   ÿÿý
zLexer._next_tokenr   r   c                 C  sî   | j }|  ¡ dkr1|  d¡dv r1|  ¡  |  ¡  |  ¡ r0|  ¡ dv r0|  ¡  |  ¡ r0|  ¡ dv s"n6|  ¡ dkrW|  d¡dv rW|  ¡  |  ¡  |  ¡ dv rV|  ¡  |  ¡ dv sLn|  ¡  ¡ rg|  ¡  |  ¡  ¡ s]| j|| j … }ttj|||ƒS )NÚ0r   )ÚxÚXÚ0123456789abcdefABCDEF)r'   ÚB)r[   Ú1)r0   r@   rB   rL   r/   r   r   ÚINTEGER)r   r   r   ÚstartÚtextr   r   r   rM   —   s(   ÿ€ÿ€ÿzLexer._read_numberc                 C  s,  |   ¡  g }	 |  ¡ }|r|dkrtd||ƒ‚|dkr |   ¡  nk|dkrƒ|   ¡  |  ¡ }|dkrg|   ¡  d}|  ¡ rP|  ¡ dv rP||   ¡ 7 }|  ¡ rP|  ¡ dv s@|sZtd	| j| jƒ‚| tt|d
ƒd@ ƒ¡ n#|tv rw|   ¡  | t| ¡ ntd|› d| j| jƒ‚| |   ¡ ¡ qt	t
jd |¡||ƒS )NTr!   zUnterminated string literalr   r%   r\   r=   r^   zEmpty hex escapeé   éÿ   zUnknown escape sequence '\r   )rB   r@   r	   r   r   r6   Úchrr   Ú_SIMPLE_ESCAPESr   r   ÚSTRINGÚjoin)r   r   r   ÚcharsrA   ÚescÚ
hex_digitsr   r   r   rN   ©   s8   ÿèzLexer._read_stringrY   Úboolc                 C  sÊ   | j }|  ¡ dkr|  ¡  |  ¡ r1|  ¡  ¡ s|  ¡ dkr1|  ¡  |  ¡ r1|  ¡  ¡ s|  ¡ dks| j|| j … }|rM|  ¡ dkrM|  ¡  ttj|||ƒS | ¡ t	v r]ttj
| ¡ ||ƒS ttj|||ƒS )NrE   rD   rJ   )r0   r@   rB   Úisalnumr/   r   r   ÚLABELÚlowerr   ÚKEYWORDÚIDENT)r   r   r   rY   rb   rc   r   r   r   rP   Ç   s     ÿzLexer._read_identifierN)r.   r   )r2   r3   )r   )r<   r   r2   r   )r2   r   )r2   r   )r   r   r   r   r2   r   )r   r   r   r   rY   rm   r2   r   )r   r   r   r   r;   r@   rB   r5   rM   rN   rP   r   r   r   r   r-   0   s    





F
r-   r.   r   r2   r3   c                 C  s   t | ƒ ¡ S r4   )r-   r;   )r.   r   r   r   r;   Ú   s   r;   N)r.   r   r2   r3   )Ú__doc__Ú
__future__r   r9   r   r   r   r   r   Ú	Exceptionr	   rg   r-   r;   r   r   r   r   Ú<module>   s$    	ö +