B
    Ö³aÅ<  ã               @   s  d Z dZdZdZdZdZdZdZdZd	Z	d
Z
dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd Z d!Z!d"Z"d#Z#d$Z$d%Z%G d&d'„ d'ƒZ&d(d)„ Z'd*d+„ Z(e'ƒ Z)e(ƒ Z*G d,d-„ d-ƒZ+G d.d/„ d/ƒZ,G d0d1„ d1ƒZ-G d2d3„ d3ƒZ.e.ƒ Z/d4d5„ Z0G d6d7„ d7ƒZ1d8S )9ÚSPZR0ÚNOPÚHLTÚBRKÚADDÚSUBÚINCÚDECÚMLTÚDIVÚMODÚORÚANDÚXORÚNOTÚLSHÚRSHÚBSLÚBSRÚMOVÚIMMÚLODÚSTRÚCPYÚPSHÚPOPÚCALÚRETÚJMPÚBRZÚBNZÚBREÚBNEÚBRLÚBLEÚBRGÚBGEc               @   s*   e Zd ZdZddg dfdd„Zdd„ ZdS )	ÚClassz Represents a compile-time class.Z	classNameNFc             C   sH   || _ |d kr&|jr&td|j  d ƒ‚|| _|| _|| _d| _d| _d S )NzClass 'z%' is sealed and can not be inherited.F)ÚNameZSealedÚ
ValueErrorÚParentClassÚFieldsÚ
_ValueTypeÚ_Pending)ÚselfÚnameZparentClassZfieldsÚsealed© r0   úN/mnt/chromeos/GoogleDrive/MyDrive/Programming/Python/URCL/URCL-Toolkit/urcl.pyÚ__init__/   s    zClass.__init__c             C   s4   | j rtdƒ‚t| jƒ}| jdkr0|| j ¡ 7 }|S )z%Get the size of this class in memory.z!Can not get size of pending type.N)r,   r(   Úlenr*   r)   ÚGetSize)r-   Úresultr0   r0   r1   r4   9   s    

zClass.GetSize)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r2   r4   r0   r0   r0   r1   r&   -   s   
r&   c              C   s   t ddd} d| _| S )z+Get the type that represents a native word.ÚWORDT)r/   )r&   r+   )r5   r0   r0   r1   ÚGetWordClassB   s    r;   c              C   s   t ddd} d| _| S )z9Get the type that can be replaced by another class later.ÚPENDINGT)r/   )r&   r,   )r5   r0   r0   r1   ÚGetPendingClassH   s    r=   c               @   s.   e Zd ZdZedfdd„Zdd„ Zdd„ Zd	S )
ÚFieldz Represents a compile-time field.Z	fieldNamec             C   s   || _ || _d S )N)ÚTyper'   )r-   Útyper.   r0   r0   r1   r2   S   s    zField.__init__c             C   s   | j jS )z*Returns true if the field is a value type.)r?   r+   )r-   r0   r0   r1   ÚIsValueW   s    zField.IsValuec             C   s
   | j j S )z,Returns true if the field is a pointer type.)r?   r+   )r-   r0   r0   r1   Ú	IsPointer[   s    zField.IsPointerN)r6   r7   r8   r9   r<   r2   rA   rB   r0   r0   r0   r1   r>   Q   s   r>   c               @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚRegisterMapzAn allocator for registers.c             C   s   d| _ | j | _g | _d S )Né   )Ú_RegistersStartÚ_NextRegisterÚ_FreeRegisters)r-   r0   r0   r1   r2   a   s    zRegisterMap.__init__c             C   s@   t | jƒdkrt| j ¡ ƒS | j}|  jd7  _dt|ƒ S dS )zAllocate a register for use.é    rD   ÚRN)r3   rG   ÚstrÚpoprF   )r-   r5   r0   r0   r1   ÚNewf   s
    zRegisterMap.Newc             C   s   | j  |¡ dS )z"Make a register available for use.N)rG   Úappend)r-   Úregr0   r0   r1   ÚFreeo   s    zRegisterMap.Freec             C   s   | j | _g | _dS )z$Free all registers currently in use.N)rE   rF   rG   )r-   r0   r0   r1   ÚResets   s    zRegisterMap.ResetN)r6   r7   r8   r9   r2   rL   rO   rP   r0   r0   r0   r1   rC   _   s
   	rC   c               @   s2   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ ZdS )ÚInstructionzRepresents an URCL instruction.r   Nc             C   s   || _ || _|| _|| _d S )N)Ú	OperationÚOperandAÚOperandBÚOperandC)r-   Ú	operationÚoperandAÚoperandBÚoperandCr0   r0   r1   r2   z   s    zInstruction.__init__c             C   s2   | j dkrdS | jdkrdS | jdkr*dS dS dS )z/Get the number of operands in this instruction.NrH   rD   é   é   )rS   rT   rU   )r-   r0   r0   r1   ÚGetOperandCount€   s    


