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.

144 lines
2.9KB

  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. push ix \ pop de
  44. ld a, d
  45. or e
  46. jr .success
  47. .foundEQ:
  48. ; we found an '=' char and HL is pointing to it. DE is pointing to the
  49. ; beginning of our string. Let's separate those two strings.
  50. ; But before we do that, to we have a '<' or a '>' at the left of (HL)?
  51. dec hl
  52. ld a, (hl)
  53. cp '<'
  54. jr z, .foundLTE
  55. cp '>'
  56. jr z, .foundGTE
  57. inc hl
  58. ; Ok, we are a straight '='. Proceed.
  59. call .splitLR
  60. ; HL now point to right-hand, DE to left-hand
  61. call .parseLeftRight
  62. jr nz, .end ; error, stop
  63. xor a ; clear carry and prepare value for False
  64. sbc hl, de
  65. jr nz, .success ; NZ? equality not met. A already 0, return.
  66. ; Z? equality met, make A=1, set Z
  67. inc a
  68. jr .success
  69. .foundLTE:
  70. ; Almost the same as '<', but we have two sep chars
  71. call .splitLR
  72. inc hl ; skip the '=' char
  73. call .parseLeftRight
  74. jr nz, .end
  75. ld a, 1 ; prepare for True
  76. sbc hl, de
  77. jr nc, .success ; Left <= Right, True
  78. ; Left > Right, False
  79. dec a
  80. jr .success
  81. .foundGTE:
  82. ; Almost the same as '<='
  83. call .splitLR
  84. inc hl ; skip the '=' char
  85. call .parseLeftRight
  86. jr nz, .end
  87. ld a, 1 ; prepare for True
  88. sbc hl, de
  89. jr z, .success ; Left == Right, True
  90. jr c, .success ; Left > Right, True
  91. ; Left < Right, False
  92. dec a
  93. jr .success
  94. .foundLT:
  95. ; Same thing as EQ, but for '<'
  96. call .splitLR
  97. call .parseLeftRight
  98. jr nz, .end
  99. xor a
  100. sbc hl, de
  101. jr z, .success ; Left == Right, False
  102. jr c, .success ; Left > Right, False
  103. ; Left < Right, True
  104. inc a
  105. jr .success
  106. .foundGT:
  107. ; Same thing as EQ, but for '>'
  108. call .splitLR
  109. call .parseLeftRight
  110. jr nz, .end
  111. xor a
  112. sbc hl, de
  113. jr nc, .success ; Left <= Right, False
  114. ; Left > Right, True
  115. inc a
  116. jr .success
  117. .splitLR:
  118. xor a
  119. ld (hl), a
  120. inc hl
  121. ret
  122. ; Given string pointers in (HL) and (DE), evaluate those two expressions and
  123. ; place their corresponding values in HL and DE.
  124. .parseLeftRight:
  125. ; let's start with HL
  126. call parseExpr
  127. ret nz
  128. push ix ; --> lvl 1. save (HL) value in stack.
  129. ex de, hl
  130. call parseExpr
  131. ret nz
  132. push ix \ pop de
  133. pop hl ; <-- lvl 1. restore.
  134. ret