New doc system done for core
[io.git] / libs / iovm / source / IoState.c
blob161fdb5bc82996ea1c1b9a082cec185d6f162e30
2 //metadoc State copyright Steve Dekorte 2002
3 //metadoc State license BSD revised
5 #define IOSTATE_C 1
6 #include "IoState.h"
7 #undef IOSTATE_C
9 #include "IoObject.h"
10 #include "IoCall.h"
11 #include "IoCoroutine.h"
12 #include "IoSeq.h"
13 #include "IoNumber.h"
14 #include "IoCFunction.h"
15 #include "IoBlock.h"
16 #include "IoList.h"
17 #include "IoMap.h"
18 //#include "IoRange.h"
19 #include "IoFile.h"
20 #include "IoDate.h"
21 #include "IoDuration.h"
22 #include "IoSeq.h"
23 #include "IoMessage_parser.h"
24 #include "IoDynLib.h"
25 #include "IoWeakLink.h"
27 #include "IoSystem.h"
28 #include "IoCompiler.h"
29 #include "IoDebugger.h"
30 #include "IoCollector.h"
31 #include "IoSandbox.h"
32 #include "IoDirectory.h"
33 //#include "IoEditLine.h"
35 #include <stdlib.h>
37 void IoVMCodeInit(IoObject *context);
39 void IoState_new_atAddress(void *address)
41 IoState *self = (IoState *)address;
42 IoCFunction *cFunctionProto;
43 IoSeq *seqProto;
45 // collector
47 self->collector = Collector_new();
48 IoState_pushCollectorPause(self);
50 Collector_setMarkFunc_(self->collector, (CollectorMarkFunc *)IoObject_mark);
51 Collector_setWillFreeFunc_(self->collector, (CollectorWillFreeFunc *)IoObject_willFree);
52 Collector_setFreeFunc_(self->collector, (CollectorFreeFunc *)IoObject_free);
54 self->mainArgs = MainArgs_new();
55 self->primitives = PHash_new();
57 self->recycledObjects = List_new();
58 self->maxRecycledObjects = IOSTATE_DEFAULT_MAX_RECYCLED_OBJECTS;
60 // Sandbox
62 self->messageCount = 0;
63 self->messageCountLimit = 0;
64 self->endTime = 0;
66 // symbol table
68 self->symbols = SHash_new();
70 SHash_setKeysEqualCallback(self->symbols, (SHashKeysEqualCallback *)UArray_equalsWithHashCheck_);
71 SHash_setHashForKeyCallback(self->symbols, (SHashHashforKeyCallback *)UArray_hash);
74 Problem:
75 - there are some interdependencies here:
76 - creating instances requires a retain stack
77 - we need a Coroutine to use for our retainStack
78 - defining any primitive methods requires Strings and CFunctions
80 Solution:
81 - create a temporary fake stack
82 - create Object, CFunction and String protos sans methods.
83 - then add methods to Object, CFunction and String
86 self->currentIoStack = Stack_new(); // temp retain stack until coro is up
88 self->objectProto = IoObject_proto(self); // need to do this first, so we have a retain stack
89 //IoState_retain_(self, self->objectProto);
91 self->mainCoroutine = IoCoroutine_proto(self);
92 Stack_free(self->currentIoStack);
93 self->currentIoStack = NULL;
95 IoState_setCurrentCoroutine_(self, self->mainCoroutine);
97 seqProto = IoSeq_proto(self);
99 IoState_setupQuickAccessSymbols(self);
101 IoObject_rawSetProto_(seqProto, self->objectProto);
103 cFunctionProto = IoCFunction_proto(self);
104 self->localsUpdateSlotCFunc = IoState_retain_(self,
105 IoCFunction_newWithFunctionPointer_tag_name_(self,
106 IoObject_localsUpdateSlot, NULL, "localsUpdate"));
108 IoSeq_protoFinish(seqProto);
109 IoObject_protoFinish(self);
110 IoCFunction_protoFinish(self);
111 IoCoroutine_protoFinish(self->mainCoroutine);
113 self->setSlotBlock = IoState_retain_(self, IoObject_getSlot_(self->objectProto, SIOSYMBOL("setSlot")));
115 // setup lobby
118 IoObject *objectProto = self->objectProto;
119 IoObject *protos = IOCLONE(objectProto);
120 IoObject *core = IOCLONE(objectProto);
122 self->core = core;
123 self->lobby = IOCLONE(objectProto);
124 IoState_retain_(self, self->lobby);
125 IoState_retain_(self, self->core);
127 // setup namespace
129 IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Lobby"), self->lobby);
130 IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Protos"), protos);
131 IoObject_setSlot_to_(protos, SIOSYMBOL("Core"), core);
132 IoObject_setSlot_to_(protos, SIOSYMBOL("Addons"), IOCLONE(objectProto));
134 IoObject_setSlot_to_(core, SIOSYMBOL("Compiler"), IoCompiler_proto(self));
135 IoObject_setSlot_to_(core, SIOSYMBOL("Collector"), IoCollector_proto(self));
136 IoObject_setSlot_to_(core, SIOSYMBOL("Exception"), IOCLONE(objectProto));
138 // setup proto chain
140 IoObject_rawSetProto_(objectProto, self->lobby);
141 IoObject_rawSetProto_(self->lobby, protos);
142 IoObject_rawSetProto_(protos, core);
144 // add protos to namespace
146 IoObject_setSlot_to_(core, SIOSYMBOL("Object"), objectProto);
147 IoObject_setSlot_to_(core, SIOSYMBOL("Sequence"), seqProto);
148 IoObject_setSlot_to_(core, SIOSYMBOL("Number"), IoNumber_proto(self));
150 IoState_setupCachedNumbers(self);
153 IoObject *systemProto = IoSystem_proto(self);
154 IoObject_setSlot_to_(core, SIOSYMBOL("System"), systemProto);
157 IoState_setupSingletons(self);
158 IoState_setupCachedMessages(self);
161 self->debugger = IoState_retain_(self, IoDebugger_proto(self));
162 IoObject_setSlot_to_(core, SIOSYMBOL("Debugger"), self->debugger);
164 self->vmWillSendMessage = IoMessage_newWithName_(self, SIOSYMBOL("vmWillSendMessage"));
165 IoMessage_cachedResult_(self->nilMessage, self->ioNil);
166 IoState_retain_(self, self->vmWillSendMessage);
169 IoObject_setSlot_to_(core, SIOSYMBOL("Block"), IoBlock_proto(self));
170 IoObject_setSlot_to_(core, SIOSYMBOL("List"), IoList_proto(self));
171 IoObject_setSlot_to_(core, SIOSYMBOL("Map"), IoMap_proto(self));
172 //IoObject_setSlot_to_(core, SIOSYMBOL("Range"), IoRange_proto(self));
173 IoObject_setSlot_to_(core, SIOSYMBOL("Coroutine"), self->mainCoroutine);
174 IoObject_setSlot_to_(core, SIOSYMBOL("File"), IoFile_proto(self));
175 IoObject_setSlot_to_(core, SIOSYMBOL("Directory"), IoDirectory_proto(self));
176 IoObject_setSlot_to_(core, SIOSYMBOL("Date"), IoDate_proto(self));
177 IoObject_setSlot_to_(core, SIOSYMBOL("Duration"), IoDuration_proto(self));
178 IoObject_setSlot_to_(core, SIOSYMBOL("WeakLink"), IoWeakLink_proto(self));
179 IoObject_setSlot_to_(core, SIOSYMBOL("Sandbox"), IoSandbox_proto(self));
180 //IoObject_setSlot_to_(core, SIOSYMBOL("EditLine"), IoEditLine_proto(self));
182 #if !defined(__SYMBIAN32__)
183 IoObject_setSlot_to_(core, SIOSYMBOL("DynLib"), IoDynLib_proto(self));
184 #endif
186 //self->store =
187 //IoObject_setSlot_to_(core, SIOSYMBOL("Store"), self->store);
188 IoObject_setSlot_to_(core, SIOSYMBOL("CFunction"), cFunctionProto);
190 self->localsProto = IoState_retain_(self, IoObject_localsProto(self));
191 IoObject_setSlot_to_(core, SIOSYMBOL("Locals"), self->localsProto);
193 self->stopStatus = MESSAGE_STOP_STATUS_NORMAL;
194 self->returnValue = self->ioNil;
196 IoState_clearRetainStack(self);
198 IoState_popCollectorPause(self);
200 //Collector_collect(self->collector);
202 //io_show_mem("before IoVMCodeInit");
203 IoVMCodeInit(core);
205 //io_show_mem("after IoVMCodeInit");
206 //Collector_collect(self->collector);
207 //io_show_mem("after Collector_collect");
209 // IoState_popCollectorPause(self);
210 IoState_clearRetainStack(self);
212 Collector_collect(self->collector);
213 //io_show_mem("after IoState_clearRetainStack and Collector_collect");
217 IoState *IoState_new(void)
219 IoState *self = (IoState *)io_calloc(1, sizeof(IoState));
220 IoState_new_atAddress(self);
221 return self;
224 void IoState_setupQuickAccessSymbols(IoState *self)
226 self->activateSymbol = IoState_retain_(self, SIOSYMBOL("activate"));
227 self->forwardSymbol = IoState_retain_(self, SIOSYMBOL("forward"));
228 self->selfSymbol = IoState_retain_(self, SIOSYMBOL("self"));
229 self->setSlotSymbol = IoState_retain_(self, SIOSYMBOL("setSlot"));
230 self->setSlotWithTypeSymbol = IoState_retain_(self, SIOSYMBOL("setSlotWithType"));
231 self->updateSlotSymbol = IoState_retain_(self, SIOSYMBOL("updateSlot"));
232 self->callSymbol = IoState_retain_(self, SIOSYMBOL("call"));
233 self->typeSymbol = IoState_retain_(self, SIOSYMBOL("type"));
234 self->opShuffleSymbol = IoState_retain_(self, SIOSYMBOL("opShuffle"));
235 self->noShufflingSymbol = IoState_retain_(self, SIOSYMBOL("__noShuffling__"));
236 self->semicolonSymbol = IoState_retain_(self, SIOSYMBOL(";"));
237 self->stackSizeSymbol = IoState_retain_(self, SIOSYMBOL("stackSize"));
240 void IoState_setupSingletons(IoState *self)
242 IoObject *core = self->core;
243 // nil
245 self->ioNil = IOCLONE(self->objectProto);
246 IoObject_setSlot_to_(core, SIOSYMBOL("nil"), self->ioNil);
247 //IoObject_setSlot_to_(core, self->noShufflingSymbol, self->ioNil);
248 IoObject_setSlot_to_(core, SIOSYMBOL("Message"), IoMessage_proto(self));
249 IoObject_setSlot_to_(core, SIOSYMBOL("Call"), IoCall_proto(self));
251 self->nilMessage = IoMessage_newWithName_(self, SIOSYMBOL("nil"));
252 IoMessage_cachedResult_(self->nilMessage, self->ioNil);
253 IoState_retain_(self, self->nilMessage);
255 // true
257 self->ioTrue = IoObject_new(self);
258 IoObject_setSlot_to_(core, SIOSYMBOL("true"), self->ioTrue);
259 IoObject_setSlot_to_(self->ioTrue, SIOSYMBOL("type"), SIOSYMBOL("true"));
260 IoState_retain_(self, self->ioTrue);
262 // false
264 self->ioFalse = IoObject_new(self);
265 IoObject_setSlot_to_(core, SIOSYMBOL("false"), self->ioFalse);
266 IoObject_setSlot_to_(self->ioFalse, SIOSYMBOL("type"), SIOSYMBOL("false"));
267 IoState_retain_(self, self->ioFalse);
269 // Flow control: Normal
270 self->ioNormal = IoObject_new(self);
271 IoObject_setSlot_to_(core, SIOSYMBOL("Normal"), self->ioNormal);
272 IoObject_setSlot_to_(self->ioNormal, SIOSYMBOL("type"), SIOSYMBOL("Normal"));
273 IoState_retain_(self, self->ioNormal);
275 // Flow control: Break
276 self->ioBreak = IoObject_new(self);
277 IoObject_setSlot_to_(core, SIOSYMBOL("Break"), self->ioBreak);
278 IoObject_setSlot_to_(self->ioBreak, SIOSYMBOL("type"), SIOSYMBOL("Break"));
279 IoState_retain_(self, self->ioBreak);
281 // Flow control: Continue
282 self->ioContinue = IoObject_new(self);
283 IoObject_setSlot_to_(core, SIOSYMBOL("Continue"), self->ioContinue);
284 IoObject_setSlot_to_(self->ioContinue, SIOSYMBOL("type"), SIOSYMBOL("Continue"));
285 IoState_retain_(self, self->ioContinue);
287 // Flow control: Return
288 self->ioReturn = IoObject_new(self);
289 IoObject_setSlot_to_(core, SIOSYMBOL("Return"), self->ioReturn);
290 IoObject_setSlot_to_(self->ioReturn, SIOSYMBOL("type"), SIOSYMBOL("Return"));
291 IoState_retain_(self, self->ioReturn);
293 // Flow control: Eol
294 self->ioEol = IoObject_new(self);
295 IoObject_setSlot_to_(core, SIOSYMBOL("Eol"), self->ioEol);
296 IoObject_setSlot_to_(self->ioEol, SIOSYMBOL("type"), SIOSYMBOL("Eol"));
297 IoState_retain_(self, self->ioEol);
300 void IoState_setupCachedMessages(IoState *self)
302 self->asStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("asString"));
303 IoState_retain_(self, self->asStringMessage);
305 self->collectedLinkMessage = IoMessage_newWithName_(self, SIOSYMBOL("collectedLink"));
306 IoState_retain_(self, self->collectedLinkMessage);
308 self->compareMessage = IoMessage_newWithName_(self, SIOSYMBOL("compare"));
309 IoState_retain_(self, self->compareMessage);
311 //self->doStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("doString"));
312 //IoState_retain_(self, self->doStringMessage);
314 self->printMessage = IoMessage_newWithName_(self, SIOSYMBOL("print"));
315 IoState_retain_(self, self->printMessage);
317 self->initMessage = IoMessage_newWithName_(self, SIOSYMBOL("init"));
318 IoState_retain_(self, self->initMessage);
320 self->willFreeMessage = IoMessage_newWithName_(self, SIOSYMBOL("willFree"));
321 IoState_retain_(self, self->willFreeMessage);
323 self->runMessage = IoMessage_newWithName_(self, SIOSYMBOL("run"));
324 IoState_retain_(self, self->runMessage);
326 self->mainMessage = IoMessage_newWithName_(self, SIOSYMBOL("main"));
327 IoState_retain_(self, self->mainMessage);
329 self->opShuffleMessage = IoMessage_newWithName_(self, self->opShuffleSymbol);
330 IoState_retain_(self, self->opShuffleMessage);
332 self->yieldMessage = IoMessage_newWithName_(self, SIOSYMBOL("yield"));
333 IoState_retain_(self, self->yieldMessage);
336 IoObject *IoObject_initBindings(IoObject *self, IoObject *locals, IoMessage *m)
338 IOSTATE->bindingsInitCallback(IOSTATE, self);
339 return self;
342 void IoState_init(IoState *self)
344 if (self->bindingsInitCallback)
346 IoState_pushCollectorPause(self);
347 self->bindingsInitCallback(self, self->core);
348 IoState_popCollectorPause(self);
349 IoState_clearRetainStack(self);
353 void IoState_registerProtoWithFunc_(IoState *self, IoObject *proto, IoStateProtoFunc *func)
355 if (PHash_at_(self->primitives, (void *)func))
357 IoState_fatalError_(self, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice");
360 IoState_retain_(self, proto);
361 PHash_at_put_(self->primitives, (void *)func, proto);
362 //printf("registered %s\n", IoObject_name(proto));
365 IoObject *IoState_protoWithName_(IoState *self, const char *name)
367 PHASH_FOREACH(self->primitives, key, proto, if (!strcmp(IoObject_name(proto), name)) { return proto; });
368 return NULL;
371 List *IoState_tagList(IoState *self) // caller must io_free returned List
373 List *tags = List_new();
374 PHASH_FOREACH(self->primitives, k, proto, List_append_(tags, IoObject_tag((IoObject *)proto)));
375 return tags;
378 void IoState_done(IoState *self)
380 // this should only be called from the main coro from outside of Io
382 List *tags = IoState_tagList(self); // need to get the tags before we io_free the protos
384 self->maxRecycledObjects = 0;
386 Collector_freeAllValues(self->collector); // io_free all objects known to the collector
387 Collector_free(self->collector);
389 List_do_(tags, (ListDoCallback *)IoTag_free);
390 List_free(tags);
392 PHash_free(self->primitives);
393 SHash_free(self->symbols);
395 LIST_DO_(self->recycledObjects, IoObject_dealloc); // this doesn't work now that objects and marks are separate
396 List_free(self->recycledObjects);
397 List_free(self->cachedNumbers);
399 MainArgs_free(self->mainArgs);
402 void IoState_free(IoState *self)
404 IoState_done(self);
405 io_free(self);
408 IoObject *IoState_lobby(IoState *self)
410 return self->lobby;
413 void IoState_setLobby_(IoState *self, IoObject *obj)
415 self->lobby = obj;
418 void MissingProtoError(void)
420 printf("missing proto\n");
423 IoObject *IoState_protoWithInitFunction_(IoState *self, IoStateProtoFunc *func)
425 IoObject *proto = PHash_at_(self->primitives, (void *)func);
427 //printf("IoState_protoWithInitFunction_(self, %p)\n", (void *)func);
429 if (!proto)
431 //MissingProtoError();
432 printf("missing proto %p\n", (void *)func);
434 IoState_fatalError_(self, "IoState_protoWithInitFunction() Error: missing proto");
437 return proto;
441 // command line ------------------------------------------------
443 void IoState_argc_argv_(IoState *self, int argc, const char *argv[])
445 IoList *args = IoList_new(self);
446 int i;
448 for (i = 1; i < argc; i ++)
450 IoList_rawAppend_(args, SIOSYMBOL(argv[i]));
454 IoObject *system = IoObject_getSlot_(self->lobby, SIOSYMBOL("System"));
455 IoObject_setSlot_to_(system, SIOSYMBOL("args"), args);
458 MainArgs_argc_argv_(self->mainArgs, argc, argv);
461 // store -------------------------------------------------------
463 IoObject *IoState_objectWithPid_(IoState *self, PID_TYPE pid)
465 return self->ioNil;
468 // doString -------------------------------------------------------
470 IoObject *IoState_rawOn_doCString_withLabel_(IoState *self,
471 IoObject *target,
472 const char *s,
473 const char *label)
475 IoMessage *m = IoMessage_newFromText_label_(self, s, label);
476 return IoMessage_locals_performOn_(m, target, target);
479 // CLI ---------------------------------------------------------
481 void IoState_rawPrompt(IoState *self)
483 int max = 1024 * 16;
484 char *s = io_calloc(1, max);
485 IoObject *result;
487 for (;;)
489 fputs("Io> ", stdout);
490 fflush(stdout);
491 fgets(s, max, stdin);
493 if (feof(stdin))
495 break;
498 result = IoState_rawOn_doCString_withLabel_(self, self->lobby, s, "IoState_rawPrompt()");
500 fputs("==> ", stdout);
501 IoObject_print(result);
502 fputs("\n", stdout);
505 io_free(s);
508 void IoState_runCLI(IoState *self)
510 IoObject *result = IoState_on_doCString_withLabel_(self, self->lobby, "CLI run", "IoState_runCLI()");
512 if (!self->shouldExit && ISNUMBER(result))
514 self->exitResult = CNUMBER(result);
518 IOVM_API int IoState_exitResult(IoState *self)
520 return self->exitResult;