Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.0KB

  1. ; Parse an expression yielding a truth value from (HL) and set A accordingly.
  2. ; 0 for False, nonzero for True.
  3. ; How it evaluates truth is that it looks for =, <, >, >= or <= in (HL) and,
  4. ; if it finds it, evaluate left and right expressions separately. Then it
  5. ; compares both sides and set A accordingly.
  6. ; If comparison operators aren't found, the whole string is sent to parseExpr
  7. ; and zero means False, nonzero means True.
  8. ; **This routine mutates (HL).**
  9. ; Z for success.
  10. parseTruth:
  11. push ix
  12. push de
  13. ld a, '='
  14. call .maybeFind
  15. jr z, .foundEQ
  16. ld a, '<'
  17. call .maybeFind
  18. jr z, .foundLT
  19. ld a, '>'
  20. call .maybeFind
  21. jr z, .foundGT
  22. jr .simple
  23. .success:
  24. cp a ; ensure Z
  25. .end:
  26. pop de
  27. pop ix
  28. ret
  29. .maybeFind:
  30. push hl ; --> lvl 1
  31. call findchar
  32. jr nz, .notFound
  33. ; found! We want to keep new HL around. Let's pop old HL in DE
  34. pop de ; <-- lvl 1
  35. ret
  36. .notFound:
  37. ; not found, restore HL
  38. pop hl ; <-- lvl 1
  39. ret
  40. .simple:
  41. call parseExpr
  42. jr nz, .end
  43. ld a, d
  44. or e
  45. jr .success
  46. .foundEQ:
  47. ; we found an '=' char and HL is pointing to it. DE is pointing to the
  48. ; beginning of our string. Let's separate those two strings.
  49. ; But before we do that, to we have a '<' or a '>' at the left of (HL)?
  50. dec hl
  51. ld a, (hl)
  52. cp '<'
  53. jr z, .foundLTE
  54. cp '>'
  55. jr z, .foundGTE
  56. inc hl
  57. ; Ok, we are a straight '='. Proceed.
  58. call .splitLR
  59. ; HL now point to right-hand, DE to left-hand
  60. call .parseLeftRight
  61. jr nz, .end ; error, stop
  62. xor a ; clear carry and prepare value for False
  63. sbc hl, de
  64. jr nz, .success ; NZ? equality not met. A already 0, return.
  65. ; Z? equality met, make A=1, set Z
  66. inc a
  67. jr .success
  68. .foundLTE:
  69. ; Almost the same as '<', but we have two sep chars
  70. call .splitLR
  71. inc hl ; skip the '=' char
  72. call .parseLeftRight
  73. jr nz, .end
  74. ld a, 1 ; prepare for True
  75. sbc hl, de
  76. jr nc, .success ; Left <= Right, True
  77. ; Left > Right, False
  78. dec a
  79. jr .success
  80. .foundGTE:
  81. ; Almost the same as '<='
  82. call .splitLR
  83. inc hl ; skip the '=' char
  84. call .parseLeftRight
  85. jr nz, .end
  86. ld a, 1 ; prepare for True
  87. sbc hl, de
  88. jr z, .success ; Left == Right, True
  89. jr c, .success ; Left > Right, True
  90. ; Left < Right, False
  91. dec a
  92. jr .success
  93. .foundLT:
  94. ; Same thing as EQ, but for '<'
  95. call .splitLR
  96. call .parseLeftRight
  97. jr nz, .end
  98. xor a
  99. sbc hl, de
  100. jr z, .success ; Left == Right, False
  101. jr c, .success ; Left > Right, False
  102. ; Left < Right, True
  103. inc a
  104. jr .success
  105. .foundGT:
  106. ; Same thing as EQ, but for '>'
  107. call .splitLR
  108. call .parseLeftRight
  109. jr nz, .end
  110. xor a
  111. sbc hl, de
  112. jr nc, .success ; Left <= Right, False
  113. ; Left > Right, True
  114. inc a
  115. jr .success
  116. .splitLR:
  117. xor a
  118. ld (hl), a
  119. inc hl
  120. ret
  121. ; Given string pointers in (HL) and (DE), evaluate those two expressions and
  122. ; place their corresponding values in HL and DE.
  123. .parseLeftRight:
  124. ; let's start with HL
  125. push de ; --> lvl 1
  126. call parseExpr
  127. pop hl ; <-- lvl 1, orig DE
  128. ret nz
  129. push de ; --> lvl 1. save HL value in stack.
  130. ; Now, for DE. (DE) is now in HL
  131. call parseExpr ; DE in place
  132. pop hl ; <-- lvl 1. restore saved HL
  133. ret