USE: kernel
USE: namespaces
USE: words
+USE: lists
: DS ( -- address ) "ds" dlsym-self ;
ECX DS R>[I]
] "generator" set-word-property
+#replace-immediate [
+ DS ECX [I]>R
+ address ECX I>[R]
+ ECX DS R>[I]
+] "generator" set-word-property
+
+#replace-indirect [
+ DS ECX [I]>R
+ intern-literal EAX [I]>R
+ EAX ECX R>[R]
+ ECX DS R>[I]
+] "generator" set-word-property
+
#call [
dup postpone-word
CALL compiled-offset defer-xt
#cleanup [
dup 0 = [ drop ] [ ESP R+I ] ifte
] "generator" set-word-property
+
+[
+ [ #drop drop ]
+ [ #dup dup ]
+ [ #swap swap ]
+ [ #over over ]
+ [ #pick pick ]
+ [ #>r >r ]
+ [ #r> r> ]
+] [
+ uncons
+ [ car CALL compiled-offset defer-xt drop ] cons
+ "generator" set-word-property
+] each
SYMBOL: #push-immediate
SYMBOL: #push-indirect
+SYMBOL: #replace-immediate
+SYMBOL: #replace-indirect
SYMBOL: #jump-t ( branch if top of stack is true )
SYMBOL: #jump ( tail-call )
SYMBOL: #jump-label ( tail-call )
] "linearizer" set-word-property
#values [ drop ] "linearizer" set-word-property
-
-[
- [ #drop drop ]
- [ #dup dup ]
- [ #swap swap ]
- [ #over over ]
- [ #pick pick ]
- [ #>r >r ]
- [ #r> r> ]
-] [
- uncons
- [ car #call swons , drop ] cons
- "linearizer" set-word-property
-] each
] ifte ;
: simplify-node ( node rest -- rest ? )
- over car "simplify" word-property [
- call
- ] [
- swap , f
- ] ifte* ;
+ over car "simplify" [ swap , f ] singleton ;
: find-label ( label linear -- rest )
[ cdr over = ] some? cdr nip ;
purge-labels [ (simplify) ] make-list ;
: follow ( linear -- linear )
- dup car car "follow" word-property dup [
- call
- ] [
- drop
- ] ifte ;
+ dup car car "follow" [ ] singleton ;
#label [
cdr follow
: follows? ( op linear -- ? )
follow dup [ car car = ] [ 2drop f ] ifte ;
-GENERIC: call-simplifier ( node rest -- rest ? )
-M: cons call-simplifier ( node rest -- ? )
+GENERIC: simplify-call ( node rest -- rest ? )
+M: cons simplify-call ( node rest -- rest ? )
swap , f ;
PREDICATE: cons return-follows #return swap follows? ;
-M: return-follows call-simplifier ( node rest -- rest ? )
+M: return-follows simplify-call ( node rest -- rest ? )
>r
unswons [
[ #call | #jump ]
[ #call-label | #jump-label ]
] assoc swons , r> t ;
-#call [ call-simplifier ] "simplify" set-word-property
-#call-label [ call-simplifier ] "simplify" set-word-property
+#call [ simplify-call ] "simplify" set-word-property
+#call-label [ simplify-call ] "simplify" set-word-property
+
+GENERIC: simplify-drop ( node rest -- rest ? )
+M: cons simplify-drop ( node rest -- rest ? )
+ swap , f ;
+
+PREDICATE: cons push-next ( list -- ? )
+ dup [
+ car car [ #push-immediate #push-indirect ] contains?
+ ] when ;
+
+M: push-next simplify-drop ( node rest -- rest ? )
+ nip uncons >r unswons [
+ [ #push-immediate | #replace-immediate ]
+ [ #push-indirect | #replace-indirect ]
+ ] assoc swons , r> t ;
+
+#drop [ simplify-drop ] "simplify" set-word-property
>r dup type r> dispatch ; inline
: 2generic ( n n vtable -- )
- >r 2dup arithmetic-type r> dispatch ; inline
+ >r arithmetic-type r> dispatch ; inline
: hashcode ( obj -- hash )
#! If two objects are =, they must have equal hashcodes.
[ sbuf-clone " sbuf -- sbuf " [ 1 | 1 ] ]
[ sbuf= " sbuf sbuf -- ? " [ 2 | 1 ] ]
[ sbuf-hashcode " sbuf -- n " [ 1 | 1 ] ]
- [ arithmetic-type " n n -- type " [ 2 | 1 ] ]
+ [ arithmetic-type " n n -- type " [ 2 | 3 ] ]
[ number? " obj -- ? " [ 1 | 1 ] ]
[ >fixnum " n -- fixnum " [ 1 | 1 ] ]
[ >bignum " n -- bignum " [ 1 | 1 ] ]
USE: test
USE: inference
USE: lists
+USE: kernel
[ [ ] ] [ [ ] simplify ] unit-test
[ [ [ #return ] ] ] [ [ [ #return ] ] simplify ] unit-test
[ #return ]
] simplify car
] unit-test
+
+[
+ t
+] [
+ [
+ [ #push-immediate | 1 ]
+ ] push-next? >boolean
+] unit-test
+
+[
+ [
+ [ #replace-immediate | 1 ]
+ [ #return ]
+ ]
+] [
+ [ drop 1 ] dataflow linearize simplify
+] unit-test
#include "factor.h"
-CELL arithmetic_type(CELL obj1, CELL obj2)
+void primitive_arithmetic_type(void)
{
+ CELL obj1 = dpeek();
+ CELL obj2 = get(ds - CELLS);
+
CELL type1 = type_of(obj1);
CELL type2 = type_of(obj2);
CELL type;
- switch(type1)
+ switch(type2)
{
case FIXNUM_TYPE:
- type = type2;
+ switch(type1)
+ {
+ case BIGNUM_TYPE:
+ put(ds - CELLS,tag_object(to_bignum(obj2)));
+ break;
+ case FLOAT_TYPE:
+ put(ds - CELLS,tag_object(make_float(to_float((obj2)))));
+ break;
+ }
+ type = type1;
break;
case BIGNUM_TYPE:
- switch(type2)
+ switch(type1)
{
case FIXNUM_TYPE:
+ drepl(tag_object(to_bignum(obj1)));
+ type = type2;
+ break;
+ case FLOAT_TYPE:
+ put(ds - CELLS,tag_object(make_float(to_float((obj2)))));
type = type1;
break;
default:
- type = type2;
+ type = type1;
break;
}
break;
case RATIO_TYPE:
- switch(type2)
+ switch(type1)
{
case FIXNUM_TYPE:
case BIGNUM_TYPE:
+ type = type2;
+ break;
+ case FLOAT_TYPE:
+ put(ds - CELLS,tag_object(make_float(to_float((obj2)))));
type = type1;
break;
default:
- type = type2;
+ type = type1;
break;
}
break;
case FLOAT_TYPE:
- switch(type2)
+ switch(type1)
{
case FIXNUM_TYPE:
case BIGNUM_TYPE:
case RATIO_TYPE:
- type = type1;
+ drepl(tag_object(make_float(to_float(obj1))));
+ type = type2;
break;
default:
- type = type2;
+ type = type1;
break;
}
break;
case COMPLEX_TYPE:
- switch(type2)
+ switch(type1)
{
case FIXNUM_TYPE:
case BIGNUM_TYPE:
case RATIO_TYPE:
case FLOAT_TYPE:
- type = type1;
+ type = type2;
break;
default:
- type = type2;
+ type = type1;
break;
}
break;
default:
- type = type1;
+ type = type2;
break;
}
- return type;
-}
-
-void primitive_arithmetic_type(void)
-{
- CELL obj2 = dpop();
- CELL obj1 = dpop();
- dpush(tag_fixnum(arithmetic_type(obj1,obj2)));
+ dpush(tag_fixnum(type));
}
bool realp(CELL tagged)
#include "factor.h"
-CELL arithmetic_type(CELL obj1, CELL obj2);
void primitive_arithmetic_type(void);
bool realp(CELL tagged);
#define GC_AND_POP_BIGNUMS(x,y) \
F_ARRAY *x, *y; \
maybe_garbage_collection(); \
- y = to_bignum(dpop()); \
- x = to_bignum(dpop());
+ y = untag_bignum_fast(dpop()); \
+ x = untag_bignum_fast(dpop());
void primitive_bignum_add(void)
{
CELL bignum_pos_one;
CELL bignum_neg_one;
+INLINE F_ARRAY* untag_bignum_fast(CELL tagged)
+{
+ return (F_ARRAY*)UNTAG(tagged);
+}
+
INLINE F_ARRAY* untag_bignum(CELL tagged)
{
type_check(BIGNUM_TYPE,tagged);
- return (F_ARRAY*)UNTAG(tagged);
+ return untag_bignum_fast(tagged);
}
F_FIXNUM to_integer(CELL x);
#define GC_AND_POP_FLOATS(x,y) \
double x, y; \
maybe_garbage_collection(); \
- y = to_float(dpop()); \
- x = to_float(dpop());
+ y = untag_float_fast(dpop()); \
+ x = untag_float_fast(dpop());
void primitive_float_eq(void)
{
void primitive_fatan2(void)
{
- GC_AND_POP_FLOATS(x,y);
+ double x, y;
+ maybe_garbage_collection();
+ y = to_float(dpop());
+ x = to_float(dpop());
dpush(tag_object(make_float(atan2(x,y))));
}
void primitive_fpow(void)
{
- GC_AND_POP_FLOATS(x,y);
+ double x, y;
+ maybe_garbage_collection();
+ y = to_float(dpop());
+ x = to_float(dpop());
dpush(tag_object(make_float(pow(x,y))));
}