zInstruction.GetOperandCountc             C   sJ   | j dkrg S | jdkr | j gS | jdkr6| j | jgS | j | j| jgS dS )z/Get a list of the operands in this instruction.N)rS   rT   rU   )r-   r0   r0   r1   ÚGetOperands‹   s    


zInstruction.GetOperandsc             C   sŽ   | j dkr| jS | jdkr.| jd t| j ƒ S | jdkrZ| jd t| j ƒ d t| jƒ S | jd t| j ƒ d t| jƒ d t| jƒ S dS )z$Convert the instruction to a string.Nú )rS   rR   rT   rJ   rU   )r-   r0   r0   r1   Ú__str__–   s    


"zInstruction.__str__)r   NNN)r6   r7   r8   r9   r2   r\   r]   r_   r0   r0   r0   r1   rQ   x   s
   
rQ   c               @   s   e Zd ZdZdd„ ZdS )ÚURCLEmitzLThe default emitter target type. Outputs emitter instructions as plain URCL.c             C   sÈ   d}xlt t|jƒƒD ]Z}||jkrXx4t t|j| ƒƒD ]}|t|j| | ƒd 7 }q6W |t|j| ƒd 7 }qW t|jƒ|jkrÄx@t t|jt|jƒ ƒƒD ]$}|t|jt|jƒ | ƒd 7 }qœW |S )NÚ Ú
)Úranger3   ÚInstructionsÚLabelsrJ   )r-   Úemitterr5   ÚiÚjr0   r0   r1   ÚEmit£   s    
$zURCLEmit.EmitN)r6   r7   r8   r9   ri   r0   r0   r0   r1   r`   ¡   s   r`   c             C   sÐ   t | ƒ ¡ } t| ƒdkrdS |  d¡r*dS |  d¡r@d| kr@| S |  dd¡ dd¡ dd¡ d¡} d	}xFtd
ƒD ]:}|t| ƒkrŒ|  d¡ qp| |  d¡sž|rpd| |< d}qpW t| d  	¡ | d | d | d ƒS )zdParse an URCL instruction from a string. Returns None is the instruction is a comment or empty line.rH   Nz//Ú.r^   ú,z //z  Fé   TrD   rZ   r[   )
rJ   Ústripr3   Ú
startswithÚreplaceÚsplitrc   rM   rQ   Úupper)ÚtextZcommentrg   r0   r0   r1   ÚParseInstruction±   s     
"rs   c               @   s  e Zd ZdZeddddfdd„Zdd	„ Zd7dd„Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zeefdd„Zefdd„Zeefdd„Zd8dd „Zd!d"„ Zeddfd#d$„Zd%d&„ Zdedfd'd(„Zddefd)d*„Zdefd+d,„Zdefd-d.„Zedefd/d0„Zedefd1d2„Zd3d4„ Zd5d6„ ZdS )9ÚEmitterz!An emitter for URCL instructions.FrH   l   ÿÿÿÿ Tc             C   s&  g | _ i | _tƒ | _|| _|r,| j ¡ | _nd | _d| _||k rL|}|}|}|| _|| _	|| _
d | _d | _d | _d| _|s"d| _
d| _|  ¡ }|  ¡ | _|  ¡ | _|  ¡ | _|  t| jt¡ |  t|¡ |  | j¡ |  | j| j¡ |  t¡ |  | j¡ |  | j¡ |  t¡ |  |¡ d| _
d S )NrH   FT)rd   re   rC   Ú
_RegistersÚ_EmitterTargetrL   ÚBPÚ_NextAnonLabelÚ_MemoryManagerMinAddressÚ_MemoryManagerMaxAddressÚ_InlineMemoryManagementÚ_MemoryManagerAllocateÚ_MemoryManagerFreeÚ_MemoryManagerRegisterÚ_PushRegistersOnMemManageÚNewLabelÚNewRegisterri   r   ÚZEROr   Ú	MarkLabelÚ
NewPointerr   ÚFreePointer)r-   Ú
emitTargetZuseR1AsBasePointerZmemoryManagerMinAddressÚmemoryManagerMaxAddressÚinlineMemoryManagementZswapZ
entryPointr0   r0   r1   r2   Æ   sH    





