o
    hj                     @  s  d Z ddlmZ ddlmZmZ G dd dZG dd deZeG dd	 d	eZeG d
d deZ	eG dd deZ
eG dd deZeG dd deZeG dd deZeG dd deZeG dd deZG dd deZeG dd deZeG dd deZeG dd deZeG d d! d!eZeG d"d# d#eZeG d$d% d%eZeG d&d' d'eZeG d(d) d)eZeG d*d+ d+eZeG d,d- d-eZeG d.d/ d/eZeG d0d1 d1eZeG d2d3 d3eZeG d4d5 d5eZeZ eG d6d7 d7eZ!eG d8d9 d9eZ"eG d:d; d;eZ#eG d<d= d=eZ$eG d>d? d?eZ%eG d@dA dAeZ&eG dBdC dCeZ'eG dDdE dEeZ(dFS )GaU  AST node definitions for MicroBasic.

Shape follows the confirmed grammar in docs/reverse_engineering.md plus the
manual's documented syntax for constructs whose bytecode we didn't need to
special-case at the AST level (e.g. compound assignment desugars to a plain
AssignStmt at parse time -- see parser.py -- so there's no AugAssign node).
    )annotations)	dataclassfieldc                   @     e Zd ZdZdS )NodezBase class for all AST nodes.N__name__
__module____qualname____doc__ r   r   P/sessions/nice-awesome-ritchie/mnt/compiler/src/microbasic_compiler/ast_nodes.pyr      s    r   c                   @     e Zd ZdS )ExprNr   r	   r
   r   r   r   r   r          r   c                   @     e Zd ZU ded< dS )
IntLiteralintvalueNr   r	   r
   __annotations__r   r   r   r   r         
 r   c                   @  r   )BoolLiteralboolr   Nr   r   r   r   r   r      r   r   c                   @  r   )StringLiteralstrr   Nr   r   r   r   r   r   "   r   r   c                   @  s"   e Zd ZU ded< dZded< dS )VarRefr   nameNExpr | Noneindex)r   r	   r
   r   r    r   r   r   r   r   '   s   
 r   c                   @  s   e Zd ZU ded< ded< dS )UnaryOpr   opr   operandNr   r   r   r   r   r!   -   s   
 r!   c                   @  s&   e Zd ZU ded< ded< ded< dS )BinaryOpr   r"   r   leftrightNr   r   r   r   r   r$   3   s   
 r$   c                   @  ,   e Zd ZU dZded< eedZded< dS )CallzA function call used as an expression, e.g. GetValue(_TEMP, 1).

    Also doubles as a statement (SetCommand(...), SetConfig(...), Wait(...))
    when wrapped in ExprStmt -- see below.
    r   r   default_factory
list[Expr]argsN)r   r	   r
   r   r   r   listr,   r   r   r   r   r(   :   s   
 r(   c                   @  s*   e Zd ZU dZded< ded< ded< dS )
IncDecExprz8++x / --x / x++ / x-- used where the result is consumed.r   varr"   r   prefixNr   r	   r
   r   r   r   r   r   r   r.   E   s
   
 r.   c                   @  r   )StmtNr   r   r   r   r   r2   O   r   r2   c                   @      e Zd ZU eedZded< dS )Programr)   
list[Stmt]
statementsN)r   r	   r
   r   r-   r6   r   r   r   r   r   r4   S      
 r4   c                   @  r   )Labelr   r   Nr   r   r   r   r   r8   X   r   r8   c                   @  s*   e Zd ZU ded< ded< dZded< dS )DimStmtr   r   var_typeNz
int | None	array_len)r   r	   r
   r   r;   r   r   r   r   r9   ]   s   
 r9   c                   @  r   )OptionExplicitStmtzx`Option Explicit` directive. Accepted and currently a no-op --
    codegen doesn't yet enforce declare-before-use. TODO.Nr   r   r   r   r   r<   d   s    r<   c                   @  "   e Zd ZU dZded< ded< dS )
