4 * Copyright (C) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "st-primitives.h"
26 #include "st-processor.h"
28 #include "st-large-integer.h"
31 #include "st-object.h"
32 #include "st-behavior.h"
33 #include "st-context.h"
34 #include "st-method.h"
35 #include "st-symbol.h"
36 #include "st-character.h"
37 #include "st-unicode.h"
47 #define ST_PRIMITIVE_FAIL(pr) \
52 set_success (st_processor
*pr
, bool success
)
54 pr
->success
= pr
->success
&& success
;
58 pop_integer (st_processor
*pr
)
60 st_oop object
= ST_STACK_POP (pr
);
62 if (ST_LIKELY (st_object_is_smi (object
)))
63 return st_smi_value (object
);
65 ST_PRIMITIVE_FAIL (pr
);
70 pop_integer32 (st_processor
*pr
)
72 st_oop object
= ST_STACK_POP (pr
);
74 if (ST_LIKELY (st_object_is_smi (object
)))
75 return st_smi_value (object
);
76 else if (st_object_class (object
) == st_large_integer_class
)
77 return (st_smi
) mp_get_int (st_large_integer_value (object
));
79 ST_PRIMITIVE_FAIL (pr
);
84 SmallInteger_add (st_processor
*pr
)
86 st_smi y
= pop_integer (pr
);
87 st_smi x
= pop_integer (pr
);
90 if (ST_LIKELY (pr
->success
)) {
91 result
= st_smi_new (x
+ y
);
92 ST_STACK_PUSH (pr
, result
);
96 ST_STACK_UNPOP (pr
, 2);
100 SmallInteger_sub (st_processor
*pr
)
102 st_smi y
= pop_integer (pr
);
103 st_smi x
= pop_integer (pr
);
106 if (ST_LIKELY (pr
->success
)) {
107 result
= st_smi_new (x
- y
);
108 ST_STACK_PUSH (pr
, result
);
112 ST_STACK_UNPOP (pr
, 2);
116 SmallInteger_lt (st_processor
*pr
)
118 st_smi y
= pop_integer (pr
);
119 st_smi x
= pop_integer (pr
);
122 if (ST_LIKELY (pr
->success
)) {
123 result
= (x
< y
) ? st_true
: st_false
;
124 ST_STACK_PUSH (pr
, result
);
128 ST_STACK_UNPOP (pr
, 2);
132 SmallInteger_gt (st_processor
*pr
)
134 st_smi y
= pop_integer (pr
);
135 st_smi x
= pop_integer (pr
);
138 if (ST_LIKELY (pr
->success
)) {
139 result
= (x
> y
) ? st_true
: st_false
;
140 ST_STACK_PUSH (pr
, result
);
144 ST_STACK_UNPOP (pr
, 2);
148 SmallInteger_le (st_processor
*pr
)
150 st_smi y
= pop_integer (pr
);
151 st_smi x
= pop_integer (pr
);
154 if (ST_LIKELY (pr
->success
)) {
155 result
= (x
<= y
) ? st_true
: st_false
;
156 ST_STACK_PUSH (pr
, result
);
160 ST_STACK_UNPOP (pr
, 2);
164 SmallInteger_ge (st_processor
*pr
)
166 st_smi y
= pop_integer (pr
);
167 st_smi x
= pop_integer (pr
);
170 if (ST_LIKELY (pr
->success
)) {
171 result
= (x
>= y
) ? st_true
: st_false
;
172 ST_STACK_PUSH (pr
, result
);
176 ST_STACK_UNPOP (pr
, 2);
180 SmallInteger_eq (st_processor
*pr
)
182 st_smi y
= pop_integer (pr
);
183 st_smi x
= pop_integer (pr
);
186 if (ST_LIKELY (pr
->success
)) {
187 result
= (x
== y
) ? st_true
: st_false
;
188 ST_STACK_PUSH (pr
, result
);
192 ST_STACK_UNPOP (pr
, 2);
196 SmallInteger_ne (st_processor
*pr
)
198 st_smi y
= pop_integer (pr
);
199 st_smi x
= pop_integer (pr
);
202 if (ST_LIKELY (pr
->success
)) {
203 result
= (x
!= y
) ? st_true
: st_false
;
204 ST_STACK_PUSH (pr
, result
);
208 ST_STACK_UNPOP (pr
, 2);
212 SmallInteger_mul (st_processor
*pr
)
214 st_smi y
= pop_integer (pr
);
215 st_smi x
= pop_integer (pr
);
218 if (ST_LIKELY (pr
->success
)) {
219 result
= st_smi_new (x
* y
);
220 ST_STACK_PUSH (pr
, result
);
224 ST_STACK_UNPOP (pr
, 2);
229 SmallInteger_div (st_processor
*pr
)
231 st_smi y
= pop_integer (pr
);
232 st_smi x
= pop_integer (pr
);
235 if (ST_LIKELY (pr
->success
)) {
237 if (y
!= 0 && x
% y
== 0) {
238 result
= st_smi_new (x
/ y
);
239 ST_STACK_PUSH (pr
, result
);
242 ST_PRIMITIVE_FAIL (pr
);
246 ST_STACK_UNPOP (pr
, 2);
250 SmallInteger_intDiv (st_processor
*pr
)
252 st_smi y
= pop_integer (pr
);
253 st_smi x
= pop_integer (pr
);
256 if (ST_LIKELY (pr
->success
)) {
259 result
= st_smi_new (x
/ y
);
260 ST_STACK_PUSH (pr
, result
);
263 ST_PRIMITIVE_FAIL (pr
);
267 ST_STACK_UNPOP (pr
, 2);
271 SmallInteger_mod (st_processor
*pr
)
273 st_smi y
= pop_integer (pr
);
274 st_smi x
= pop_integer (pr
);
277 if (ST_LIKELY (pr
->success
)) {
278 result
= st_smi_new (x
% y
);
279 ST_STACK_PUSH (pr
, result
);
283 ST_STACK_UNPOP (pr
, 2);
287 SmallInteger_bitOr (st_processor
*pr
)
289 st_smi y
= pop_integer (pr
);
290 st_smi x
= pop_integer (pr
);
291 st_oop result
= st_nil
;
293 if (ST_LIKELY (pr
->success
)) {
294 result
= st_smi_new (x
| y
);
295 ST_STACK_PUSH (pr
, result
);
299 ST_STACK_UNPOP (pr
, 2);
303 SmallInteger_bitXor (st_processor
*pr
)
305 st_smi y
= pop_integer (pr
);
306 st_smi x
= pop_integer (pr
);
309 if (ST_LIKELY (pr
->success
)) {
310 result
= st_smi_new (x
^ y
);
311 ST_STACK_PUSH (pr
, result
);
315 ST_STACK_UNPOP (pr
, 2);
319 SmallInteger_bitAnd (st_processor
*pr
)
321 st_smi y
= pop_integer (pr
);
322 st_smi x
= pop_integer (pr
);
323 st_oop result
= st_nil
;
325 if (ST_LIKELY (pr
->success
)) {
326 result
= st_smi_new (x
& y
);
327 ST_STACK_PUSH (pr
, result
);
331 ST_STACK_UNPOP (pr
, 2);
335 SmallInteger_bitShift (st_processor
*pr
)
337 st_smi y
= pop_integer (pr
);
338 st_smi x
= pop_integer (pr
);
339 st_oop result
= st_nil
;
341 if (ST_LIKELY (pr
->success
)) {
343 result
= st_smi_new (x
<< y
);
345 result
= st_smi_new (x
>> (-y
));
347 result
= st_smi_new (x
);
349 ST_STACK_PUSH (pr
, result
);
353 ST_STACK_UNPOP (pr
, 2);
357 SmallInteger_asFloat (st_processor
*pr
)
359 st_smi x
= pop_integer (pr
);
360 st_oop result
= st_nil
;
362 if (ST_LIKELY (pr
->success
)) {
363 result
= st_float_new ((double) x
);
364 ST_STACK_PUSH (pr
, result
);
368 ST_STACK_UNPOP (pr
, 1);
372 SmallInteger_asLargeInteger (st_processor
*pr
)
374 st_smi receiver
= pop_integer (pr
);
378 mp_init_set (&value
, abs (receiver
));
381 mp_neg (&value
, &value
);
383 result
= st_large_integer_new (&value
);
384 ST_STACK_PUSH (pr
, result
);
387 #define VALUE(oop) (&(ST_LARGE_INTEGER(oop)->value))
389 /* useful macros to avoid duplication of error-handling code */
391 #define OP_PROLOGUE \
396 #define BINARY_OP(op, a, b) \
398 result = op (VALUE (a), VALUE (b), &value);
400 #define BINARY_DIV_OP(op, a, b) \
402 result = op (VALUE (a), VALUE (b), &value, NULL);
404 #define UNARY_OP(op, a) \
406 result = op (VALUE (a), &value);
410 pop_large_integer (st_processor
*pr
)
412 st_oop object
= ST_STACK_POP (pr
);
414 set_success (pr
, st_object_class (object
) == st_large_integer_class
);
420 LargeInteger_add (st_processor
*pr
)
422 st_oop b
= pop_large_integer (pr
);
423 st_oop a
= pop_large_integer (pr
);
427 ST_STACK_UNPOP (pr
, 2);
431 BINARY_OP (mp_add
, a
, b
);
433 result
= st_large_integer_new (&value
);
434 ST_STACK_PUSH (pr
, result
);
438 LargeInteger_sub (st_processor
*pr
)
440 st_oop b
= pop_large_integer (pr
);
441 st_oop a
= pop_large_integer (pr
);
445 ST_STACK_UNPOP (pr
, 2);
449 BINARY_OP (mp_sub
, a
, b
);
451 result
= st_large_integer_new (&value
);
452 ST_STACK_PUSH (pr
, result
);
456 LargeInteger_mul (st_processor
*pr
)
458 st_oop b
= pop_large_integer (pr
);
459 st_oop a
= pop_large_integer (pr
);
463 ST_STACK_UNPOP (pr
, 2);
467 BINARY_OP (mp_mul
, a
, b
);
469 result
= st_large_integer_new (&value
);
470 ST_STACK_PUSH (pr
, result
);
474 LargeInteger_div (st_processor
*pr
)
476 st_oop b
= pop_large_integer (pr
);
477 st_oop a
= pop_large_integer (pr
);
478 mp_int quotient
, remainder
;
482 ST_STACK_UNPOP (pr
, 2);
486 mp_init_multi ("ient
, &remainder
, NULL
);
487 mp_div (VALUE (a
), VALUE (b
), "ient
, &remainder
);
492 mp_radix_size (&remainder
, 10, &size
);
493 str
= st_malloc (size
);
494 mp_toradix (&remainder
, str
, 10);
496 if (mp_cmp_d (&remainder
, 0) == MP_EQ
) {
497 result
= st_large_integer_new ("ient
);
498 ST_STACK_PUSH (pr
, result
);
499 mp_clear (&remainder
);
501 set_success (pr
, false);
502 ST_STACK_UNPOP (pr
, 2);
503 mp_clear_multi ("ient
, &remainder
, NULL
);
508 LargeInteger_intDiv (st_processor
*pr
)
510 st_oop b
= pop_large_integer (pr
);
511 st_oop a
= pop_large_integer (pr
);
515 ST_STACK_UNPOP (pr
, 2);
519 BINARY_DIV_OP (mp_div
, a
, b
);
521 result
= st_large_integer_new (&value
);
522 ST_STACK_PUSH (pr
, result
);
526 LargeInteger_mod (st_processor
*pr
)
528 st_oop b
= pop_large_integer (pr
);
529 st_oop a
= pop_large_integer (pr
);
533 ST_STACK_UNPOP (pr
, 2);
537 BINARY_OP (mp_mod
, a
, b
);
539 result
= st_large_integer_new (&value
);
540 ST_STACK_PUSH (pr
, result
);
544 LargeInteger_gcd (st_processor
*pr
)
546 st_oop b
= pop_large_integer (pr
);
547 st_oop a
= pop_large_integer (pr
);
551 ST_STACK_UNPOP (pr
, 2);
555 BINARY_OP (mp_gcd
, a
, b
);
557 result
= st_large_integer_new (&value
);
558 ST_STACK_PUSH (pr
, result
);
562 LargeInteger_lcm (st_processor
*pr
)
564 st_oop b
= pop_large_integer (pr
);
565 st_oop a
= pop_large_integer (pr
);
569 ST_STACK_UNPOP (pr
, 2);
573 BINARY_OP (mp_lcm
, a
, b
);
575 result
= st_large_integer_new (&value
);
576 ST_STACK_PUSH (pr
, result
);
580 LargeInteger_eq (st_processor
*pr
)
582 st_oop b
= pop_large_integer (pr
);
583 st_oop a
= pop_large_integer (pr
);
588 ST_STACK_UNPOP (pr
, 2);
592 relation
= mp_cmp (VALUE (a
), VALUE (b
));
593 result
= (relation
== MP_EQ
) ? st_true
: st_false
;
594 ST_STACK_PUSH (pr
, result
);
598 LargeInteger_ne (st_processor
*pr
)
600 st_oop b
= pop_large_integer (pr
);
601 st_oop a
= pop_large_integer (pr
);
606 ST_STACK_UNPOP (pr
, 2);
610 relation
= mp_cmp (VALUE (a
), VALUE (b
));
611 result
= (relation
== MP_EQ
) ? st_false
: st_true
;
612 ST_STACK_PUSH (pr
, result
);
616 LargeInteger_lt (st_processor
*pr
)
618 st_oop b
= pop_large_integer (pr
);
619 st_oop a
= pop_large_integer (pr
);
624 ST_STACK_UNPOP (pr
, 2);
628 relation
= mp_cmp (VALUE (a
), VALUE (b
));
629 result
= (relation
== MP_LT
) ? st_true
: st_false
;
630 ST_STACK_PUSH (pr
, result
);
634 LargeInteger_gt (st_processor
*pr
)
636 st_oop b
= pop_large_integer (pr
);
637 st_oop a
= pop_large_integer (pr
);
643 ST_STACK_UNPOP (pr
, 2);
647 relation
= mp_cmp (VALUE (a
), VALUE (b
));
648 result
= (relation
== MP_GT
) ? st_true
: st_false
;
649 ST_STACK_PUSH (pr
, result
);
653 LargeInteger_le (st_processor
*pr
)
655 st_oop b
= pop_large_integer (pr
);
656 st_oop a
= pop_large_integer (pr
);
661 ST_STACK_UNPOP (pr
, 2);
665 relation
= mp_cmp (VALUE (a
), VALUE (b
));
666 result
= (relation
== MP_LT
|| relation
== MP_EQ
) ? st_true
: st_false
;
667 ST_STACK_PUSH (pr
, result
);
671 LargeInteger_ge (st_processor
*pr
)
673 st_oop b
= pop_large_integer (pr
);
674 st_oop a
= pop_large_integer (pr
);
679 ST_STACK_UNPOP (pr
, 2);
683 relation
= mp_cmp (VALUE (a
), VALUE (b
));
684 result
= (relation
== MP_GT
|| relation
== MP_EQ
) ? st_true
: st_false
;
685 ST_STACK_PUSH (pr
, result
);
689 LargeInteger_squared (st_processor
*pr
)
691 st_oop receiver
= pop_large_integer (pr
);
695 ST_STACK_UNPOP (pr
, 1);
699 UNARY_OP (mp_sqr
, receiver
);
701 result
= st_large_integer_new (&value
);
702 ST_STACK_PUSH (pr
, result
);
706 LargeInteger_bitOr (st_processor
*pr
)
708 st_oop b
= pop_large_integer (pr
);
709 st_oop a
= pop_large_integer (pr
);
713 ST_STACK_UNPOP (pr
, 2);
717 BINARY_OP (mp_or
, a
, b
);
719 result
= st_large_integer_new (&value
);
720 ST_STACK_PUSH (pr
, result
);
724 LargeInteger_bitAnd (st_processor
*pr
)
726 st_oop b
= pop_large_integer (pr
);
727 st_oop a
= pop_large_integer (pr
);
731 ST_STACK_UNPOP (pr
, 2);
735 BINARY_OP (mp_and
, a
, b
);
737 result
= st_large_integer_new (&value
);
738 ST_STACK_PUSH (pr
, result
);
742 LargeInteger_bitXor (st_processor
*pr
)
744 st_oop b
= pop_large_integer (pr
);
745 st_oop a
= pop_large_integer (pr
);
749 ST_STACK_UNPOP (pr
, 2);
753 BINARY_OP (mp_xor
, a
, b
);
755 result
= st_large_integer_new (&value
);
756 ST_STACK_PUSH (pr
, result
);
760 LargeInteger_bitShift (st_processor
*pr
)
762 st_smi displacement
= pop_integer32 (pr
);
763 st_oop receiver
= pop_large_integer (pr
);
768 ST_STACK_UNPOP (pr
, 2);
774 if (displacement
>= 0)
775 mp_mul_2d (VALUE (receiver
), displacement
, &value
);
777 mp_div_2d (VALUE (receiver
), abs (displacement
), &value
, NULL
);
779 result
= st_large_integer_new (&value
);
780 ST_STACK_PUSH (pr
, result
);
784 LargeInteger_asFloat (st_processor
*pr
)
786 st_oop receiver
= pop_large_integer (pr
);
790 string
= st_large_integer_to_string (receiver
, 10);
792 dblval
= strtod (string
, NULL
);
795 ST_STACK_PUSH (pr
, st_float_new (dblval
));
799 LargeInteger_printString (st_processor
*pr
)
801 st_smi radix
= pop_integer (pr
);
802 st_oop x
= pop_large_integer (pr
);
806 if (radix
< 2 || radix
> 36)
807 set_success (pr
, false);
810 string
= st_large_integer_to_string (x
, radix
);
811 result
= st_string_new (string
);
815 ST_STACK_PUSH (pr
, result
);
817 ST_STACK_UNPOP (pr
, 2);
821 LargeInteger_hash (st_processor
*pr
)
823 st_oop receiver
= ST_STACK_POP (pr
);
830 value
= st_large_integer_value (receiver
);
831 c
= (const char *) value
->dp
;
832 len
= value
->used
* sizeof (mp_digit
);
835 for(unsigned int i
= 0; i
< len
; i
++)
837 hash
= ((hash
<< 5) + hash
) + c
[i
];
844 ST_STACK_PUSH (pr
, st_smi_new (result
));
849 pop_float (st_processor
*pr
)
851 st_oop object
= ST_STACK_POP (pr
);
853 set_success (pr
, st_object_class (object
) == st_float_class
);
859 Float_add (st_processor
*pr
)
861 st_oop y
= pop_float (pr
);
862 st_oop x
= pop_float (pr
);
863 st_oop result
= st_nil
;
866 result
= st_float_new (st_float_value (x
) + st_float_value (y
));
869 ST_STACK_PUSH (pr
, result
);
871 ST_STACK_UNPOP (pr
, 2);
875 Float_sub (st_processor
*pr
)
877 st_oop y
= pop_float (pr
);
878 st_oop x
= pop_float (pr
);
879 st_oop result
= st_nil
;
882 result
= st_float_new (st_float_value (x
) - st_float_value (y
));
885 ST_STACK_PUSH (pr
, result
);
887 ST_STACK_UNPOP (pr
, 2);
891 Float_lt (st_processor
*pr
)
893 st_oop y
= pop_float (pr
);
894 st_oop x
= pop_float (pr
);
895 st_oop result
= st_nil
;
898 result
= isless (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
901 ST_STACK_PUSH (pr
, result
);
903 ST_STACK_UNPOP (pr
, 2);
907 Float_gt (st_processor
*pr
)
909 st_oop y
= pop_float (pr
);
910 st_oop x
= pop_float (pr
);
911 st_oop result
= st_nil
;
914 result
= isgreater (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
917 ST_STACK_PUSH (pr
, result
);
919 ST_STACK_UNPOP (pr
, 2);
923 Float_le (st_processor
*pr
)
925 st_oop y
= pop_float (pr
);
926 st_oop x
= pop_float (pr
);
927 st_oop result
= st_nil
;
930 result
= islessequal (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
933 ST_STACK_PUSH (pr
, result
);
935 ST_STACK_UNPOP (pr
, 2);
939 Float_ge (st_processor
*pr
)
941 st_oop y
= pop_float (pr
);
942 st_oop x
= pop_float (pr
);
943 st_oop result
= st_nil
;
946 result
= isgreaterequal (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
949 ST_STACK_PUSH (pr
, result
);
951 ST_STACK_UNPOP (pr
, 2);
955 Float_eq (st_processor
*pr
)
957 st_oop y
= pop_float (pr
);
958 st_oop x
= pop_float (pr
);
959 st_oop result
= st_nil
;
962 result
= (st_float_value (x
) == st_float_value (y
)) ? st_true
: st_false
;
965 ST_STACK_PUSH (pr
, result
);
967 ST_STACK_UNPOP (pr
, 2);
971 Float_ne (st_processor
*pr
)
973 st_oop y
= pop_float (pr
);
974 st_oop x
= pop_float (pr
);
975 st_oop result
= st_nil
;
978 result
= (st_float_value (x
) != st_float_value (y
)) ? st_true
: st_false
;
981 ST_STACK_PUSH (pr
, result
);
983 ST_STACK_UNPOP (pr
, 2);
987 Float_mul (st_processor
*pr
)
989 st_oop y
= pop_float (pr
);
990 st_oop x
= pop_float (pr
);
991 st_oop result
= st_nil
;
994 result
= st_float_new (st_float_value (x
) * st_float_value (y
));
997 ST_STACK_PUSH (pr
, result
);
999 ST_STACK_UNPOP (pr
, 2);
1003 Float_div (st_processor
*pr
)
1005 st_oop y
= pop_float (pr
);
1006 st_oop x
= pop_float (pr
);
1007 st_oop result
= st_nil
;
1009 set_success (pr
, y
!= 0);
1012 result
= st_float_new (st_float_value (x
) / st_float_value (y
));
1015 ST_STACK_PUSH (pr
, result
);
1017 ST_STACK_UNPOP (pr
, 2);
1021 Float_sin (st_processor
*pr
)
1023 st_oop receiver
= ST_STACK_POP (pr
);
1027 value
= st_float_value (receiver
);
1029 result
= st_float_new (sin (value
));
1032 ST_STACK_PUSH (pr
, result
);
1034 ST_STACK_UNPOP (pr
, 1);
1038 Float_cos (st_processor
*pr
)
1040 st_oop receiver
= ST_STACK_POP (pr
);
1044 value
= st_float_value (receiver
);
1046 result
= st_float_new (cos (value
));
1049 ST_STACK_PUSH (pr
, result
);
1051 ST_STACK_UNPOP (pr
, 1);
1055 Float_tan (st_processor
*pr
)
1057 st_oop receiver
= ST_STACK_POP (pr
);
1061 value
= st_float_value (receiver
);
1063 result
= st_float_new (tan (value
));
1066 ST_STACK_PUSH (pr
, result
);
1068 ST_STACK_UNPOP (pr
, 1);
1072 Float_arcSin (st_processor
*pr
)
1074 st_oop receiver
= ST_STACK_POP (pr
);
1078 value
= st_float_value (receiver
);
1080 result
= st_float_new (asin (value
));
1083 ST_STACK_PUSH (pr
, result
);
1085 ST_STACK_UNPOP (pr
, 1);
1089 Float_arcCos (st_processor
*pr
)
1091 st_oop receiver
= ST_STACK_POP (pr
);
1095 value
= st_float_value (receiver
);
1097 result
= st_float_new (acos (value
));
1100 ST_STACK_PUSH (pr
, result
);
1102 ST_STACK_UNPOP (pr
, 1);
1106 Float_arcTan (st_processor
*pr
)
1108 st_oop receiver
= ST_STACK_POP (pr
);
1112 value
= st_float_value (receiver
);
1114 result
= st_float_new (atan (value
));
1117 ST_STACK_PUSH (pr
, result
);
1119 ST_STACK_UNPOP (pr
, 1);
1123 Float_sqrt (st_processor
*pr
)
1125 st_oop receiver
= ST_STACK_POP (pr
);
1129 value
= st_float_value (receiver
);
1131 result
= st_float_new (sqrt (value
));
1134 ST_STACK_PUSH (pr
, result
);
1136 ST_STACK_UNPOP (pr
, 1);
1140 Float_log (st_processor
*pr
)
1142 st_oop receiver
= ST_STACK_POP (pr
);
1146 value
= st_float_value (receiver
);
1148 result
= st_float_new (log10 (value
));
1151 ST_STACK_PUSH (pr
, result
);
1153 ST_STACK_UNPOP (pr
, 1);
1157 Float_ln (st_processor
*pr
)
1159 st_oop receiver
= ST_STACK_POP (pr
);
1163 value
= st_float_value (receiver
);
1165 result
= st_float_new (log (value
));
1168 ST_STACK_PUSH (pr
, result
);
1170 ST_STACK_UNPOP (pr
, 1);
1174 Float_exp (st_processor
*pr
)
1176 st_oop receiver
= ST_STACK_POP (pr
);
1180 value
= st_float_value (receiver
);
1182 result
= st_float_new (exp (value
));
1185 ST_STACK_PUSH (pr
, result
);
1187 ST_STACK_UNPOP (pr
, 1);
1191 Float_truncated (st_processor
*pr
)
1193 st_oop receiver
= ST_STACK_POP (pr
);
1196 result
= (st_smi
) trunc (st_float_value (receiver
));
1198 ST_STACK_PUSH (pr
, st_smi_new (result
));
1202 Float_fractionPart (st_processor
*pr
)
1204 st_oop receiver
= ST_STACK_POP (pr
);
1205 double frac_part
, int_part
;
1208 frac_part
= modf (st_float_value (receiver
), &int_part
);
1210 result
= st_float_new (frac_part
);
1212 ST_STACK_PUSH (pr
, result
);
1216 Float_integerPart (st_processor
*pr
)
1218 st_oop receiver
= ST_STACK_POP (pr
);
1222 modf (st_float_value (receiver
), &int_part
);
1224 result
= st_smi_new ((st_smi
) int_part
);
1225 ST_STACK_PUSH (pr
, result
);
1229 Float_hash (st_processor
*pr
)
1231 st_oop receiver
= ST_STACK_POP (pr
);
1232 unsigned int hash
= 0;
1237 value
= st_float_value (receiver
);
1240 value
= fabs (value
);
1242 c
= (unsigned char *) & value
;
1243 for (int i
= 0; i
< sizeof (double); i
++) {
1244 hash
= (hash
* 971) ^ c
[i
];
1252 ST_STACK_PUSH (pr
, st_smi_new (result
));
1256 print_backtrace (st_processor
*pr
)
1260 context
= pr
->context
;
1262 while (context
!= st_nil
) {
1269 if (st_object_class (context
) == st_block_context_class
)
1270 home
= ST_BLOCK_CONTEXT_HOME (context
);
1274 receiver
= ST_METHOD_CONTEXT_RECEIVER (home
);
1276 selector
= (char*) st_byte_array_bytes (ST_METHOD_SELECTOR (ST_METHOD_CONTEXT_METHOD (home
)));
1278 if (st_object_class (st_object_class (receiver
)) == st_metaclass_class
)
1279 class = st_strdup_printf ("%s class", (char *) st_byte_array_bytes (ST_CLASS (receiver
)->name
));
1281 class = (char*) st_byte_array_bytes (ST_CLASS (st_object_class (receiver
))->name
);
1283 printf ("%s>>#%s", class, selector
);
1284 if (st_object_class (context
) == st_block_context_class
)
1289 if (st_object_class (context
) == st_block_context_class
)
1290 context
= ST_BLOCK_CONTEXT_CALLER (context
);
1292 context
= ST_CONTEXT_PART_SENDER (context
);
1297 Object_error (st_processor
*pr
)
1301 message
= ST_STACK_POP (pr
);
1303 printf ("= An error occurred during program execution\n");
1304 printf ("= %s\n", st_byte_array_bytes (message
));
1306 printf ("\nTraceback:\n");
1307 print_backtrace (pr
);
1313 Object_class (st_processor
*pr
)
1317 object
= ST_STACK_POP (pr
);
1319 ST_STACK_PUSH (pr
, st_object_class (object
));
1323 Object_identityHash (st_processor
*pr
)
1328 object
= ST_STACK_POP (pr
);
1330 if (st_object_is_heap (object
))
1331 result
= ST_OBJECT_HASH (object
);
1332 else if (st_object_is_smi (object
))
1333 result
= st_smi_new (st_smi_hash (object
));
1335 result
= st_smi_new (st_character_hash (object
));
1337 ST_STACK_PUSH (pr
, result
);
1341 Object_copy (st_processor
*pr
)
1348 (void) ST_STACK_POP (pr
);
1350 if (!st_object_is_heap (pr
->message_receiver
)) {
1351 ST_STACK_PUSH (pr
, pr
->message_receiver
);
1355 switch (st_object_format (pr
->message_receiver
)) {
1357 case ST_FORMAT_OBJECT
:
1359 class = ST_OBJECT_CLASS (pr
->message_receiver
);
1360 size
= st_smi_value (ST_BEHAVIOR_INSTANCE_SIZE (class));
1361 copy
= st_object_new (class);
1362 st_oops_copy (ST_OBJECT_FIELDS (copy
),
1363 ST_OBJECT_FIELDS (pr
->message_receiver
),
1368 case ST_FORMAT_ARRAY
:
1370 size
= st_smi_value (ST_ARRAYED_OBJECT (pr
->message_receiver
)->size
);
1371 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (pr
->message_receiver
), size
);
1372 st_oops_copy (ST_ARRAY (copy
)->elements
,
1373 ST_ARRAY (pr
->message_receiver
)->elements
,
1377 case ST_FORMAT_BYTE_ARRAY
:
1379 size
= st_smi_value (ST_ARRAYED_OBJECT (pr
->message_receiver
)->size
);
1380 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (pr
->message_receiver
), size
);
1381 memcpy (st_byte_array_bytes (copy
),
1382 st_byte_array_bytes (pr
->message_receiver
),
1386 case ST_FORMAT_FLOAT_ARRAY
:
1388 size
= st_smi_value (st_arrayed_object_size (pr
->message_receiver
));
1389 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (pr
->message_receiver
), size
);
1390 memcpy (st_float_array_elements (copy
),
1391 st_float_array_elements (pr
->message_receiver
),
1392 sizeof (double) * size
);
1396 case ST_FORMAT_WORD_ARRAY
:
1398 size
= st_smi_value (st_arrayed_object_size (pr
->message_receiver
));
1399 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (pr
->message_receiver
), size
);
1400 memcpy (st_word_array_elements (copy
),
1401 st_word_array_elements (pr
->message_receiver
),
1402 sizeof (st_uint
) * size
);
1405 case ST_FORMAT_FLOAT
:
1407 copy
= st_object_new (st_float_class
);
1408 st_float_set_value (copy
, st_float_value (pr
->message_receiver
));
1411 case ST_FORMAT_LARGE_INTEGER
:
1416 copy
= st_large_integer_new (NULL
);
1418 result
= mp_init_copy (st_large_integer_value (copy
),
1419 st_large_integer_value (pr
->message_receiver
));
1420 if (result
!= MP_OKAY
)
1421 st_assert_not_reached ();
1424 case ST_FORMAT_CONTEXT
:
1425 case ST_FORMAT_INTEGER_ARRAY
:
1427 /* not implemented yet */
1428 st_assert_not_reached ();
1431 ST_STACK_PUSH (pr
, copy
);
1435 Object_equivalent (st_processor
*pr
)
1437 st_oop y
= ST_STACK_POP (pr
);
1438 st_oop x
= ST_STACK_POP (pr
);
1440 ST_STACK_PUSH (pr
, ((x
== y
) ? st_true
: st_false
));
1444 Object_perform (st_processor
*pr
)
1449 st_uint selector_index
;
1451 selector
= pr
->message_selector
;
1452 pr
->message_selector
= pr
->stack
[pr_sp
- pr
->message_argcount
];
1453 receiver
= pr
->message_receiver
;
1455 set_success (pr
, st_object_is_symbol (pr
->message_selector
));
1456 pr
->new_method
= st_processor_lookup_method (pr
, st_object_class (receiver
));
1457 set_success (pr
, st_method_get_arg_count (method
) == (pr
->message_argcount
- 1));
1460 selector_index
= pr_sp
- pr
->message_argcount
;
1462 st_oops_move (pr
->stack
+ selector_index
,
1463 pr
->stack
+ selector_index
+ 1,
1464 pr
->message_argcount
- 1);
1467 pr
->message_argcount
-= 1;
1468 st_processor_execute_method (pr
);
1471 pr
->message_selector
= selector
;
1476 Object_perform_withArguments (st_processor
*pr
)
1484 array
= ST_STACK_POP (pr
);
1486 set_success (pr
, st_object_class (array
) == st_array_class
);
1488 if (st_object_class (pr
->context
) == st_block_context_class
)
1489 method
= ST_METHOD_CONTEXT_METHOD (ST_BLOCK_CONTEXT_HOME (pr
->context
));
1491 method
= ST_METHOD_CONTEXT_METHOD (pr
->context
);
1493 array_size
= st_smi_value (st_arrayed_object_size (array
));
1494 set_success (pr
, (pr_sp
+ array_size
- 1) < (st_method_get_large_context (method
) ? 32 : 12));
1498 selector
= pr
->message_selector
;
1499 pr
->message_selector
= ST_STACK_POP (pr
);
1500 receiver
= ST_STACK_PEEK (pr
);
1501 pr
->message_argcount
= array_size
;
1503 set_success (pr
, st_object_is_symbol (pr
->message_selector
));
1505 st_oops_copy (pr
->stack
+ pr_sp
,
1506 st_array_elements (array
),
1509 pr_sp
+= array_size
;
1511 pr
->new_method
= st_processor_lookup_method (pr
, st_object_class (receiver
));
1512 set_success (pr
, st_method_get_arg_count (pr
->new_method
) == array_size
);
1515 st_processor_execute_method (pr
);
1517 pr_sp
-= pr
->message_argcount
;
1518 ST_STACK_PUSH (pr
, pr
->message_selector
);
1519 ST_STACK_PUSH (pr
, array
);
1520 pr
->message_argcount
= 2;
1521 pr
->message_selector
= selector
;
1525 ST_STACK_UNPOP (pr
, 1);
1530 Behavior_new (st_processor
*pr
)
1536 class = ST_STACK_POP (pr
);
1538 switch (st_smi_value (ST_BEHAVIOR_FORMAT (class))) {
1539 case ST_FORMAT_OBJECT
:
1540 instance
= st_object_allocate (class);
1541 case ST_FORMAT_CONTEXT
:
1542 /* not implemented */
1545 case ST_FORMAT_FLOAT
:
1546 instance
= st_float_allocate (class);
1547 case ST_FORMAT_LARGE_INTEGER
:
1548 instance
= st_large_integer_allocate (class, NULL
);
1550 /* should not reach */
1554 ST_STACK_PUSH (pr
, instance
);
1558 Behavior_newSize (st_processor
*pr
)
1565 size
= pop_integer32 (pr
);
1566 class = ST_STACK_POP (pr
);
1568 switch (st_smi_value (ST_BEHAVIOR_FORMAT (class))) {
1569 case ST_FORMAT_ARRAY
:
1570 instance
= st_array_allocate (class, size
);
1572 case ST_FORMAT_BYTE_ARRAY
:
1573 instance
= st_byte_array_allocate (class, size
);
1575 case ST_FORMAT_WORD_ARRAY
:
1576 instance
= st_word_array_allocate (class, size
);
1578 case ST_FORMAT_FLOAT_ARRAY
:
1579 instance
= st_float_array_allocate (class, size
);
1581 case ST_FORMAT_INTEGER_ARRAY
:
1582 /* not implemented */
1586 /* should not reach */
1590 ST_STACK_PUSH (pr
, instance
);
1594 SequenceableCollection_size (st_processor
*pr
)
1598 object
= ST_STACK_POP (pr
);
1600 ST_STACK_PUSH (pr
, st_arrayed_object_size (object
));
1604 Array_at (st_processor
*pr
)
1606 st_smi index
= pop_integer32 (pr
);
1607 st_oop receiver
= ST_STACK_POP (pr
);
1609 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1610 set_success (pr
, false);
1611 ST_STACK_UNPOP (pr
, 2);
1615 ST_STACK_PUSH (pr
, st_array_at (receiver
, index
));
1619 Array_at_put (st_processor
*pr
)
1621 st_oop object
= ST_STACK_POP (pr
);
1622 st_smi index
= pop_integer32 (pr
);
1623 st_oop receiver
= ST_STACK_POP (pr
);
1625 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1626 set_success (pr
, false);
1627 ST_STACK_UNPOP (pr
, 3);
1631 st_array_at_put (receiver
, index
, object
);
1632 ST_STACK_PUSH (pr
, object
);
1636 ByteArray_at (st_processor
*pr
)
1638 st_smi index
= pop_integer32 (pr
);
1639 st_oop receiver
= ST_STACK_POP (pr
);
1643 ST_STACK_UNPOP (pr
, 2);
1647 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1648 set_success (pr
, false);
1649 ST_STACK_UNPOP (pr
, 2);
1653 result
= st_smi_new (st_byte_array_at (receiver
, index
));
1655 ST_STACK_PUSH (pr
, result
);
1659 ByteArray_at_put (st_processor
*pr
)
1661 st_smi byte
= pop_integer (pr
);
1662 st_smi index
= pop_integer32 (pr
);
1663 st_oop receiver
= ST_STACK_POP (pr
);
1666 ST_STACK_UNPOP (pr
, 3);
1670 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1671 set_success (pr
, false);
1672 ST_STACK_UNPOP (pr
, 3);
1676 st_byte_array_at_put (receiver
, index
, byte
);
1678 ST_STACK_PUSH (pr
, st_smi_new (byte
));
1682 ByteArray_hash (st_processor
*pr
)
1684 st_oop receiver
= ST_STACK_POP (pr
);
1687 hash
= st_byte_array_hash (receiver
);
1689 ST_STACK_PUSH (pr
, st_smi_new (hash
));
1693 ByteString_at (st_processor
*pr
)
1695 st_smi index
= pop_integer32 (pr
);
1696 st_oop receiver
= ST_STACK_POP (pr
);
1700 if (ST_UNLIKELY (!pr
->success
)) {
1701 ST_STACK_UNPOP (pr
, 2);
1705 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1706 set_success (pr
, false);
1707 ST_STACK_UNPOP (pr
, 2);
1711 character
= st_character_new (st_byte_array_at (receiver
, index
));
1713 ST_STACK_PUSH (pr
, character
);
1717 ByteString_at_put (st_processor
*pr
)
1719 st_oop character
= ST_STACK_POP (pr
);
1720 st_smi index
= pop_integer32 (pr
);
1721 st_oop receiver
= ST_STACK_POP (pr
);
1724 ST_STACK_UNPOP (pr
, 3);
1728 set_success (pr
, st_object_class (character
) == st_character_class
);
1730 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1731 set_success (pr
, false);
1732 ST_STACK_UNPOP (pr
, 3);
1736 st_byte_array_at_put (receiver
, index
, (st_uchar
) st_character_value (character
));
1738 ST_STACK_PUSH (pr
, character
);
1743 ByteString_size (st_processor
*pr
)
1748 receiver
= ST_STACK_POP (pr
);
1750 size
= st_arrayed_object_size (receiver
);
1752 /* TODO: allow size to go into a LargeInteger on overflow */
1753 ST_STACK_PUSH (pr
, size
);
1757 ByteString_compare (st_processor
*pr
)
1759 st_oop argument
= ST_STACK_POP (pr
);
1760 st_oop receiver
= ST_STACK_POP (pr
);
1763 if (st_object_format (argument
) != ST_FORMAT_BYTE_ARRAY
)
1764 set_success (pr
, false);
1767 order
= strcmp ((const char *) st_byte_array_bytes (receiver
),
1768 (const char *) st_byte_array_bytes (argument
));
1771 ST_STACK_PUSH (pr
, st_smi_new (order
));
1773 ST_STACK_UNPOP (pr
, 2);
1777 WideString_at (st_processor
*pr
)
1779 st_smi index
= pop_integer32 (pr
);
1780 st_oop receiver
= ST_STACK_POP (pr
);
1785 ST_STACK_UNPOP (pr
, 2);
1789 if (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
))) {
1790 set_success (pr
, false);
1791 ST_STACK_UNPOP (pr
, 2);
1795 c
= st_word_array_at (receiver
, index
);
1797 ST_STACK_PUSH (pr
, st_character_new (c
));
1801 WideString_at_put (st_processor
*pr
)
1803 st_oop character
= ST_STACK_POP (pr
);
1804 st_smi index
= pop_integer32 (pr
);
1805 st_oop receiver
= ST_STACK_POP (pr
);
1810 ST_STACK_UNPOP (pr
, 3);
1814 set_success (pr
, st_object_class (character
) == st_character_class
);
1816 if (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
))) {
1817 set_success (pr
, false);
1818 ST_STACK_UNPOP (pr
, 3);
1822 st_word_array_at_put (receiver
, index
, character
);
1824 ST_STACK_PUSH (pr
, character
);
1828 WordArray_at (st_processor
*pr
)
1834 index
= pop_integer32 (pr
);
1835 receiver
= ST_STACK_POP (pr
);
1837 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1838 set_success (pr
, false);
1839 ST_STACK_UNPOP (pr
, 2);
1843 element
= st_word_array_at (receiver
, index
);
1845 ST_STACK_PUSH (pr
, st_smi_new (element
));
1849 WordArray_at_put (st_processor
*pr
)
1851 st_smi value
= pop_integer (pr
);
1852 st_smi index
= pop_integer32 (pr
);
1853 st_oop receiver
= ST_STACK_POP (pr
);
1856 ST_STACK_UNPOP (pr
, 3);
1860 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1861 set_success (pr
, false);
1862 ST_STACK_UNPOP (pr
, 3);
1866 st_word_array_at_put (receiver
, index
, value
);
1868 ST_STACK_PUSH (pr
, st_smi_new (value
));
1872 FloatArray_at (st_processor
*pr
)
1878 index
= pop_integer32 (pr
);
1879 receiver
= ST_STACK_POP (pr
);
1881 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1882 set_success (pr
, false);
1883 ST_STACK_UNPOP (pr
, 2);
1887 element
= st_float_array_at (receiver
, index
);
1888 ST_STACK_PUSH (pr
, st_float_new (element
));
1892 FloatArray_at_put (st_processor
*pr
)
1894 st_oop flt
= ST_STACK_POP (pr
);
1895 st_smi index
= pop_integer32 (pr
);
1896 st_oop receiver
= ST_STACK_POP (pr
);
1898 set_success (pr
, st_object_is_heap (flt
) &&
1899 st_object_format (flt
) == ST_FORMAT_FLOAT
);
1901 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1902 set_success (pr
, false);
1903 ST_STACK_UNPOP (pr
, 3);
1908 ST_STACK_UNPOP (pr
, 3);
1912 st_float_array_at_put (receiver
, index
, st_float_value (flt
));
1913 ST_STACK_PUSH (pr
, flt
);
1917 activate_block_context (st_processor
*pr
)
1922 block
= pr
->message_receiver
;
1923 argcount
= st_smi_value (ST_BLOCK_CONTEXT_ARGCOUNT (block
));
1924 if (argcount
!= pr
->message_argcount
) {
1925 pr
->success
= false;
1929 st_oops_copy (ST_BLOCK_CONTEXT_STACK (block
),
1930 pr
->stack
+ pr_sp
- argcount
,
1933 pr_sp
-= pr
->message_argcount
+ 1;
1935 ST_CONTEXT_PART_IP (block
) = ST_BLOCK_CONTEXT_INITIALIP (block
);
1936 ST_CONTEXT_PART_SP (block
) = st_smi_new (argcount
);
1937 ST_BLOCK_CONTEXT_CALLER (block
) = pr
->context
;
1939 st_processor_set_active_context (pr
, block
);
1943 BlockContext_value (st_processor
*pr
)
1945 activate_block_context (pr
);
1949 BlockContext_valueWithArguments (st_processor
*pr
)
1955 block
= pr
->message_receiver
;
1956 values
= ST_STACK_PEEK (pr
);
1958 if (st_object_class (values
) != st_array_class
) {
1959 set_success (pr
, false);
1963 argcount
= st_smi_value (ST_BLOCK_CONTEXT_ARGCOUNT (block
));
1964 if (argcount
!= st_smi_value (st_arrayed_object_size (values
))) {
1965 set_success (pr
, false);
1969 st_oops_copy (ST_BLOCK_CONTEXT_STACK (block
),
1970 ST_ARRAY (values
)->elements
,
1973 pr_sp
-= pr
->message_argcount
+ 1;
1975 ST_CONTEXT_PART_IP (block
) = ST_BLOCK_CONTEXT_INITIALIP (block
);
1976 ST_CONTEXT_PART_SP (block
) = st_smi_new (argcount
);
1977 ST_BLOCK_CONTEXT_CALLER (block
) = pr
->context
;
1979 st_processor_set_active_context (pr
, block
);
1983 UndefinedObject_exitWithResult (st_processor
*pr
)
1985 longjmp (pr
->main_loop
, 0);
1989 Character_value (st_processor
*pr
)
1991 st_oop receiver
= ST_STACK_POP (pr
);
1993 ST_STACK_PUSH (pr
, st_smi_new (st_character_value (receiver
)));
1997 Character_characterFor (st_processor
*pr
)
2002 value
= pop_integer (pr
);
2003 receiver
= ST_STACK_POP (pr
);
2006 ST_STACK_PUSH (pr
, st_character_new (value
));
2008 ST_STACK_UNPOP (pr
, 2);
2012 FileStream_open (st_processor
*pr
)
2020 mode_oop
= ST_STACK_POP (pr
);
2021 name
= ST_STACK_POP (pr
);
2023 if (st_object_class (mode_oop
) != st_symbol_class
) {
2024 ST_PRIMITIVE_FAIL (pr
);
2028 if (st_object_class (name
) != st_string_class
) {
2029 ST_PRIMITIVE_FAIL (pr
);
2033 str
= st_byte_array_bytes (mode_oop
);
2034 if (streq (str
, "read"))
2036 else if (streq (str
, "write"))
2038 else if (streq (str
, "readWrite"))
2041 ST_PRIMITIVE_FAIL (pr
);
2045 str
= st_byte_array_bytes (name
);
2046 fd
= open (str
, O_CREAT
| mode
, 0644);
2047 ST_STACK_PUSH (pr
, st_smi_new (fd
));
2051 FileStream_close (st_processor
*pr
)
2056 fd
= pop_integer (pr
);
2057 (void) ST_STACK_POP (pr
);
2060 ST_STACK_UNPOP (pr
, 2);
2064 if (close (fd
) != 0) {
2065 ST_STACK_UNPOP (pr
, 2);
2066 ST_PRIMITIVE_FAIL (pr
);
2069 ST_STACK_PUSH (pr
, pr
->message_receiver
);
2073 FileStream_write (st_processor
*pr
)
2078 byte
= pop_integer (pr
);
2079 fd
= pop_integer (pr
);
2080 (void) ST_STACK_POP (pr
);
2083 ST_PRIMITIVE_FAIL (pr
);
2084 ST_STACK_UNPOP (pr
, 3);
2087 if (write (fd
, &byte
, 1) < 0) {
2088 ST_PRIMITIVE_FAIL (pr
);
2089 ST_STACK_UNPOP (pr
, 3);
2092 ST_STACK_PUSH (pr
, pr
->message_receiver
);
2096 FileStream_read (st_processor
*pr
)
2102 FileStream_writeN (st_processor
*pr
)
2109 array
= ST_STACK_POP (pr
);
2110 fd
= pop_integer (pr
);
2112 if (st_object_format (array
) != ST_FORMAT_BYTE_ARRAY
) {
2113 ST_PRIMITIVE_FAIL (pr
);
2120 size
= st_smi_value (st_arrayed_object_size (array
));
2121 buf
= st_byte_array_bytes (array
);
2123 write (fd
, buf
, size
);
2125 ST_STACK_PUSH (pr
, st_true
);
2129 FileStream_readN (st_processor
*pr
)
2135 FileStream_position (st_processor
*pr
)
2141 FileStream_setPosition (st_processor
*pr
)
2146 const struct st_primitive st_primitives
[] = {
2147 { "SmallInteger_add", SmallInteger_add
},
2148 { "SmallInteger_sub", SmallInteger_sub
},
2149 { "SmallInteger_lt", SmallInteger_lt
},
2150 { "SmallInteger_gt", SmallInteger_gt
},
2151 { "SmallInteger_le", SmallInteger_le
},
2152 { "SmallInteger_ge", SmallInteger_ge
},
2153 { "SmallInteger_eq", SmallInteger_eq
},
2154 { "SmallInteger_ne", SmallInteger_ne
},
2155 { "SmallInteger_mul", SmallInteger_mul
},
2156 { "SmallInteger_div", SmallInteger_div
},
2157 { "SmallInteger_intDiv", SmallInteger_intDiv
},
2158 { "SmallInteger_mod", SmallInteger_mod
},
2159 { "SmallInteger_bitOr", SmallInteger_bitOr
},
2160 { "SmallInteger_bitXor", SmallInteger_bitXor
},
2161 { "SmallInteger_bitAnd", SmallInteger_bitAnd
},
2162 { "SmallInteger_bitShift", SmallInteger_bitShift
},
2163 { "SmallInteger_asFloat", SmallInteger_asFloat
},
2164 { "SmallInteger_asLargeInteger", SmallInteger_asLargeInteger
},
2166 { "LargeInteger_add", LargeInteger_add
},
2167 { "LargeInteger_sub", LargeInteger_sub
},
2168 { "LargeInteger_lt", LargeInteger_lt
},
2169 { "LargeInteger_gt", LargeInteger_gt
},
2170 { "LargeInteger_le", LargeInteger_le
},
2171 { "LargeInteger_ge", LargeInteger_ge
},
2172 { "LargeInteger_eq", LargeInteger_eq
},
2173 { "LargeInteger_ne", LargeInteger_ne
},
2174 { "LargeInteger_mul", LargeInteger_mul
},
2175 { "LargeInteger_div", LargeInteger_div
},
2176 { "LargeInteger_intDiv", LargeInteger_intDiv
},
2177 { "LargeInteger_mod", LargeInteger_mod
},
2178 { "LargeInteger_gcd", LargeInteger_gcd
},
2179 { "LargeInteger_lcm", LargeInteger_lcm
},
2180 { "LargeInteger_squared", LargeInteger_squared
},
2181 { "LargeInteger_bitOr", LargeInteger_bitOr
},
2182 { "LargeInteger_bitXor", LargeInteger_bitXor
},
2183 { "LargeInteger_bitAnd", LargeInteger_bitAnd
},
2184 { "LargeInteger_bitShift", LargeInteger_bitShift
},
2185 { "LargeInteger_printString", LargeInteger_printString
},
2186 { "LargeInteger_asFloat", LargeInteger_asFloat
},
2187 { "LargeInteger_hash", LargeInteger_hash
},
2189 { "Float_add", Float_add
},
2190 { "Float_sub", Float_sub
},
2191 { "Float_lt", Float_lt
},
2192 { "Float_gt", Float_gt
},
2193 { "Float_le", Float_le
},
2194 { "Float_ge", Float_ge
},
2195 { "Float_eq", Float_eq
},
2196 { "Float_ne", Float_ne
},
2197 { "Float_mul", Float_mul
},
2198 { "Float_div", Float_div
},
2199 { "Float_exp", Float_exp
},
2200 { "Float_sin", Float_sin
},
2201 { "Float_cos", Float_cos
},
2202 { "Float_tan", Float_tan
},
2203 { "Float_arcSin", Float_arcSin
},
2204 { "Float_arcCos", Float_arcCos
},
2205 { "Float_arcTan", Float_arcTan
},
2206 { "Float_ln", Float_ln
},
2207 { "Float_log", Float_log
},
2208 { "Float_sqrt", Float_sqrt
},
2209 { "Float_truncated", Float_truncated
},
2210 { "Float_fractionPart", Float_fractionPart
},
2211 { "Float_integerPart", Float_integerPart
},
2212 { "Float_hash", Float_hash
},
2214 { "Object_error", Object_error
},
2215 { "Object_class", Object_class
},
2216 { "Object_identityHash", Object_identityHash
},
2217 { "Object_copy", Object_copy
},
2218 { "Object_equivalent", Object_equivalent
},
2219 { "Object_perform", Object_perform
},
2220 { "Object_perform_withArguments", Object_perform_withArguments
},
2222 { "Behavior_new", Behavior_new
},
2223 { "Behavior_newSize", Behavior_newSize
},
2226 { "SequenceableCollection_size", SequenceableCollection_size
},
2228 { "Array_at", Array_at
},
2229 { "Array_at_put", Array_at_put
},
2231 { "ByteArray_at", ByteArray_at
},
2232 { "ByteArray_at_put", ByteArray_at_put
},
2233 { "ByteArray_hash", ByteArray_hash
},
2235 { "ByteString_at", ByteString_at
},
2236 { "ByteString_at_put", ByteString_at_put
},
2237 { "ByteString_size", ByteString_size
},
2238 { "ByteString_compare", ByteString_compare
},
2240 { "WideString_at", WideString_at
},
2241 { "WideString_at_put", WideString_at_put
},
2243 { "WordArray_at", WordArray_at
},
2244 { "WordArray_at_put", WordArray_at_put
},
2246 { "FloatArray_at", FloatArray_at
},
2247 { "FloatArray_at_put", FloatArray_at_put
},
2249 { "UndefinedObject_exitWithResult", UndefinedObject_exitWithResult
},
2251 { "Character_value", Character_value
},
2252 { "Character_characterFor", Character_characterFor
},
2254 { "BlockContext_value", BlockContext_value
},
2255 { "BlockContext_valueWithArguments", BlockContext_valueWithArguments
},
2257 { "FileStream_open", FileStream_open
},
2258 { "FileStream_close", FileStream_close
},
2259 { "FileStream_write", FileStream_write
},
2260 { "FileStream_read", FileStream_read
},
2261 { "FileStream_writeN", FileStream_writeN
},
2262 { "FileStream_readN", FileStream_readN
},
2263 { "FileStream_position", FileStream_position
},
2264 { "FileStream_setPosition", FileStream_setPosition
},
2267 /* returns 0 if there no primitive function corresponding
2268 * to the given name */
2270 st_primitive_index_for_name (const char *name
)
2272 st_assert (name
!= NULL
);
2273 for (int i
= 0; i
< ST_N_ELEMENTS (st_primitives
); i
++)
2274 if (streq (name
, st_primitives
[i
].name
))