1 /*
2 * Copyright © 1988-2004 Keith Packard and Bart Massey.
3 * All Rights Reserved. See the file COPYING in this directory
4 * for licensing information.
5 */
6
7 #if LOCAL_BUILD
8 #include "nickle-config.h"
9 #include "mem.h"
10 #include "value.h"
11 #include "opcode.h"
12 #else
13 #include <nickle/nickle-config.h>
14 #include <nickle/mem.h>
15 #include <nickle/value.h>
16 #include <nickle/opcode.h>
17 #endif
18 #include <assert.h>
19
20 typedef struct _func *FuncPtr;
21 typedef struct _namespace *NamespacePtr;
22 typedef struct _command *CommandPtr;
23
24 typedef struct _symbolBase {
25 DataType *data;
26 SymbolPtr next;
27 Atom name;
28 Class class;
29 Type *type;
30 Bool forward; /* forward declaration of a function */
31 } SymbolBase;
32
33 typedef struct _symbolType {
34 SymbolBase symbol;
35 } SymbolType;
36
37 typedef struct _symbolGlobal {
38 SymbolBase symbol;
39 BoxPtr value;
40 } SymbolGlobal;
41
42 typedef struct _symbolLocal {
43 SymbolBase symbol;
44 int element;
45 Bool staticScope; /* dynamic scope equal to static */
46 CodePtr code;
47 } SymbolLocal;
48
49 typedef struct _symbolNamespace {
50 SymbolBase symbol;
51 NamespacePtr namespace;
52 } SymbolNamespace;
53
54 typedef struct _symbolException {
55 SymbolBase symbol;
56 Value doc;
57 } SymbolException;
58
59 typedef union _symbol {
60 SymbolBase symbol;
61 SymbolType type;
62 SymbolGlobal global;
63 SymbolLocal local;
64 SymbolNamespace namespace;
65 SymbolException exception;
66 } Symbol;
67
68 extern SymbolPtr NewSymbolType (Atom name, Type *type);
69 extern SymbolPtr NewSymbolException (Atom name, Type *type, Value doc);
70 extern SymbolPtr NewSymbolConst (Atom name, Type *type);
71 extern SymbolPtr NewSymbolGlobal (Atom name, Type *type);
72 extern SymbolPtr NewSymbolGlobalValue (Atom name, BoxPtr value);
73 extern SymbolPtr NewSymbolArg (Atom name, Type *type);
74 extern SymbolPtr NewSymbolStatic (Atom name, Type *Rep);
75 extern SymbolPtr NewSymbolAuto (Atom name, Type *type);
76 extern SymbolPtr NewSymbolNamespace (Atom name, NamespacePtr namespace);
77
_TypeNameType(TypePtr t)78 static inline Type *_TypeNameType(TypePtr t) {
79 if (t->name.name)
80 return t->name.name->symbol.type;
81 else
82 return NULL;
83 }
84
85 #define TypeNameType(t) _TypeNameType(t)
86
87 typedef struct _namelist *NamelistPtr;
88
89 typedef struct _namelist {
90 DataType *data;
91 NamelistPtr next;
92 SymbolPtr symbol;
93 Publish publish;
94 } Namelist;
95
96 typedef struct _namespace {
97 DataType *data;
98 NamespacePtr previous;
99 NamelistPtr names;
100 Publish publish;
101 } Namespace;
102
103 NamespacePtr NewNamespace (NamespacePtr previous);
104 SymbolPtr NamespaceFindName (NamespacePtr namespace, Atom atom, Bool search);
105 Bool NamespaceIsNamePrivate (NamespacePtr namespace, Atom atom, Bool search);
106 SymbolPtr NamespaceAddName (NamespacePtr namespace, SymbolPtr symbol, Publish publish);
107 Bool NamespaceRemoveName (NamespacePtr namespace, Atom atom);
108 void NamespaceImport (NamespacePtr namespace, NamespacePtr import, Publish publish);
109 void NamespaceInit (void);
110
111 extern NamespacePtr GlobalNamespace, TopNamespace, CurrentNamespace, DebugNamespace, LexNamespace;
112 extern FramePtr CurrentFrame;
113
114 typedef struct _command {
115 DataType *data;
116 CommandPtr previous;
117 Atom name;
118 Value func;
119 Bool names;
120 } Command;
121
122 CommandPtr NewCommand (CommandPtr previous, Atom name, Value func, Bool names);
123 CommandPtr CommandFind (CommandPtr command, Atom name);
124 CommandPtr CommandRemove (CommandPtr command, Atom name);
125
126 extern CommandPtr CurrentCommands;
127
128 typedef struct _DeclList *DeclListPtr;
129 typedef struct _DeclList {
130 DataType *data;
131 DeclListPtr next;
132 Atom name;
133 SymbolPtr symbol;
134 ExprPtr init;
135 } DeclList;
136
137 extern DeclListPtr NewDeclList (Atom name, ExprPtr init, DeclListPtr next);
138
139 typedef struct _MemList *MemListPtr;
140 typedef struct _MemList {
141 DataType *data;
142 MemListPtr next;
143 Type *type;
144 AtomListPtr atoms;
145 } MemList;
146
147 extern MemListPtr NewMemList (AtomListPtr atoms, Type *type, MemListPtr next);
148
149 typedef struct _Fulltype {
150 Publish publish;
151 Class class;
152 Type *type;
153 } Fulltype;
154
155 typedef struct _funcDecl {
156 Fulltype type;
157 DeclList *decl;
158 } FuncDecl;
159
160 typedef struct _frame {
161 DataType *data;
162 FramePtr previous;
163 FramePtr staticLink;
164 Value function;
165 BoxPtr frame;
166 BoxPtr statics;
167 InstPtr savePc;
168 ObjPtr saveObj;
169 } Frame;
170
171 extern FramePtr NewFrame (Value function,
172 FramePtr previous,
173 FramePtr staticLink,
174 BoxTypesPtr dynamics,
175 BoxPtr statics);
176
177 typedef struct _catch {
178 Continuation continuation;
179 SymbolPtr exception;
180 } Catch;
181
182 CatchPtr NewCatch (Value thread, SymbolPtr exception);
183
184 typedef struct _twixt {
185 Continuation continuation;
186 InstPtr leave;
187 int depth;
188 } Twixt;
189
190 TwixtPtr
191 NewTwixt (ContinuationPtr continuation, InstPtr enter, InstPtr leave);
192
193 InstPtr TwixtJump (Value thread, TwixtPtr twixt, Bool enter);
194
TwixtDepth(Twixt * t)195 static inline int TwixtDepth(Twixt *t) {
196 if (t)
197 return t->depth;
198 else
199 return 0;
200 }
201
202 TwixtPtr TwixtNext (TwixtPtr twixt, TwixtPtr last);
203
204 # define NOTHING 0
205 # define CONT 1
206 # define BRK 2
207 # define RET 3
208
209 typedef struct _exprBase {
210 DataType *data;
211 int tag;
212 Atom file;
213 int line;
214 NamespacePtr namespace;
215 Type *type;
216 double_digit ticks;
217 double_digit sub_ticks;
218 } ExprBase;
219
220 typedef struct _exprTree {
221 ExprBase expr;
222 ExprPtr left;
223 ExprPtr right;
224 } ExprTree;
225
226 typedef struct _exprConst {
227 ExprBase expr;
228 Value constant;
229 } ExprConst;
230
231 typedef struct _exprAtom {
232 ExprBase expr;
233 Atom atom;
234 SymbolPtr symbol;
235 Bool privateFound; /* used to clarify error message for missing names */
236 } ExprAtom;
237
238 typedef struct _exprCode {
239 ExprBase expr;
240 CodePtr code;
241 } ExprCode;
242
243 typedef struct _exprDecls {
244 ExprBase expr;
245 DeclListPtr decl;
246 Class class;
247 Type *type;
248 Publish publish;
249 } ExprDecl;
250
251 typedef struct _exprType {
252 ExprBase expr;
253 ExprPtr left;
254 Type *type;
255 } ExprType;
256
257 typedef union _expr {
258 ExprBase base;
259 ExprTree tree;
260 ExprConst constant;
261 ExprAtom atom;
262 ExprCode code;
263 ExprDecl decl;
264 ExprType type;
265 } Expr;
266
267 Expr *NewExprTree (int tag, Expr *left, Expr *right);
268 Expr *NewExprComma (Expr *left, Expr *right);
269 Expr *NewExprConst (int tag, Value val);
270 Expr *NewExprAtom (Atom atom, SymbolPtr symbol, Bool privateFound);
271 Expr *NewExprCode (CodePtr code, ExprPtr name);
272 Expr *NewExprDecl (int tag, DeclListPtr decl, Class class, Type *type, Publish publish);
273 Expr *NewExprType (int tag, Expr *left, Type *type);
274 Expr *ExprRehang (Expr *expr, Expr *right);
275
276
277 typedef struct _codeBase {
278 DataType *data;
279 Bool builtin;
280 Type *type;
281 int argc;
282 Bool varargs;
283 ArgType *args;
284 ExprPtr name;
285 CodePtr previous;
286 CodePtr func; /* function context, usually self */
287 Value doc; /* documentation */
288 } CodeBase;
289
290 /*
291 * Static initializers:
292 *
293 * Two kinds:
294 * static
295 * global
296 *
297 * Static initializers are essentially parallel functions called when
298 * the function is evaluated; the value resulting from this evaluation
299 * contains a pointer to the function body along with a block of initialized
300 * statics. They can therefore access any *static* variables in the
301 * function scope as well as any other variables in *dynamic* scope
302 * at the time of function evaluation, which means they can access
303 * any name they can see *except* for dynamic variables in the function
304 * scope.
305 *
306 * Global initializers are run in a global context, they can only access
307 * variables which have global lifetime, that means only global variables.
308 * When found inside a function context, they are placed in the static
309 * initializer block of the enclosing function at global scope.
310 *
311 *
312 * function foo() {
313 * auto foo_a = 1;
314 * static foo_s = 2;
315 * global foo_g = 3;
316 *
317 * function bar() {
318 * auto bar_a1 = 4; <- can touch any name in scope
319 * global bar_g1 = foo_g; <- legal
320 * global bar_g2 = foo_s; <- not legal
321 * static bar_s1 = foo_g; <- legal
322 * static bar_s2 = foo_s; <- legal
323 * static bar_s3 = foo_a; <- legal
324 * static bar_s4 = bar_a1; <- not legal
325 * }
326 * }
327 */
328
329 typedef struct _funcBody {
330 ObjPtr obj;
331 BoxTypesPtr dynamics;
332 } FuncBody, *FuncBodyPtr;
333
334 typedef struct _funcCode {
335 CodeBase base;
336 ExprPtr code;
337
338 FuncBody body;
339 FuncBody staticInit;
340
341 BoxTypesPtr statics;
342 Bool inStaticInit;
343 Bool inGlobalInit;
344 } FuncCode, *FuncCodePtr;
345
346 typedef union _builtinFunc {
347 Value (*builtinN)(int, Value *);
348 Value (*builtin0)(void);
349 Value (*builtin1)(Value);
350 Value (*builtin2)(Value,Value);
351 Value (*builtin3)(Value,Value,Value);
352 Value (*builtin4)(Value,Value,Value,Value);
353 Value (*builtin5)(Value,Value,Value,Value,Value);
354 Value (*builtin6)(Value,Value,Value,Value,Value,Value);
355 Value (*builtin7)(Value,Value,Value,Value,Value,Value,Value);
356 Value (*builtin8)(Value,Value,Value,Value,Value,Value,Value,Value);
357 Value (*builtinNJ)(InstPtr *, int, Value *);
358 Value (*builtin0J)(InstPtr *);
359 Value (*builtin1J)(InstPtr *,Value);
360 Value (*builtin2J)(InstPtr *,Value,Value);
361 } BuiltinFunc;
362
363 typedef struct _builtinCode {
364 CodeBase base;
365 Bool needsNext;
366 BuiltinFunc b;
367 } BuiltinCode, *BuiltinCodePtr;
368
369 typedef union _code {
370 CodeBase base;
371 FuncCode func;
372 BuiltinCode builtin;
373 } Code;
374
375 CodePtr NewFuncCode (Type *type, ArgType *args, ExprPtr code, Value doc);
376 CodePtr NewBuiltinCode (Type *type, ArgType *args, int argc,
377 BuiltinFunc func, Bool needsNext, char *doc);
378 Value NewFunc (CodePtr, FramePtr);
379
380 typedef struct _farJump {
381 DataType *data;
382 int inst;
383 int twixt;
384 int catch;
385 int frame;
386 } FarJump, *FarJumpPtr;
387
388 FarJumpPtr NewFarJump (int inst, int twixt, int catch, int frame);
389 Value FarJumpContinuation (ContinuationPtr continuation, FarJumpPtr farJump);
390
391 #define InstPush 0x01
392
393 typedef struct _instBase {
394 OpCode opCode;
395 short flags;
396 } InstBase;
397
398 typedef struct _instBox {
399 InstBase inst;
400 BoxPtr box;
401 } InstBox;
402
403 typedef struct _instFrame {
404 InstBase inst;
405 short staticLink;
406 short element;
407 } InstFrame;
408
409 typedef struct _instConst {
410 InstBase inst;
411 Value constant;
412 } InstConst;
413
414 typedef struct _instAtom {
415 InstBase inst;
416 Atom atom;
417 } InstAtom;
418
419 typedef struct _instInt {
420 InstBase inst;
421 int value;
422 } InstInt;
423
424 typedef struct _instStruct {
425 InstBase inst;
426 StructType *structs;
427 } InstStruct;
428
429 typedef struct _instArray {
430 InstBase inst;
431 short ndim;
432 short resizable;
433 TypePtr type;
434 } InstArray;
435
436 typedef enum _aInitMode {
437 AInitModeStart, /* Build initialization data on stack */
438 AInitModeElement, /* Initialize one element */
439 AInitModeRepeat, /* Duplicate initialization values along row */
440 AInitModeFunc, /* Build stack frame for function call */
441 AInitModeTest, /* Check to see if the array is completely initialized */
442 AInitModeFuncDone /* Clean up */
443 } AInitMode;
444
445 typedef struct _instAInit {
446 InstBase inst;
447 int dim;
448 AInitMode mode;
449 } InstAInit;
450
451 typedef struct _instHash {
452 InstBase inst;
453 TypePtr type;
454 } InstHash;
455
456 typedef struct _instCode {
457 InstBase inst;
458 CodePtr code;
459 } InstCode;
460
461 typedef enum _branchMod {
462 BranchModNone, BranchModBreak, BranchModContinue,
463 BranchModReturn, BranchModReturnVoid, BranchModCatch
464 } BranchMod;
465
466 typedef struct _instBranch {
467 InstBase inst;
468 int offset;
469 BranchMod mod;
470 } InstBranch;
471
472 typedef struct _instBinOp {
473 InstBase inst;
474 BinaryOp op;
475 } InstBinOp;
476
477 typedef struct _instBinFunc {
478 InstBase inst;
479 BinaryFunc func;
480 } InstBinFunc;
481
482 typedef struct _instUnOp {
483 InstBase inst;
484 UnaryOp op;
485 } InstUnOp;
486
487 typedef struct _instUnFunc {
488 InstBase inst;
489 UnaryFunc func;
490 } InstUnFunc;
491
492 typedef struct _instAssign {
493 InstBase inst;
494 Bool initialize;
495 } InstAssign;
496
497 typedef struct _instObj {
498 InstBase inst;
499 ObjPtr obj;
500 } InstObj;
501
502 typedef struct _instCatch {
503 InstBase inst;
504 int offset;
505 SymbolPtr exception;
506 } InstCatch;
507
508 typedef struct _instRaise {
509 InstBase inst;
510 int argc;
511 SymbolPtr exception;
512 } InstRaise;
513
514 typedef struct _instTwixt {
515 InstBase inst;
516 int enter;
517 int leave;
518 } InstTwixt;
519
520 typedef struct _instTagCase {
521 InstBase inst;
522 int offset;
523 Atom tag;
524 } InstTagCase;
525
526 typedef struct _instUnwind {
527 InstBase inst;
528 int twixt;
529 int catch;
530 } InstUnwind;
531
532 typedef struct _instFarJump {
533 InstBase inst;
534 FarJumpPtr farJump;
535 BranchMod mod;
536 } InstFarJump;
537
538 typedef struct _instIsType {
539 InstBase inst;
540 TypePtr type;
541 } InstIsType;
542
543 typedef union _inst {
544 InstBase base;
545 InstBox box;
546 InstFrame frame;
547 InstConst constant;
548 InstAtom atom;
549 InstInt ints;
550 InstStruct structs;
551 InstArray array;
552 InstAInit ainit;
553 InstHash hash;
554 InstCode code;
555 InstBranch branch;
556 InstBinOp binop;
557 InstBinFunc binfunc;
558 InstUnOp unop;
559 InstUnFunc unfunc;
560 InstAssign assign;
561 InstObj obj;
562 InstCatch catch;
563 InstRaise raise;
564 InstTwixt twixt;
565 InstTagCase tagcase;
566 InstUnwind unwind;
567 InstFarJump farJump;
568 InstIsType isType;
569 } Inst;
570
571 /*
572 * A structure used to process non-structured
573 * control flow changes (break, continue, return)
574 * within the presence of twixt/catch
575 */
576
577 typedef enum _nonLocalKind {
578 NonLocalControl, NonLocalTwixt, NonLocalTry, NonLocalCatch
579 } NonLocalKind;
580
581 #define NON_LOCAL_RETURN 0
582 #define NON_LOCAL_BREAK 1
583 #define NON_LOCAL_CONTINUE 2
584
585 typedef struct _nonLocal {
586 DataType *data;
587 struct _nonLocal *prev;
588 NonLocalKind kind; /* kind of non local object */
589 int target; /* what kind of targets */
590 ObjPtr obj;
591 } NonLocal, *NonLocalPtr;
592
593 typedef struct _Stat {
594 int inst;
595 ExprPtr stat;
596 } Stat, *StatPtr;
597
598 typedef struct _obj {
599 DataType *data;
600 int size;
601 int used;
602 int size_stat;
603 int used_stat;
604 double_digit ticks;
605 double_digit sub_ticks;
606 Bool error;
607 NonLocal *nonLocal;
608 Inst insts[0];
609 } Obj;
610
ObjCode(Obj * obj,int i)611 static inline InstPtr ObjCode(Obj *obj, int i) {
612 return &(obj->insts[i]);
613 }
614
ObjLast(Obj * obj)615 static inline int ObjLast(Obj *obj) {
616 return obj->used - 1;
617 }
618
ObjStat(Obj * obj,int i)619 static inline StatPtr ObjStat(Obj *obj, int i) {
620 StatPtr stats = (StatPtr) ObjCode(obj,obj->size);
621 return &stats[i];
622 }
623
624 ObjPtr CompileStat (ExprPtr expr, CodePtr code);
625 ObjPtr CompileExpr (ExprPtr expr, CodePtr code);
626 ExprPtr ObjStatement (ObjPtr obj, InstPtr inst);
627
628 typedef enum _wakeKind {
629 WakeAll, WakeOne
630 } WakeKind;
631
632 extern Bool lastThreadError;
633
634 Value NewThread (FramePtr frame, ObjPtr code);
635 void ThreadSleep (Value thread, Value sleep, int priority);
636 void ThreadStepped (Value thread);
637 void ThreadsWakeup (Value sleep, WakeKind wake);
638 void ThreadsRun (Value thread, Value lex);
639 void ThreadsInterrupt (void);
640 void ThreadsSignal (Value signal);
641 void ThreadsContinue (void);
642 void ThreadFinish (Value thread, Bool error);
643 void ThreadSetState (Value thread, ThreadState state);
644 void ThreadInit (void);
645 void TraceFunction (Value file, FramePtr frame, CodePtr code, ExprPtr name);
646 void TraceFrame (Value file, FramePtr frame, ObjPtr obj, InstPtr pc, int depth);
647 void ThreadStackDump (Value thread);
648 void ThreadsBlock (void);
649
650 typedef void (*NickleBlockHandler) (void *closure);
651
652 void
653 ThreadsRegisterBlockHandler (NickleBlockHandler handler, void *closure);
654
655 void
656 ThreadsUnregisterBlockHandler (NickleBlockHandler handler, void *closure);
657
658 typedef struct _jump {
659 DataType *data;
660 TwixtPtr enter;
661 TwixtPtr entering;
662 TwixtPtr leave;
663 TwixtPtr parent;
664 ContinuationPtr continuation;
665 Value ret;
666 } Jump;
667
668 Value JumpContinue (Value thread, InstPtr *next);
669 InstPtr JumpStart (Value thread, ContinuationPtr continuation, Value ret);
670 JumpPtr NewJump (TwixtPtr leave, TwixtPtr enter,
671 TwixtPtr parent, ContinuationPtr continuation, Value ret);
672
673 extern Value running; /* current thread */
674 extern Value stopped; /* stopped threads */
675 extern Bool complete; /* must complete current inst */
676 extern Bool profiling; /* profiling is active */
677
678 void InstDump (InstPtr inst, int indent, int i, int *branch, int maxbranch);
679 void ObjDump (ObjPtr obj, int indent);
680
681 void SymbolInit (void);
682
683 extern NamespacePtr DebugNamespace;
684 extern NamespacePtr FileNamespace;
685 extern NamespacePtr MathNamespace;
686 #ifdef BSD_RANDOM
687 extern NamespacePtr BSDRandomNamespace;
688 #endif
689 extern NamespacePtr SemaphoreNamespace;
690 extern NamespacePtr StringNamespace;
691 extern NamespacePtr ThreadNamespace;
692 extern NamespacePtr CommandNamespace;
693 #ifdef GCD_DEBUG
694 extern NamespacePtr GcdNamespace;
695 #endif
696 extern NamespacePtr EnvironNamespace;
697 extern NamespacePtr DateNamespace;
698
699 void BuiltinInit (void);
700
701 Bool DebugSetFrame (Value continuation, int offset);
702 void DebugStart (Value continuation);
703 void DebugBreak (Value thread);
704
705 void ProfileInterrupt (Value thread);
706
707 typedef Bool (*TimerFunc) (void *closure);
708
709 unsigned long TimeInMs (void);
710
711 void TimerInsert (void *closure, TimerFunc func,
712 unsigned long delta, unsigned long incr);
713 void TimerInterrupt (void);
714 void TimerInit (void);
715
716 void IoInit (void);
717 void IoStart (void);
718 void IoStop (void);
719 void IoFini (void);
720 Bool IoTimeout (void *);
721 void IoNoticeWriteBlocked (void);
722 #ifdef NO_PIPE_SIGIO
723 void IoNoticeReadBlocked (void);
724 #endif
725 void IoNoticeTtyUnowned (void);
726 void IoInterrupt (void);
727
728 void FileFini (void);
729 void ProcessInterrupt (void);
730
731 void *AllocateTemp (int size);
732
733 typedef struct _ProfileData {
734 double_digit sub;
735 double_digit self;
736 } ProfileData;
737
738 void PrettyPrint (Value f, Publish publish, SymbolPtr name);
739 void PrettyCode (Value f, CodePtr code, Atom name, Class class,
740 Publish publish, int level, Bool nest);
741 void PrettyStat (Value F, Expr *e, Bool nest);
742 void PrettyExpr (Value f, Expr *e, int parentPrec, int level, Bool nest);
743
744 void EditFunction (SymbolPtr name, Publish publish);
745 void EditFile (Value file_name);
746
747 Value lookupVar (char *ns, char *n);
748 void setVar (NamespacePtr, char *, Value, Type *type);
749 void GetNamespace (NamespacePtr *, FramePtr *, CodePtr *);
750 Bool NamespaceLocate (Value names, NamespacePtr *s, SymbolPtr *symbol, Publish *publish, Bool complain);
751 ExprPtr BuildName (char *ns_name, char *name);
752 ExprPtr BuildCall (char *, char *, int, ...);
753 ExprPtr BuildFullname (ExprPtr colonnames, Atom name);
754 ExprPtr BuildRawname (ExprPtr colonnames, Atom name);
755
756 Atom LexFileName (void);
757 int LexFileLine (void);
758 Bool LexInteractive (void);
759 Bool LexResetInteractive (void);
760 void LexInit (void);
761 void NewLexInput (Value file, Atom name, Bool after, Bool interactive);
762 #if HAVE_LIBREADLINE
763 extern volatile int stdin_in_readline;
764 #endif
765
766 int yywrap (void);
767 void yyerror (char *msg);
768 void ParseError (char *fmt, ...);
769 int yylex (void);
770 Bool LexFile (char *file, Bool complain, Bool after);
771 Value atov (char *, int), aetov (char *, int);
772 extern int ignorenl;
773 void skipcomment (void);
774 Value lexdoc (void);
775 void skipline (void);
776 int lexEscape (int);
777
778 extern void init (void);
779 extern int yyparse (void);
780 extern int stdin_interactive;
781
782 void intr(int);
783 void stop (int), die (int), segv (int);
784
785 void
786 catchSignal (int sig, void (*func) (int sig));
787
788 void
789 resetSignal (int sig, void (*func) (int sig));
790
791 extern Value yyinput;
792
793 /* Standard exceptions */
794 typedef enum _standardException {
795 exception_none,
796 exception_uninitialized_value, /* */
797 exception_invalid_argument, /* string integer poly */
798 exception_readonly_box, /* poly */
799 exception_invalid_array_bounds, /* poly poly */
800 exception_divide_by_zero, /* number number */
801 exception_invalid_struct_member,/* poly string */
802 exception_invalid_binop_values, /* poly poly */
803 exception_invalid_unop_value, /* poly */
804 exception_open_error, /* string integer string */
805 exception_io_error, /* string integer file */
806 exception_name_error, /* string integer string */
807 exception_signal, /* integer */
808 exception_system_error, /* string integer poly */
809 exception_io_eof, /* file */
810 _num_standard_exceptions
811 } StandardException;
812
813 void
814 RaiseException (Value thread, SymbolPtr exception, Value ret, InstPtr *next);
815
816 void
817 RegisterStandardException (StandardException se,
818 SymbolPtr sym);
819
820 void
821 RaiseStandardException (StandardException se,
822 int argc,
823 ...);
824
825 SymbolPtr
826 CheckStandardException (void);
827
828 Value
829 JumpStandardException (Value thread, InstPtr *next);
830
831 static inline Value
IntIncDec(Value av,BinaryOp operator)832 IntIncDec (Value av, BinaryOp operator)
833 {
834 int a = ValueInt(av);
835
836 if (operator == PlusOp)
837 a++;
838 else
839 a--;
840 if (NICKLE_INT_CARRIED(a))
841 return NewIntInteger (a);
842 return NewInt (a);
843 }
844
ValueIncDec(Value v,BinaryOp o)845 static inline Value ValueIncDec(Value v, BinaryOp o) {
846 if (ValueIsInt(v))
847 return IntIncDec(v,o);
848 else
849 return BinaryOperate(v, One, o);
850 }
851
BoxValue(BoxPtr box,int e)852 static inline Value BoxValue (BoxPtr box, int e) {
853 Value v = BoxElements(box)[e];
854 if (!v)
855 {
856 RaiseStandardException (exception_uninitialized_value, 0);
857 return (Void);
858 }
859 return v;
860 }
861
Dereference(Value v)862 static inline Value Dereference (Value v) {
863 if (!ValueIsRef(v)) {
864 RaiseStandardException (exception_invalid_unop_value, 1,
865 v);
866 return Void;
867 }
868 v = RefValueGet(v);
869 if (!v) {
870 RaiseStandardException (exception_uninitialized_value, 0);
871 return (Void);
872 }
873 return REFERENCE (v);
874 }
875
876 /* vararg builtins */
877 Value do_printf (int, Value *);
878 Value do_fprintf (int, Value *);
879 Value do_imprecise (int, Value *);
880 Value do_Thread_kill (int, Value *);
881 Value do_Thread_trace (int, Value *);
882 Value do_Thread_trace (int, Value *);
883 Value do_History_show (int, Value *);
884 Value do_string_to_integer (int, Value *);
885 Value do_Semaphore_new (int, Value *);
886 Value do_Command_undefine (int, Value *);
887 Value do_Command_pretty_print (int , Value *);
888
889 /* zero argument builtins */
890 Value do_Thread_cont (void);
891 Value do_Thread_current (void);
892 Value do_Thread_list (void);
893 Value do_time (void);
894 Value do_File_string_write (void);
895 Value do_Debug_up (void);
896 Value do_Debug_down (void);
897 Value do_Debug_done (void);
898 Value do_Debug_collect (void);
899 Value do_Debug_help (void);
900 Value do_File_mkpipe (void);
901 Value do_millis (void);
902
903 /* one argument builtins */
904 Value do_sleep (Value);
905 Value do_exit (Value);
906 Value do_dim (Value);
907 Value do_dims (Value);
908 Value do_reference (Value);
909 Value do_string_to_real (Value);
910 Value do_abs (Value);
911 Value do_floor (Value);
912 Value do_func_args (Value);
913 Value do_ceil (Value);
914 Value do_exponent (Value);
915 Value do_mantissa (Value);
916 Value do_numerator (Value);
917 Value do_denominator (Value);
918 Value do_precision (Value);
919 Value do_sign (Value);
920 Value do_bit_width (Value);
921 Value do_is_int (Value);
922 Value do_is_rational (Value);
923 Value do_is_number (Value);
924 Value do_is_string (Value);
925 Value do_is_file (Value);
926 Value do_is_thread (Value);
927 Value do_is_semaphore (Value);
928 Value do_is_continuation (Value);
929 Value do_is_array (Value);
930 Value do_is_hash (Value);
931 Value do_is_ref (Value);
932 Value do_is_struct (Value);
933 Value do_is_func (Value);
934 Value do_is_bool (Value);
935 Value do_is_void (Value);
936 Value do_is_uninit (Value);
937 Value do_make_uninit (Value);
938 Value do_hash (Value);
939 Value do_Thread_get_priority (Value);
940 Value do_Thread_id_to_thread (Value);
941 Value do_Thread_join (Value);
942 Value do_Semaphore_signal (Value);
943 Value do_Semaphore_count (Value);
944 Value do_Semaphore_wait (Value);
945 Value do_Semaphore_test (Value);
946 Value do_File_close (Value);
947 Value do_File_flush (Value);
948 Value do_File_getb (Value);
949 Value do_File_getc (Value);
950 Value do_File_end (Value);
951 Value do_File_error (Value);
952 Value do_File_clear_error (Value);
953 Value do_File_string_read (Value);
954 Value do_File_string_string (Value);
955 Value do_File_isatty (Value);
956 Value do_File_status (Value);
957 Value do_File_unlink (Value);
958 Value do_File_rmdir (Value);
959 Value do_String_length (Value);
960 Value do_String_new (Value);
961 Value do_Primitive_random (Value);
962 Value do_Primitive_srandom (Value);
963 Value do_Debug_dump (Value);
964 Value do_Debug_dump_active (void);
965 Value do_Command_delete (Value);
966 Value do_Command_edit (Value);
967 Value do_Command_display (Value);
968 Value do_Command_valid_name (Value);
969 Value do_Environ_check (Value);
970 Value do_Environ_get (Value);
971 Value do_Environ_unset (Value);
972 Value do_profile (Value);
973
974 /* two argument builtins */
975 Value do_Thread_set_priority (Value, Value);
976 Value do_Thread_signal (Value, Value);
977 Value do_File_open (Value, Value);
978 Value do_gcd (Value, Value);
979 Value do_xor (Value, Value);
980 Value do_Math_pow (Value, Value);
981 Value do_Math_assignpow (Value, Value);
982 Value do_Math_popcount (Value);
983 Value do_Math_factorial (Value);
984 Value do_File_putb (Value, Value);
985 Value do_File_putc (Value, Value);
986 Value do_File_ungetb (Value, Value);
987 Value do_File_ungetc (Value, Value);
988 Value do_File_setbuf (Value, Value);
989 Value do_File_rename (Value, Value);
990 Value do_File_mkdir (Value, Value);
991 Value do_String_index (Value, Value);
992 Value do_setjmp (Value, Value);
993 Value do_setdims (Value, Value);
994 Value do_setdim (Value, Value);
995 Value do_Command_new (Value, Value);
996 Value do_Command_new_names (Value, Value);
997 #ifdef GCD_DEBUG
998 Value do_Gcd_bdivmod (Value, Value);
999 Value do_Gcd_kary_reduction (Value, Value);
1000 #endif
1001 Value do_Environ_set (Value, Value);
1002
1003 /* three argument builtins */
1004 Value do_File_vfprintf (Value, Value, Value);
1005 Value do_String_substr (Value, Value, Value);
1006 Value do_File_reopen (Value, Value, Value);
1007 Value do_File_filter (Value file, Value argv, Value filev);
1008
1009 /* four argument builtins */
1010 Value do_Command_lex_input (Value file, Value name, Value after, Value interactive);
1011
1012 /* seven argument builtins */
1013 Value do_File_print (Value, Value, Value, Value, Value, Value, Value);
1014
1015 /* two argument non-local builtins */
1016 Value do_longjmp (InstPtr *, Value, Value);
1017
1018 /* hash builtins (for testing) */
1019 Value do_hash_new (void);
1020 Value do_hash_get (Value, Value);
1021 Value do_hash_del (Value, Value);
1022 Value do_hash_test (Value, Value);
1023 Value do_hash_set (Value, Value, Value);
1024 Value do_hash_keys (Value);
1025