zEmitter.__init__c             C   s   | j dkr|  ¡ | _ | j S )z@Get or allocate a register designated as the stack base pointer.N)rw   r   )r-   r0   r0   r1   ÚGetBasePointerø   s    

zEmitter.GetBasePointerra   c             C   s0   t |ƒdkr(dt| jƒ }|  jd7  _d| S )z0Create a new label with an optional custom name.rH   Z_anonlabel_rD   rj   )r3   rJ   rx   )r-   r.   r0   r0   r1   r€   þ   s    zEmitter.NewLabelc             C   sB   t | jƒ| jkr,| jt | jƒ  |g7  < n|g| jt | jƒ< dS )z*Mark a label at the current emit location.N)r3   rd   re   )r-   Úlabelr0   r0   r1   rƒ     s    zEmitter.MarkLabelc             C   s4   t |ƒ}t|ƒdkr |d dks(|dkr,dS dS dS )z)Determine if a value is an URCL register.rH   rI   r   TFN)rJ   r3   )r-   Úvaluer0   r0   r1   Ú
IsRegister  s     zEmitter.IsRegisterc             C   s(   t |ƒ}t|ƒdko&|d dko&d|kS )z&Determine if a value is an URCL label.rH   rj   r^   )rJ   r3   )r-   r‹   r0   r0   r1   ÚIsLabel  s    zEmitter.IsLabelc             C   s
   | j  ¡ S )zAllocate a register for use.)ru   rL   )r-   r0   r0   r1   r     s    zEmitter.NewRegisterc             C   s   | j  |¡ dS )z"Make a register available for use.N)ru   rO   )r-   rN   r0   r0   r1   ÚFreeRegister  s    zEmitter.FreeRegisterc       
      C   sº  | j rj|  ¡ }|  ¡ }|  ¡ }|  ¡ }|  ¡ }|  ¡ }|  ¡ }	| jrj|  t|¡ |  t|¡ |  t|	¡ |  t|| j¡ |  t|t	¡ |  
|¡ |  t|||¡ |  t||¡ |  t||¡ |  t|	|d¡ |  t||¡ |  t||	¡ |  t|||¡ |  t||¡ |  t||d¡ |  t||¡ |  t||d¡ |  t|¡ |  
|¡ |  t|t	¡ |  t|¡ |  
|¡ |  t||d¡ |  t|¡ |  t|	| j|¡ |  t||	|¡ |  t||¡ |  t||d¡ |  t||¡ |  t||d¡ |  t|¡ |  t|||¡ |  t|t	¡ |  
|¡ | jrJ|  t|	¡ |  t|¡ |  t|¡ |  |¡ |  |¡ |  |	¡ nL|  |¡rˆ|  t| j|¡ n|  t| j|¡ |  t| j¡ |  t|| j¡ dS )z†Allocate a block of memory. It is advisable to use inlineMemoryManagement=False in the emitter options if calling this more than once.rD   N)r{   r€   r   r   ri   r   r   ry   r   r‚   rƒ   r   r   r   r   r   r   r"   r   r   r   r   r   rz   r   rŽ   rŒ   r~   r   r|   )
r-   ZinSizeÚ
outPointerZ
searchLoopZ	createNewZoutOfMemoryÚfinishÚcurrentBlockÚlengthr‹   r0   r0   r1   r„   !  sn    





zEmitter.NewPointerc             C   s  | j rÄ|  ¡ }|  ¡ }|  ¡ }| jr<|  t|¡ |  t|¡ |  t||¡ |  t||d¡ |  t||¡ |  t	||d¡ |  t
||¡ |  |¡ | jr®|  t|¡ |  t|¡ |  |¡ |  |¡ n:|  |¡rà|  t| j|¡ n|  t| j|¡ |  t| j¡ dS )z‚Free a block of memory. It is advisable to use inlineMemoryManagement=False in the emitter options if calling this more than once.rD   éþÿÿÿN)r{   r€   r   r   ri   r   r   r   r   r   r   rƒ   r   rŽ   rŒ   r   r~   r   r   r}   )r-   Ú	inPointerr   r‘   r’   r0   r0   r1   r…   x  s,    


