2003-08-19 15:19:38 -04:00
|
|
|
/* Delay and force.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kernel.h"
|
|
|
|
|
2003-08-19 15:24:23 -04:00
|
|
|
Object P_Promisep (Object x) {
|
2003-08-19 15:19:38 -04:00
|
|
|
return TYPE(x) == T_Promise ? True : False;
|
|
|
|
}
|
|
|
|
|
2003-08-19 15:24:23 -04:00
|
|
|
Object P_Delay (Object argl) {
|
2003-08-19 15:19:38 -04:00
|
|
|
Object d;
|
|
|
|
GC_Node;
|
|
|
|
|
|
|
|
GC_Link (argl);
|
|
|
|
d = Alloc_Object (sizeof (struct S_Promise), T_Promise, 0);
|
|
|
|
GC_Unlink;
|
|
|
|
PROMISE(d)->done = 0;
|
|
|
|
PROMISE(d)->env = The_Environment;
|
|
|
|
PROMISE(d)->thunk = Car (argl);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2003-08-19 15:24:23 -04:00
|
|
|
Object P_Force (Object d) {
|
2003-08-19 15:19:38 -04:00
|
|
|
Object ret, a[2];
|
|
|
|
GC_Node;
|
|
|
|
TC_Prolog;
|
|
|
|
|
|
|
|
Check_Type (d, T_Promise);
|
|
|
|
if (PROMISE(d)->done)
|
|
|
|
return PROMISE(d)->thunk;
|
|
|
|
GC_Link (d);
|
|
|
|
a[0] = PROMISE(d)->thunk; a[1] = PROMISE(d)->env;
|
|
|
|
TC_Disable;
|
|
|
|
ret = P_Eval (2, a);
|
|
|
|
TC_Enable;
|
|
|
|
GC_Unlink;
|
|
|
|
if (PROMISE(d)->done) /* take care of recursive force calls */
|
|
|
|
return PROMISE(d)->thunk;
|
|
|
|
PROMISE(d)->thunk = ret;
|
|
|
|
PROMISE(d)->done = 1;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2003-08-19 15:24:23 -04:00
|
|
|
Object P_Promise_Environment (Object p) {
|
2003-08-19 15:19:38 -04:00
|
|
|
Check_Type (p, T_Promise);
|
|
|
|
return PROMISE(p)->env;
|
|
|
|
}
|