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