zEmitter.FreePointerc             C   s   |   | ¡ |¡ dS )z2Allocate a block of memory for the specified type.N)r„   r4   )r-   r@   r   r0   r0   r1   Ú	NewObjectœ  s    zEmitter.NewObjectr   Nc             C   s   | j  t||||ƒ¡ dS )zCEmit an URCL instruction with the specified operation and operands.N)rd   rM   rQ   )r-   rV   rW   rX   rY   r0   r0   r1   ri      s    zEmitter.Emitc             C   s   dS )NrH   r0   )r-   Úargr0   r0   r1   Ú_CallFunctionDefaultArguments¤  s    z%Emitter._CallFunctionDefaultArgumentsc             C   s:   |   ttt|¡ || |ƒ}|   t|¡ |   ttt|¡ dS )z´Emit a function call that passes the arguments pushed onto the stack by the specified emitArgsFunc(emitter, emitArgsFuncArg), which returns the number of arguments that was pushed.N)ri   r   r   r   r   )r-   rŠ   ZemitArgsFuncZemitArgsFuncArgZoutCountZinCountr0   r0   r1   ÚCallFunction§  s    
zEmitter.CallFunctionc             C   s   d S )Nr0   )r-   r–   ÚreturnLabelr0   r0   r1   Ú_EmitFunctionDefaultBody®  s    z Emitter._EmitFunctionDefaultBodyc             C   sŠ   |   |¡ |  t|  ¡ ¡ |  t|  ¡ t¡ |  ttt|¡ |  ¡ }|| ||ƒ |   |¡ |  tt|  ¡ ¡ |  t|  ¡ ¡ |  t	¡ dS )zfEmit a function that executes the code emitted by emitBodyFunc(emitter, emitBodyFuncArg, returnLabel).N)
rƒ   ri   r   r‰   r   r   r   r€   r   r   )r-   rŠ   Z
localCountZemitBodyFuncZemitBodyFuncArgr™   r0   r0   r1   ÚEmitFunction±  s    

zEmitter.EmitFunctionc             C   s.   |   t||  ¡ || d ¡ |   t||¡ dS )z]Get the value of the function argument with the specified total arguments and argument index.rD   N)ri   r   r‰   r   )r-   ZargumentCountZargumentIndexÚoutValuer0   r0   r1   ÚEmitGetArgument¾  s    zEmitter.EmitGetArgumentc             C   s&   |   t||  ¡ |¡ |   t||¡ dS )zCGet the value of the function local with the specified local index.N)ri   r   r‰   r   )r-   Ú
localIndexrœ   r0   r0   r1   ÚEmitGetLocalÃ  s    zEmitter.EmitGetLocalc             C   s8   |   ¡ }|  t||  ¡ |¡ |  t||¡ |  |¡ dS )zMSet the value of the function local with the specified local index and value.N)r   ri   r   r‰   r   rŽ   )r-   rž   ÚinValueZlocalPointerr0   r0   r1   ÚEmitSetLocalÈ  s    zEmitter.EmitSetLocalc             C   s4   |   ¡ }|  t|||¡ |  t||¡ |  |¡ dS )zMGet the value of the object field with the specified pointer and field index.N)r   ri   r   r   r…   )r-   r”   Ú
fieldIndexrœ   ÚfieldPointerr0   r0   r1   ÚEmitGetObjectFieldÏ  s    zEmitter.EmitGetObjectFieldc             C   s4   |   ¡ }|  t|||¡ |  t||¡ |  |¡ dS )zMSet the value of the object field with the specified pointer and field index.N)r   ri   r   r   rŽ   )r-   r”   r¢   r    r£   r0   r0   r1   ÚEmitSetObjectFieldÖ  s    zEmitter.EmitSetObjectFieldc             C   s   t | ƒS )z9Compile the emitter instructions with the emitter target.)rJ   )r-   r0   r0   r1   ÚCompileÝ  s    zEmitter.Compilec             C   s   | j  | ¡S )z9Compile the emitter instructions with the emitter target.)rv   ri   )r-   r0   r0   r1   r_   á  s    zEmitter.__str__)ra   )r   NNN)r6   r7   r8   r9   ÚDEFAULT_TARGETr2   r‰   r€   rƒ   rŒ   r   r   rŽ   r‚   r„   r…   r<   r•   ri   r—   r˜   rš   r›   r   rŸ   r¡   r¤   r¥   r¦   r_   r0   r0   r0   r1   rt   Ä   s0   2
W$
rt   N)2r   r‚   r   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r;   r=   r:   r<   r>   rC   rQ   r`   r§   rs   rt   r0   r0   r0   r1   Ú<module>   sb   )