1 /* <Built-in procedures> */
3 /* Creates a closure and adds it to the top-level
4 @param name (string) the name of the built-in procedure
5 @param code (void*) the address of the built-in procedure (label address)
7 #define CREATE_BUILTIN_CLOS(name,code) \
8 r_res = (int)getSymbol((name),topLevel); /* create a hash bucket */ \
9 ((SymbolEntry*)r_res)->sob = makeSchemeClosure(NULL,(code)); \
10 ASSERT_ALWAYS( ((SymbolEntry*)r_res)->sob!=NULL,"" ); \
11 ((SymbolEntry*)r_res)->isDefined = 1;
13 /* The stack when in a built-in precedure (there is no fp):
15 | ret | - return address
16 | sp | - the old sp (before entering this procedure)
17 | env | - points to the enviroment vector
18 | n | - number of arguments
22 | An-1 | - argument n-1
24 Macros for built-in procedures:
26 #define BI_ST_ARG(n) (stack[sp-4-(n)])
27 #define BI_ST_ARG_COUNT() (stack[sp-3])
28 #define BI_RETURN() goto *pop()
30 goto Lstart; /* skip all definitions */
33 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==1,MSG_ERR_ARGCOUNT("car",1) );
35 ASSERT_ALWAYS( IS_SOB_PAIR(r[0]), MSG_ERR_NOTPAIR );
36 r_res = (int)SOB_PAIR_CAR(r[0]);
40 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==1,MSG_ERR_ARGCOUNT("cdr",1) );
42 ASSERT_ALWAYS( IS_SOB_PAIR(r[0]), MSG_ERR_NOTPAIR );
43 r_res = (int)SOB_PAIR_CDR(r[0]);
47 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==1,MSG_ERR_ARGCOUNT("symbol?",1) );
49 if ( IS_SOB_SYMBOL(r[0]) ) goto Lsymbol_true;
50 r_res = (int)&sc_false;
53 r_res = (int)&sc_true;
57 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("set-car!",2) );
60 ASSERT_ALWAYS( IS_SOB_PAIR(r[0]), MSG_ERR_NOTPAIR );
61 SOB_PAIR_CAR(r[0]) = (SchemeObject*)r[1];
66 ASSERT_ALWAYS( BI_ST_ARG_COUNT()>=1,MSG_ERR_ARGCOUNT("make-vector",1) );
68 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
69 r[0] = SOB_INT_VALUE(r[0]);
70 r_res = (int)makeSchemeVectorInit(r[0],&sc_void);
71 /* initialize vector elements
72 for (int i=1; i<BI_ST_ARG_COUNT(); ++i)
73 SOB_VECTOR_SET(r_res,i,BI_ST_ARG(i));
78 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==3,MSG_ERR_ARGCOUNT("vector-set!",3) );
80 ASSERT_ALWAYS(IS_SOB_VECTOR((SchemeObject*)r[0]), "");
82 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
83 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
85 SOB_VECTOR_SET((SchemeObject*)r[0],r[1],(SchemeObject*)r[2]);
86 r_res = (int)&sc_void;
90 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("vector-ref",2) );
92 ASSERT_ALWAYS(IS_SOB_VECTOR((SchemeObject*)r[0]), "");
94 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
95 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
96 r_res = (int)SOB_VECTOR_REF((SchemeObject*)r[0],r[1]);
100 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("binary=?",2) );
102 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
103 r[0] = SOB_INT_VALUE((SchemeObject*)r[0]);
105 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
106 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
107 if (r[0] != r[1]) goto LbinaryEQ_false;
108 r_res = (int)&sc_true;
111 r_res = (int)&sc_false;
115 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("binary-add",2) );
117 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
118 r[0] = SOB_INT_VALUE((SchemeObject*)r[0]);
120 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
121 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
123 r_res = (int)makeSchemeInt( r_res );
127 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("binary-sub",2) );
129 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
130 r[0] = SOB_INT_VALUE((SchemeObject*)r[0]);
132 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
133 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
135 r_res = (int)makeSchemeInt( r_res );
139 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("binary-mul",2) );
141 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
142 r[0] = SOB_INT_VALUE((SchemeObject*)r[0]);
144 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
145 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
146 r_res = (int)r[0] * (int)r[1]; /* multiply as signed integers */
147 r_res = (int)makeSchemeInt( r_res );
151 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("binary-div",2) );
153 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
154 r[0] = SOB_INT_VALUE((SchemeObject*)r[0]);
156 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
157 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
158 r_res = (int)r[0] / (int)r[1]; /* divide as signed integers */
159 r_res = (int)makeSchemeInt( r_res );
163 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==2,MSG_ERR_ARGCOUNT("binary<?",2) );
165 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[0]), "");
166 r[0] = SOB_INT_VALUE((SchemeObject*)r[0]);
168 ASSERT_ALWAYS(IS_SOB_INT((SchemeObject*)r[1]), "");
169 r[1] = SOB_INT_VALUE((SchemeObject*)r[1]);
170 r_res = ((int)r[0] < (int)r[1]); /* compare as signed integers */
171 r_res = (int)makeSchemeBool( r_res );
175 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==1,MSG_ERR_ARGCOUNT("box",1) );
177 r_res = (int)makeSchemeVectorInit( 1,(SchemeObject*)(r[0]) );
181 ASSERT_ALWAYS( BI_ST_ARG_COUNT()==1,MSG_ERR_ARGCOUNT("null?",1) );
183 r_res = (int)makeSchemeBool( IS_SOB_NIL(r[0]) );
187 /* create closures for the free variables of the built-in procedures */
188 CREATE_BUILTIN_CLOS("car" ,&&Lcar);
189 CREATE_BUILTIN_CLOS("cdr" ,&&Lcdr);
190 CREATE_BUILTIN_CLOS("symbol?" ,&&Lsymbol);
191 CREATE_BUILTIN_CLOS("set-car!" ,&&Lset_car);
192 CREATE_BUILTIN_CLOS("make-vector" ,&&Lmake_vector);
193 CREATE_BUILTIN_CLOS("vector-set!" ,&&Lvector_set);
194 CREATE_BUILTIN_CLOS("vector-ref" ,&&Lvector_ref);
195 CREATE_BUILTIN_CLOS("binary=?" ,&&LbinaryEQ);
196 CREATE_BUILTIN_CLOS("binary-add" ,&&LbinaryADD);
197 CREATE_BUILTIN_CLOS("binary-sub" ,&&LbinarySUB);
198 CREATE_BUILTIN_CLOS("binary-mul" ,&&LbinaryMUL);
199 CREATE_BUILTIN_CLOS("binary-mul" ,&&LbinaryMUL);
200 CREATE_BUILTIN_CLOS("binary-div" ,&&LbinaryDIV);
201 CREATE_BUILTIN_CLOS("binary<?" ,&&LbinaryLT);
202 CREATE_BUILTIN_CLOS("box" ,&&Lbox);
203 CREATE_BUILTIN_CLOS("null?" ,&&Lnull);
205 CREATE_BUILTIN_CLOS("",&&L);
208 /* </Built-in procedures> */