Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / lang / LangSource / PyrMathOps.cpp
blob5d357d38646388619802458653cc869a74d920be
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <math.h>
22 #include <stdlib.h>
23 #include <string.h>
25 #include "Opcodes.h"
26 #include "PyrInterpreter.h"
27 #include "PyrPrimitive.h"
28 #include "PyrPrimitiveProto.h"
29 #include "PyrMathPrim.h"
30 #include "PyrKernel.h"
31 #include "PyrMessage.h"
32 #include "PyrParseNode.h"
33 #include "PyrSignal.h"
34 #include "PyrSched.h"
35 #include "PyrSymbol.h"
36 #include "SC_InlineUnaryOp.h"
37 #include "SC_InlineBinaryOp.h"
38 #include "MiscInlineMath.h"
39 #include "PyrKernelProto.h"
41 #include <limits>
43 double hypotx(double x, double y);
45 #define IS_BINARY_BOOL_OP(op) ((op)>=opEQ && (op)<=opGE)
47 int doSpecialUnaryArithMsg(VMGlobals *g, int numArgsPushed)
49 PyrSlot *a;
50 PyrSymbol *msg;
51 int opcode = g->primitiveIndex;
53 a = g->sp;
55 switch (GetTag(a)) {
56 case tagInt :
57 switch (opcode) {
58 case opNeg : SetRaw(a, -slotRawInt(a)); break;
59 //case opNot : goto send_normal_1;
60 case opIsNil : SetFalse(a); break;
61 case opNotNil : SetTrue(a); break;
62 case opBitNot : SetRaw(a, ~slotRawInt(a)); break;
63 case opAbs : SetRaw(a, sc_abs(slotRawInt(a))); break;
64 case opAsFloat : SetFloat(a, (double)slotRawInt(a)); break;
65 case opAsInt : SetRaw(a, (int)slotRawInt(a)); break;
66 case opCeil : SetRaw(a, slotRawInt(a)); break;
67 case opFloor : SetRaw(a, slotRawInt(a)); break;
68 case opFrac : SetRaw(a, 0); break;
69 case opSign : SetRaw(a, slotRawInt(a) > 0 ? 1 : (slotRawInt(a) == 0 ? 0 : -1)); break;
70 case opSquared : SetRaw(a, slotRawInt(a) * slotRawInt(a)); break;
71 case opCubed : SetRaw(a, slotRawInt(a) * slotRawInt(a) * slotRawInt(a)); break;
72 case opSqrt : SetFloat(a, sqrt((double)slotRawInt(a))); break;
73 case opExp : SetFloat(a, exp((double)slotRawInt(a))); break;
74 case opRecip : SetFloat(a, 1. / slotRawInt(a)); break;
75 case opMIDICPS : SetFloat(a, sc_midicps((double)slotRawInt(a))); break;
76 case opCPSMIDI : SetFloat(a, sc_cpsmidi((double)slotRawInt(a))); break;
77 case opMIDIRatio : SetFloat(a, sc_midiratio((double)slotRawInt(a))); break;
78 case opRatioMIDI : SetFloat(a, sc_ratiomidi((double)slotRawInt(a))); break;
79 case opAmpDb : SetFloat(a, sc_ampdb((double)slotRawInt(a))); break;
80 case opDbAmp : SetFloat(a, sc_dbamp((double)slotRawInt(a))); break;
81 case opOctCPS : SetFloat(a, sc_octcps((double)slotRawInt(a))); break;
82 case opCPSOct : SetFloat(a, sc_cpsoct((double)slotRawInt(a))); break;
83 case opLog : SetFloat(a, log((double)slotRawInt(a))); break;
84 case opLog2 : SetFloat(a, sc_log2((double)slotRawInt(a))); break;
85 case opLog10 : SetFloat(a, log10((double)slotRawInt(a))); break;
86 case opSin : SetFloat(a, sin((double)slotRawInt(a))); break;
87 case opCos : SetFloat(a, cos((double)slotRawInt(a))); break;
88 case opTan : SetFloat(a, tan((double)slotRawInt(a))); break;
89 case opArcSin : SetFloat(a, asin((double)slotRawInt(a))); break;
90 case opArcCos : SetFloat(a, acos((double)slotRawInt(a))); break;
91 case opArcTan : SetFloat(a, atan((double)slotRawInt(a))); break;
92 case opSinH : SetFloat(a, sinh((double)slotRawInt(a))); break;
93 case opCosH : SetFloat(a, cosh((double)slotRawInt(a))); break;
94 case opTanH : SetFloat(a, tanh((double)slotRawInt(a))); break;
95 case opRand : SetRaw(a, g->rgen->irand(slotRawInt(a))); break;
96 case opRand2 : SetRaw(a, g->rgen->irand2(slotRawInt(a))); break;
97 case opLinRand : SetRaw(a, g->rgen->ilinrand(slotRawInt(a))); break;
98 case opBiLinRand : SetRaw(a, g->rgen->ibilinrand(slotRawInt(a))); break;
100 // case opExpRand : SetFloat(a, g->rgen->exprand(slotRawInt(a))); break;
101 // case opBiExpRand : SetFloat(a, g->rgen->biexprand(slotRawInt(a))); break;
102 case opSum3Rand : SetFloat(a, g->rgen->sum3rand(slotRawInt(a))); break;
104 // case opGammaRand : SetFloat(a, g->rgen->gammarand(slotRawInt(a))); break;
105 // case opGaussRand : SetFloat(a, g->rgen->gaussrand(slotRawInt(a))); break;
106 // case opPoiRand : SetFloat(a, g->rgen->poirand(slotRawInt(a))); break;
108 case opDistort : SetFloat(a, sc_distort((double)slotRawInt(a))); break;
109 case opSoftClip : SetFloat(a, sc_softclip((double)slotRawInt(a))); break;
110 case opCoin : SetBool(a, (slotRawInt(a))); break;
111 case opRectWindow : SetFloat(a, sc_rectwindow((double)slotRawInt(a))); break;
112 case opHanWindow : SetFloat(a, sc_hanwindow((double)slotRawInt(a))); break;
113 case opWelchWindow : SetFloat(a, sc_welwindow((double)slotRawInt(a))); break;
114 case opTriWindow : SetFloat(a, sc_triwindow((double)slotRawInt(a))); break;
115 case opSCurve : SetFloat(a, sc_scurve((double)slotRawInt(a))); break;
116 case opRamp : SetFloat(a, sc_ramp((double)slotRawInt(a))); break;
117 default : goto send_normal_1;
119 break;
120 case tagChar :
121 switch (opcode) {
122 //case opNot : goto send_normal_1;
123 case opIsNil : SetFalse(a); break;
124 case opNotNil : SetTrue(a); break;
125 case opAsInt : SetTagRaw(a, tagInt); break;
126 case opDigitValue :
127 if (slotRawInt(a) >= '0' && slotRawInt(a) <= '9') SetInt(a, slotRawInt(a) - '0');
128 else if (slotRawInt(a) >= 'A' && slotRawInt(a) <= 'Z') SetInt(a, slotRawInt(a) - 'A');
129 else if (slotRawInt(a) >= 'a' && slotRawInt(a) <= 'z') SetInt(a, slotRawInt(a) - 'a');
130 else SetInt(a, 0);
131 break;
132 default : goto send_normal_1;
134 break;
135 case tagPtr :
136 switch (opcode) {
137 case opIsNil : SetFalse(a); break;
138 case opNotNil : SetTrue(a); break;
139 default : goto send_normal_1;
141 break;
142 case tagNil :
143 switch (opcode) {
144 case opIsNil : SetTrue(a); break;
145 case opNotNil : SetFalse(a); break;
146 default : goto send_normal_1;
148 break;
149 case tagFalse :
150 switch (opcode) {
151 case opNot : SetTrue(a); break;
152 case opIsNil : /*SetFalse(a);*/ break;
153 case opNotNil : SetTrue(a); break;
154 default : goto send_normal_1;
156 break;
157 case tagTrue :
158 switch (opcode) {
159 case opNot : SetFalse(a); break;
160 case opIsNil : SetFalse(a); break;
161 case opNotNil : /*SetTrue(a);*/ break;
162 default : goto send_normal_1;
164 break;
165 case tagSym :
166 switch (opcode) {
167 case opAsFloat :
168 case opAsInt :
169 goto send_normal_1;
170 case opIsNil : SetFalse(a); break;
171 case opNotNil : SetTrue(a); break;
172 default : /* SetSymbol(a, slotRawSymbol(a)); */ break;
174 break;
175 case tagObj :
176 if (isKindOf(slotRawObject(a), class_signal)) {
177 switch (opcode) {
178 case opNeg : SetRaw(a, signal_invert(g, slotRawObject(a))); break;
179 case opIsNil : SetFalse(a); break;
180 case opNotNil : SetTrue(a); break;
181 case opAbs : SetRaw(a, signal_abs(g, slotRawObject(a))); break;
182 case opSign : SetRaw(a, signal_sign(g, slotRawObject(a))); break;
183 case opSquared : SetRaw(a, signal_squared(g, slotRawObject(a))); break;
184 case opCubed : SetRaw(a, signal_cubed(g, slotRawObject(a))); break;
185 case opSqrt : SetRaw(a, signal_sqrt(g, slotRawObject(a))); break;
186 case opExp : SetRaw(a, signal_exp(g, slotRawObject(a))); break;
187 case opRecip : SetRaw(a, signal_recip(g, slotRawObject(a))); break;
188 case opLog : SetRaw(a, signal_log(g, slotRawObject(a))); break;
189 case opLog2 : SetRaw(a, signal_log2(g, slotRawObject(a))); break;
190 case opLog10 : SetRaw(a, signal_log10(g, slotRawObject(a))); break;
191 case opSin : SetRaw(a, signal_sin(g, slotRawObject(a))); break;
192 //case opSin : SetRaw(a, signal_fsin(g, slotRawObject(a))); break;
193 case opCos : SetRaw(a, signal_cos(g, slotRawObject(a))); break;
194 case opTan : SetRaw(a, signal_tan(g, slotRawObject(a))); break;
195 case opArcSin : SetRaw(a, signal_asin(g, slotRawObject(a))); break;
196 case opArcCos : SetRaw(a, signal_acos(g, slotRawObject(a))); break;
197 case opArcTan : SetRaw(a, signal_atan(g, slotRawObject(a))); break;
198 case opSinH : SetRaw(a, signal_sinh(g, slotRawObject(a))); break;
199 case opCosH : SetRaw(a, signal_cosh(g, slotRawObject(a))); break;
200 case opTanH : SetRaw(a, signal_tanh(g, slotRawObject(a))); break;
201 case opDistort : SetRaw(a, signal_distort(g, slotRawObject(a))); break;
202 case opSoftClip : SetRaw(a, signal_softclip(g, slotRawObject(a))); break;
203 default : goto send_normal_1;
205 } else {
206 goto send_normal_1;
208 break;
209 default : // double
210 switch (opcode) {
211 case opNeg : SetRaw(a, -slotRawFloat(a)); break;
212 case opIsNil : SetFalse(a); break;
213 case opNotNil : SetTrue(a); break;
214 case opBitNot : SetRaw(a, ~(int)slotRawFloat(a)); break;
215 case opAbs : SetRaw(a, sc_abs(slotRawFloat(a))); break;
216 case opAsFloat : SetRaw(a, (double)slotRawFloat(a)); break;
217 case opAsInt :
219 double val = slotRawFloat(a);
220 if (val == std::numeric_limits<double>::infinity())
221 SetInt(a, std::numeric_limits<int>::max());
222 else
223 SetInt(a, (int)val);
224 break;
226 case opCeil : SetRaw(a, ceil(slotRawFloat(a))); break;
227 case opFloor : SetRaw(a, floor(slotRawFloat(a))); break;
228 case opFrac : SetRaw(a, sc_frac(slotRawFloat(a))); break;
229 case opSign : SetRaw(a, slotRawFloat(a) > 0. ? 1.0 : (slotRawFloat(a) == 0 ? 0.0 : -1.0)); break;
230 case opSquared : SetRaw(a, slotRawFloat(a) * slotRawFloat(a)); break;
231 case opCubed : SetRaw(a, slotRawFloat(a) * slotRawFloat(a) * slotRawFloat(a)); break;
232 case opSqrt : SetRaw(a, sqrt(slotRawFloat(a))); break;
233 case opExp : SetRaw(a, exp(slotRawFloat(a))); break;
234 case opRecip : SetRaw(a, 1./slotRawFloat(a)); break;
235 case opMIDICPS : SetRaw(a, sc_midicps(slotRawFloat(a))); break;
236 case opCPSMIDI : SetRaw(a, sc_cpsmidi(slotRawFloat(a))); break;
237 case opMIDIRatio : SetRaw(a, sc_midiratio((double)slotRawFloat(a))); break;
238 case opRatioMIDI : SetRaw(a, sc_ratiomidi((double)slotRawFloat(a))); break;
239 case opAmpDb : SetRaw(a, sc_ampdb(slotRawFloat(a))); break;
240 case opDbAmp : SetRaw(a, sc_dbamp(slotRawFloat(a))); break;
241 case opOctCPS : SetRaw(a, sc_octcps(slotRawFloat(a))); break;
242 case opCPSOct : SetRaw(a, sc_cpsoct(slotRawFloat(a))); break;
243 case opLog : SetRaw(a, log(slotRawFloat(a))); break;
244 case opLog2 : SetRaw(a, sc_log2(slotRawFloat(a))); break;
245 case opLog10 : SetRaw(a, log10(slotRawFloat(a))); break;
246 case opSin : SetRaw(a, sin(slotRawFloat(a))); break;
247 case opCos : SetRaw(a, cos(slotRawFloat(a))); break;
248 case opTan : SetRaw(a, tan(slotRawFloat(a))); break;
249 case opArcSin : SetRaw(a, asin(slotRawFloat(a))); break;
250 case opArcCos : SetRaw(a, acos(slotRawFloat(a))); break;
251 case opArcTan : SetRaw(a, atan(slotRawFloat(a))); break;
252 case opSinH : SetRaw(a, sinh(slotRawFloat(a))); break;
253 case opCosH : SetRaw(a, cosh(slotRawFloat(a))); break;
254 case opTanH : SetRaw(a, tanh(slotRawFloat(a))); break;
255 case opRand : SetRaw(a, g->rgen->frand() * slotRawFloat(a)); break;
256 case opRand2 : SetRaw(a, g->rgen->frand2() * slotRawFloat(a)); break;
257 case opLinRand : SetRaw(a, g->rgen->linrand(slotRawFloat(a))); break;
258 case opBiLinRand : SetRaw(a, g->rgen->bilinrand(slotRawFloat(a))); break;
260 // case opExpRand : SetRaw(a, g->rgen->exprand(slotRawFloat(a))); break;
261 // case opBiExpRand : SetRaw(a, g->rgen->biexprand(slotRawFloat(a))); break;
262 case opSum3Rand : SetRaw(a, g->rgen->sum3rand(slotRawFloat(a))); break;
264 // case opGammaRand : SetRaw(a, g->rgen->gammarand(slotRawFloat(a))); break;
265 // case opGaussRand : SetRaw(a, g->rgen->gaussrand(slotRawFloat(a))); break;
266 // case opPoiRand : SetRaw(a, g->rgen->poirand(slotRawFloat(a))); break;
268 case opDistort : SetRaw(a, sc_distort(slotRawFloat(a))); break;
269 case opSoftClip : SetRaw(a, sc_softclip(slotRawFloat(a))); break;
270 case opCoin : SetBool(a, g->rgen->frand() < slotRawFloat(a)); break;
271 case opRectWindow : SetRaw(a, sc_rectwindow(slotRawFloat(a))); break;
272 case opHanWindow : SetRaw(a, sc_hanwindow(slotRawFloat(a))); break;
273 case opWelchWindow : SetRaw(a, sc_welwindow(slotRawFloat(a))); break;
274 case opTriWindow : SetRaw(a, sc_triwindow(slotRawFloat(a))); break;
275 case opSCurve : SetRaw(a, sc_scurve(slotRawFloat(a))); break;
276 case opRamp : SetRaw(a, sc_ramp(slotRawFloat(a))); break;
277 default : goto send_normal_1;
279 break;
282 #if TAILCALLOPTIMIZE
283 g->tailCall = 0;
284 #endif
285 return errNone;
287 send_normal_1:
288 if (numArgsPushed != -1) // special case flag meaning it is a primitive
289 return errFailed;
291 msg = gSpecialUnarySelectors[opcode];
292 sendMessage(g, msg, 1);
294 return errNone;
297 int prSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed)
299 return doSpecialBinaryArithMsg(g, numArgsPushed, true);
302 int doSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed, bool isPrimitive)
304 PyrSlot *a, *b;
305 PyrSymbol *msg;
306 int opcode = g->primitiveIndex;
308 a = g->sp - (numArgsPushed - 1);
309 b = a + 1;
311 switch (GetTag(a)) {
312 case tagInt : {
313 switch (GetTag(b)) {
314 case tagInt :
315 switch (opcode) {
316 case opAdd : SetRaw(a, slotRawInt(a) + slotRawInt(b)); break;
317 case opSub : SetRaw(a, slotRawInt(a) - slotRawInt(b)); break;
318 case opMul : SetRaw(a, slotRawInt(a) * slotRawInt(b)); break;
319 case opIDiv : SetRaw(a, sc_div(slotRawInt(a), slotRawInt(b))); break;
320 case opFDiv : SetFloat(a, (double)slotRawInt(a) / (double)slotRawInt(b)); break;
321 case opMod : SetRaw(a, sc_mod((int)slotRawInt(a), (int)slotRawInt(b))); break;
322 case opEQ : SetBool(a, slotRawInt(a) == slotRawInt(b)); break;
323 case opNE : SetBool(a, slotRawInt(a) != slotRawInt(b)); break;
324 case opLT : SetBool(a, slotRawInt(a) < slotRawInt(b)); break;
325 case opGT : SetBool(a, slotRawInt(a) > slotRawInt(b)); break;
326 case opLE : SetBool(a, slotRawInt(a) <= slotRawInt(b)); break;
327 case opGE : SetBool(a, slotRawInt(a) >= slotRawInt(b)); break;
328 //case opIdentical : SetBool(a, slotRawInt(a) == slotRawInt(b)); break;
329 //case opNotIdentical : SetBool(a, slotRawInt(a) != slotRawInt(b)); break;
330 case opMin : SetRaw(a, sc_min(slotRawInt(a), slotRawInt(b))); break;
331 case opMax : SetRaw(a, sc_max(slotRawInt(a), slotRawInt(b))); break;
332 case opBitAnd : SetRaw(a, slotRawInt(a) & slotRawInt(b)); break;
333 case opBitOr : SetRaw(a, slotRawInt(a) | slotRawInt(b)); break;
334 case opBitXor : SetRaw(a, slotRawInt(a) ^ slotRawInt(b)); break;
335 case opLCM : SetRaw(a, sc_lcm(slotRawInt(a), slotRawInt(b))); break;
336 case opGCD : SetRaw(a, sc_gcd(slotRawInt(a), slotRawInt(b))); break;
337 case opRound : SetRaw(a, sc_round((int)slotRawInt(a), (int)slotRawInt(b))); break;
338 case opRoundUp :SetRaw(a, sc_roundUp((int)slotRawInt(a), (int)slotRawInt(b))); break;
339 case opTrunc : SetRaw(a, sc_trunc((int)slotRawInt(a), (int)slotRawInt(b))); break;
340 case opAtan2 : SetFloat(a, atan2((double)slotRawInt(a), (double)slotRawInt(b))); break;
341 case opHypot : SetFloat(a, hypot((double)slotRawInt(a), (double)slotRawInt(b))); break;
342 case opHypotx : SetFloat(a, hypotx((double)slotRawInt(a), (double)slotRawInt(b))); break;
343 case opPow : SetFloat(a, pow((double)slotRawInt(a), (double)slotRawInt(b))); break;
344 case opShiftLeft : {
345 long ia = slotRawInt(a);
346 long ib = slotRawInt(b);
347 if (ib>0) ia <<= ib;
348 else if (ib<0) ia >>= -ib;
349 SetRaw(a, ia);
350 } break;
351 case opShiftRight : {
352 long ia = slotRawInt(a);
353 long ib = slotRawInt(b);
354 if (ib>0) ia >>= ib;
355 else if (ib<0) ia <<= -ib;
356 SetRaw(a, ia);
357 } break;
358 case opUnsignedShift : {
359 unsigned long ia = slotRawInt(a);
360 long ib = slotRawInt(b);
361 if (ib>0) ia >>= ib;
362 else if (ib<0) ia <<= -ib;
363 SetRaw(a, (long)ia);
364 } break;
365 case opRing1 : SetRaw(a, sc_ring1(slotRawInt(a), slotRawInt(b))); break;
366 case opRing2 : SetRaw(a, sc_ring2(slotRawInt(a), slotRawInt(b))); break;
367 case opRing3 : SetRaw(a, sc_ring3(slotRawInt(a), slotRawInt(b))); break;
368 case opRing4 : SetRaw(a, sc_ring4(slotRawInt(a), slotRawInt(a))); break;
369 case opDifSqr : SetRaw(a, sc_difsqr(slotRawInt(a), slotRawInt(b))); break;
370 case opSumSqr : SetRaw(a, sc_sumsqr(slotRawInt(a), slotRawInt(b))); break;
371 case opSqrSum : SetRaw(a, sc_sqrsum(slotRawInt(a), slotRawInt(b))); break;
372 case opSqrDif : SetRaw(a, sc_sqrdif(slotRawInt(a), slotRawInt(b))); break;
373 case opAbsDif : SetRaw(a, sc_abs(slotRawInt(a) - slotRawInt(b))); break;
374 case opThresh : SetRaw(a, sc_thresh(slotRawInt(a), slotRawInt(b))); break;
375 case opAMClip : SetRaw(a, sc_amclip(slotRawInt(a), slotRawInt(b))); break;
376 case opScaleNeg : SetRaw(a, sc_scaleneg(slotRawInt(a), slotRawInt(b))); break;
377 case opClip2 : SetRaw(a, sc_clip2(slotRawInt(a), slotRawInt(b))); break;
378 case opFold2 : SetRaw(a, sc_fold2(slotRawInt(a), slotRawInt(b))); break;
379 case opWrap2 : SetRaw(a, sc_wrap2(slotRawInt(a), slotRawInt(b))); break;
380 case opExcess : SetRaw(a, sc_excess(slotRawInt(a), slotRawInt(b))); break;
381 case opFirstArg : SetRaw(a, slotRawInt(a)); break;
382 case opRandRange : SetRaw(a, slotRawInt(b) > slotRawInt(a) ? slotRawInt(a) + g->rgen->irand(slotRawInt(b) - slotRawInt(a) + 1)
383 : slotRawInt(b) + g->rgen->irand(slotRawInt(a) - slotRawInt(b) + 1));
384 break;
385 case opExpRandRange :
386 SetFloat(a, g->rgen->exprandrng(slotRawInt(a), slotRawInt(b)));
387 break;
388 default : goto send_normal_2;
390 break;
391 case tagChar :
392 case tagPtr :
393 case tagNil :
394 case tagFalse :
395 case tagTrue :
396 goto send_normal_2;
397 case tagSym :
398 if (IS_BINARY_BOOL_OP(opcode))
399 SetBool(a, opcode == opNE);
400 else
401 SetSymbol(a, slotRawSymbol(b));
402 break;
403 case tagObj :
404 if (isKindOf(slotRawObject(b), class_signal)) {
405 switch (opcode) {
406 case opAdd : SetObject(a, signal_add_xf(g, slotRawObject(b), slotRawInt(a))); break;
407 case opSub : SetObject(a, signal_sub_fx(g, slotRawInt(a), slotRawObject(b))); break;
408 case opMul : SetObject(a, signal_mul_xf(g, slotRawObject(b), slotRawInt(a))); break;
409 case opIDiv : SetObject(a, signal_div_fx(g, slotRawInt(a), slotRawObject(b))); break;
410 case opFDiv : SetObject(a, signal_div_fx(g, slotRawInt(a), slotRawObject(b))); break;
411 case opEQ : SetFalse(a); break;
412 case opNE : SetTrue(a); break;
413 case opMin : SetObject(a, signal_min_xf(g, slotRawObject(b), slotRawInt(a))); break;
414 case opMax : SetObject(a, signal_max_xf(g, slotRawObject(b), slotRawInt(a))); break;
415 case opRing1 : SetObject(a, signal_ring1_fx(g, slotRawInt(a), slotRawObject(b))); break;
416 case opRing2 : SetObject(a, signal_ring2_fx(g, slotRawInt(a), slotRawObject(b))); break;
417 case opRing3 : SetObject(a, signal_ring3_fx(g, slotRawInt(a), slotRawObject(b))); break;
418 case opRing4 : SetObject(a, signal_ring4_fx(g, slotRawInt(a), slotRawObject(b))); break;
419 case opDifSqr : SetObject(a, signal_difsqr_fx(g, slotRawInt(a), slotRawObject(b))); break;
420 case opSumSqr : SetObject(a, signal_sumsqr_fx(g, slotRawInt(a), slotRawObject(b))); break;
421 case opSqrSum : SetObject(a, signal_sqrsum_fx(g, slotRawInt(a), slotRawObject(b))); break;
422 case opSqrDif : SetObject(a, signal_sqrdif_fx(g, slotRawInt(a), slotRawObject(b))); break;
423 case opAbsDif : SetObject(a, signal_absdif_fx(g, slotRawInt(a), slotRawObject(b))); break;
424 case opThresh : SetObject(a, signal_thresh_fx(g, slotRawInt(a), slotRawObject(b))); break;
425 case opAMClip : SetObject(a, signal_amclip_fx(g, slotRawInt(a), slotRawObject(b))); break;
426 case opScaleNeg : SetObject(a, signal_scaleneg_fx(g, slotRawInt(a), slotRawObject(b))); break;
427 case opClip2 : SetObject(a, signal_clip2_fx(g, slotRawInt(a), slotRawObject(b))); break;
428 case opFold2 : SetObject(a, signal_fold2_fx(g, slotRawInt(a), slotRawObject(b))); break;
429 case opWrap2 : SetObject(a, signal_wrap2_fx(g, slotRawInt(a), slotRawObject(b))); break;
430 case opExcess : SetObject(a, signal_excess_fx(g, slotRawInt(a), slotRawObject(b))); break;
431 case opFirstArg : SetObject(a, slotRawObject(a)); break;
432 default : goto send_normal_2;
434 } else {
435 goto send_normal_2;
437 break;
438 default :
439 switch (opcode) {
440 case opAdd : SetFloat(a, slotRawInt(a) + slotRawFloat(b)); break;
441 case opSub : SetFloat(a, slotRawInt(a) - slotRawFloat(b)); break;
442 case opMul : SetFloat(a, slotRawInt(a) * slotRawFloat(b)); break;
443 case opIDiv : SetRaw(a, (long)floor(slotRawInt(a) / slotRawFloat(b))); break;
444 case opFDiv : SetFloat(a, slotRawInt(a) / slotRawFloat(b)); break;
445 case opMod : SetFloat(a, sc_mod((double)slotRawInt(a), slotRawFloat(b))); break;
446 case opEQ : SetBool(a, slotRawInt(a) == slotRawFloat(b)); break;
447 case opNE : SetBool(a, slotRawInt(a) != slotRawFloat(b)); break;
448 case opLT : SetBool(a, slotRawInt(a) < slotRawFloat(b)); break;
449 case opGT : SetBool(a, slotRawInt(a) > slotRawFloat(b)); break;
450 case opLE : SetBool(a, slotRawInt(a) <= slotRawFloat(b)); break;
451 case opGE : SetBool(a, slotRawInt(a) >= slotRawFloat(b)); break;
452 //case opIdentical : SetFalse(a); break;
453 //case opNotIdentical : SetTrue(a); break;
454 case opMin : SetFloat(a, sc_min((double)slotRawInt(a), slotRawFloat(b))); break;
455 case opMax : SetFloat(a, sc_max((double)slotRawInt(a), slotRawFloat(b))); break;
456 case opRound : SetFloat(a, sc_round((double)slotRawInt(a), slotRawFloat(b))); break;
457 case opRoundUp : SetFloat(a, sc_roundUp((double)slotRawInt(a), slotRawFloat(b))); break;
458 case opTrunc : SetFloat(a, sc_trunc((double)slotRawInt(a), slotRawFloat(b))); break;
459 case opAtan2 : SetFloat(a, atan2(slotRawInt(a), slotRawFloat(b))); break;
460 case opHypot : SetFloat(a, hypot(slotRawInt(a), slotRawFloat(b))); break;
461 case opHypotx : SetFloat(a, hypotx(slotRawInt(a), slotRawFloat(b))); break;
462 case opPow : SetFloat(a, pow((double)slotRawInt(a), slotRawFloat(b))); break;
463 case opRing1 : SetFloat(a, sc_ring1((double)slotRawInt(a), slotRawFloat(b))); break;
464 case opRing2 : SetFloat(a, sc_ring2((double)slotRawInt(a), slotRawFloat(b))); break;
465 case opRing3 : SetFloat(a, sc_ring3((double)slotRawInt(a), slotRawFloat(b))); break;
466 case opRing4 : SetFloat(a, sc_ring4((double)slotRawInt(a), slotRawFloat(b))); break;
467 case opDifSqr : SetFloat(a, sc_difsqr((double)slotRawInt(a), slotRawFloat(b))); break;
468 case opSumSqr : SetFloat(a, sc_sumsqr((double)slotRawInt(a), slotRawFloat(b))); break;
469 case opSqrSum : SetFloat(a, sc_sqrsum((double)slotRawInt(a), slotRawFloat(b))); break;
470 case opSqrDif : SetFloat(a, sc_sqrdif((double)slotRawInt(a), slotRawFloat(b))); break;
471 case opAbsDif : SetFloat(a, sc_abs(slotRawInt(a) - slotRawFloat(b))); break;
472 case opThresh : SetRaw(a, sc_thresh(slotRawInt(a), slotRawFloat(b))); break;
473 case opAMClip : SetFloat(a, sc_amclip((double)slotRawInt(a), slotRawFloat(b))); break;
474 case opScaleNeg : SetFloat(a, sc_scaleneg((double)slotRawInt(a), slotRawFloat(b))); break;
475 case opClip2 : SetFloat(a, sc_clip2((double)slotRawInt(a), slotRawFloat(b))); break;
476 case opFold2 : SetFloat(a, sc_fold2((double)slotRawInt(a), slotRawFloat(b))); break;
477 case opWrap2 : SetFloat(a, sc_wrap2((double)slotRawInt(a), -slotRawFloat(b))); break;
478 case opExcess : SetFloat(a, sc_excess((double)slotRawInt(a), slotRawFloat(b))); break;
479 case opFirstArg : SetInt(a, slotRawInt(a)); break;
480 case opRandRange :
481 SetFloat(a, slotRawInt(a) + g->rgen->frand() * (slotRawFloat(b) - slotRawInt(a)));
482 break;
483 case opExpRandRange :
484 SetFloat(a, g->rgen->exprandrng(slotRawInt(a), slotRawFloat(b)));
485 break;
486 default : goto send_normal_2;
488 break;
490 } break;
491 case tagChar : {
492 if (IsChar(b)) {
493 switch (opcode) {
494 case opEQ : SetBool(a, slotRawChar(a) == slotRawChar(b)); break;
495 case opNE : SetBool(a, slotRawChar(a) != slotRawChar(b)); break;
496 case opLT : SetBool(a, slotRawChar(a) < slotRawChar(b)); break;
497 case opGT : SetBool(a, slotRawChar(a) > slotRawChar(b)); break;
498 case opLE : SetBool(a, slotRawChar(a) <= slotRawChar(b)); break;
499 case opGE : SetBool(a, slotRawChar(a) >= slotRawChar(b)); break;
500 //case opIdentical : SetBool(a, slotRawChar(a) == slotRawChar(b)); break;
501 //case opNotIdentical : SetBool(a, slotRawChar(a) != slotRawChar(b)); break;
502 case opMin : SetRawChar(a, sc_min(slotRawChar(a), slotRawChar(b))); break;
503 case opMax : SetRawChar(a, sc_max(slotRawChar(a), slotRawChar(b))); break;
504 default : goto send_normal_2;
506 } else {
507 goto send_normal_2;
509 } break;
510 case tagPtr :
511 case tagNil :
512 case tagFalse :
513 case tagTrue :
514 goto send_normal_2;
515 case tagSym :
516 if (IsSym(b)) {
517 switch (opcode) {
518 case opEQ : SetBool(a, slotRawSymbol(a) == slotRawSymbol(b)); break;
519 case opNE : SetBool(a, slotRawSymbol(a) != slotRawSymbol(b)); break;
520 case opLT : SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) < 0); break;
521 case opGT : SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) > 0); break;
522 case opLE : SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) <= 0); break;
523 case opGE : SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) >= 0); break;
524 //default : leave first operand on stack
526 } else {
527 if (IS_BINARY_BOOL_OP(opcode))
528 SetBool(a, opcode == opNE);
530 break;
531 case tagObj : {
532 if (isKindOf(slotRawObject(a), class_signal)) {
533 switch (GetTag(b)) {
534 case tagInt :
535 switch (opcode) {
536 case opAdd : SetRaw(a, signal_add_xf(g, slotRawObject(a), slotRawInt(b))); break;
537 case opSub : SetRaw(a, signal_sub_xf(g, slotRawObject(a), slotRawInt(b))); break;
538 case opMul : SetRaw(a, signal_mul_xf(g, slotRawObject(a), slotRawInt(b))); break;
539 case opIDiv : SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawInt(b))); break;
540 case opFDiv : SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawInt(b))); break;
541 case opEQ : SetFalse(a); break;
542 case opNE : SetTrue(a); break;
543 case opMin : SetRaw(a, signal_min_xf(g, slotRawObject(a), slotRawInt(b))); break;
544 case opMax : SetRaw(a, signal_max_xf(g, slotRawObject(a), slotRawInt(b))); break;
545 case opFill : SetRaw(a, signal_fill(slotRawObject(a), slotRawInt(b))); break;
546 case opRing1 : SetRaw(a, signal_ring1_xf(g, slotRawObject(a), slotRawInt(b))); break;
547 case opRing2 : SetRaw(a, signal_ring2_xf(g, slotRawObject(a), slotRawInt(b))); break;
548 case opRing3 : SetRaw(a, signal_ring3_xf(g, slotRawObject(a), slotRawInt(b))); break;
549 case opRing4 : SetRaw(a, signal_ring4_xf(g, slotRawObject(a), slotRawInt(b))); break;
550 case opDifSqr : SetRaw(a, signal_difsqr_xf(g, slotRawObject(a), slotRawInt(b))); break;
551 case opSumSqr : SetRaw(a, signal_sumsqr_xf(g, slotRawObject(a), slotRawInt(b))); break;
552 case opSqrSum : SetRaw(a, signal_sqrsum_xf(g, slotRawObject(a), slotRawInt(b))); break;
553 case opSqrDif : SetRaw(a, signal_sqrdif_xf(g, slotRawObject(a), slotRawInt(b))); break;
554 case opAbsDif : SetRaw(a, signal_absdif_xf(g, slotRawObject(a), slotRawInt(b))); break;
555 case opThresh : SetRaw(a, signal_thresh_xf(g, slotRawObject(a), slotRawInt(b))); break;
556 case opAMClip : SetRaw(a, signal_amclip_xf(g, slotRawObject(a), slotRawInt(b))); break;
557 case opScaleNeg : SetRaw(a, signal_scaleneg_xf(g, slotRawObject(a), slotRawInt(b))); break;
558 case opClip2 : SetRaw(a, signal_clip2_xf(g, slotRawObject(a), slotRawInt(b))); break;
559 case opFold2 : SetRaw(a, signal_fold2_xf(g, slotRawObject(a), slotRawInt(b))); break;
560 case opWrap2 : SetRaw(a, signal_wrap2_xf(g, slotRawObject(a), slotRawInt(b))); break;
561 case opExcess : SetRaw(a, signal_excess_xf(g, slotRawObject(a), slotRawInt(b))); break;
562 case opFirstArg : SetRaw(a, slotRawObject(a)); break;
563 default : goto send_normal_2;
565 break;
566 case tagChar :
567 case tagPtr :
568 case tagNil :
569 case tagFalse :
570 case tagTrue :
571 goto send_normal_2;
572 case tagSym :
573 if (IS_BINARY_BOOL_OP(opcode))
574 SetBool(a, opcode == opNE);
575 else
576 SetSymbol(a, slotRawSymbol(b));
577 break;
578 case tagObj :
579 if (isKindOf(slotRawObject(b), class_signal)) {
580 switch (opcode) {
581 case opAdd : SetRaw(a, signal_add_xx(g, slotRawObject(a), slotRawObject(b))); break;
582 case opSub : SetRaw(a, signal_sub_xx(g, slotRawObject(a), slotRawObject(b))); break;
583 case opMul : SetRaw(a, signal_mul_xx(g, slotRawObject(a), slotRawObject(b))); break;
584 case opIDiv : SetRaw(a, signal_div_xx(g, slotRawObject(a), slotRawObject(b))); break;
585 case opFDiv : SetRaw(a, signal_div_xx(g, slotRawObject(a), slotRawObject(b))); break;
586 case opEQ : SetBool(a, signal_equal_xx(g, slotRawObject(a), slotRawObject(b))); break;
587 case opNE : SetBool(a, !signal_equal_xx(g, slotRawObject(a), slotRawObject(b))); break;
588 case opMin : SetRaw(a, signal_min_xx(g, slotRawObject(a), slotRawObject(b))); break;
589 case opMax : SetRaw(a, signal_max_xx(g, slotRawObject(a), slotRawObject(b))); break;
590 case opRing1 : SetRaw(a, signal_ring1_xx(g, slotRawObject(a), slotRawObject(b))); break;
591 case opRing2 : SetRaw(a, signal_ring2_xx(g, slotRawObject(a), slotRawObject(b))); break;
592 case opRing3 : SetRaw(a, signal_ring3_xx(g, slotRawObject(a), slotRawObject(b))); break;
593 case opRing4 : SetRaw(a, signal_ring4_xx(g, slotRawObject(a), slotRawObject(b))); break;
594 case opDifSqr : SetRaw(a, signal_difsqr_xx(g, slotRawObject(a), slotRawObject(b))); break;
595 case opSumSqr : SetRaw(a, signal_sumsqr_xx(g, slotRawObject(a), slotRawObject(b))); break;
596 case opSqrSum : SetRaw(a, signal_sqrsum_xx(g, slotRawObject(a), slotRawObject(b))); break;
597 case opSqrDif : SetRaw(a, signal_sqrdif_xx(g, slotRawObject(a), slotRawObject(b))); break;
598 case opAbsDif : SetRaw(a, signal_absdif_xx(g, slotRawObject(a), slotRawObject(b))); break;
599 case opThresh : SetRaw(a, signal_thresh_xx(g, slotRawObject(a), slotRawObject(b))); break;
600 case opAMClip : SetRaw(a, signal_amclip_xx(g, slotRawObject(a), slotRawObject(b))); break;
601 case opScaleNeg : SetRaw(a, signal_scaleneg_xx(g, slotRawObject(a), slotRawObject(b))); break;
602 case opClip2 : SetRaw(a, signal_clip2_xx(g, slotRawObject(a), slotRawObject(b))); break;
603 case opFold2 : SetRaw(a, signal_fold2_xx(g, slotRawObject(a), slotRawObject(b))); break;
604 case opWrap2 : SetRaw(a, signal_wrap2_xx(g, slotRawObject(a), slotRawObject(b))); break;
605 case opExcess : SetRaw(a, signal_excess_xx(g, slotRawObject(a), slotRawObject(b))); break;
606 case opFirstArg : SetRaw(a, slotRawObject(a)); break;
607 default : goto send_normal_2;
609 } else goto send_normal_2;
610 break;
611 default : // double
612 switch (opcode) {
613 case opAdd : SetRaw(a, signal_add_xf(g, slotRawObject(a), slotRawFloat(b))); break;
614 case opSub : SetRaw(a, signal_sub_xf(g, slotRawObject(a), slotRawFloat(b))); break;
615 case opMul : SetRaw(a, signal_mul_xf(g, slotRawObject(a), slotRawFloat(b))); break;
616 case opIDiv : SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawFloat(b))); break;
617 case opFDiv : SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawFloat(b))); break;
618 case opEQ : SetFalse(a); break;
619 case opNE : SetTrue(a); break;
620 case opMin : SetRaw(a, signal_min_xf(g, slotRawObject(a), slotRawFloat(b))); break;
621 case opMax : SetRaw(a, signal_max_xf(g, slotRawObject(a), slotRawFloat(b))); break;
622 case opFill : SetRaw(a, signal_fill(slotRawObject(a), slotRawFloat(b))); break;
623 case opRing1 : SetRaw(a, signal_ring1_xf(g, slotRawObject(a), slotRawFloat(b))); break;
624 case opRing2 : SetRaw(a, signal_ring2_xf(g, slotRawObject(a), slotRawFloat(b))); break;
625 case opRing3 : SetRaw(a, signal_ring3_xf(g, slotRawObject(a), slotRawFloat(b))); break;
626 case opRing4 : SetRaw(a, signal_ring4_xf(g, slotRawObject(a), slotRawFloat(b))); break;
627 case opDifSqr : SetRaw(a, signal_difsqr_xf(g, slotRawObject(a), slotRawFloat(b))); break;
628 case opSumSqr : SetRaw(a, signal_sumsqr_xf(g, slotRawObject(a), slotRawFloat(b))); break;
629 case opSqrSum : SetRaw(a, signal_sqrsum_xf(g, slotRawObject(a), slotRawFloat(b))); break;
630 case opSqrDif : SetRaw(a, signal_sqrdif_xf(g, slotRawObject(a), slotRawFloat(b))); break;
631 case opAbsDif : SetRaw(a, signal_absdif_xf(g, slotRawObject(a), slotRawFloat(b))); break;
632 case opThresh : SetRaw(a, signal_thresh_xf(g, slotRawObject(a), slotRawFloat(b))); break;
633 case opAMClip : SetRaw(a, signal_amclip_xf(g, slotRawObject(a), slotRawFloat(b))); break;
634 case opScaleNeg : SetRaw(a, signal_scaleneg_xf(g, slotRawObject(a), slotRawFloat(b))); break;
635 case opClip2 : SetRaw(a, signal_clip2_xf(g, slotRawObject(a), slotRawFloat(b))); break;
636 case opFold2 : SetRaw(a, signal_fold2_xf(g, slotRawObject(a), slotRawFloat(b))); break;
637 case opWrap2 : SetRaw(a, signal_wrap2_xf(g, slotRawObject(a), slotRawFloat(b))); break;
638 case opExcess : SetRaw(a, signal_excess_xf(g, slotRawObject(a), slotRawFloat(b))); break;
639 case opFirstArg : SetRaw(a, slotRawObject(a)); break;
640 default : goto send_normal_2;
642 break;
644 } else {
645 goto send_normal_2;
647 } break;
648 default : { // double
649 switch (GetTag(b)) {
650 case tagInt :
651 switch (opcode) {
652 case opAdd : SetRaw(a, slotRawFloat(a) + slotRawInt(b)); break;
653 case opSub : SetRaw(a, slotRawFloat(a) - slotRawInt(b)); break;
654 case opMul : SetRaw(a, slotRawFloat(a) * slotRawInt(b)); break;
655 case opIDiv : SetInt(a, (long)floor(slotRawFloat(a) / slotRawInt(b))); break;
656 case opFDiv : SetRaw(a, slotRawFloat(a) / slotRawInt(b)); break;
657 case opMod : SetRaw(a, sc_mod(slotRawFloat(a), (double)slotRawInt(b))); break;
658 case opEQ : SetBool(a, slotRawFloat(a) == slotRawInt(b)); break;
659 case opNE : SetBool(a, slotRawFloat(a) != slotRawInt(b)); break;
660 case opLT : SetBool(a, slotRawFloat(a) < slotRawInt(b)); break;
661 case opGT : SetBool(a, slotRawFloat(a) > slotRawInt(b)); break;
662 case opLE : SetBool(a, slotRawFloat(a) <= slotRawInt(b)); break;
663 case opGE : SetBool(a, slotRawFloat(a) >= slotRawInt(b)); break;
664 //case opIdentical : SetFalse(a); break;
665 //case opNotIdentical : SetTrue(a); break;
666 case opMin : SetRaw(a, sc_min(slotRawFloat(a), (double)slotRawInt(b))); break;
667 case opMax : SetRaw(a, sc_max(slotRawFloat(a), (double)slotRawInt(b))); break;
668 case opRound : SetRaw(a, sc_round(slotRawFloat(a), (double)slotRawInt(b))); break;
669 case opRoundUp : SetRaw(a, sc_roundUp(slotRawFloat(a), (double)slotRawInt(b))); break;
670 case opTrunc : SetRaw(a, sc_trunc(slotRawFloat(a), (double)slotRawInt(b))); break;
671 case opAtan2 : SetRaw(a, atan2(slotRawFloat(a), slotRawInt(b))); break;
672 case opHypot : SetRaw(a, hypot(slotRawFloat(a), slotRawInt(b))); break;
673 case opHypotx : SetRaw(a, hypotx(slotRawFloat(a), slotRawInt(b))); break;
674 case opPow : SetRaw(a, pow(slotRawFloat(a), (double)slotRawInt(b))); break;
675 case opRing1 : SetRaw(a, sc_ring1(slotRawFloat(a), (double)slotRawInt(b))); break;
676 case opRing2 : SetRaw(a, sc_ring2(slotRawFloat(a), (double)slotRawInt(b))); break;
677 case opRing3 : SetRaw(a, sc_ring3(slotRawFloat(a), (double)slotRawInt(b))); break;
678 case opRing4 : SetRaw(a, sc_ring4(slotRawFloat(a), (double)slotRawInt(b))); break;
679 case opDifSqr : SetRaw(a, sc_difsqr(slotRawFloat(a), (double)slotRawInt(b))); break;
680 case opSumSqr : SetRaw(a, sc_sumsqr(slotRawFloat(a), (double)slotRawInt(b))); break;
681 case opSqrSum : SetRaw(a, sc_sqrsum(slotRawFloat(a), (double)slotRawInt(b))); break;
682 case opSqrDif : SetRaw(a, sc_sqrdif(slotRawFloat(a), (double)slotRawInt(b))); break;
683 case opAbsDif : SetRaw(a, sc_abs(slotRawFloat(a) - slotRawInt(b))); break;
684 case opThresh : SetRaw(a, sc_thresh(slotRawFloat(a), slotRawInt(b))); break;
685 case opAMClip : SetRaw(a, sc_amclip(slotRawFloat(a), (double)slotRawInt(b))); break;
686 case opScaleNeg : SetRaw(a, sc_scaleneg(slotRawFloat(a), (double)slotRawInt(b))); break;
687 case opClip2 : SetRaw(a, sc_clip2(slotRawFloat(a), (double)slotRawInt(b))); break;
688 case opFold2 : SetRaw(a, sc_fold2(slotRawFloat(a), (double)slotRawInt(b))); break;
689 case opWrap2 : SetRaw(a, sc_wrap2(slotRawFloat(a), (double)slotRawInt(b))); break;
690 case opExcess : SetRaw(a, sc_excess(slotRawFloat(a), (double)slotRawInt(b))); break;
691 case opFirstArg : SetRaw(a, slotRawFloat(a)); break;
692 case opRandRange :
693 SetRaw(a, slotRawFloat(a) + g->rgen->frand() * (slotRawInt(b) - slotRawFloat(a)));
694 break;
695 case opExpRandRange :
696 SetRaw(a, g->rgen->exprandrng(slotRawFloat(a), slotRawInt(b)));
697 break;
698 default : goto send_normal_2;
700 break;
701 case tagChar :
702 case tagPtr :
703 case tagNil :
704 case tagFalse :
705 case tagTrue :
706 goto send_normal_2;
707 case tagSym :
708 if (IS_BINARY_BOOL_OP(opcode))
709 SetBool(a, opcode == opNE);
710 else
711 SetSymbol(a, slotRawSymbol(b));
712 break;
713 case tagObj :
714 if (isKindOf(slotRawObject(b), class_signal)) {
715 switch (opcode) {
716 case opAdd : SetObject(a, signal_add_xf(g, slotRawObject(b), slotRawFloat(a))); break;
717 case opSub : SetObject(a, signal_sub_fx(g, slotRawFloat(a), slotRawObject(b))); break;
718 case opMul : SetObject(a, signal_mul_xf(g, slotRawObject(b), slotRawFloat(a))); break;
719 case opIDiv : SetObject(a, signal_div_fx(g, slotRawFloat(a), slotRawObject(b))); break;
720 case opFDiv : SetObject(a, signal_div_fx(g, slotRawFloat(a), slotRawObject(b))); break;
721 case opEQ : SetFalse(a); break;
722 case opNE : SetTrue(a); break;
723 case opMin : SetObject(a, signal_min_xf(g, slotRawObject(b), slotRawFloat(a))); break;
724 case opMax : SetObject(a, signal_max_xf(g, slotRawObject(b), slotRawFloat(a))); break;
725 case opRing1 : SetObject(a, signal_ring1_fx(g, slotRawFloat(a), slotRawObject(b))); break;
726 case opRing2 : SetObject(a, signal_ring2_fx(g, slotRawFloat(a), slotRawObject(b))); break;
727 case opRing3 : SetObject(a, signal_ring3_fx(g, slotRawFloat(a), slotRawObject(b))); break;
728 case opRing4 : SetObject(a, signal_ring4_fx(g, slotRawFloat(a), slotRawObject(b))); break;
729 case opDifSqr : SetObject(a, signal_difsqr_fx(g, slotRawFloat(a), slotRawObject(b))); break;
730 case opSumSqr : SetObject(a, signal_sumsqr_fx(g, slotRawFloat(a), slotRawObject(b))); break;
731 case opSqrSum : SetObject(a, signal_sqrsum_fx(g, slotRawFloat(a), slotRawObject(b))); break;
732 case opSqrDif : SetObject(a, signal_sqrdif_fx(g, slotRawFloat(a), slotRawObject(b))); break;
733 case opAbsDif : SetObject(a, signal_absdif_fx(g, slotRawFloat(a), slotRawObject(b))); break;
734 case opThresh : SetObject(a, signal_thresh_fx(g, slotRawFloat(a), slotRawObject(b))); break;
735 case opAMClip : SetObject(a, signal_amclip_fx(g, slotRawFloat(a), slotRawObject(b))); break;
736 case opScaleNeg : SetObject(a, signal_scaleneg_fx(g, slotRawFloat(a), slotRawObject(b))); break;
737 case opClip2 : SetObject(a, signal_clip2_fx(g, slotRawFloat(a), slotRawObject(b))); break;
738 case opFold2 : SetObject(a, signal_fold2_fx(g, slotRawFloat(a), slotRawObject(b))); break;
739 case opWrap2 : SetObject(a, signal_wrap2_fx(g, slotRawFloat(a), slotRawObject(b))); break;
740 case opExcess : SetObject(a, signal_excess_fx(g, slotRawFloat(a), slotRawObject(b))); break;
741 case opFirstArg : SetObject(a, slotRawObject(a)); break;
742 default : goto send_normal_2;
744 } else goto send_normal_2;
745 break;
746 default : // double
747 switch (opcode) {
748 case opAdd : SetRaw(a, slotRawFloat(a) + slotRawFloat(b)); break;
749 case opSub : SetRaw(a, slotRawFloat(a) - slotRawFloat(b)); break;
750 case opMul : SetRaw(a, slotRawFloat(a) * slotRawFloat(b)); break;
751 case opIDiv : SetInt(a, (long)floor(slotRawFloat(a) / slotRawFloat(b))); break;
752 case opFDiv : SetRaw(a, slotRawFloat(a) / slotRawFloat(b)); break;
753 case opMod : SetRaw(a, sc_mod(slotRawFloat(a), slotRawFloat(b))); break;
754 case opEQ : SetBool(a, slotRawFloat(a) == slotRawFloat(b)); break;
755 case opNE : SetBool(a, slotRawFloat(a) != slotRawFloat(b)); break;
756 case opLT : SetBool(a, slotRawFloat(a) < slotRawFloat(b)); break;
757 case opGT : SetBool(a, slotRawFloat(a) > slotRawFloat(b)); break;
758 case opLE : SetBool(a, slotRawFloat(a) <= slotRawFloat(b)); break;
759 case opGE : SetBool(a, slotRawFloat(a) >= slotRawFloat(b)); break;
760 //case opIdentical : SetBool(a, slotRawFloat(a) == slotRawFloat(b)); break;
761 //case opNotIdentical : SetBool(a, slotRawFloat(a) != slotRawFloat(b)); break;
762 case opMin : SetRaw(a, sc_min(slotRawFloat(a), slotRawFloat(b))); break;
763 case opMax : SetRaw(a, sc_max(slotRawFloat(a), slotRawFloat(b))); break;
764 case opRound : SetRaw(a, sc_round(slotRawFloat(a), slotRawFloat(b))); break;
765 case opRoundUp : SetRaw(a, sc_roundUp(slotRawFloat(a), slotRawFloat(b))); break;
766 case opTrunc : SetRaw(a, sc_trunc(slotRawFloat(a), slotRawFloat(b))); break;
767 case opAtan2 : SetRaw(a, atan2(slotRawFloat(a), slotRawFloat(b))); break;
768 case opHypot : SetRaw(a, hypot(slotRawFloat(a), slotRawFloat(b))); break;
769 case opHypotx : SetRaw(a, hypotx(slotRawFloat(a), slotRawFloat(b))); break;
770 case opPow : SetRaw(a, pow(slotRawFloat(a), slotRawFloat(b))); break;
771 case opRing1 : SetRaw(a, sc_ring1(slotRawFloat(a), slotRawFloat(b))); break;
772 case opRing2 : SetRaw(a, sc_ring2(slotRawFloat(a), slotRawFloat(b))); break;
773 case opRing3 : SetRaw(a, sc_ring3(slotRawFloat(a), slotRawFloat(b))); break;
774 case opRing4 : SetRaw(a, sc_ring4(slotRawFloat(a), slotRawFloat(b))); break;
775 case opDifSqr : SetRaw(a, sc_difsqr(slotRawFloat(a), slotRawFloat(b))); break;
776 case opSumSqr : SetRaw(a, sc_sumsqr(slotRawFloat(a), slotRawFloat(b))); break;
777 case opSqrSum : SetRaw(a, sc_sqrsum(slotRawFloat(a), slotRawFloat(b))); break;
778 case opSqrDif : SetRaw(a, sc_sqrdif(slotRawFloat(a), slotRawFloat(b))); break;
779 case opAbsDif : SetRaw(a, sc_abs(slotRawFloat(a) - slotRawFloat(b))); break;
780 case opThresh : SetRaw(a, sc_thresh(slotRawFloat(a), slotRawFloat(b))); break;
781 case opAMClip : SetRaw(a, sc_amclip(slotRawFloat(a), slotRawFloat(b))); break;
782 case opScaleNeg : SetRaw(a, sc_scaleneg(slotRawFloat(a), slotRawFloat(b))); break;
783 case opClip2 : SetRaw(a, sc_clip2(slotRawFloat(a), slotRawFloat(b))); break;
784 case opFold2 : SetRaw(a, sc_fold2(slotRawFloat(a), slotRawFloat(b))); break;
785 case opWrap2 : SetRaw(a, sc_wrap2(slotRawFloat(a), slotRawFloat(b))); break;
786 case opExcess : SetRaw(a, sc_excess(slotRawFloat(a), slotRawFloat(b))); break;
787 case opFirstArg : SetRaw(a, slotRawFloat(a)); break;
788 case opRandRange :
789 SetRaw(a, slotRawFloat(a) + g->rgen->frand() * (slotRawFloat(b) - slotRawFloat(a)));
790 break;
791 case opExpRandRange :
792 SetRaw(a, g->rgen->exprandrng(slotRawFloat(a), slotRawFloat(b)));
793 break;
794 default : goto send_normal_2;
796 break;
798 } break;
800 g->sp = a; // drop
801 g->numpop = 0;
802 #if TAILCALLOPTIMIZE
803 g->tailCall = 0;
804 #endif
805 return errNone;
807 send_normal_2:
808 if (isPrimitive) // special case flag meaning it is a primitive
809 return errFailed; // arguments remain on the stack
811 msg = gSpecialBinarySelectors[opcode];
812 sendMessage(g, msg, numArgsPushed);
813 return errNone;