AssignStmta0  Always a plain '=' by the time this reaches codegen -- compound
    assignment operators (+=, -=, *=, /=, <<=, >>=) are desugared into this
    (target = target op value) during parsing, since that's confirmed to be
    exactly how the real compiler treats them (see reverse_engineering.md,
    batch 3).r   targetr   r   Nr1   r   r   r   r   r>   j   s   
 r>   c                   @  s<   e Zd ZU ded< ded< eedZded< dZd	ed
< dS )IfStmtr   	conditionr5   
then_blockr)   zlist[tuple[Expr, list[Stmt]]]elseif_clausesNzlist[Stmt] | None
else_block)r   r	   r
   r   r   r-   rC   rD   r   r   r   r   r@   u   s
   
 r@   c                   @  r   )GotoStmtr   labelNr   r   r   r   r   rE   }   r   rE   c                   @  r   )	GosubStmtr   rF   Nr   r   r   r   r   rG      r   rG   c                   @  r   )
ReturnStmtNr   r   r   r   r   rH          rH   c                   @  r   )TerminateStmtNr   r   r   r   r   rJ      rI   rJ   c                   @  r   )WaitStmtr   millisecondsNr   r   r   r   r   rK      r   rK   c                   @  r3   )	PrintStmtr)   r+   r,   N)r   r	   r
   r   r-   r,   r   r   r   r   r   rM      r7   rM   c                   @  s   e Zd ZU dZded< dS )ExprStmtzHA bare call used for side effects, e.g. SetCommand(...), SetConfig(...).r(   callNr1   r   r   r   r   rN      s   
 rN   c                   @  s"   e Zd ZU dZded< ded< dS )
IncDecStmtzBare x++ / x-- / ++x / --x as a full statement (result discarded).
    Compiles to the compact 3-instruction form (LOAD, INC/DEC, STORE)
    rather than IncDecExpr's 4-instruction consumed form.r   r/   r"   Nr1   r   r   r   r   rP      s   
 rP   c                   @  r   )ExitStmtLoopKindkindNr   r   r   r   r   rQ      r   rQ   c                   @  r   )ContinueStmtrR   rS   Nr   r   r   r   r   rT      r   rT   c                   @  r'   )	WhileStmtzCovers both `While...End While` and `Do While...Loop` -- confirmed
    byte-identical, so the parser normalizes both source forms to this node.r   rA   r)   r5   bodyNr   r	   r
   r   r   r   r-   rV   r   r   r   r   rU         
 rU   c                   @  r'   )DoUntilStmtz`Do Until <cond> ... Loop` -- pre-test, exits when condition becomes
    true (mirror image of WhileStmt, which exits when condition is false).r   rA   r)   r5   rV   NrW   r   r   r   r   rY      rX   rY   c                   @  r=   )DoLoopWhileStmtzl`Do ... Loop While <cond>` -- post-test, body always runs >= 1 time,
    loops back while condition is true.r5   rV   r   rA   Nr1   r   r   r   r   rZ         
 rZ   c                   @  r=   )DoLoopUntilStmtz`Do ... Loop Until <cond>` -- post-test, body always runs >= 1 time,
    loops back while condition is false (exits once true).r5   rV   r   rA   Nr1   r   r   r   r   r\      r[   r\   c                   @  D   e Zd ZU dZded< ded< ded< ded< eed	Zd
ed< dS )ForTraditionalStmtzTraditional `For var = init To limit [Step step] ... Next`.
    Confirmed to allocate two hidden Integer slots (limit, step) and use a
    step-sign-generic exit test -- see codegen.py.r   r/   r   initlimitr   stepr)   r5   rV   NrW   r   r   r   r   r^         
 r^   c                   @  r]   )ForCStyleStmtz`For var = init AndWhile cond [Evaluate stmt] ... Next`. Confirmed:
    if no Evaluate clause is given, the compiler auto-increments var by 1
    each iteration (reverse_engineering.md, batch 3).r   r/   r   r_   rA   zStmt | Noneevaluater)   r5   rV   NrW   r   r   r   r   rc      rb   rc   N))r   
__future__r   dataclassesr   r   r   r   r   r   r   r   r!   r$   r(   r.   r2   r4   r8   r9   r<   r>   r@   rE   rG   rH   rJ   rK   rM   rN   rP   r   rR   rQ   rT   rU   rY   rZ   r\   r^   rc   r   r   r   r   <module>   s    
	
