Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXPRESSION PARSER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4.  
  5.  
  6. token_end       equ     1
  7. token_reg       equ     2
  8. token_hex       equ     3
  9. token_add       equ     4
  10. token_sub       equ     5
  11. token_mul       equ     6
  12. token_div       equ     7
  13. token_lp        equ     8
  14. token_rp        equ     9
  15. token_err       equ     -1
  16.  
  17.  
  18. ;-----------------------------------------------------------------------------
  19. ;               Check if byte - some kind of instruction prefix
  20.  
  21. is_prefix:
  22.         cmp     al, 0x64        ; fs:
  23.         jz      .ret
  24.         cmp     al, 0x65        ; gs:
  25.         jz      .ret
  26.         cmp     al, 0x66        ; use16/32
  27.         jz      .ret
  28.         cmp     al, 0x67        ; addr16/32
  29.         jz      .ret
  30.         cmp     al, 0xF0        ; lock
  31.         jz      .ret
  32.         cmp     al, 0xF2        ; repnz
  33.         jz      .ret
  34.         cmp     al, 0xF3        ; rep(z)
  35.         jz      .ret
  36.         cmp     al, 0x2E        ; cs:
  37.         jz      .ret
  38.         cmp     al, 0x36        ; ss:
  39.         jz      .ret
  40.         cmp     al, 0x3E        ; ds:
  41.         jz      .ret
  42.         cmp     al, 0x26        ; es:
  43.    
  44.     .ret:
  45.         ret
  46.  
  47. ;-----------------------------------------------------------------------------
  48. ;                   Check if byte is hex digit
  49.  
  50. is_hex_digit:
  51.         cmp     al, '0'
  52.         jb      .no
  53.         cmp     al, '9'
  54.         jbe     .09
  55.         cmp     al, 'A'
  56.         jb      .no
  57.         cmp     al, 'F'
  58.         jbe     .AF
  59.         cmp     al, 'a'
  60.         jb      .no
  61.         cmp     al, 'f'
  62.         jbe     .af
  63.  
  64.     .no:
  65.         stc
  66.         ret
  67.  
  68.     .09:
  69.         sub     al, '0'
  70. ;       clc
  71.         ret
  72.  
  73.     .AF:
  74.         sub     al, 'A'-10
  75. ;       clc
  76.         ret
  77.  
  78.     .af:
  79.         sub     al, 'a'-10
  80. ;       clc
  81.         ret
  82.  
  83. ;-----------------------------------------------------------------------------
  84. ;                      Find register in the table
  85.  
  86. find_reg:
  87.         mov     edi, reg_table
  88.    
  89.     .findreg:
  90.         movzx   ecx, byte [edi]
  91.         stc
  92.         jecxz   .regnotfound
  93.         inc     edi
  94.         push    esi edi ecx
  95.    
  96.     @@:
  97.         lodsb
  98.         or      al, 20h
  99.         scasb
  100.         loopz   @b
  101.         pop     ecx edi esi
  102.         lea     edi, [edi+ecx+1]
  103.         jnz     .findreg
  104.         movzx   edi, byte [edi-1]
  105.         add     esi, ecx
  106.  
  107.     .regnotfound:
  108.         ret
  109.  
  110. ;-----------------------------------------------------------------------------
  111. ;                      Tokenize expressions
  112.  
  113. expr_get_token:
  114.         lodsb
  115.         cmp     al, 0
  116.         jz      .end_token
  117.         cmp     al, ' '
  118.         jbe     expr_get_token
  119.         cmp     al, '+'
  120.         jz      .add
  121.         cmp     al, '-'
  122.         jz      .sub
  123.         cmp     al, '*'
  124.         jz      .mul
  125.         cmp     al, '/'
  126.         jz      .div
  127.         cmp     al, '('
  128.         jz      .lp
  129.         cmp     al, ')'
  130.         jnz     .notsign
  131.    
  132.     .rp:
  133.         mov     al, token_rp
  134.         ret
  135.    
  136.     .div:
  137.         mov     al, token_div
  138.         ret
  139.  
  140.     .end_token:
  141.         mov     al, token_end
  142.         ret
  143.    
  144.     .add:
  145.         mov     al, token_add
  146.         ret
  147.  
  148.     .sub:
  149.         mov     al, token_sub
  150.         ret
  151.  
  152.     .mul:
  153.         mov     al, token_mul
  154.         ret
  155.  
  156.     .lp:
  157.         mov     al, token_lp
  158.         ret
  159.  
  160.     .notsign:
  161.         dec     esi
  162.         call    find_reg
  163.         jc      .regnotfound
  164.         mov     al, token_reg
  165.         ret
  166.  
  167.     .regnotfound:
  168.     ; test for symbol
  169.         push    esi
  170.  
  171.     @@:
  172.         lodsb
  173.         cmp     al, ' '
  174.         ja      @b
  175.         push    eax
  176.         mov     byte [esi], 0
  177.         xchg    esi, [esp+4]
  178.         call    find_symbol_name
  179.         mov     edi, eax
  180.         pop     eax
  181.         xchg    esi, [esp]
  182.         mov     byte [esi], al
  183.         jc      @f
  184.         add     esp, 4
  185.         mov     al, token_hex
  186.         ret
  187.  
  188.     @@:
  189.         pop     esi
  190.     ; test for hex number
  191.         xor     ecx, ecx
  192.         xor     edi, edi
  193.         xor     eax, eax
  194.  
  195.     @@:
  196.         lodsb
  197.         call    is_hex_digit
  198.         jc      @f
  199.         shl     edi, 4
  200.         or      edi, eax
  201.         inc     ecx
  202.         jmp     @b
  203.  
  204.     @@:
  205.         dec     esi
  206.         jecxz   .err
  207.         cmp     ecx, 8
  208.         ja      .err
  209.         mov     al, token_hex
  210.         ret
  211.  
  212.     .err:
  213.         mov     al, token_err
  214.         mov     esi, aParseError
  215.         ret
  216.  
  217. ;-----------------------------------------------------------------------------
  218.  
  219. expr_read2:
  220.         cmp     al, token_hex
  221.         jz      .hex
  222.         cmp     al, token_reg
  223.         jz      .reg
  224.         cmp     al, token_lp
  225.         jz      .lp
  226.         mov     al, token_err
  227.         mov     esi, aParseError
  228.         ret
  229.  
  230.     .hex:
  231.         mov     ebp, edi
  232.  
  233.     .ret:
  234.         jmp     expr_get_token
  235.  
  236.     .reg:
  237.         cmp     edi, 24
  238.         jz      .eip
  239.         sub     edi, 4
  240.         jb      .8lo
  241.         sub     edi, 4
  242.         jb      .8hi
  243.         sub     edi, 8
  244.         jb      .16
  245.         mov     ebp, [_eax+edi*4]
  246.         jmp     .ret
  247.  
  248.     .16:
  249.         movzx   ebp, word [_eax+(edi+8)*4]
  250.         jmp     .ret
  251.  
  252.     .8lo:
  253.         movzx   ebp, byte [_eax+(edi+4)*4]
  254.         jmp     .ret
  255.  
  256.     .8hi:
  257.         movzx   ebp, byte [_eax+(edi+4)*4+1]
  258.         jmp     .ret
  259.  
  260.     .eip:
  261.         mov     ebp, [_eip]
  262.         jmp     .ret
  263.  
  264.     .lp:
  265.         call    expr_get_token
  266.         call    expr_read0
  267.         cmp     al, token_err
  268.         jz      @f
  269.         cmp     al, token_rp
  270.         jz      expr_get_token
  271.         mov     al, token_err
  272.         mov     esi, aParseError
  273.  
  274.     @@:
  275.         ret
  276.  
  277. ;-----------------------------------------------------------------------------
  278.  
  279. expr_read1:
  280.         call    expr_read2
  281.  
  282.     .1:
  283.         cmp     al, token_mul
  284.         jz      .mul
  285.         cmp     al, token_div
  286.         jz      .div
  287.         ret
  288.  
  289.     .mul:
  290.         push    ebp
  291.         call    expr_get_token
  292.         call    expr_read2
  293.         pop     edx
  294.     ; ebp := edx*ebp
  295.         imul    ebp, edx
  296.         jmp     .1
  297.  
  298.     .div:
  299.         push    ebp
  300.         call    expr_get_token
  301.         call    expr_read2
  302.         pop     edx
  303.     ; ebp := edx/ebp
  304.         test    ebp, ebp
  305.         jz      .div0
  306.         push    eax
  307.         xor     eax, eax
  308.         xchg    eax, edx
  309.         div     ebp
  310.         xchg    eax, ebp
  311.         pop     eax
  312.         jmp     .1
  313.  
  314.     .div0:
  315.         mov     al, token_err
  316.         mov     esi, aDivByZero
  317.         ret
  318.  
  319. ;-----------------------------------------------------------------------------
  320.  
  321. expr_read0:
  322.         xor     ebp, ebp
  323.         cmp     al, token_add
  324.         jz      .add
  325.         cmp     al, token_sub
  326.         jz      .sub
  327.         call    expr_read1
  328.  
  329.     .1:
  330.         cmp     al, token_add
  331.         jz      .add
  332.         cmp     al, token_sub
  333.         jz      .sub
  334.         ret
  335.  
  336.     .add:
  337.         push    ebp
  338.         call    expr_get_token
  339.         call    expr_read1
  340.         pop     edx
  341.     ; ebp := edx+ebp
  342.         add     ebp, edx
  343.         jmp     .1
  344.  
  345.     .sub:
  346.         push    ebp
  347.         call    expr_get_token
  348.         call    expr_read1
  349.         pop     edx
  350.     ; ebp := edx-ebp
  351.         xchg    edx, ebp
  352.         sub     ebp, edx
  353.         jmp     .1
  354.  
  355. ;-----------------------------------------------------------------------------
  356.  
  357. ; in: esi->expression
  358. ; out: CF=1 if error
  359. ;      CF=0 and ebp=value if ok
  360. calc_expression:
  361.         call    expr_get_token
  362.         call    expr_read0
  363.         cmp     al, token_end
  364.         jz      .end
  365.         cmp     al, token_err
  366.         jz      @f
  367.         mov     esi, aParseError
  368.  
  369.     @@:
  370.         call    put_message
  371.         stc
  372.         ret
  373.  
  374.     .end:
  375.         clc
  376.         ret
  377.  
  378. ;-----------------------------------------------------------------------------
  379.  
  380. get_arg:
  381.         lodsb
  382.         cmp     al, ' '
  383.         ja      get_arg
  384.         mov     byte [esi-1], 0
  385.         cmp     al, 0
  386.         jnz     .skip_spaces
  387.         dec     esi
  388.  
  389.     .skip_spaces:
  390.         lodsb
  391.         cmp     al, 0
  392.         jz      @f
  393.         cmp     al, ' '
  394.         jbe     .skip_spaces
  395.  
  396.     @@:
  397.         dec     esi
  398.         ret
  399.  
  400.  
  401.  
  402. ; vim: ft=fasm tabstop=4
  403.  
  404.