UNPKG

4.34 kBtext/coffeescriptView Raw
1# If the number of args is odd then the last arg is the default result.
2
3
4
5Eval_test = ->
6 orig = p1
7 p1 = cdr(p1)
8 while (iscons(p1))
9
10 # odd number of parameters means that the
11 # last argument becomes the default case
12 # i.e. the one without a test.
13 if (cdr(p1) == symbol(NIL))
14 push(car(p1)); # default case
15 Eval()
16 return
17
18 # load the next test and eval it
19 push(car(p1))
20 Eval_predicate()
21 p2 = pop()
22 if isone(p2)
23 # test succesful, we found out output
24 push(cadr(p1))
25 Eval()
26 return
27 else if !iszero(p2)
28 # we couldn't determine the result
29 # of a test. This means we can't conclude
30 # anything about the result of the
31 # overall test, so we must bail
32 # with the unevalled test
33 push orig
34 return
35
36 # test unsuccessful, continue to the
37 # next pair of test,value
38 p1 = cddr(p1)
39
40 # no test matched and there was no
41 # catch-all case, so we return zero.
42 push_integer 0
43
44# we test A==B by first subtracting and checking if we symbolically
45# get zero. If not, we evaluate to float and check if we get a zero.
46# If we get another NUMBER then we know they are different.
47# If we get something else, then we don't know and we return the
48# unaveluated test, which is the same as saying "maybe".
49Eval_testeq = ->
50 # first try without simplifyng both sides
51 orig = p1
52 push(cadr(p1))
53 Eval()
54 push(caddr(p1))
55 Eval()
56 subtract()
57 subtractionResult = pop()
58 if (iszero(subtractionResult))
59 p1 = subtractionResult
60 push_integer(1)
61 else
62 # they don't seem equal but
63 # let's try again after doing
64 # a simplification on both sides
65 push(cadr(p1))
66 Eval()
67 simplify()
68 push(caddr(p1))
69 Eval()
70 simplify()
71 subtract()
72 p1 = pop()
73
74 if (iszero(p1))
75 # if we get symbolically to a zero
76 # then we have perfect equivalence.
77 push_integer(1)
78 else
79 # let's try to evaluate to a float
80 push p1
81 yyfloat()
82 p1 = pop()
83 if (iszero(p1))
84 # if we got to zero then fine
85 push_integer(1)
86 else if isnum(p1)
87 # if we got to any other number then
88 # we know they are different
89 push_integer(0)
90 else
91 # if we didn't get to a number then we
92 # don't know whether the quantities are
93 # different so do nothing
94 push orig
95
96# Relational operators expect a numeric result for operand difference.
97
98Eval_testge = ->
99 orig = p1
100 comparison = cmp_args()
101
102 if !comparison?
103 push orig
104 return
105
106 if ( comparison >= 0)
107 push_integer(1)
108 else
109 push_integer(0)
110
111Eval_testgt = ->
112 orig = p1
113 comparison = cmp_args()
114
115 if !comparison?
116 push orig
117 return
118
119 if ( comparison > 0)
120 push_integer(1)
121 else
122 push_integer(0)
123
124Eval_testle = ->
125 orig = p1
126 comparison = cmp_args()
127
128 if !comparison?
129 push orig
130 return
131
132 if ( comparison <= 0)
133 push_integer(1)
134 else
135 push_integer(0)
136
137Eval_testlt = ->
138 orig = p1
139 comparison = cmp_args()
140
141 if !comparison?
142 push orig
143 return
144
145 if ( comparison < 0)
146 push_integer(1)
147 else
148 push_integer(0)
149
150# not definition
151Eval_not = ->
152 push(cadr(p1))
153 Eval_predicate()
154 p1 = pop()
155 if (iszero(p1))
156 push_integer(1)
157 else
158 push_integer(0)
159
160### and =====================================================================
161
162Tags
163----
164scripting, JS, internal, treenode, general concept
165
166Parameters
167----------
168a,b,...
169
170General description
171-------------------
172Logical-and of predicate expressions.
173
174###
175
176# and definition
177Eval_and = ->
178 p1 = cdr(p1)
179 while (iscons(p1))
180 push(car(p1))
181 Eval_predicate()
182 p2 = pop()
183 if (iszero(p2))
184 push_integer(0)
185 return
186 p1 = cdr(p1)
187 push_integer(1)
188
189# or definition
190Eval_or = ->
191 p1 = cdr(p1)
192 while (iscons(p1))
193 push(car(p1))
194 Eval_predicate()
195 p2 = pop()
196 if (!iszero(p2))
197 push_integer(1)
198 return
199 p1 = cdr(p1)
200 push_integer(0)
201
202# use subtract for cases like A < A + 1
203
204# TODO you could be smarter here and
205# simplify both sides only in the case
206# of "relational operator: cannot determine..."
207# a bit like we do in Eval_testeq
208cmp_args = ->
209 t = 0
210
211 push(cadr(p1))
212 Eval()
213 simplify()
214 push(caddr(p1))
215 Eval()
216 simplify()
217 subtract()
218 p1 = pop()
219
220 # try floating point if necessary
221
222 if (p1.k != NUM && p1.k != DOUBLE)
223 push(p1)
224 yyfloat()
225 Eval()
226 p1 = pop()
227
228 if (iszero(p1))
229 return 0
230
231 switch (p1.k)
232 when NUM
233 if (MSIGN(p1.q.a) == -1)
234 t = -1
235 else
236 t = 1
237 when DOUBLE
238 if (p1.d < 0.0)
239 t = -1
240 else
241 t = 1
242 else
243 t = null
244
245 return t
246
247