Advertisement
Zeda

Shunting-Yard

Sep 27th, 2017
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define bcall(x) rst 28h \ .dw x
  2. saveSScreen = 86ECh
  3. scrap=saveSScreen
  4. outhead=8000h
  5. stackhead = 8002h
  6. .db $BB,$6D
  7. .org $9D95
  8.     ld hl,test
  9.     ld bc,test_end-test
  10.     call shuntingyard
  11.     call rpn
  12.     ld hl,scrap
  13.     bcall(450Ah)
  14.     bcall(452Eh)
  15.     ret
  16. shuntingyard:
  17.     ld de,scrap
  18.     ld (outhead),de
  19.     ld d,(scrap/256)+3
  20.     ld (stackhead),de
  21. _:
  22.     ld a,(hl)
  23.     call +_
  24.     cpi
  25.     jp pe,-_
  26.     ld hl,scrap+768
  27.     ld de,(stackhead)
  28.     or a
  29.     sbc hl,de
  30.     ld b,h
  31.     ld c,l
  32.     ld hl,(outhead)
  33.     ex de,hl
  34.     jr z,$+3
  35.     ldir
  36.     dec de
  37.     xor a
  38.     ld (de),a
  39.     ret
  40. _:
  41.     cp '.'
  42.     jp z,num_dec
  43.     cp 30h
  44.     jr c,+_
  45.     cp 3Ah
  46.     jp c,num
  47. _:
  48.     cp '('
  49.     jp nz,+_
  50.     ex de,hl
  51.     ld hl,(stackhead)
  52.     dec hl
  53.     ld (hl),','
  54.     dec hl
  55.     ld (hl),a
  56.     ld (stackhead),hl
  57.     ex de,hl
  58.     ret
  59. _:
  60.     cp ')'
  61.     jp nz,checkunops
  62.     push hl
  63.     push bc
  64.     ld hl,scrap+768
  65.     ld de,(stackhead)
  66.     sbc hl,de
  67.     jp z,ERR_Unmatched_lparens
  68.     ld b,h
  69.     ld c,l
  70.     ex de,hl
  71.     ld de,(outhead)
  72. ;BC is the size of the stack. Use this in case there is a missing ')' so we don't read garbage.
  73. ;basically search for the matching '(' while piping out the stack to the output.
  74. outerloop:
  75.     ld a,(hl)
  76.     cp '('
  77.     jr z,parens_found
  78.     ld a,','
  79. _:
  80.     cp (hl)
  81.     ldi
  82.     jp po,ERR_Unmatched_lparens
  83.     jr z,outerloop
  84.     jp -_
  85. parens_found:
  86.     inc hl
  87.     inc hl
  88.     ld (outhead),de
  89.     ld (stackhead),hl
  90.     pop bc
  91.     pop hl
  92.     ret
  93. checkunops:
  94. checkbinops:
  95. ;;  if the token is an operator, then:
  96. ;;      while there is an operator at the top of the operator stack with
  97. ;;          greater than or equal to precedence and the operator is left associative:
  98. ;;              pop operators from the operator stack, onto the output queue.
  99. ;;      push the read operator onto the operator stack.
  100. ;;
  101. ;;
  102.     push bc
  103.     ex de,hl
  104.     call getprecedence
  105.     ld a,c
  106.     pop bc
  107.     ex de,hl
  108.     jp c,search_function
  109.     ;now C is the precedence, with lower bit = 1 if left-associative
  110.     push bc
  111.     push hl
  112.     ld de,(stackhead)
  113.     ld hl,scrap+768
  114.     sbc hl,de
  115.     ld b,h
  116.     ld c,l
  117.     ld hl,(outhead)
  118.     ex de,hl
  119.     jr z,pushop
  120.     ;a is the precedence against which to compare
  121. _:
  122.     push hl
  123.     push bc
  124.     push af
  125.     ld a,(hl)
  126.     call getprecedence
  127.     jr c,+_
  128.     pop hl
  129.     ld a,h      ;incoming
  130.     cp c
  131.     jr nz,$+4
  132.     rra \ nop
  133.  
  134.     pop bc
  135.     pop hl
  136.    
  137.  ;======================================================
  138.     jr nc,pushop
  139. .echo "The following code only works until we have to add >1 byte tokens."
  140.  ldi
  141.  ldi
  142.     jp pe,-_
  143.     jp $+6
  144. _:
  145.     pop af
  146.     pop bc
  147.     pop hl
  148. pushop:
  149.     ld (outhead),de
  150.     pop de
  151.     dec hl
  152.     ld (hl),','
  153.     dec hl
  154.     ld a,(de)
  155.     ld (stackhead),hl
  156.     ld (hl),a
  157.     ex de,hl
  158.     pop bc
  159.     ret
  160. search_function:
  161.     jp ERR_Func_Not_Found
  162. getprecedence:
  163.     ld hl,binops
  164.     ld b,(binops_end-binops)/2
  165. _:
  166.     cp (hl)
  167.     inc hl
  168.     ld c,(hl)
  169.     ret z
  170.     inc hl
  171.     djnz -_
  172.     scf
  173.     ret
  174. binops:
  175.     .db 4,  $01
  176.     .db '=',$50
  177.     .db '|',$60
  178.     .db '&',$70
  179.     .db '-',$81     ;right associative
  180.     .db '+',$80     ;left associative
  181.     .db '/',$83     ;right associative
  182.     .db '*',$82     ;left associative
  183.     .db '^',$85     ;right associative
  184. binops_end:
  185. num:
  186.     ld de,(outhead)
  187. _:
  188.     ldi
  189.     jp po,+_
  190.     ld a,(hl)
  191.     cp '.'
  192.     jr z,num_dec+4
  193.     cp 30h
  194.     jr c,+_
  195.     cp 3Ah
  196.     jr c,-_
  197. _:
  198.     ld a,','
  199.     ld (de),a
  200.     inc de
  201.     ld (outhead),de
  202.     dec hl
  203.     inc bc
  204.     ret
  205. num_dec:
  206.     ld de,(outhead)
  207. _:
  208.     ldi
  209.     jp po,+_
  210.     ld a,(hl)
  211.     cp 30h
  212.     jr c,+_
  213.     cp 3Ah
  214.     jr c,-_
  215. _:
  216.     cp '.'
  217.     jp z,ERR_Syntax_00
  218.     ld a,','
  219.     ld (de),a
  220.     inc de
  221.     ld (outhead),de
  222.     dec hl
  223.     inc bc
  224.     ret
  225. ERR_Syntax_00:      ;Too many decimal points.
  226. ERR_Func_Not_Found:
  227. ERR_Unmatched_lparens:
  228.     ret
  229. rpn:
  230.     ret
  231. test:
  232. ;    .db "(3.1415926535)"
  233. .db "(3.142+6/2-7)*3^6*3"
  234. test_end:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement