root/trunk/orca/op.c

Revision 144, 29.8 kB (checked in by krobillard, 2 years ago)

Native arguments are now kept on the stack until after the call and the
result is now always put into a1.

Line 
1/*============================================================================
2    ORCA Interpreter
3    Copyright (C) 2005-2006  Karl Robillard
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18===========================================================================*/
19
20#include "os.h"
21#include "ovalue.h"
22
23
24void orErrorOp( const char* name, OValue* val )
25{
26    orError( "Invalid type %s for %s", orDatatypeName( orType(val) ), name );
27}
28
29
30void orOpAdd( OValue* a1 )
31{
32    OValue* b = a1 + 1;
33    if( orIs(a1, OT_INTEGER) )
34    {
35        if( orIs(b, OT_INTEGER) )
36        {
37            orResult( OT_INTEGER, orInt(a1) + orInt(b) );
38            return;
39        }
40        else if( orIs(b, OT_DECIMAL) )
41        {
42            orResultDECIMAL( (double) orInt(a1) + orDecimal(b) );
43            return;
44        }
45        else if( orIs(b, OT_TUPLE) )
46        {
47            int tmp, i;
48            OValue *res;
49
50            res = b;
51
52            for( i = 0; i < res->argc; i++ )
53            {
54                tmp = orInt(a1) + b->tuple[i];
55                res->tuple[i] = orToByteRange(tmp);
56            }   
57
58            orResultCopy( *res );
59            return;
60        }
61        a1 = b;
62    }
63    else if( orIs(a1, OT_DECIMAL) )
64    {
65        if( orIs(b, OT_INTEGER) )
66        {
67            orResultDECIMAL( orDecimal(a1) + (double) orInt(b) );
68            return;
69        }
70        else if( orIs(b, OT_DECIMAL) )
71        {
72            orResultDECIMAL( orDecimal(a1) + orDecimal(b) );
73            return;
74        }
75#ifdef LANG_ORCA
76        else if( orIs(b, OT_TUPLE) )
77        {
78            int tmp, i;
79            OValue *res;
80
81            res = b;
82
83            for( i = 0; i < res->argc; i++ )
84            {
85                tmp = (int) orDecimal(a1) + b->tuple[i];
86                res->tuple[i] = orToByteRange(tmp);
87            }   
88
89            orResultCopy( *res );
90            return;
91        }
92#endif
93        a1 = b;
94    }
95    else if( orIs(a1, OT_TUPLE) )
96    {
97        if( orIs(b, OT_TUPLE) )
98        {
99            int tmp, i;
100            OValue* res;
101           
102            res = a1;
103           
104            res->argc = a1->argc > b->argc ? a1->argc : b->argc;
105            for( i = 0; i < res->argc; i++ )
106            {
107                tmp = a1->tuple[i] + b->tuple[i];
108                res->tuple[i] = orToByteRange(tmp);
109            }
110            return;
111        }
112        else if( orIs(b, OT_INTEGER) )
113        {
114            int tmp, i;
115            OValue *res;
116
117            res = a1;
118
119            for( i = 0; i < res->argc; i++ )
120            {
121                tmp = a1->tuple[i] + orInt(b);
122                res->tuple[i] = orToByteRange(tmp);
123            }           
124            return;
125        }
126        else if( orIs(b, OT_DECIMAL) )
127        {
128            int tmp, i;
129            OValue *res;
130
131            res = a1;
132
133            for( i = 0; i < res->argc; i++ )
134            {
135                tmp = a1->tuple[i] + (int) orDecimal(b);
136                res->tuple[i] = orToByteRange(tmp);
137            }           
138            return;
139        }
140        a1 = b;
141    }
142    else if( orIs(a1, OT_TIME) )
143    {
144        if( orIs(b, OT_TIME) )
145        {
146            orSeconds(a1) += orSeconds(b);
147            return;
148        }
149    }
150    orErrorOp( "+", a1 );
151}
152
153
154void orOpSub( OValue* a1 )
155{
156    OValue* b = a1 + 1;
157    if( orIs(a1, OT_INTEGER) )
158    {
159        if( orIs(b, OT_INTEGER) )
160        {
161            orResult( OT_INTEGER, orInt(a1) - orInt(b) );
162            return;
163        }
164        else if( orIs(b, OT_DECIMAL) )
165        {
166            orResultDECIMAL( (double) orInt(a1) - orDecimal(b) );
167            return;
168        }
169#ifdef LANG_ORCA
170        else if( orIs(b, OT_TUPLE) )
171        {
172            int tmp, i;
173            OValue *res;
174
175            res = b;
176
177            for( i = 0; i < res->argc; i++ )
178            {
179                tmp = orInt(a1) - b->tuple[i];
180                res->tuple[i] = orToByteRange(tmp);
181            }   
182
183            orResultCopy( *res );
184            return;
185        }
186#endif
187        a1 = b;
188    }
189    else if( orIs(a1, OT_DECIMAL) )
190    {
191        if( orIs(b, OT_INTEGER) )
192        {
193            orResultDECIMAL( orDecimal(a1) - (double) orInt(b) );
194            return;
195        }
196        else if( orIs(b, OT_DECIMAL) )
197        {
198            orResultDECIMAL( orDecimal(a1) - orDecimal(b) );
199            return;
200        }
201#ifdef LANG_ORCA
202        else if( orIs(b, OT_TUPLE) )
203        {
204            int tmp, i;
205            OValue *res;
206
207            res = b;
208
209            for( i = 0; i < res->argc; i++ )
210            {
211                tmp = (int) orDecimal(a1) - b->tuple[i];
212                res->tuple[i] = orToByteRange(tmp);
213            }   
214
215            orResultCopy( *res );
216            return;
217        }
218#endif
219        a1 = b;
220    }
221    else if( orIs(a1, OT_TUPLE) )
222    {
223        if( orIs(b, OT_TUPLE) )
224        {
225            int tmp, i;
226            OValue* res;
227           
228            res = a1;
229           
230            res->argc = a1->argc > b->argc ? a1->argc : b->argc;
231            for( i = 0; i < res->argc; i++ )
232            {
233                tmp = a1->tuple[i] - b->tuple[i];
234                res->tuple[i] = orToByteRange(tmp);
235            }
236            return;
237        }
238        else if( orIs(b, OT_INTEGER) )
239        {
240            int tmp, i;
241            OValue *res;
242
243            res = a1;
244
245            for( i = 0; i < res->argc; i++ )
246            {
247                tmp = a1->tuple[i] - orInt(b);
248                res->tuple[i] = orToByteRange(tmp);
249            }           
250            return;
251        }
252        else if( orIs(b, OT_DECIMAL) )
253        {
254            int tmp, i;
255            OValue *res;
256
257            res = a1;
258
259            for( i = 0; i < res->argc; i++ )
260            {
261                tmp = a1->tuple[i] - (int) orDecimal(b);
262                res->tuple[i] = orToByteRange(tmp);
263            }           
264            return;
265        }
266        a1 = b;
267    }
268    else if( orIs(a1, OT_TIME) )
269    {
270        if( orIs(b, OT_TIME) )
271        {
272            orSeconds(a1) -= orSeconds(b);
273            return;
274        }
275    }
276    orErrorOp( "-", a1 );
277}
278
279
280void orOpMul( OValue* a1 )
281{
282    OValue* b = a1 + 1;
283    if( orIs(a1, OT_INTEGER) )
284    {
285        if( orIs(b, OT_INTEGER) )
286        {
287            orResult( OT_INTEGER, orInt(a1) * orInt(b) );
288            return;
289        }
290        else if( orIs(b, OT_DECIMAL) )
291        {
292            orResultDECIMAL( (double) orInt(a1) * orDecimal(b) );
293            return;
294        }
295        else if( orIs(b, OT_TUPLE) )
296        {
297            int tmp, i;
298            OValue *res;
299
300            res = b;
301
302            for( i = 0; i < res->argc; i++ )
303            {
304                tmp = orInt(a1) * b->tuple[i];
305                res->tuple[i] = orToByteRange(tmp);
306            }   
307
308            orResultCopy( *res );
309            return;
310        }
311        a1 = b;
312    }
313    else if( orIs(a1, OT_DECIMAL) )
314    {
315        if( orIs(b, OT_INTEGER) )
316        {
317            orResultDECIMAL( orDecimal(a1) * (double) orInt(b) );
318            return;
319        }
320        else if( orIs(b, OT_DECIMAL) )
321        {
322            orResultDECIMAL( orDecimal(a1) * orDecimal(b) );
323            return;
324        }
325#ifdef LANG_ORCA
326        else if( orIs(b, OT_TUPLE) )
327        {
328            int tmp, i;
329            OValue *res;
330
331            res = b;
332
333            for( i = 0; i < res->argc; i++ )
334            {
335                tmp = (int) orDecimal(a1) * b->tuple[i];
336                res->tuple[i] = orToByteRange(tmp);
337            }   
338
339            orResultCopy( *res );
340            return;
341        }
342#endif
343        a1 = b;
344    }
345    else if( orIs(a1, OT_TUPLE) )
346    {
347        if( orIs(b, OT_TUPLE) )
348        {
349            int tmp, i;
350            OValue* res;
351           
352            res = a1;
353           
354            res->argc = a1->argc > b->argc ? a1->argc : b->argc;
355            for( i = 0; i < res->argc; i++ )
356            {
357                tmp = a1->tuple[i] * b->tuple[i];
358                res->tuple[i] = orToByteRange(tmp);
359            }
360            return;
361        }
362        else if( orIs(b, OT_INTEGER) )
363        {
364            int tmp, i;
365            OValue *res;
366
367            res = a1;
368
369            for( i = 0; i < res->argc; i++ )
370            {
371                tmp = a1->tuple[i] * orInt(b);
372                res->tuple[i] = orToByteRange(tmp);
373            }           
374            return;
375        }
376        else if( orIs(b, OT_DECIMAL) )
377        {
378            int tmp, i;
379            OValue *res;
380
381            res = a1;
382
383            for( i = 0; i < res->argc; i++ )
384            {
385                tmp = a1->tuple[i] * (int) orDecimal(b);
386                res->tuple[i] = orToByteRange(tmp);
387            }           
388            return;
389        }
390        a1 = b;
391    }
392    orErrorOp( "*", a1 );
393}
394
395
396void orOpDiv( OValue* a1 )
397{
398    OValue* b = a1 + 1;
399    if( orIs(a1, OT_INTEGER) )
400    {
401        if( orIs(b, OT_INTEGER) )
402        {
403            if( orInt(b) == 0 )
404                goto div0;
405            orResult( OT_INTEGER, orInt(a1) / orInt(b) );
406            return;
407        }
408        else if( orIs(b, OT_DECIMAL) )
409        {
410            if( orDecimal(b) == 0.0 )
411                goto div0;
412            orResultDECIMAL( (double) orInt(a1) / orDecimal(b) );
413            return;
414        }
415#ifdef LANG_ORCA
416        else if( orIs(b, OT_TUPLE) )
417        {
418            int tmp, i;
419            OValue *res;
420
421            res = b;
422
423            for( i = 0; i < res->argc; i++ )
424            {
425                if( b->tuple[i] == 0 )
426                    goto div0;
427                tmp = orInt(a1) / b->tuple[i];
428                res->tuple[i] = orToByteRange(tmp);
429            }   
430
431            orResultCopy( *res );
432            return;
433        }
434#endif
435        a1 = b;
436    }
437    else if( orIs(a1, OT_DECIMAL) )
438    {
439        if( orIs(b, OT_INTEGER) )
440        {
441            if( orInt(b) == 0 )
442                goto div0;
443            orResultDECIMAL( orDecimal(a1) / (double) orInt(b) );
444            return;
445        }
446        else if( orIs(b, OT_DECIMAL) )
447        {
448            if( orDecimal(b) == 0.0 )
449                goto div0;
450            orResultDECIMAL( orDecimal(a1) / orDecimal(b) );
451            return;
452        }
453#ifdef LANG_ORCA
454        else if( orIs(b, OT_TUPLE) )
455        {
456            int tmp, i;
457            OValue *res;
458
459            res = b;
460
461            for( i = 0; i < res->argc; i++ )
462            {
463                if( b->tuple[i] == 0 )
464                    goto div0;
465                tmp = (int) orDecimal(a1) / b->tuple[i];
466                res->tuple[i] = orToByteRange(tmp);
467            }   
468
469            orResultCopy( *res );
470            return;
471        }
472#endif
473        a1 = b;
474    }
475    else if( orIs(a1, OT_TUPLE) )
476    {
477        if( orIs(b, OT_TUPLE) )
478        {
479            int tmp, i;
480            OValue* res;
481           
482            res = a1;
483           
484            res->argc = a1->argc > b->argc ? a1->argc : b->argc;
485            for( i = 0; i < res->argc; i++ )
486            {
487                if( b->tuple[i] == 0 )
488                    goto div0;
489                tmp = a1->tuple[i] / b->tuple[i];
490                res->tuple[i] = orToByteRange(tmp);
491            }
492            return;
493        }
494        else if( orIs(b, OT_INTEGER) )
495        {
496            int tmp, i;
497            OValue *res;
498
499            res = a1;
500
501            for( i = 0; i < res->argc; i++ )
502            {
503                if( orInt(b) == 0 )
504                    goto div0;
505                tmp = a1->tuple[i] / orInt(b);
506                res->tuple[i] = orToByteRange(tmp);
507            }           
508            return;
509        }
510        else if( orIs(b, OT_DECIMAL) )
511        {
512            int tmp, i;
513            OValue *res;
514
515            res = a1;
516
517            for( i = 0; i < res->argc; i++ )
518            {
519                if( orDecimal(b) == 0 )
520                    goto div0;
521                tmp = a1->tuple[i] / (int) orDecimal(b);
522                res->tuple[i] = orToByteRange(tmp);
523            }           
524            return;
525        }
526        a1 = b;
527    }
528    orErrorOp( "/", a1 );
529    return;
530
531div0:
532
533    orErrorT( OR_ERROR_MATH, "Divide by zero" );
534}
535
536
537#define CMP_LESS     0
538#define CMP_EQUAL    1
539#define CMP_GREATER  2
540#define CMP_ERROR_B  3
541#define CMP_ERROR_A  4
542
543/*
544  Returns CMP_ value.
545*/
546static int compareValue( const OValue* a, const OValue* b )
547{
548    if( orIs(a, OT_INTEGER) )
549    {
550        if( orIs(b, OT_INTEGER) )
551        {
552            if( orInt(a) > orInt(b) )
553                return CMP_GREATER;
554            if( orInt(a) < orInt(b) )
555                return CMP_LESS;
556            return CMP_EQUAL;
557        }
558        else if( orIs(b, OT_DECIMAL) )
559        {
560            double da = (double) orInt(a);
561            if( da > orDecimal(b) )
562                return CMP_GREATER;
563            if( da < orDecimal(b) )
564                return CMP_LESS;
565            return CMP_EQUAL;
566        }
567        return CMP_ERROR_B;
568    }
569    else if( orIs(a, OT_DECIMAL) )
570    {
571        if( orIs(b, OT_INTEGER) )
572        {
573            double db = (double) orInt(b);
574            if( orDecimal(a) > db )
575                return CMP_GREATER;
576            if( orDecimal(a) < db )
577                return CMP_LESS;
578            return CMP_EQUAL;
579        }
580        else if( orIs(b, OT_DECIMAL) )
581        {
582            if( orDecimal(a) > orDecimal(b) )
583                return CMP_GREATER;
584            if( orDecimal(a) < orDecimal(b) )
585                return CMP_LESS;
586            return CMP_EQUAL;
587        }
588        return CMP_ERROR_B;
589    }
590    else if( orIs(a, OT_TUPLE) )
591    {
592        if( orIs(b, OT_TUPLE) )
593        {
594            int i, len;           
595            len = orTupleLen(a) > orTupleLen(b) ? orTupleLen(a) : orTupleLen(b);
596            for( i = 0; i < len; i++ )
597            {
598                if( a->tuple[i] > b->tuple[i] )
599                    return CMP_GREATER;
600                if( a->tuple[i] < b->tuple[i] )
601                    return CMP_LESS;
602            }
603            return CMP_EQUAL;
604        }
605        return CMP_ERROR_B;
606    }
607    return CMP_ERROR_A;
608}
609
610
611void orOpGreater( OValue* a1 )
612{
613    OValue* b = a1 + 1;
614    switch( compareValue( a1, b ) )
615    {
616        case CMP_LESS:
617        case CMP_EQUAL:
618            orResult( OT_LOGIC, OR_FALSE );
619            break;
620        case CMP_GREATER:
621            orResult( OT_LOGIC, OR_TRUE );
622            break;
623        case CMP_ERROR_B:
624            a1 = b;
625        case CMP_ERROR_A:
626            orErrorOp( ">", a1 );
627            break;
628    }
629}
630
631
632void orOpLess( OValue* a1 )
633{
634    OValue* b = a1 + 1;
635    switch( compareValue( a1, b ) )
636    {
637        case CMP_LESS:
638            orResult( OT_LOGIC, OR_TRUE );
639            break;
640        case CMP_EQUAL:
641        case CMP_GREATER:
642            orResult( OT_LOGIC, OR_FALSE );
643            break;
644        case CMP_ERROR_B:
645            a1 = b;
646        case CMP_ERROR_A:
647            orErrorOp( "<", a1 );
648            break;
649    }
650}
651
652
653#define LOWERCASE(c) \
654    if( (c >= 'A') && (c <= 'Z') ) \
655        c = c + ('a' - 'A')
656
657static int stringSame( const OValue* a, const OValue* b, int compareCase )
658{
659    OString* sa;
660    OString* sb;
661    int lenA;
662    int lenB;
663
664    sa   = orSTRING(a);
665    lenA = orSeriesLen(sa, a);
666
667    sb   = orSTRING(b);
668    lenB = orSeriesLen(sb, b);
669
670    if( lenA == lenB )
671    {
672        const char* ca;
673        const char* cb;
674        const char* end;
675
676        ca  = orStrChars( sa, a );
677        cb  = orStrChars( sb, b );
678
679        if( ca == cb )
680            return 1;
681
682        end = ca + lenA;
683
684        if( compareCase )
685        {
686            while( ca != end )
687            {
688                if( *ca++ != *cb++ )
689                    return 0;
690            }
691        }
692        else
693        {
694            while( ca != end )
695            {
696                lenA = *ca++;
697                lenB = *cb++;
698
699                LOWERCASE( lenA );
700                LOWERCASE( lenB );
701
702                if( lenA != lenB )
703                    return 0;
704            }
705        }
706        return 1;
707    }
708
709    return 0;
710}
711
712
713static int orTypeEqual( const OValue* a, const OValue* b )
714{
715    int logic = 0;
716
717    if( orType(a) == orType(b) )
718    {
719        switch( orType(a) )
720        {
721            case OT_BLOCK:
722            case OT_PAREN:
723            case OT_PATH:
724            case OT_LITPATH:
725            case OT_SETPATH:
726                // TODO: compare all values.
727                if( (a->series.n == b->series.n) &&
728                    (a->series.it == b->series.it) )
729                    logic = 1;
730                break;
731
732            case OT_STRING:
733            case OT_ISSUE:
734            case OT_TAG:
735            case OT_FILE:
736                logic = stringSame( a, b, 0 );
737                break;
738
739            case OT_BINARY:
740            case OT_BITSET:
741                logic = stringSame( a, b, 1 );
742                break;
743
744            case OT_TUPLE:
745                logic = (compareValue( a, b ) == CMP_EQUAL) ? 1 : 0;
746                break;
747
748            case OT_DECIMAL:
749                if( orDecimal(a) == orDecimal(b) )
750                    logic = 1;
751                break;
752
753            case OT_CHAR:
754            case OT_LOGIC:
755            case OT_INTEGER:
756                if( orInt(a) == orInt(b) )
757                    logic = 1;
758                break;
759
760            case OT_WORD:
761                if( orAtom(a) == orAtom(b) )
762                    logic = 1;
763                break;
764        }
765    }
766
767    return logic;
768}
769
770
771int orEqual( const OValue* a, const OValue* b )
772{
773    if( orIsWord(orType(a)) && orIsWord(orType(b)) )
774    {
775        if( orAtom(a) == orAtom(b) )
776            return 1;
777    }
778    else if( orIs(a, OT_INTEGER) )
779    {
780        if( orIs(b, OT_INTEGER) )
781        {
782            if( orInt(a) == orInt(b) )
783                return 1;
784        }
785        else if( orIs(b, OT_DECIMAL) )
786        {
787            if( ((double) orInt(a)) == orDecimal(b) )
788                return 1;
789        }
790        return 0;
791    }
792    else if( orIs(a, OT_DECIMAL) )
793    {
794        if( orIs(b, OT_INTEGER) )
795        {
796            if( orDecimal(a) == ((double) orInt(b)) )
797                return 1;
798        }
799        else if( orIs(b, OT_DECIMAL) )
800        {
801            if( orDecimal(a) == orDecimal(b) )
802                return 1;
803        }
804        return 0;
805    }
806
807    return orTypeEqual( a, b );
808}
809
810
811void orOpTypeEqual( OValue* a1 )
812{
813    int logic = orTypeEqual( a1, a1 + 1 );
814    orResult( OT_LOGIC, logic );
815}
816
817
818void orOpEqual( OValue* a1 )
819{
820    int logic = orEqual( a1, a1 + 1 );
821    orResult( OT_LOGIC, logic );
822}
823
824
825void orOpNotEqual( OValue* a1 )
826{
827    int logic = orEqual( a1, a1 + 1 ) ^ 1;
828    orResult( OT_LOGIC, logic );
829}
830
831
832void orOpSame( OValue* a1 )
833{
834    int logic = 0;
835    OValue* b = a1 + 1;
836
837    if( orIs(a1, OT_INTEGER) )
838    {
839        if( orIs(b, OT_INTEGER) )
840            logic = (orInt(a1) == orInt(b));
841        else if( orIs(b, OT_DECIMAL) )
842            logic = ((double) orInt(a1) == orDecimal(b));
843    }
844    else if( orIs(a1, OT_DECIMAL) )
845    {
846        if( orIs(b, OT_INTEGER) )
847            logic = (orDecimal(a1) == (double) orInt(b));
848        else if( orIs(b, OT_DECIMAL) )
849            logic = (orDecimal(a1) == orDecimal(b));
850    }
851    else if( orType(a1) == orType(b) )
852    {
853        if( orIs(a1, OT_WORD) )
854        {
855            if( (a1->word.atom == b->word.atom) &&
856                (a1->word.context == b->word.context) )
857                logic = 1;
858        }
859        else if( orIs(a1, OT_OBJECT) )
860        {
861            if( a1->index == b->index )
862                logic = 1;
863        }
864        else if( orIsSeries( orType(a1) ) )
865        {
866            if( (a1->series.n == b->series.n) &&
867                (a1->series.it == b->series.it) )
868                logic = 1;
869        }
870        else if( orIs(a1, OT_TUPLE) )
871        {
872            logic = compareValue( a1, b );
873        }
874    }
875    orResult( OT_LOGIC, logic );
876}
877
878
879void orOpLTEqual( OValue* a1 )
880{
881    OValue* b = a1 + 1;
882    switch( compareValue( a1, b ) )
883    {
884        case CMP_LESS:
885        case CMP_EQUAL:
886            orResult( OT_LOGIC, OR_TRUE );
887            break;
888        case CMP_GREATER:
889            orResult( OT_LOGIC, OR_FALSE );
890            break;
891        case CMP_ERROR_B:
892            a1 = b;
893        case CMP_ERROR_A:
894            orErrorOp( "<=", a1 );
895            break;
896    }
897}
898
899
900void orOpGTEqual( OValue* a1 )
901{
902    OValue* b = a1 + 1;
903    switch( compareValue( a1, b ) )
904    {
905        case CMP_LESS:
906            orResult( OT_LOGIC, OR_FALSE );
907            break;
908        case CMP_EQUAL:
909        case CMP_GREATER:
910            orResult( OT_LOGIC, OR_TRUE );
911            break;
912        case CMP_ERROR_B:
913            a1 = b;
914        case CMP_ERROR_A:
915            orErrorOp( ">=", a1 );
916            break;
917    }
918}
919
920
921void orOpAnd( OValue* a1 )
922{
923    OValue* b = a1 + 1;
924    if( orIs(a1, OT_INTEGER) )
925    {
926        if( orIs(b, OT_INTEGER) )
927        {
928            orResult( OT_INTEGER, orInt(a1) & orInt(b) );
929            return;
930        }
931#ifdef LANG_ORCA
932        else if( orIs(b, OT_TUPLE) )
933        {
934            int i;
935            OValue *res;
936
937            res = b;
938
939            for( i = 0; i < res->argc; i++ )
940            {
941                res->tuple[i] =  orInt(a1) & b->tuple[i];
942            }   
943
944            orResultCopy( *res );
945            return;
946        }
947#endif
948        a1 = b;
949    }
950#ifdef LANG_ORCA
951    else if( orIs(a1, OT_DECIMAL) )
952    {
953        if( orIs(b, OT_TUPLE) )
954        {
955            int i;
956            OValue *res;
957
958            res = b;
959
960            for( i = 0; i < res->argc; i++ )
961            {
962                res->tuple[i] =  (int) orDecimal(a1) & b->tuple[i];
963            }   
964
965            orResultCopy( *res );
966            return;
967        }
968        a1 = b;
969    }
970#endif
971    else if( orIs(a1, OT_LOGIC) )
972    {
973        if( orIs(b, OT_LOGIC) )
974        {
975            orResult( OT_LOGIC, orInt(a1) & orInt(b) );
976            return;
977        }
978        else if( orIs(b, OT_NONE) )
979        {
980            // Weird - cannot take none as first argument.
981            orResultFALSE;
982            return;
983        }
984        a1 = b;
985    }
986    else if( orIs(a1, OT_TUPLE) )
987    {
988        if( orIs(b, OT_TUPLE) )
989        {
990            int i;           
991            a1->argc = a1->argc > b->argc ? a1->argc : b->argc;
992            for( i = 0; i < a1->argc; i++ )
993            {
994                a1->tuple[i] = a1->tuple[i] & b->tuple[i];
995            }
996            return;
997        }
998        else if( orIs(b, OT_INTEGER) )
999        {
1000            int i;
1001            for( i = 0; i < a1->argc; i++ )
1002            {
1003                a1->tuple[i] = a1->tuple[i] & orInt(b);
1004            }           
1005            return;
1006        }
1007        else if( orIs(b, OT_DECIMAL) )
1008        {
1009            int i;
1010            for( i = 0; i < a1->argc; i++ )
1011            {
1012                a1->tuple[i] = a1->tuple[i] & (int) orDecimal(b);                     
1013            }           
1014            return;
1015        }
1016        a1 = b;
1017    }
1018    orErrorOp( "and", a1 );
1019}
1020
1021
1022void orOpOr( OValue* a1 )
1023{
1024    OValue* b = a1 + 1;
1025    if( orIs(a1, OT_INTEGER) )
1026    {
1027        if( orIs(b, OT_INTEGER) )
1028        {
1029            orResult( OT_INTEGER, orInt(a1) | orInt(b) );
1030            return;
1031        }
1032#ifdef LANG_ORCA
1033        else if( orIs(b, OT_TUPLE) )
1034        {
1035            int i;
1036            OValue *res;
1037
1038            res = b;
1039
1040            for( i = 0; i < res->argc; i++ )
1041            {
1042                res->tuple[i] =  orInt(a1) | b->tuple[i];
1043            }   
1044
1045            orResultCopy( *res );
1046            return;
1047        }
1048#endif
1049        a1 = b;
1050    }
1051#ifdef LANG_ORCA
1052    else if( orIs(a1, OT_DECIMAL) )
1053    {
1054        if( orIs(b, OT_TUPLE) )
1055        {
1056            int i;
1057            OValue *res;
1058
1059            res = b;
1060
1061            for( i = 0; i < res->argc; i++ )
1062            {
1063                res->tuple[i] =  (int) orDecimal(a1) | b->tuple[i];
1064            }   
1065
1066            orResultCopy( *res );
1067            return;
1068        }
1069        a1 = b;
1070    }
1071#endif
1072    else if( orIs(a1, OT_LOGIC) )
1073    {
1074        if( orIs(b, OT_LOGIC) )
1075        {
1076            orResult( OT_LOGIC, orInt(a1) | orInt(b) );
1077            return;
1078        }
1079        a1 = b;
1080    }
1081    else if( orIs(a1, OT_TUPLE) )
1082    {
1083        if( orIs(b, OT_TUPLE) )
1084        {
1085            int i;           
1086            a1->argc = a1->argc > b->argc ? a1->argc : b->argc;
1087            for( i = 0; i < a1->argc; i++ )
1088            {
1089                a1->tuple[i] = a1->tuple[i] | b->tuple[i];
1090            }
1091            return;
1092        }
1093        else if( orIs(b, OT_INTEGER) )
1094        {
1095            int i;
1096#ifndef LANG_ORCA
1097            int tmp;
1098#endif
1099            for( i = 0; i < a1->argc; i++ )
1100            {
1101#ifdef LANG_ORCA
1102                a1->tuple[i] = a1->tuple[i] | orInt(b);
1103#else
1104                tmp =  orToByteRange( orInt(b) );
1105                if( tmp == 0 )
1106                    a1->tuple[i] = 0;
1107                else if( tmp == 255 )
1108                    a1->tuple[i] = 255;
1109                else
1110                    a1->tuple[i] = a1->tuple[i] | orInt(b);
1111#endif
1112            }           
1113            return;
1114        }
1115        else if( orIs(b, OT_DECIMAL) )
1116        {
1117            int i;
1118#ifndef LANG_ORCA
1119            int tmp;
1120#endif
1121            for( i = 0; i < a1->argc; i++ )
1122            {
1123#ifdef LANG_ORCA
1124                a1->tuple[i] = a1->tuple[i] | (int) orDecimal(b);
1125#else
1126                tmp =  orToByteRange( (int) orDecimal(b) );
1127                if( tmp == 0 )
1128                    a1->tuple[i] = 0;
1129                else if( tmp == 255 )
1130                    a1->tuple[i] = 255;
1131                else
1132                    a1->tuple[i] = a1->tuple[i] | orToByteRange( (int) orDecimal(b) );
1133#endif