nickle_2.81.orig/0002775000175000000620000000000013202543026013077 5ustar keithpstaffnickle_2.81.orig/builtin-math.c0000664000175000000620000000630711641024421015642 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * math.c * * provide builtin functions for the Math namespace */ #include #include #include #include "builtin.h" NamespacePtr MathNamespace; void import_Math_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { { do_Math_popcount, "popcount", "i", "i", "\n" " int popcount (int i)\n" "\n" " Return the number of '1' bits in 'i'.\n" }, { do_Math_factorial, "factorial", "i", "i", "\n" " int factorial (int i)\n" "\n" " Return the factorial of 'i'.\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_Math_assignpow, "assign_pow", "n", "*Ri", "\n" " real assign_pow (*real a, int b)\n" "\n" " Return *a ** b, also storing that result back in *a.\n" }, { do_Math_pow, "pow", "n", "Ri", "\n" " real pow (real a, int b)\n" "\n" " Return a ** b.\n" }, { 0 } }; MathNamespace = BuiltinNamespace (/*parent*/ 0, "Math")->namespace.namespace; BuiltinFuncs1 (&MathNamespace, funcs_1); BuiltinFuncs2 (&MathNamespace, funcs_2); EXIT (); } Value do_Math_pow (Value a, Value b) { ENTER (); RETURN (Pow (a, b)); } Value do_Math_assignpow (Value a, Value b) { ENTER (); Value ret; ret = Pow (RefValueGet(a), b); RefValueSet (a, ret); RETURN (ret); } static unsigned count_bits (unsigned n) { unsigned c3 = 0x0f0f0f0f; unsigned c2 = c3 ^ (c3 << 2); /* c2 == 0x33333333 */ unsigned c1 = c2 ^ (c2 << 1); /* c1 == 0x55555555 */ unsigned left = (n >> 1) & c1; n = left + (n & c1); left = (n >> 2) & c2; n = left + (n & c2); left = (n >> 4) & c3; n = left + (n & c3); n += (n >> 8); n += (n >> 16); return (n & 0xff); } Value Popcount (Value av) { ENTER (); Natural *i; Value ret; digit *d; int n; unsigned part; if (!Integralp (ValueTag(av))) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Math::popcount: not an integer"), av, Void); RETURN (Void); } if (Negativep (av)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Math::popcount: negative argument"), av, Void); RETURN (Void); } switch (ValueTag(av)) { case rep_int: ret = NewInt (count_bits (ValueInt(av))); break; case rep_integer: i = IntegerMag (av); n = i->length; d = NaturalDigits(i); part = 0; ret = Zero; while (n--) { if (part >= MAX_NICKLE_INT - 32) { ret = Plus (ret, NewInt (part)); part = 0; if (aborting) break; } part += count_bits (*d++); } if (ret == Zero) ret = NewInt (part); else ret = Plus (ret, NewInt (part)); break; default: RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Math::popcount: not an integer"), av, Void); RETURN (Void); } RETURN (ret); } Value do_Math_popcount(Value v) { ENTER (); RETURN (Popcount (v)); } Value do_Math_factorial(Value v) { ENTER (); RETURN (Factorial (v)); } nickle_2.81.orig/builtin-debug.c0000664000175000000620000000513410414112462015774 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * debug.c * * provide builtin functions for the Debug namespace */ #include #include #include #include "builtin.h" NamespacePtr DebugNamespace; #ifdef MEM_TRACE Value do_Debug_dump_active (void); #endif void import_Debug_namespace() { ENTER (); static const struct fbuiltin_0 funcs_0[] = { { do_Debug_collect, "collect", "v", "", "\n" " void collect ()\n" "\n" " Invokes the garbage collector\n" }, { do_Debug_done, "done", "v", "", "\n" " void done ()\n" "\n" " Terminates the debugger, returning control\n" " to the enclosing non-debugging read/eval/print loop.\n" }, { do_Debug_down, "down", "b", "", "\n" " bool down ()\n" "\n" " Moves the current debug context one frame down the call chain.\n" " Returns whether this was possible or not.\n" }, { do_Debug_up, "up", "b", "", "\n" " bool up ()\n" "\n" " Moves the current debug context one frame up the call chain.\n" " Returns whether this was possible or not.\n" }, { do_Debug_help, "help", "v", "", "\n" " void help ()\n" "\n" " Displays a bit of help for using the debugger.\n" }, #ifdef MEM_TRACE { do_Debug_dump_active, "dump_active", "v", "", "\n" " void dump_active ()\n" "\n" " Dump out active memory usage.\n" }, #endif { 0 } }; static const struct fbuiltin_1 funcs_1[] = { { do_Debug_dump, "dump", "v", "p", "\n" " void dump (poly f)\n" "\n" " Dump out bytecodes for function 'f'.\n" }, { 0 } }; static const struct fbuiltin_v funcs_v[] = { { do_Thread_trace, "trace", "v", ".p", "\n" " void trace ()\n" " void trace (continuation c)\n" " void trace (thread t)\n" " void trace (continuation c, int depth)\n" " void trace (thread t, int depth)\n" "\n" " Display a stack trace for a thread or continuation.\n" " While debugging, there is a default continuation of the\n" " thread being debugged.\n" " If 'depth' is not provided, it will show 20 frames.\n" }, { 0 } }; DebugNamespace = BuiltinNamespace (/*parent*/ 0, "Debug")->namespace.namespace; BuiltinFuncs0 (&DebugNamespace, funcs_0); BuiltinFuncs1 (&DebugNamespace, funcs_1); BuiltinFuncsV (&DebugNamespace, funcs_v); EXIT (); } Value do_Debug_collect (void) { ENTER (); MemCollect (); RETURN (Void); } nickle_2.81.orig/string.c0000664000175000000620000001153611641007303014553 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" Value Blank; int StringInit (void) { ENTER (); Blank = NewStrString(""); MemAddRoot (Blank); EXIT (); return 1; } static Value StringPlus (Value av, Value bv, int expandOk) { ENTER(); Value ret; ret = NewString (av->string.length + bv->string.length); (void) memcpy (StringChars(&ret->string), StringChars(&av->string), av->string.length); (void) memcpy (StringChars(&ret->string) + av->string.length, StringChars(&bv->string), bv->string.length); RETURN (ret); } static Value StringEqual (Value av, Value bv, int expandOk) { if (av->string.length != bv->string.length) return FalseVal; if (!memcmp (StringChars (&av->string), StringChars(&bv->string), av->string.length)) return TrueVal; return FalseVal; } static Value StringLess (Value av, Value bv, int expandOk) { long len; int c; len = av->string.length; if (len > bv->string.length) len = bv->string.length; c = memcmp (StringChars (&av->string), StringChars(&bv->string), len); if (c < 0) return TrueVal; if (c == 0 && av->string.length < bv->string.length) return TrueVal; return FalseVal; } static Bool StringPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { char *string = StringChars (&av->string); long len = av->string.length; int print_width; print_width = FileStringWidth (string, len, format); while (width > print_width) { FileOutchar (f, fill); width--; } FilePutString (f, string, len, format); while (-width > print_width) { FileOutchar (f, fill); width++; } return True; } char * StringNextChar (char *src, unsigned *dst, long *len) { unsigned result = *src++; if (!*len) return 0; (*len)--; if (result & 0x80) { int m = 0x20; int extra = 1; while (result & m) { extra++; m >>= 1; } result &= (m - 1); while (extra--) { char c = *src++; (*len)--; if ((c & 0x80) == 0) { src--; (*len)++; result = 0; break; } result = (result << 6) | (c & 0x3f); } } *dst = result; return src; } unsigned StringGet (char *src, long len, int i) { unsigned c; do { src = StringNextChar (src, &c, &len); if (!src) return 0; } while (i-- > 0); return c; } int StringLength (char *src, long len) { int l = 0; unsigned c; while ((src = StringNextChar (src, &c, &len))) l++; return l; } int StringPutChar (unsigned c, char *dest) { int bits; char *d = dest; if (c < 0x80) { *d++= c; bits= -6; } else if (c < 0x800) { *d++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; } else if (c < 0x10000) { *d++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; } else if (c < 0x200000) { *d++= ((c >> 18) & 0x07) | 0xF0; bits= 12; } else if (c < 0x4000000) { *d++= ((c >> 24) & 0x03) | 0xF8; bits= 18; } else if (c < 0x80000000) { *d++= ((c >> 30) & 0x01) | 0xFC; bits= 24; } else return 0; for ( ; bits >= 0; bits-= 6) { *d++= ((c >> bits) & 0x3F) | 0x80; } return d - dest; } int StringCharSize (unsigned c) { if (c < 0x80) return 1; else if (c < 0x800) return 2; else if (c < 0x10000) return 3; else if (c < 0x200000) return 4; else if (c < 0x4000000) return 5; else if (c < 0x80000000) return 6; else return 0; } char * StrzPart (Value v, char *error) { if (!ValueIsString (v) || strlen (StringChars(&v->string)) != v->string.length) { RaiseStandardException (exception_invalid_argument, 3, NewStrString (error), NewInt (0), v); return 0; } return StringChars (&v->string); } static HashValue StringHash (Value av) { return HashCrc32 ((unsigned char *) StringChars(&av->string), av->string.length); } ValueRep StringRep = { { 0, 0, "StringRep" }, /* base */ rep_string, /* tag */ { /* binary */ StringPlus, 0, 0, 0, 0, 0, StringLess, StringEqual, 0, 0, }, { 0, }, 0, 0, StringPrint, 0, StringHash, }; Value NewString (long length) { ENTER (); Value ret; ret = ALLOCATE (&StringRep.data, sizeof (String) + length + 1); ret->string.length = length; StringChars(&ret->string)[length] = '\0'; RETURN (ret); } Value NewStrString (const char *str) { ENTER (); Value ret; ret = NewString (strlen (str)); strcpy (StringChars (&ret->string), str); RETURN (ret); } Value NewCharString (int c) { ENTER (); int size = StringCharSize (c); Value ret = NewString (size); StringPutChar (c, StringChars (&ret->string)); RETURN (ret); } nickle_2.81.orig/sched.c0000664000175000000620000006642111765451310014346 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include "nickle.h" #include "ref.h" Value running; Value stopped; Bool signalException; extern void dumpSleep (void), dumpThreads (void); static void _ThreadInsert (Value thread) { Value *prev, t; switch (thread->thread.state) { case ThreadRunning: prev = &running; break; case ThreadSuspended: prev = &stopped; break; case ThreadFinished: default: return; } for (; (t = *prev); prev = &t->thread.next) if (t->thread.priority < thread->thread.priority) break; thread->thread.next = t; *prev = thread; } static void _ThreadRemove (Value thread) { Value *prev; switch (thread->thread.state) { case ThreadRunning: prev = &running; break; case ThreadSuspended: prev = &stopped; break; case ThreadFinished: default: return; } for (; *prev != thread; prev = &(*prev)->thread.next); *prev = thread->thread.next; } void ThreadSetState (Value thread, ThreadState state) { if (state != thread->thread.state) { _ThreadRemove (thread); thread->thread.state = state; _ThreadInsert (thread); } } void ThreadSleep (Value thread, Value sleep, int priority) { thread->thread.priority = priority; thread->thread.sleep = sleep; SetSignalSuspend (); } void ThreadStepped (Value thread) { Value t; if ((t = thread->thread.next) && thread->thread.priority <= t->thread.priority) { _ThreadRemove (thread); _ThreadInsert (thread); } } void ThreadsWakeup (Value sleep, WakeKind kind) { Value thread, next; for (thread = stopped; thread; thread = next) { next = thread->thread.next; if ((thread->thread.state == ThreadSuspended) && thread->thread.sleep == sleep) { thread->thread.sleep = 0; ThreadSetState (thread, ThreadRunning); if (kind == WakeOne) break; } } } Bool lastThreadError; void ThreadFinish (Value thread, Bool error) { if (thread->thread.state != ThreadFinished) { ThreadSetState (thread, ThreadFinished); ThreadsWakeup (thread, WakeAll); lastThreadError = error; } } Value do_Thread_join (Value target) { ENTER (); if (!ValueIsThread(target)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("join needs thread argument"), target, Void); RETURN (Void); } if (target->thread.state != ThreadFinished) { ThreadSleep (running, target, PrioritySync); RETURN (Void); } RETURN (target->thread.continuation.value); } static void ThreadListState (Value thread) { switch (thread->thread.state) { case ThreadRunning: FilePuts (FileStdout, " running"); break; case ThreadSuspended: FilePuts (FileStdout, " suspended"); break; case ThreadFinished: FilePuts (FileStdout, " finished"); break; } } Value do_Thread_list (void) { ENTER (); Value t; for (t = running; t; t = t->thread.next) { FilePrintf (FileStdout, "\t%%%d", t->thread.id); ThreadListState (t); FileOutput (FileStdout, '\n'); } for (t = stopped; t; t = t->thread.next) { FilePrintf (FileStdout, "\t%%%d", t->thread.id); ThreadListState (t); if (t->thread.sleep) FilePrintf (FileStdout, " %g", t->thread.sleep); FileOutput (FileStdout, '\n'); } RETURN(Void); } Value do_Thread_id_to_thread (Value id) { ENTER (); int i; Value t; i = IntPart (id, "Invalid thread id"); if (aborting) RETURN (Void); for (t = running; t; t = t->thread.next) if (t->thread.id == i) RETURN (t); for (t = stopped; t; t = t->thread.next) if (t->thread.id == i) RETURN (t); RETURN (Void); } Value do_Thread_current (void) { ENTER (); Value ret; if (running) ret = running; else ret = Void; RETURN (ret); } Value do_Thread_set_priority (Value thread, Value priority) { ENTER (); int i; if (!ValueIsThread(thread)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("set_priority: not a thread"), thread, priority); RETURN (Void); } i = IntPart (priority, "Invalid thread priority"); if (aborting) RETURN (Void); if (i != thread->thread.priority) { _ThreadRemove (thread); thread->thread.priority = i; _ThreadInsert (thread); } RETURN (NewInt (thread->thread.priority)); } Value do_Thread_get_priority (Value thread) { ENTER (); if (!ValueIsThread(thread)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("get_priority: not a thread"), thread, Void); RETURN (Void); } RETURN (NewInt (thread->thread.priority)); } static int KillThread (Value thread) { int ret; if (!ValueIsThread(thread)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("kill: not a thread"), thread, Void); return 0; } if (thread->thread.state == ThreadFinished) ret = 0; else ret = 1; ThreadFinish (thread, False); return ret; } Value do_Thread_kill (int n, Value *p) { ENTER (); Value thread; int ret = 0; if (n == 0) { thread = lookupVar (0, "thread"); if (!ValueIsThread(thread)) RaiseStandardException (exception_invalid_argument, 3, NewStrString ("kill: no default thread"), thread, Void); else ret = KillThread (thread); } else { while (n--) ret += KillThread (*p++); } RETURN (NewInt (ret)); } void TraceFunction (Value file, FramePtr frame, CodePtr code, ExprPtr name) { int fe; FilePuts (file, " "); if (name) PrettyExpr (file, name, -1, 0, False); else FilePuts (file, ""); FilePuts (file, " ("); for (fe = 0; fe < code->base.argc; fe++) { if (fe) FilePuts (file, ", "); FilePrintf (file, "%G", BoxValue (frame->frame, fe)); } FilePuts (file, ")\n"); } static void TraceStatement (Value file, ExprPtr stat) { FilePrintf (file, "%A:%d: ", stat->base.file, stat->base.line); PrettyStat (file, stat, False); } void TraceFrame (Value file, FramePtr frame, ObjPtr obj, InstPtr pc, int depth) { ENTER (); int max; CodePtr code; if (obj && pc) TraceStatement (file, ObjStatement (obj, pc)); for (max = depth; frame && max--; frame = frame->previous) { code = frame->function->func.code; TraceFunction (file, frame, code, code->base.name); TraceStatement (file, ObjStatement (frame->saveObj, frame->savePc)); } EXIT (); } #ifdef DEBUG_JUMP static void TraceIndent (int indent) { while (indent--) FilePuts (FileStdout, " "); } #endif Value do_Thread_trace (int n, Value *p) { ENTER (); Value v; FramePtr frame; InstPtr pc; ObjPtr obj; int depth = 20; if (n == 0) v = lookupVar (0, "cont"); else v = p[0]; if (n > 1) { depth = IntPart (p[1], "Invalid trace depth"); if (aborting) RETURN (Void); } switch (ValueTag(v)) { case rep_thread: case rep_continuation: frame = v->continuation.frame; pc = v->continuation.pc; obj = v->continuation.obj; break; default: if (n == 0) RaiseStandardException (exception_invalid_argument, 3, NewStrString ("trace: no default continuation"), NewInt (0), Void); else RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Thread::trace: neither continuation nor thread"), NewInt (0), v); RETURN (Void); } TraceFrame (FileStdout, frame, obj, pc, depth); RETURN(Void); } static void ThreadMark (void *object) { ThreadPtr thread = object; ContinuationMark (&thread->continuation); MemReference (thread->jump); MemReference (thread->sleep); MemReference (thread->next); } static Bool ThreadPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePrintf (f, "%%%d", av->thread.id); return True; } ValueRep ThreadRep = { { ThreadMark, 0, "ThreadRep" }, /* base */ rep_thread, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, ValueEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, ThreadPrint, 0, }; static int ThreadId; Value NewThread (FramePtr frame, ObjPtr code) { ENTER (); Value ret; ret = ALLOCATE (&ThreadRep.data, sizeof (Thread)); ret->thread.jump = 0; ret->thread.state = ThreadRunning; ret->thread.priority = 0; ret->thread.sleep = 0; ret->thread.id = ++ThreadId; ret->thread.partial = 0; ret->thread.next = 0; ContinuationInit (&ret->thread.continuation); ret->thread.continuation.obj = code; ret->thread.continuation.pc = ObjCode (code, 0); ret->thread.continuation.frame = frame; complete = True; if (code->error) ret->thread.state = ThreadFinished; _ThreadInsert (ret); RETURN (ret); } typedef struct _blockHandler { DataType *data; struct _blockHandler *next; NickleBlockHandler handler; void *closure; } BlockHandler; static void BlockHandlerMark (void *object) { BlockHandler *bh = object; MemReference (bh->next); } DataType BlockHandlerType = { BlockHandlerMark, 0, "BlockHandlerType" }; static BlockHandler *blockHandlers; void ThreadsRegisterBlockHandler (NickleBlockHandler handler, void *closure) { ENTER (); BlockHandler *bh = ALLOCATE (&BlockHandlerType, sizeof (BlockHandler)); bh->next = blockHandlers; blockHandlers = bh; bh->handler = handler; bh->closure = closure; EXIT (); } void ThreadsUnregisterBlockHandler (NickleBlockHandler handler, void *closure) { ENTER (); BlockHandler **prev, *bh; for (prev = &blockHandlers; (bh = *prev); prev = &bh->next) { if (bh->handler == handler && bh->closure == closure) { bh->handler = 0; *prev = bh->next; } } EXIT (); } void ThreadsBlock (void) { BlockHandler *bh, *next; for (bh = blockHandlers; bh; bh = next) { next = bh->next; if (bh->handler) (*bh->handler) (bh->closure); } /* Pend in either select or sigsuspend, depending * on whether there are files blocked */ if (!running) FileCheckBlocked(True); } ReferencePtr RunningReference, StoppedReference; ReferencePtr BlockHandlerReference; void ThreadInit (void) { ENTER (); RunningReference = NewReference ((void **) &running); MemAddRoot (RunningReference); StoppedReference = NewReference ((void **) &stopped); MemAddRoot (StoppedReference); BlockHandlerReference = NewReference ((void **) &blockHandlers); MemAddRoot (BlockHandlerReference); EXIT (); } DataType FarJumpType = { 0, 0, "FarJumpType" }; FarJumpPtr NewFarJump (int inst, int twixt, int catch, int frame) { ENTER (); FarJumpPtr farJump; farJump = ALLOCATE (&FarJumpType, sizeof (FarJump)); farJump->inst = inst; farJump->twixt = twixt; farJump->catch = catch; farJump->frame = frame; RETURN (farJump); } Value FarJumpContinuation (ContinuationPtr continuation, FarJumpPtr farJump) { ENTER (); Value ret; CatchPtr catch; TwixtPtr twixt; FramePtr frame; InstPtr pc; ObjPtr obj; int twixts; int catches; int frames; ret = NewContinuation (continuation, 0); /* * Unwind twixts */ twixts = farJump->twixt; twixt = ret->continuation.twixts; while (twixts--) twixt = twixt->continuation.twixts; ret->continuation.twixts = twixt; /* * Unwind catches */ #ifdef DEBUG_JUMP FilePrintf (FileStdout, "FarJump catches before: "); ThreadCatches (running); #endif catches = farJump->catch; catch = ret->continuation.catches; while (catches--) catch = catch->continuation.catches; ret->continuation.catches = catch; #ifdef DEBUG_JUMP FilePrintf (FileStdout, "FarJump catches after: "); ThreadCatches (running); #endif /* * Unwind frames */ frames = farJump->frame; frame = ret->continuation.frame; obj = continuation->obj; pc = continuation->pc; if (farJump->inst < 0) frames++; while (frames--) { pc = frame->savePc; obj = frame->saveObj; frame = frame->previous; } ret->continuation.frame = frame; /* * Set pc for non-return jumps */ if (farJump->inst >= 0) pc = ObjCode (obj, farJump->inst); /* * Assertion here -- the stack is OK because * only intervening catch frames are on the stack * and they never have extra values on the stack */ ret->continuation.pc = pc; ret->continuation.obj = obj; RETURN (ret); } void ContinuationMark (void *object) { ContinuationPtr continuation = object; assert (!continuation->pc || (ObjCode (continuation->obj, 0) <= continuation->pc && continuation->pc <= ObjCode (continuation->obj, ObjLast(continuation->obj)))); MemReference (continuation->obj); MemReference (continuation->frame); MemReference (continuation->stack); MemReference (continuation->value); MemReference (continuation->catches); MemReference (continuation->twixts); } static Bool ContinuationPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePuts (f, "continutation"); return True; } ValueRep ContinuationRep = { { ContinuationMark, 0, "ContinuationRep" }, /* base */ rep_continuation, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, ValueEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, ContinuationPrint, 0, }; Value NewContinuation (ContinuationPtr continuation, InstPtr pc) { ENTER (); Value ret; ret = ALLOCATE (&ContinuationRep.data, sizeof (Continuation)); ContinuationSet (&ret->continuation, continuation); ret->continuation.pc = pc; RETURN (ret); } static ContinuationPtr EmptyContinuation (void) { ENTER (); Value ret; ret = ALLOCATE (&ContinuationRep.data, sizeof (Continuation)); ContinuationInit (&ret->continuation); RETURN (&ret->continuation); } #ifdef DEBUG_JUMP int dump_jump = 0; void ContinuationTrace (char *where, Continuation *continuation, int indent) { int s; StackObject *stack = continuation->stack; CatchPtr catches = continuation->catches; TwixtPtr twixts = continuation->twixts; ObjPtr obj = continuation->obj; InstPtr pc = continuation->pc; if (!dump_jump) return; TraceIndent (indent); FilePuts (FileStdout, "*** "); FilePuts (FileStdout, where); FilePuts (FileStdout, " ***\n"); TraceIndent (indent); FilePuts (FileStdout, "stack: "); for (s = 0; STACK_TOP(stack) + (s) < STACK_MAX(stack); s++) { if (s) FilePuts (FileStdout, ", "); FilePrintf (FileStdout, "%g", STACK_ELT(stack, s)); } FilePuts (FileStdout, "\n"); TraceIndent (indent); FilePuts (FileStdout, "frame:\nCALLS\n"); TraceFrame (FileStdout, continuation->frame, obj, pc, 20); FilePuts (FileStdout, "END CALLS\n"); TraceIndent (indent); FilePuts (FileStdout, "catches: "); for (s = 0; catches; catches = catches->continuation.catches, s++) { if (s) FilePuts (FileStdout, ", "); FilePrintf (FileStdout, "%A", catches->exception->symbol.name); } FilePuts (FileStdout, "\n"); TraceIndent (indent); FilePuts (FileStdout, "statement: "); if (obj && pc) PrettyStat (FileStdout, ObjStatement (obj, pc), False); else FilePuts (FileStdout, "corrupted continuation!\n"); for (s = 0; twixts; twixts = twixts->continuation.twixts, s++) { ContinuationTrace ("twixt", &twixts->continuation, indent+1); } } #endif InstPtr ContinuationSet (ContinuationPtr dst, ContinuationPtr src) { ENTER (); dst->value = src->value; dst->pc = 0; dst->obj = src->obj; dst->frame = src->frame; dst->stack = 0; dst->catches = src->catches; dst->twixts = src->twixts; /* last, to make sure remaining entries are initialized before any GC */ dst->stack = StackCopy (src->stack); RETURN (src->pc); } void ContinuationInit (ContinuationPtr dst) { dst->pc = 0; dst->obj = 0; dst->frame = 0; dst->value = Void; dst->catches = 0; dst->twixts = 0; dst->stack = 0; dst->stack = StackCreate (); } static void MarkJump (void *object) { JumpPtr jump = object; MemReference (jump->enter); MemReference (jump->entering); MemReference (jump->leave); MemReference (jump->parent); MemReference (jump->continuation); MemReference (jump->ret); } DataType JumpType = { MarkJump, 0, "JumpType" }; JumpPtr NewJump (TwixtPtr leave, TwixtPtr enter, TwixtPtr parent, ContinuationPtr continuation, Value ret) { ENTER (); JumpPtr jump; jump = ALLOCATE (&JumpType, sizeof (Jump)); jump->leave = leave; jump->enter = enter; jump->entering = TwixtNext (parent, enter); jump->parent = parent; jump->continuation = continuation; jump->ret = ret; RETURN (jump); } /* * An unhandled exception will attempt to jump to NULL, * catch that and invoke the debugger. When the exception * was raised, the code carefully pushed a continuation from * the point of the exception to pass to the debugger */ static void JumpUnhandledException (Value thread) { Value continuation = STACK_POP (thread->thread.continuation.stack); /* make exec loop reschedule */ if (thread == running) SetSignalError (); DebugStart (continuation); ThreadFinish (thread, True); } /* * Figure out where to go next in a longjmp through twixts */ Value JumpContinue (Value thread, InstPtr *next) { ENTER (); JumpPtr jump = thread->thread.jump; TwixtPtr twixt; if (jump->leave) { /* * Going up */ twixt = jump->leave; ContinuationSet (&thread->thread.continuation, &twixt->continuation); *next = twixt->leave; jump->leave = twixt->continuation.twixts; /* * Matching element of the twixt chain, next time start * back down the other side */ if (jump->leave == jump->parent) jump->leave = 0; } else if (jump->entering) { /* * Going down */ twixt = jump->entering; *next = ContinuationSet (&thread->thread.continuation, &twixt->continuation); jump->entering = TwixtNext (jump->entering, jump->enter); } else { /* * All done, set to final continuation and drop the jump object */ *next = ContinuationSet (&thread->thread.continuation, jump->continuation); thread->thread.jump = 0; } if (!*next) JumpUnhandledException (thread); RETURN (jump->ret); } /* * Build a Jump that threads through all of the necessary twixt blocks * ending up at 'continuation' returning 'ret' */ InstPtr JumpStart (Value thread, ContinuationPtr continuation, Value ret) { ENTER (); int diff; TwixtPtr leave = thread->thread.continuation.twixts; TwixtPtr enter = continuation->twixts; TwixtPtr leave_parent, enter_parent, parent; InstPtr next; /* * Make both lists the same length. Note that either can be empty */ leave_parent = leave; enter_parent = enter; diff = TwixtDepth (leave_parent) - TwixtDepth (enter_parent); if (diff >= 0) while (diff-- > 0) leave_parent = leave_parent->continuation.twixts; else while (diff++ < 0) enter_parent = enter_parent->continuation.twixts; /* * Now find the common parent */ while (leave_parent != enter_parent) { leave_parent = leave_parent->continuation.twixts; enter_parent = enter_parent->continuation.twixts; } parent = enter_parent; /* * Build a data structure to get from leave to enter via parent */ thread->thread.jump = NewJump (leave, enter, parent, continuation, ret); /* * Don't need the jump return value yet; we're off to the twixt * blocks; after that, the return value will get retrieved by the * final OpLeaveDone or OpEnterDone instruction */ (void) JumpContinue (thread, &next); RETURN (next); } Value ContinuationJump (Value thread, ContinuationPtr continuation, Value ret, InstPtr *next) { #ifdef DEBUG_JUMP ContinuationTrace ("ContinuationJump from", &thread->thread.continuation, 1); ContinuationTrace ("ContinuationJump to", continuation, 1); #endif ENTER (); /* * If there are twixt enter or leave blocks to execute, build a Jump * that walks them and then resets the continuation. * * Otherwise, just jump */ if (thread->thread.continuation.twixts != continuation->twixts) *next = JumpStart (thread, continuation, ret); else *next = ContinuationSet (&thread->thread.continuation, continuation); if (!*next) JumpUnhandledException (thread); RETURN (ret); } /* * It is necessary that SetJump and LongJump have the same number * of arguments -- the arguments pushed by SetJump will have to be * popped when LongJump executes. If this is not so, the stack copy * created here should be adjusted to account for this difference */ Value do_setjmp (Value continuation_ref, Value ret) { ENTER (); Value continuation; if (!ValueIsRef(continuation_ref)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("setjump: not a reference"), NewInt (0), continuation_ref); RETURN (Void); } continuation = NewContinuation (&running->thread.continuation, running->thread.continuation.pc + 1); /* * Adjust stack for set jump return */ STACK_DROP (continuation->continuation.stack, 2); RefValueSet (continuation_ref, continuation); #ifdef DEBUG_JUMP ContinuationTrace ("do_setjmp", &continuation->continuation, 1); #endif RETURN (ret); } Value do_longjmp (InstPtr *next, Value continuation, Value ret) { ENTER (); if (!running) RETURN (Void); if (!ValueIsContinuation(continuation)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("longjmp: non-continuation argument"), NewInt (0), continuation); RETURN (Void); } RETURN (ContinuationJump (running, &continuation->continuation, ret, next)); } static void CatchMark (void *object) { CatchPtr catch = object; ContinuationMark (&catch->continuation); MemReference (catch->exception); } DataType CatchType = { CatchMark, 0, "CatchType" }; CatchPtr NewCatch (Value thread, SymbolPtr exception) { ENTER(); CatchPtr catch; catch = ALLOCATE (&CatchType, sizeof (Catch)); catch->exception = exception; ContinuationSet (&catch->continuation, &thread->thread.continuation); catch->continuation.pc = thread->thread.continuation.pc + 1; RETURN (catch); } static void TwixtMark (void *object) { TwixtPtr twixt = object; ContinuationMark (&twixt->continuation); } DataType TwixtType = { TwixtMark, 0, "TwixtType" }; TwixtPtr NewTwixt (ContinuationPtr continuation, InstPtr enter, InstPtr leave) { ENTER (); TwixtPtr twixt; twixt = ALLOCATE (&TwixtType, sizeof (Twixt)); twixt->leave = leave; if (continuation->twixts) twixt->depth = continuation->twixts->depth + 1; else twixt->depth = 1; ContinuationSet (&twixt->continuation, continuation); twixt->continuation.pc = enter; RETURN (twixt); } /* * Twixts are chained deepest first. Walking * down the list is a bit of work */ TwixtPtr TwixtNext (TwixtPtr twixt, TwixtPtr last) { if (last == twixt) return 0; while (last->continuation.twixts != twixt) last = last->continuation.twixts; return last; } void RaiseException (Value thread, SymbolPtr except, Value args, InstPtr *next) { ENTER (); CatchPtr catch; ContinuationPtr continuation = 0; for (catch = thread->thread.continuation.catches; catch; catch = catch->continuation.catches) { if (catch->exception == except) { continuation = &catch->continuation; /* * Hold a reference to this nested value because * ContinuationJump is about to smash the thread */ REFERENCE (catch); break; } } /* unhandled exception -- build an empty continuation and jump to it */ if (!continuation) { int i; InstPtr pc = thread->thread.continuation.pc; PrintError ("Unhandled exception %A (", except->symbol.name); if (args) { int dim = ArrayLimits(&args->array)[0]; for (i = 0; i < dim; i++) { PrintError ("%g", ArrayValue (&args->array, i)); if (i < dim - 1) PrintError (", "); } } PrintError (")\n"); TraceFrame (FileStderr, thread->thread.continuation.frame, thread->thread.continuation.obj, pc, 20); continuation = EmptyContinuation(); STACK_PUSH (continuation->stack, NewContinuation (&thread->thread.continuation, pc)); } ContinuationJump (thread, continuation, args, next); EXIT (); } SymbolPtr standardExceptions[_num_standard_exceptions]; StandardException standardException; Value standardExceptionArgs; ReferencePtr standardExceptionArgsRef; void RegisterStandardException (StandardException se, SymbolPtr sym) { ENTER (); standardExceptions[se] = sym; MemAddRoot (sym); if (!standardExceptionArgsRef) { standardExceptionArgsRef = NewReference ((void **) &standardExceptionArgs); MemAddRoot (standardExceptionArgsRef); } EXIT (); } SymbolPtr CheckStandardException (void) { SymbolPtr except = standardExceptions[standardException]; signalException = False; standardException = exception_none; standardExceptionArgs = 0; return except; } void RaiseStandardException (StandardException se, int argc, ...) { ENTER (); Value args; int i; va_list va; va_start (va, argc); i = argc; args = NewArray (False, False, typePoly, 1, &i); for (i = 0; i < argc; i++) ArrayValueSet (&args->array, i, va_arg (va, Value)); standardException = se; standardExceptionArgs = args; SetSignalException (); EXIT (); } Value JumpStandardException (Value thread, InstPtr *next) { ENTER (); SymbolPtr except = standardExceptions[standardException]; Value args = standardExceptionArgs; aborting = False; if (except) RaiseException (thread, except, args, next); standardException = exception_none; standardExceptionArgs = 0; RETURN (args); } static void SignalThread (Value thread, Value signal, Bool executing) { ENTER (); int i = 1; Value args = NewArray (False, False, typePoly, 1, &i); SymbolPtr except = standardExceptions[exception_signal]; ArrayValueSet (&args->array, 0, signal); if (thread == running && executing) { standardException = exception_signal; standardExceptionArgs = args; SetSignalException (); } else if (except) { InstPtr next; RaiseException (thread, except, args, &next); thread->thread.continuation.value = args; thread->thread.continuation.pc = next; if (thread->thread.state == ThreadSuspended) { thread->thread.sleep = 0; ThreadSetState (thread, ThreadRunning); } } EXIT (); } void ThreadsSignal (Value signal) { ENTER (); Value thread, next; /* do running first -- signalling makes threads run */ for (thread = running; thread; thread = next) { next = thread->thread.next; SignalThread (thread, signal, False); } for (thread = stopped; thread; thread = next) { next = thread->thread.next; SignalThread (thread, signal, False); } EXIT (); } Value do_Thread_signal (Value thread, Value signal) { ENTER (); SignalThread (thread, signal, True); RETURN (Void); } nickle_2.81.orig/opcode.h0000664000175000000620000000271611722530635014534 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #ifndef _CODE_H_ #define _CODE_H_ typedef enum _OpCode { OpNoop, /* * Statement op codes */ OpBranch, OpBranchFalse, OpBranchTrue, OpCase, OpTagCase, OpTagGlobal, OpTagLocal, OpDefault, OpReturn, OpReturnVoid, OpFork, OpCatch, OpEndCatch, OpRaise, OpTwixt, OpTwixtDone, OpEnterDone, OpLeaveDone, OpFarJump, OpUnwind, /* * Expr op codes */ OpGlobal, OpGlobalRef, OpGlobalRefStore, OpStatic, OpStaticRef, OpStaticRefStore, OpLocal, OpLocalRef, OpLocalRefStore, OpFetch, OpConst, OpBuildArray, OpBuildArrayInd, OpInitArray, OpBuildHash, OpInitHash, OpInitHashDef, OpBuildStruct, OpInitStruct, OpBuildUnion, OpInitUnion, OpArray, OpArrayRef, OpArrayRefStore, OpVarActual, OpCall, OpTailCall, OpExceptionCall, OpDot, OpDotRef, OpDotRefStore, OpArrow, OpArrowRef, OpArrowRefStore, OpObj, OpStaticInit, OpStaticDone, OpBinOp, OpBinFunc, OpUnOp, OpUnFunc, OpPreOp, OpPostOp, OpAssign, OpAssignOp, OpAssignFunc, OpIsType, OpHasMember, OpEnd, OpDrop } __attribute__ ((packed)) OpCode; #endif /* _CODE_H_ */ nickle_2.81.orig/ref.c0000664000175000000620000001003211726202646014022 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static Value RefPlus (Value av, Value bv, int expandOk) { ENTER(); int i; Ref *ref; if (ValueIsInt(av)) { i = IntPart (av, "Attempt to add non-integer to reference type"); if (aborting) RETURN (Void); ref = &bv->ref; } else if (ValueIsInt(bv)) { i = IntPart (bv, "Attempt to add non-integer to reference type"); if (aborting) RETURN (Void); ref = &av->ref; } else RETURN (Void); i = i + ref->element; if (i < 0 || i >= ref->box->nvalues || (!ref->box->homogeneous && i != ref->element)) { RaiseStandardException (exception_invalid_array_bounds, 2, av, bv); RETURN (Void); } RETURN (NewRef (ref->box, i)); } static Value RefMinus (Value av, Value bv, int expandOk) { ENTER(); int i; int element; Ref *ref, *bref; if (ValueIsInt(av)) { i = IntPart (av, "Attempt to subtract non-integer to reference type"); if (aborting) RETURN (Void); ref = &bv->ref; element = -ref->element; } else if (ValueIsInt(bv)) { i = -IntPart (bv, "Attempt to subtract non-integer to reference type"); if (aborting) RETURN (Void); ref = &av->ref; element = ref->element; } else { ref = &av->ref; bref = &bv->ref; if (ref->box != bref->box) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } RETURN (NewInt (ref->element - bref->element)); } i = i + element; if (i < 0 || i >= ref->box->nvalues || (!ref->box->homogeneous && i != ref->element)) { RaiseStandardException (exception_invalid_array_bounds, 2, av, bv); RETURN (Void); } RETURN (NewRef (ref->box, i)); } static Value RefLess (Value av, Value bv, int expandOk) { Ref *aref = &av->ref, *bref = &bv->ref; if (aref->box != bref->box || (!aref->box->homogeneous && aref->element != bref->element)) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); return FalseVal; } if (aref->element < bref->element) return TrueVal; return FalseVal; } static Value RefEqual (Value av, Value bv, int expandOk) { Ref *aref = &av->ref, *bref = &bv->ref; if (aref->box != bref->box || aref->element != bref->element) return FalseVal; return TrueVal; } static ValueRep * RefTypeCheck (BinaryOp op, Value av, Value bv, int expandOk) { switch (op) { case MinusOp: if (ValueIsRef(av) && ValueIsRef(bv)) return av->value.type; case PlusOp: if (ValueIsInt(av)) return bv->value.type; if (ValueIsInt(bv)) return av->value.type; break; case LessOp: case EqualOp: if (ValueIsRef(av) && ValueIsRef(bv)) return av->value.type; break; default: break; } return 0; } static Bool RefPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FileOutput (f, '&'); return Print (f, RefValueGet (av), format, base, width ? width - 1 : 0, prec, fill); } static void RefMark (void *object) { Ref *ref = object; if (ref->box->replace) ref->box = BoxRewrite (ref->box, &ref->element); MemReference (ref->box); } ValueRep RefRep = { { RefMark, 0, "RefRep" }, /* data */ rep_ref, /* tag */ { /* binary */ RefPlus, RefMinus, 0, 0, 0, 0, RefLess, RefEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, RefPrint, RefTypeCheck, }; DataCachePtr refCache; Value NewRefReal (BoxPtr box, int element, Value *re) { ENTER (); Value ret = ALLOCATE (&RefRep.data, sizeof (Ref)); ret->ref.box = box; ret->ref.element = element; *re = ret; RETURN (ret); } void RefRewrite (Value rv) { Ref *ref= &rv->ref; BoxPtr box = ref->box; if (box->replace) ref->box = BoxRewrite (box, &ref->element); } int RefInit (void) { ENTER (); refCache = NewDataCache(REF_CACHE_SIZE); EXIT (); return 1; } nickle_2.81.orig/builtin.5c0000664000175000000620000000606211711660252015004 0ustar keithpstaff# XXX Here there be dragons. # Top-level bootstrap of Nickle builtins in Nickle. # As you might expect, ordering and details are crucial. # Set up the library path correctly and # provide the "library" command. # Lives in this file because it's necessary # for bootstrapping extend namespace Command { /* actually controls library loading */ public string nickle_path = nickle_libdir; if (Environ::check("NICKLEPATH")) nickle_path = Environ::get("NICKLEPATH"); public bool lex_file (string name) /* * Push the file 'name' into the lexer and read input * from there until exhausted. Then return to the current * file. */ { return Command::lex_input (File::open (name, "r"), name, false, false); } /* currently just does ~ expansion */ public string glob(string filename) /* * Expand any leading ~/ in 'filename' to the value of the * HOME environment variable and return the resulting string */ { if (filename[0] == '~' && filename[1] == '/') { exception bad_glob(); if (!Environ::check("HOME")) raise bad_glob(); return Environ::get("HOME") + String::substr(filename, 1, String::length(filename) - 1); } return filename; } string path_first (string path) { int i = String::index (path, ":"); if (i < 0) return glob(path); if (i == 0) return "."; return glob(String::substr (path, 0, i)); } string path_rest (string path) { int i = String::index (path, ":"); if (i < 0) return ""; int l = String::length (path); if (i == l-1) return "."; return String::substr (path, i + 1, l - i - 1); } public bool lex_library (string name) /* * Search 'nickle_path' for the file 'name' and push any * found file into the lexer. Returns whether any * file was found and read. */ { for (string path = nickle_path; path != ""; path = path_rest (path)) { try return lex_file (path_first (path) + "/" + name); catch File::open_error (string name, File::error_type err, string msg) { ; } } return false; } public bool lex_string (string s) /* * Push 's' into the lexer input stack */ { return Command::lex_input (File::string_read (s), s, false, false); } new ("library", lex_library); } # Load the prerequisites for the extra commands. library "ctype.5c"; library "string.5c"; library "file.5c"; library "printf.5c"; # Get abort() in early, even if this means not autoimporting it library "abort.5c"; import Abort; library "history.5c"; # Now load the extra commands. library "parse-args.5c"; library "command.5c"; # Note that some libraries extend namespaces, and # thus aren't autoload/autoimport candidates. library "math.5c"; library "prime_sieve.5c" library "factorial.5c" library "gamma.5c" import Math; library "scanf.5c"; library "socket.5c"; # Now autoload/autoimport the bonus stuff # (But why? Let the users do it.) #autoload Mutex; #autoload ARC4; #autoload PRNG; #autoload Process; # parse the command line extend namespace Command { process_args (&argv); } nickle_2.81.orig/string.5c0000664000175000000620000001330213062260671014641 0ustar keithpstaffextend namespace String { public int rindex(string target, string pattern) /* * Return the right-most location of 'pattern' * in 'target' */ { int pl = length(pattern); for (int i = length(target) - pl; i >= 0; --i) { bool match_here() { for (int j = 0; j < pl; j++) if (target[i + j] != pattern[j]) return false; return true; } if (match_here()) return i; } return -1; } public string dirname(string path) /* * Return the directory portion of 'path' */ { int n = rindex(path, "/"); if (n == -1) return "."; return (substr(path, 0, n)); } public string[*] split(string s, string sep) /* * Split 's' at 'sep' boundaries, returning * an array of the resulting pieces */ { string[...] ss = {}; int i = -1; int j = 0; while(j < length(s)) { if (index(sep, new(s[j])) >= 0) { ss[dim(ss)] = substr(s, i + 1, j - i - 1); i = j; } j++; } ss[dim(ss)] = substr(s, i + 1, j - i - 1); return ss; } public void shiftn(&(poly[...]) array, int n) /* * Shift a growable array n elements: left is positive */ { int f = dim(array); for (int i = 0; i < f - n; i++) array[i] = array[i + n]; if (n < 0) for (int i = 0; i < -n; i++) make_uninit(&array[i]); if (n > 0) setdim(array, f - n); } public void shift(&(poly[...]) array) /* * Shift a growable array one element to the left */ { shiftn(&array, 1); } public string chump(string s) /* * Return s with any trailing newlines removed */ { int n = length(s); while(n > 0 && s[n - 1] == '\n') --n; return substr(s, 0, n); } public string chomp(string s) /* * Trim whitespace from begining and end of 's' */ { int l = length(s); int i = 0; while(i < l && Ctype::isspace(s[i])) i++; int j = l - 1; while(j >= i && Ctype::isspace(s[j])) --j; return substr(s, i, j - i + 1); } public bool inchars(int c, string s) /* * Return whether 'c' is in 's' */ { return index(s, String::new(c)) >= 0; } public string[*] wordsplit(string s, string sep) /* * Split 's' at boundaries consisting of sequences of * 'sep' characters, returning an array of the resulting * pieces */ { string[...] ss = {}; int i = 0; while(i < length(s)) { while (i < length(s) && inchars(s[i], sep)) i++; int j = i; while (j < length(s) && !inchars(s[j], sep)) j++; if (i == j) break; ss[dim(ss)] = substr(s, i, j - i); i = j; } return ss; } public typedef struct { string oq, cq, qq; } quote_context; typedef enum {normal, openq, xq} qstate; typedef string(string) dequote_t; public dequote_t make_dequote(quote_context q) /* * Construct a quote parsing function based on 'q' */ { public string _dequote(string s) { string result = ""; qstate t = qstate.normal; int c; for (int cur = 0; cur < length(s); cur++) { c = s[cur]; switch(t) { case qstate.normal: if (inchars(c, q.oq)) { t = qstate.openq; continue; } raise invalid_argument("leading garbage", 0, s); break; case qstate.openq: if (inchars(c, q.qq)) { t = qstate.xq; continue; } if (inchars(c, q.cq)) { if (cur != length(s) - 1) raise invalid_argument("trailing garbage", 0, s); t = qstate.normal; continue; } break; case qstate.xq: t = qstate.openq; break; } result = result + String::new(c); } if (t == qstate.normal || t == qstate.xq && inchars(c, q.cq)) return result; raise invalid_argument("unexpected end of string", 0, s); } return _dequote; } public dequote_t dequote = make_dequote( (quote_context) { .oq = "\"", .cq = "\"", .qq = "\\"} ); public typedef (string[*])(string) parse_csv_t; public exception bad_csv_parse(string error_msg, string[*] partial_parse); public parse_csv_t make_parse_csv(int sep, quote_context q) /* * Construct a CSV file parsing context from 'q' */ { if (length(q.oq) != 1 || length(q.cq) != 1 || length(q.qq) > 1) raise invalid_argument("make_parse_csv: quote context" + "has long bits", 0, q); global bool equiv(int c, &string s) { if (is_uninit(&s)) return false; if (s[0] != c) return false; return true; } dequote_t dq = make_dequote(q); public string[*] _parse_csv(string s) { string[...] ss = {}; string curs = ""; void consume() { string t = chomp(curs); if (t != "" && t[0] == q.oq[0]) t = dq(t); ss[dim(ss)] = t; curs = ""; } qstate t = qstate.normal; int cur = 0; while (cur < length(s)) { int c = s[cur]; switch(t) { case qstate.normal: if (c == sep) { consume(); cur++; continue; } if (equiv(c, &q.oq)) t = qstate.openq; break; case qstate.openq: if (equiv(c, &q.cq)) t = qstate.xq; break; case qstate.xq: if (equiv(c, &q.oq)) { t = qstate.openq; break; } if (c == sep) { t = qstate.normal; continue; } t = qstate.normal; break; } curs = curs + String::new(c); cur++; } if (t == qstate.openq) raise bad_csv_parse("parse_csv: unexpected " + "end of csv line", ss); consume(); return ss; } return _parse_csv; } public parse_csv_t parse_csv = make_parse_csv( ',', (quote_context) { .oq = "\"", .cq = "\"", .qq = "\""} ); public string reverse(string s) /* * Reverse the string s */ { int ns = length(s); int[ns] t = { [i] = s[ns - i - 1] }; return String::new(t); } } nickle_2.81.orig/builtin-semaphore.c0000664000175000000620000000334711720664657016720 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * semaphore.c * * provide builtin functions for the Semaphore namespace */ #include #include #include #include "builtin.h" NamespacePtr SemaphoreNamespace; void import_Semaphore_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { { do_Semaphore_signal, "signal", "v", "S", "\n" " void signal (semaphore s)\n" "\n" " Increment the count in 's' by one.\n" " If the count is <= 0, wakeup one thread waiting on 's'.\n" }, { do_Semaphore_count, "count", "i", "S", "\n" " int count (semaphore s)\n" "\n" " Return current semaphore count\n" }, { do_Semaphore_test, "test", "b", "S", "\n" " bool test (semaphore s)\n" "\n" " Return false if a 'wait' call would block, else\n" " 'wait' on 's' and return true.\n" }, { do_Semaphore_wait, "wait", "v", "S", "\n" " void wait (semaphore s)\n" "\n" " Decrement the count in 's' by one.\n" " If the count is < 0, wait until awoken when 's' is signalled.\n" }, { 0 } }; static const struct fbuiltin_v funcs_v[] = { { do_Semaphore_new, "new", "S", ".i", "\n" " semaphore new ()\n" " semaphore new (int init)\n" "\n" " Create a new semaphore.\n" " Set the initial count to 'init' if provided, else 0.\n" }, { 0 } }; SemaphoreNamespace = BuiltinNamespace (/*parent*/ 0, "Semaphore")->namespace.namespace; BuiltinFuncs1 (&SemaphoreNamespace, funcs_1); BuiltinFuncsV (&SemaphoreNamespace, funcs_v); EXIT (); } nickle_2.81.orig/stack.h0000664000175000000620000000605311765451116014371 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #ifndef _STACK_H_ #define _STACK_H_ #define STACK_ENTS_PER_CHUNK 126 typedef void *StackElement; typedef StackElement *StackPointer; typedef struct _StackChunk { DataType *type; struct _StackChunk *previous; StackElement elements[STACK_ENTS_PER_CHUNK]; } StackChunk; typedef struct _Stack { DataType *type; StackPointer stackPointer; StackChunk *current; StackChunk *save; StackElement temp; } StackObject; extern StackObject *StackCreate (void); extern StackObject *StackCopy (StackObject *stack); extern StackElement StackPush (StackObject *stack, StackElement object); extern StackElement StackPop (StackObject *stack); extern void StackDrop (StackObject *stack, int i); extern void StackReset (StackObject *stack, StackPointer stackPointer); extern StackElement StackReturn (StackObject *stack, StackPointer stackPointer, StackElement object); extern StackElement StackElt (StackObject *stack, int i); #define CHUNK_MAX(c) ((c)->elements + STACK_ENTS_PER_CHUNK) #define CHUNK_MIN(c) ((c)->elements) #define STACK_MAX(s) (CHUNK_MAX((s)->current)) #define STACK_MIN(s) (CHUNK_MIN((s)->current)) #define STACK_TOP(s) ((s)->stackPointer) #define STACK_POP(s) ((STACK_TOP(s) == STACK_MAX(s)) ? \ StackPop (s) : *STACK_TOP(s)++) #define STACK_DROP(s,i) ((STACK_TOP(s) + (i) <= STACK_MAX(s)) ? \ ((STACK_TOP(s) += (i)), 0) : (StackDrop(s, i), 0)) #define STACK_RESET(s,sp) (STACK_TOP(s) == (sp) ? 0 : \ ((STACK_TOP(s) <= (sp) && (sp) <= STACK_MAX(s)) ? \ ((STACK_TOP(s) = (sp)), 0) : \ (StackReset ((s), (sp)), 0))) #define STACK_ELT(s,i) ((STACK_TOP(s) + (i) < STACK_MAX(s)) ? \ STACK_TOP(s)[i] : StackElt(s,i)) #if 0 #define STACK_VALID(s) ((!(s)->stackPointer && !(s)->current) || \ (STACK_MIN(s) <= STACK_TOP(s) && \ STACK_TOP(s) <= STACK_MAX(s))) void panic (char *, ...); #define STACK_ASSERT(s) if (!STACK_VALID(s)) panic ("invalid stack\n"); #define STACK_CHUNK_ASSERT(c) assert((c)->type == &stackChunkType) #else #define STACK_ASSERT(s) #define STACK_CHUNK_ASSERT(c) #endif #if 0 /* * Can't work -- o gets evaluated after the stack overflow check, * if o also uses the stack, this will break */ #define STACK_PUSH(s,o) ((STACK_TOP(s) == STACK_MIN(s)) ? \ StackPush ((s), (o)) : (*--STACK_TOP(s) = (o))) #endif static inline StackElement StackPushInline(StackObject *s, StackElement o) { STACK_ASSERT (s); if (STACK_TOP(s) == STACK_MIN(s)) return StackPush (s, o); return *--STACK_TOP(s) = o; } #define STACK_PUSH(s,o) StackPushInline(s,o) static inline StackElement StackReturnInline(StackObject *s, StackPointer sp, StackElement o) { STACK_ASSERT(s); STACK_RESET(s, sp); STACK_ASSERT(s); if (STACK_TOP(s) == STACK_MIN(s)) return StackPush (s, o); return *--STACK_TOP(s) = o; } #define STACK_RETURN(s,sp,o) StackReturnInline(s,sp,o) #endif /* _STACK_H_ */ nickle_2.81.orig/symbol.c0000664000175000000620000001024410414112462014545 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static void SymbolTypeMark (void *object) { SymbolType *st = object; MemReference (st->symbol.next); MemReference (st->symbol.type); } static void SymbolGlobalMark (void *object) { SymbolGlobal *sg = object; MemReference (sg->symbol.next); MemReference (sg->symbol.type); MemReference (sg->value); } static void SymbolLocalMark (void *object) { SymbolLocal *sl = object; MemReference (sl->symbol.next); MemReference (sl->symbol.type); MemReference (sl->code); } static void SymbolNamespaceMark (void *object) { SymbolNamespace *sn = object; MemReference (sn->symbol.next); MemReference (sn->symbol.type); MemReference (sn->namespace); } static void SymbolExceptionMark (void *object) { SymbolException *se = object; MemReference (se->symbol.next); MemReference (se->symbol.type); MemReference (se->doc); } DataType SymbolTypeType = { SymbolTypeMark, 0, "SymbolTypeType" }; DataType SymbolGlobalType = { SymbolGlobalMark, 0, "SymbolGlobalType" }; DataType SymbolLocalType = { SymbolLocalMark, 0, "SymbolLocalType" }; DataType SymbolNamespaceType = { SymbolNamespaceMark, 0, "SymbolNamespaceType" }; DataType SymbolExceptionType = { SymbolExceptionMark, 0, "SymbolExceptionType" }; SymbolPtr NewSymbolType (Atom name, Type *type) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolTypeType, sizeof (SymbolType)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_typedef; s->symbol.type = type; s->symbol.forward = False; RETURN (s); } SymbolPtr NewSymbolException (Atom name, Type *type, Value doc) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolExceptionType, sizeof (SymbolException)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_exception; s->symbol.type = type; s->symbol.forward = False; s->exception.doc = doc; RETURN (s); } SymbolPtr NewSymbolConst (Atom name, Type *type) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolGlobalType, sizeof (SymbolGlobal)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_const; s->symbol.type = type; s->symbol.forward = False; s->global.value = NewBox (True, False, 1, type); RETURN (s); } SymbolPtr NewSymbolGlobal (Atom name, Type *type) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolGlobalType, sizeof (SymbolGlobal)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_global; s->symbol.type = type; s->symbol.forward = False; s->global.value = NewBox (False, False, 1, type); RETURN (s); } SymbolPtr NewSymbolArg (Atom name, Type *type) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolLocalType, sizeof (SymbolLocal)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_arg; s->symbol.type = type; s->symbol.forward = False; s->local.element = 0; RETURN (s); } SymbolPtr NewSymbolAuto (Atom name, Type *type) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolLocalType, sizeof (SymbolLocal)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_auto; s->symbol.type = type; s->symbol.forward = False; s->local.element = -1; RETURN (s); } SymbolPtr NewSymbolStatic (Atom name, Type *type) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolLocalType, sizeof (SymbolLocal)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_static; s->symbol.type = type; s->symbol.forward = False; s->local.element = -1; RETURN (s); } SymbolPtr NewSymbolNamespace (Atom name, NamespacePtr namespace) { ENTER (); SymbolPtr s; s = ALLOCATE (&SymbolNamespaceType, sizeof (SymbolNamespace)); s->symbol.next = 0; s->symbol.name = name; s->symbol.class = class_namespace; s->symbol.type = 0; s->symbol.forward = False; s->namespace.namespace = namespace; RETURN (s); } void SymbolInit () { } nickle_2.81.orig/command.5c0000664000175000000620000002143710770315532014761 0ustar keithpstaffextend namespace Command { /* * These are used by the parser when building * programs to run from the top level of the * interpreter */ public void display (poly v) /* * Used by the top-level read/eval/print loop. * For non-void 'v', * Prints out 'v' in the current default format. * Inserts 'v' into the history. */ { if (is_void (v)) return; History::insert (v); printf (format, v); putchar ('\n'); } public void display_base (poly v, int base) /* * Used by the top-level read/eval/print loop * when '# base' is appended to an expression. * For non-void 'v', * Prints out 'v' in 'base'. * Inserts 'v' into the history. */ { if (is_void (v)) return; History::insert (v); File::print (stdout, v, "g", base, 0, -1, " "); putchar ('\n'); } /* * Now add a collection of useful commands */ void do_quit (int args...) /* * quit - exit with code 0 * quit N - exit with code N */ { int code = 0; if (dim(args) > 0) code = args[0]; exit (code); } new ("quit", do_quit); void do_history (int args...) /* * history - show some recent history * history N - show N recent history * history N,M - show history from N to M */ { switch (dim (args)) { case 0: History::show (format); break; case 1: History::show (format, args[0]); break; default: History::show (format, args[0], args[1]); break; } } new ("history", do_history); string format_name(string[*] name) /* * given an array of namespace component strings, * produce a namespace-name */ { if (dim(name) == 0) return ""; string result = name[0]; for (int i = 1; i < dim(name); i++) result += sprintf("::%s", name[i]); return result; } void do_pretty_print (string[*] names...) /* * print - pretty print all public names * print name ... - pretty print given names */ { try { pretty_print (stdout, names ...); } catch invalid_argument(string msg, int i, poly value) { File::fprintf (stderr, "\"%s\": %s\n", format_name(names[i - 1]), msg); } } new_names ("print", do_pretty_print); new_names ("edit", edit); new_names ("undefine", undefine); void do_load (string f) /* * load "filename" - read commands from "filename" */ { try { lex_file (f); } catch File::open_error (string msg, File::error_type err, string name) { File::fprintf (stderr, "Cannot load \"%s\": %s\n", name, msg); } } new ("load", do_load); string make_filename(string[*] m) /* * construct a filename from a namespace name */ { string r = ""; for (int j = 0; j < dim (m); j++) { if (j > 0) r = r + "-"; bool last_lower = false; for (int i = 0; i < String::length(m[j]); i++) { int c = m[j][i]; bool cur_lower = Ctype::islower(c); if (Ctype::isupper(c)) { c = Ctype::tolower(c); if (last_lower) r = r + "-"; } r = r + String::new(c); last_lower = cur_lower; } } return r + ".5c"; } void force_import(string[*] name) /* * force an import of the given name. XXX horrible * kludge of consing up an import command in a string * and then lexing it. */ { string imp = sprintf("import %s;\n", format_name(name)); lex_string(imp); } void do_auto (string cmd, string[*][*] args, bool do_import, bool reimport) /* * core behavior for autoload / autoimport / reimport */ { /* XXX things are pushed onto the lexer stack in reverse order, so we have to be careful to generate things in the reverse of the order we want them to appear in. */ for (int i = dim(args) - 1; i >= 0; --i) { string[*] name = args[i]; if (do_import) force_import(name); if (!reimport && valid_name (name)) continue; for (int j = dim(name) - 1; j >= 0; j--) { string[*] subname = (string[j+1]) { [k] = name[k] }; if (reimport || !valid_name (subname)) { string f = make_filename(subname); if (!lex_library (f)) { File::fprintf (stderr, "Cannot %s from " + "file \"%s\", giving up.\n", cmd, f); return; } } } } } void do_autoimport (string[*] args...) /* * autoimport ModuleName ... - * if needed, load a library named "module-name.5c" and * import ModuleName; do for each argument */ { do_auto("autoimport", args, true, false); } new_names ("autoimport", do_autoimport); void do_reimport (string[*] args...) /* * reimport ModuleName ... - * load a library named "module-name.5c" and * import ModuleName; do for each argument */ { do_auto("reimport", args, true, true); } new_names ("reimport", do_reimport); void do_autoload (string[*] args...) /* * autoload ModuleName ... - * load a library named "module-name.5c". */ { do_auto("autoload", args, false, false); } new_names ("autoload", do_autoload); void do_char (int c ...) /* * char c1 c2 c3 - Print characters for given integers */ { for (int i = 0; i < dim (c); i++) printf ("%3d 0x%02x: %v\n", c[i], c[i], String::new (c[i])); } new ("char", do_char); void process_args(&string[*] argv) /* * parse nickle command-line arguments */ { bool lex_stdin = true; string script_name = ""; /* XXX Much of this architecture is driven by the fact that the lexer stacks the files to be processed rather than queueing them. */ typedef union { string library; string sfile; string script; string expr; } lexable; lexable[...] lexables = {}; void process_lexables() { } void save_lexable(lexable l) { lexables[dim(lexables)] = l; } void save_library(string arg) { save_lexable((lexable.library)arg); } void save_script(string arg) { save_lexable((lexable.script)arg); /* Add directory containing the script to the library path */ nickle_path = String::dirname (arg) + ":" + nickle_path; script_name = arg; lex_stdin = false; } void save_file(string arg) { save_lexable((lexable.sfile)arg); } void save_expr(string arg) { save_lexable((lexable.expr)arg); lex_stdin = false; } ParseArgs::argdesc argd = { .args = { { .var = { .arg_lambda = save_library}, .abbr = 'l', .name = "library", .expr_name = "lib", .desc = "Library to load."}, { .var = { .arg_lambda = save_file}, .abbr = 'f', .name = "file", .expr_name = "source", .desc = "Source file to load."}, { .var = { .arg_lambda = save_expr}, .abbr = 'e', .name = "expr", .expr_name = "expression", .desc = "Expression to evaluate."} }, .posn_args = { { .var = { .arg_lambda = save_script}, .name = "script", .optional = <>} }, .unknown = &(int user_argind), .prog_name = "nickle" }; /* actually parse the arguments */ ParseArgs::parseargs(&argd, &argv); /* Reset argv to hold remaining arguments */ if (lex_stdin && is_uninit(&user_argind)) { string[0] rest = {}; argv = rest; } else { if (is_uninit(&user_argind)) user_argind = dim(argv); string[dim(argv) - user_argind + 1] rest; rest[0] = script_name; for (int i = 1; i < dim(rest); i++) rest[i] = argv[i + user_argind - 1]; argv = rest; } /* Recall the comment above. Since the lexer stacks, we must stack stdin, which is to run last, *before* the other stuff. Bleah. */ if (lex_stdin) { /* Add the current directory to the library path */ nickle_path += ":."; /* we want stdin to be processed after all other lexables */ lex_input (stdin, "", false, File::isatty (stdin)); /* if there's a .nicklerc, we apparently want that next-to-last? */ try { lex_file (Environ::get ("HOME") + "/.nicklerc"); } catch invalid_argument (msg, int i, poly value) { /* do nothing */; } catch File::open_error (string msg, File::error_type err, string name) { /* do nothing */; } } /* now stack the other arguments, in reverse order */ for (int i = dim(lexables) - 1; i >=0; --i) { static void load_fail(string name, string msg) { File::fprintf (stderr, "Cannot load \"%s\": %s\n", name, msg); exit (1); } static void lex_script(string arg) { try { lex_file (arg); } catch File::open_error (string msg, File::error_type err, string name) { load_fail (name, msg); } } union switch(lexables[i]) { case library arg: if (!lex_library (arg)) load_fail (arg, "cannot load library"); break; case script arg: lex_script(arg); break; case sfile arg: lex_script(arg); break; case expr arg: lex_string(arg + "\n"); break; } } } } nickle_2.81.orig/sort.5c0000664000175000000620000000375310770315535014336 0ustar keithpstaff/* $Header$ * * Copyright © 2002 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ autoload PRNG; namespace Sort { /* * Quicksort with random pivot */ public void qsort (&poly[*] a, bool(poly, poly) gt) { void quicksort (int p, int r) { if (p < r) { /* swap two array elements */ void exchange (int i, int j) { poly t = a[i]; a[i] = a[j]; a[j] = t; } /* partition the array into two pieces and return the pivot */ int partition (int p, int r) { /* select a random element to pivot */ int pivot = p + PRNG::randint(p-r); exchange (pivot, r); poly x = a[r]; int i = p; for (int j = p; j < r; j++) { if (gt (x, a[j])) { exchange (i, j); i++; } } exchange (i, r); return i; } int q = partition (p, r); quicksort (p, q-1); quicksort (q+1, r); } } quicksort (0, dim(a)-1); } /* * Mergesort */ public void mergesort (&poly[*] a, bool(poly, poly) gt) { void msort (int p, int r) { if (p < r) { /* merge two sorted lists together */ void merge (int p, int q, int r) { /* temporary storage for left half of array */ int n1 = q - p + 1; poly[n1] L; for (int i = 0; i < n1; i++) L[i] = a[p+i]; /* temporary storage for right half of array */ int n2 = r - q; poly[n2] R; for (int i = 0; i < n2; i++) R[i] = a[q+i+1]; /* merge two halves back into main array */ int i = 0, j = 0, k = p; while (i < n1 && j < n2) a[k++] = gt (L[i], R[j]) ? R[j++] : L[i++]; while (i < n1) a[k++] = L[i++]; while (j < n2) a[k++] = R[j++]; } int q = (p + r) // 2; msort (p, q); msort (q+1, r); merge (p, q, r); } } msort (0, dim(a)-1); } protected int[*] randomints (int n, int max) = (int[n]) { [i] = PRNG::randint(max) }; } nickle_2.81.orig/prng.5c0000664000175000000620000000265710414112462014304 0ustar keithpstaff/* * Use ARC4 to generate large random numbers * * Bart 1999/2 * * Modified 2003/4 to support /dev/random */ autoload ARC4; namespace PRNG { import File; global bool setkey = false; public void srandom(int s) /* * Seed the PRNG with 's' */ { ARC4::nsetkey(10, abs (s)); setkey = true; } public void dev_srandom(int nbits) /* * Use 'nbits' of /dev/urandom to seed the PRNG */ { twixt(file f = open("/dev/urandom", "r"); close(f)) { int seed = 0; while (nbits >= 8) { seed = (seed << 8) | getb(f); nbits -= 8; } if (nbits > 0) seed = (seed << nbits) | (getb(f) & ((1 << nbits) - 1)); srandom(seed); } } public int randbits(int n) /* * returns an 'n'-*bit* random number in 0..(2**'n')-1 */ { int q = n >> 3; int r = n & 7; if (!setkey) srandom(0); int acc = ARC4::streambyte() >> (8 - r); while (q > 0) { --q; acc += ARC4::streambyte() << (8 * q + r); } return acc; } public int randint(int n) /* * Returns a random integer in the range 0..'n'-1 */ { return randbits(32 + bit_width (n)) % n; } public void shuffle(&poly[*] a) /* * Randomly shuffle 'a' in place */ { int na = dim(a); for (int i = 0; i < na - 1; i++) { int j = randint(na - i) + i; poly tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } } nickle_2.81.orig/error.c0000664000175000000620000000056110414112462014372 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "gram.h" Bool signalError; void PrintError (char *s, ...) { va_list args; va_start (args, s); FileVPrintf (FileStderr, s, args); va_end (args); } nickle_2.81.orig/lex.l0000664000175000000620000004760013062330755014060 0ustar keithpstaff%{ /* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "gram.h" #include "ref.h" #include #include #ifdef HAVE_LIBREADLINE #include #include #endif /* * Silence gcc by providing prototypes for these functions */ int yyget_lineno (void); FILE *yyget_in (void); FILE *yyget_out (void); int yyget_leng (void); char *yyget_text (void); void yyset_lineno (int); void yyset_in (FILE *); void yyset_out (FILE *); int yyget_debug (void); void yyset_debug (int); int yylex_destroy (void); typedef struct _lexInput { DataType data; struct _lexInput *next; Value file; Atom name; int lineno; Bool at_bol; Bool at_eof; Bool interactive; } LexInput; LexInput *lexInput; extern int ignorenl; extern int notCommand; extern int seeComment; #define FILE_END_CHAR -2 static void lexInputMark (void *object) { LexInput *lex = object; MemReference (lex->next); MemReference (lex->file); } static DataType lexInputType = { lexInputMark, 0, "lexInputType" }; void NewLexInput (Value file, Atom name, Bool after, Bool interactive) { ENTER (); LexInput *lex; lex = MemAllocate (&lexInputType, sizeof (*lex)); lex->file = file; lex->name = name; lex->lineno = 0; lex->at_bol = True; lex->at_eof = False; lex->interactive = interactive; if (after) { LexInput **prev; for (prev = &lexInput; *prev; prev = &(*prev)->next) ; lex->next = 0; *prev = lex; } else { lex->next = lexInput; lexInput = lex; } EXIT (); } #ifdef HAVE_LIBREADLINE volatile int stdin_in_readline; static void my_prep_terminal(int meta_flag) { stdin_in_readline = 1; rl_prep_terminal(meta_flag); } static void my_deprep_terminal(void) { rl_deprep_terminal(); stdin_in_readline = 0; } static int LexGetChar (void); static int ReadlineGetChar (FILE *f) { return LexGetChar (); } #endif ReferencePtr LexInputReference; void LexInit (void) { ENTER (); #if HAVE_LIBREADLINE rl_getc_function = ReadlineGetChar; rl_prep_term_function = my_prep_terminal; rl_deprep_term_function = my_deprep_terminal; rl_catch_signals = 0; #endif LexInputReference = NewReference ((void **) &lexInput); MemAddRoot (LexInputReference); EXIT (); } Atom LexFileName (void) { if (lexInput) return lexInput->name; return AtomId (""); } int LexFileLine (void) { if (lexInput) return lexInput->lineno; return 0; } Bool LexInteractive (void) { if (lexInput) return lexInput->interactive; return False; } Bool LexResetInteractive (void) { while (lexInput->next && !lexInput->interactive) { FileClose (lexInput->file); lexInput = lexInput->next; } if (lexInput->interactive) return True; return False; } Bool LexFile (char *s, Bool complain, Bool after) { Value f; int err; f = FileFopen (s, "r", &err); if (f == 0) { if (complain) (void) FilePrintf (FileStderr, "%s: %s\n", s, StringChars (&FileGetErrorMessage (err)->string)); return False; } (void) NewLexInput(f, AtomId (s), after, False); return True; } static int LexGetChar (void) { int c; for (;;) { c = FileInput (lexInput->file); if (c >= 0) return c; if (c == FileBlocked) ThreadsRun (0, lexInput->file); else { if (!lexInput->next) return FileEOF; lexInput->at_eof = True; return '\n'; } } } static Value prompt (void) { Value v; if (ignorenl) v = lookupVar (0, "prompt2"); else if (CurrentFrame) v = lookupVar (0, "prompt3"); else v = lookupVar (0, "prompt"); return v; } static int LexGetInteractiveChar (void) { #ifdef HAVE_LIBREADLINE static char *line, *line_base; int c; if (!line) { char *p; p = StrzPart (prompt (), "invalid prompt"); if (!p) p = "??? "; for (;;) { FileFlush (FileStdout, False); FileFlush (FileStderr, False); if (FileStdout->file.flags & FileOutputBlocked) ThreadsRun (0, FileStdout); else if (FileStderr->file.flags & FileOutputBlocked) ThreadsRun (0, FileStderr); else break; } rl_inhibit_completion = 1; line_base = readline (p); line = line_base; if (!line) return FileEOF; add_history (line_base); } c = (*line++) & 0xff; if (!c) { c = '\n'; free (line_base); line = 0; } return c; #else if (lexInput->at_bol) { Value v = prompt (); Print (FileStdout, v, 's', 0, 0, 0, ' '); FileFlush (FileStdout, True); } return LexGetChar (); #endif } #undef YY_INPUT #define YY_NO_UNPUT static int yy_input (char *buf, int max_size) { int c; int result = 0; while (result < max_size) { if (lexInput->at_eof) { FileClose (lexInput->file); lexInput = lexInput->next; } if (lexInput->interactive) c = LexGetInteractiveChar (); else c = LexGetChar (); if (lexInput->at_bol) { lexInput->lineno++; } lexInput->at_bol = False; if (c < 0) break; buf[result++] = c; if (c == '\n') { lexInput->at_bol = True; break; } } return result; } #define YY_INPUT(buf,result,max_size) ((result) = yy_input (buf, max_size)) #ifndef FLEX_SCANNER #undef input #undef unput int input (void) { char buf[1]; int r; YY_INPUT(buf, r, 1); if (r == 0) return 0; return buf[0]; } void unput (char c) { if (c == '\n') lexInput->lineno--; FileUnput (lexInput->file, c); } #endif %} %% "/\052" { if (seeComment) { yylval.value = lexdoc (); return COMMENT_CONST; } else skipcomment (); } ^[ \t]*# skipline(); auto { yylval.class = class_auto; return AUTO; } const { yylval.class = class_const; return CONST; } global { yylval.class = class_global; return GLOBAL; } static { yylval.class = class_static; return STATIC; } function { yylval.type = typePrim[rep_void]; return FUNCTION; } while { yylval.ints = WHILE; return WHILE; } for { yylval.ints = FOR; return FOR; } do { yylval.ints = DO; return DO; } if { yylval.ints = IF; return IF; } else { yylval.ints = ELSE; return ELSE; } switch { yylval.ints = SWITCH; return SWITCH; } break { yylval.ints = BREAK; return BREAK; } continue { yylval.ints = CONTINUE; return CONTINUE; } case { yylval.ints = CASE; return CASE; } default { yylval.ints = DEFAULT; return DEFAULT; } return { yylval.ints = RETURNTOK; return RETURNTOK; } try { yylval.ints = TRY; return TRY; } catch { yylval.ints = CATCH; return CATCH; } twixt { yylval.ints = TWIXT; return TWIXT; } poly { yylval.type = typePoly; return POLY; } bool { yylval.type = typePrim[rep_bool]; return BOOL; } int { yylval.type = typePrim[rep_integer]; return INTEGER; } rational { yylval.type = typePrim[rep_rational]; return RATIONAL; } real { yylval.type = typePrim[rep_float]; return REAL; } string { yylval.type = typePrim[rep_string]; return STRING; } file { yylval.type = typePrim[rep_file]; return FILET; } semaphore { yylval.type = typePrim[rep_semaphore]; return SEMAPHORE; } continuation { yylval.type = typePrim[rep_continuation]; return CONTINUATION; } thread { yylval.type = typePrim[rep_thread]; return THREAD; } struct { yylval.ints = STRUCT; return STRUCT; } union { yylval.ints = UNION; return UNION; } enum { yylval.ints = ENUM; return ENUM; } void { yylval.type = typePrim[rep_void]; return VOID; } foreign { yylval.type = typePrim[rep_foreign]; return FOREIGN; } true { yylval.value = TrueVal; return BOOLVAL; } false { yylval.value = FalseVal; return BOOLVAL; } typedef { yylval.ints = TYPEDEF; return TYPEDEF; } func { yylval.ints = FUNC; return FUNC; } fork { yylval.ints = FORK; return FORK; } namespace { yylval.ints = NAMESPACE; return NAMESPACE; } import { yylval.ints = IMPORT; return IMPORT; } exception { yylval.ints = EXCEPTION; return EXCEPTION; } raise { yylval.ints = RAISE; return RAISE; } protected { yylval.publish = publish_protected; return PROTECTED; } public { yylval.publish = publish_public; return PUBLIC; } extend { yylval.publish = publish_extend; return EXTEND; } is_type { yylval.ints = ISTYPE; return ISTYPE; } has_member { yylval.ints = HASMEMBER; return HASMEMBER; } ";" { yylval.ints = SEMI; return SEMI; } "," { yylval.ints = COMMA; return COMMA; } "$" { yylval.ints = DOLLAR; return DOLLAR; } "..." { yylval.ints = DOTDOTDOT; return DOTDOTDOT; } "…" { yylval.ints = DOTDOTDOT; return DOTDOTDOT; } "." { yylval.ints = DOT; return DOT; } "->" { yylval.ints = ARROW; return ARROW; } "→" { yylval.ints = ARROW; return ARROW; } "=>" { yylval.ints = DARROW; return DARROW; } "⇒" { yylval.ints = DARROW; return DARROW; } "<>" { yylval.value = Void; return VOIDVAL; } "â—Š" { yylval.value = Void; return VOIDVAL; } \n { if (lexInput->at_eof) { strcpy (yytext, "EOF"); yylval.ints = ENDFILE; return ENDFILE; } if (!ignorenl) { yylval.ints = NL; return NL; } } "(" { yylval.ints = OP; ++ignorenl; return OP; } ")" { yylval.ints = CP; if (ignorenl > 0) --ignorenl; return CP; } "*[" { yylval.ints = STAROS; ++ignorenl; return STAROS; } "[" { yylval.ints = OS; ++ignorenl; return OS; } "]" { yylval.ints = CS; if (ignorenl > 0) --ignorenl; return CS; } "{" { yylval.ints = OC; ++ignorenl; return OC; } "}" { yylval.ints = CC; if (ignorenl > 0) --ignorenl; return CC; } "+=" { yylval.ints = ASSIGNPLUS; return ASSIGNPLUS; } "-=" { yylval.ints = ASSIGNMINUS; return ASSIGNMINUS; } "*=" { yylval.ints = ASSIGNTIMES; return ASSIGNTIMES; } "×=" { yylval.ints = ASSIGNTIMES; return ASSIGNTIMES; } "/=" { yylval.ints = ASSIGNDIVIDE; return ASSIGNDIVIDE; } "÷=" { yylval.ints = ASSIGNDIVIDE; return ASSIGNDIVIDE; } "//=" { yylval.ints = ASSIGNDIV; return ASSIGNDIV; } "⫽=" { yylval.ints = ASSIGNDIV; return ASSIGNDIV; } "%=" { yylval.ints = ASSIGNMOD; return ASSIGNMOD; } "**=" { yylval.ints = ASSIGNPOW; return ASSIGNPOW; } "↑=" { yylval.ints = ASSIGNPOW; return ASSIGNPOW; } "<<=" { yylval.ints = ASSIGNSHIFTL; return ASSIGNSHIFTL; } "⪡=" { yylval.ints = ASSIGNSHIFTL; return ASSIGNSHIFTL; } ">>=" { yylval.ints = ASSIGNSHIFTR; return ASSIGNSHIFTR; } "⪢=" { yylval.ints = ASSIGNSHIFTR; return ASSIGNSHIFTR; } "^=" { yylval.ints = ASSIGNLXOR; return ASSIGNLXOR; } "&&=" { yylval.ints = ASSIGNAND; return ASSIGNAND; } "||=" { yylval.ints = ASSIGNOR; return ASSIGNOR; } "&=" { yylval.ints = ASSIGNLAND; return ASSIGNLAND; } "|=" { yylval.ints = ASSIGNLOR; return ASSIGNLOR; } "=" { yylval.ints = ASSIGN; return ASSIGN; } "+" { yylval.ints = PLUS; return PLUS; } "-" { yylval.ints = MINUS; return MINUS; } "*" { yylval.ints = TIMES; return TIMES; } "×" { yylval.ints = TIMES; return TIMES; } "/" { yylval.ints = DIVIDE; return DIVIDE; } "÷" { yylval.ints = DIVIDE; return DIVIDE; } "//" { yylval.ints = DIV; return DIV; } "⫽" { yylval.ints = DIV; return DIV; } "**" { yylval.ints = STARSTAR; return STARSTAR; } "↑" { yylval.ints = STARSTAR; return STARSTAR; } "%" { yylval.ints = MOD; return MOD; } "!" { yylval.ints = BANG; return BANG; } "#" { yylval.ints = POUND; return POUND; } "&" { yylval.ints = LAND; return LAND; } "|" { yylval.ints = LOR; return LOR; } "^" { yylval.ints = LXOR; return LXOR; } "~" { yylval.ints = LNOT; return LNOT; } "¬" { yylval.ints = LNOT; return LNOT; } "++" { yylval.ints = INC; return INC; } "⧺" { yylval.ints = INC; return INC; } "--" { yylval.ints = DEC; return DEC; } "==" { yylval.ints = EQ; return EQ; } "!=" { yylval.ints = NE; return NE; } "≠" { yylval.ints = NE; return NE; } "<" { yylval.ints = LT; return LT; } ">" { yylval.ints = GT; return GT; } "<=" { yylval.ints = LE; return LE; } "≤" { yylval.ints = LE; return LE; } ">=" { yylval.ints = GE; return GE; } "≥" { yylval.ints = GE; return GE; } "&&" { yylval.ints = AND; return AND; } "∧" { yylval.ints = AND; return AND; } "||" { yylval.ints = OR; return OR; } "∨" { yylval.ints = OR; return OR; } "<<" { yylval.ints = SHIFTL; return SHIFTL; } "⪡" { yylval.ints = SHIFTL; return SHIFTL; } ">>" { yylval.ints = SHIFTR; return SHIFTR; } "⪢" { yylval.ints = SHIFTR; return SHIFTR; } "?" { yylval.ints = QUEST; return QUEST; } "::" { yylval.ints = COLONCOLON; return COLONCOLON; } ":" { yylval.ints = COLON; return COLON; } "²" { yylval.ints = POW2; return POW2; } "³" { yylval.ints = POW3; return POW3; } " " ; "\t" ; "\r" ; \'([^\n\']|\\\')*\' { ENTER (); char *s; long len = yyleng - 1; unsigned c; s = yytext + 1; s = StringNextChar (s, &c, &len); if (c == '\\') { if (!(s = StringNextChar (s, &c, &len))) c = 0; else if ('0' <= c && c <= '7') { unsigned ch; char *ps = s; c = c - '0'; while ((s = StringNextChar (s, &ch, &len)) && '0' <= ch && ch <= '7') { c = (c << 3) | (ch - '0'); ps = s; } s = ps; } else c = lexEscape (c); } yylval.value = NewInt (c); EXIT (); REFERENCE (yylval.value); return CHAR_CONST; } \"([^\n\"]|\\\")*\" { ENTER (); char *d, *s; unsigned c; long len = yyleng - 2; yylval.value = NewString (len); d = StringChars (&yylval.value->string); s = yytext + 1; while ((s = StringNextChar (s, &c, &len))) { if (c == '\\') { if (!(s = StringNextChar (s, &c, &len))) break; if ('0' <= c && c <= '7') { unsigned ch; char *ps = s; long plen = len; c = c - '0'; while ((s = StringNextChar (s, &ch, &len)) && '0' <= ch && ch <= '7') { c = (c << 3) | (ch - '0'); ps = s; plen = len; } s = ps; len = plen; } else c = lexEscape (c); } d += StringPutChar (c, d); } *d = '\0'; yylval.value->string.length = d - StringChars(&yylval.value->string); EXIT (); REFERENCE (yylval.value); return STRING_CONST; } 0[0-7]* { yylval.value = atov(yytext+1, 8); if (yytext[1] == '\0') return TEN_NUM; else return OCTAL0_NUM; } 0o[0-7]+ { yylval.value = atov(yytext+2, 8); return OCTAL_NUM; } 0o[0-7]+\./\.\.\. { yylval.value = aetov(yytext+2, 8); return OCTAL_FLOAT; } 0o[0-7]+/\.\. { yylval.value = atov(yytext+2, 8); return OCTAL_NUM; } 0o(([0-7]+((\.[0-7]*(\{[0-7]+\})?)?))|(\.[0-7]+)|(\.[0-7]*\{[0-7]+\}))(([Ee][-+]?[0-7]+)?) { yylval.value = aetov (yytext+2, 8); return OCTAL_FLOAT; } 0b[01]+ { yylval.value = atov(yytext+2, 2); return BINARY_NUM; } 0b[0-1]+\./\.\.\. { yylval.value = aetov(yytext+2, 2); return BINARY_FLOAT; } 0b[0-1]+/\.\. { yylval.value = atov(yytext+2, 2); return BINARY_NUM; } 0b(([0-1]+((\.[0-1]*(\{[0-1]+\})?)?))|(\.[0-1]+)|(\.[0-1]*\{[0-1]+\}))(([Ee][-+]?[0-1]+)?) { yylval.value = aetov (yytext+2, 2); return BINARY_FLOAT; } 0x[0-9a-fA-F]+ { yylval.value = atov(yytext+2, 16); return HEX_NUM; } 0x[0-9a-fA-F]+\./\.\.\. { yylval.value = aetov(yytext+2, 16); return HEX_FLOAT; } 0x[0-9a-fA-F]+/\.\. { yylval.value = atov(yytext+2, 16); return HEX_NUM; } 0x(([0-9a-fA-F]+((\.[0-9a-fA-F]*(\{[0-9a-fA-F]+\})?)?))|(\.[0-9a-fA-F]+)|(\.[0-9a-fA-F]*\{[0-9a-fA-F]+\}))(([Ee][-+]?[0-9a-fA-F]+)?) { yylval.value = aetov (yytext+2, 16); return HEX_FLOAT; } [0-9]+ { yylval.value = atov(yytext, 10); return TEN_NUM; } [0-9]+\./\.\.\. { yylval.value = aetov(yytext, 10); return TEN_FLOAT; } [0-9]+/\.\. { yylval.value = atov(yytext, 10); return TEN_NUM; } (([0-9]+((\.[0-9]*(\{[0-9]+\})?)?))|(\.[0-9]+)|(\.[0-9]*\{[0-9]+\}))(([Ee][-+]?[0-9]+)?) { yylval.value = aetov (yytext, 10); return TEN_FLOAT; } [a-zA-Z\200-\377_][0-9a-zA-Z\200-\377_]* { CommandPtr c; SymbolPtr symbol; yylval.atom = AtomId (yytext); if (!notCommand && (c = CommandFind (CurrentCommands, yylval.atom))) { if (c->names) return NAMECOMMAND; return COMMAND; } if (LexNamespace) symbol = NamespaceFindName (LexNamespace, yylval.atom, False); else symbol = NamespaceFindName (CurrentNamespace, yylval.atom, True); if (symbol) { switch (symbol->symbol.class) { case class_namespace: return NAMESPACENAME; case class_typedef: return TYPENAME; default: break; } } return NAME; } . FilePrintf (FileStderr, "character \\%o ignored\n", *yytext & 0xff); %% int lexEscape (int c) { switch (c) { case '0': return '\0'; break; case 'b': return '\b'; break; case 'n': return '\n'; break; case 'r': return '\r'; break; case 't': return '\t'; break; case 'f': return '\f'; break; case 'v': return '\v'; break; default: return c; } } Value lexdoc (void) { int c; Value s = NewStrString (""); c = input(); if (lexInput->at_eof) { bail: yyerror ("Missing */ at end of file"); return Void; } for (;;) { Bool skip = False; while (c != EOF && c != '*') { if (skip && c != ' ' && c != '\t') skip = False; if (!skip) s = Plus (s, NewCharString (c)); if (c == '\n') skip = True; c = input(); if (c == EOF || lexInput->at_eof) goto bail; } c = input(); if (c == EOF || lexInput->at_eof) goto bail; if (c == '/') break; if (!skip) s = Plus (s, NewCharString ('*')); } return s; } void skipcomment (void) { int c; c = input(); if (lexInput->at_eof) { bail: yyerror ("Missing */ at end of file"); return; } for (;;) { while (c != EOF && c != '*') { c = input(); if (c == EOF || lexInput->at_eof) goto bail; } c = input(); if (c == EOF || lexInput->at_eof) goto bail; if (c == '/') return; } } void skipline (void) { int c; do { c = input(); } while (c != EOF && c != '\n'); } Value atov (char *s, int base) { ENTER (); Value result; Value b; char c; int i; b = NewInt (base); result = NewInt (0); for (;;) { c = *s++; if ('0' <= c && c <= '9') i = c - '0'; else if ('a' <= c && c <= 'z') i = c - 'a' + 10; else if ('A' <= c && c <= 'Z') i = c - 'A' + 10; else break; if (i >= base) break; result = Plus (NewInt (i), Times (result, b)); } RETURN (result); } Value aetov (char *s, int base) { ENTER (); char *int_part, *frac_part, *rep_part, *exp_part, *next; int sign, frac_len, rep_len, esign; Value v, sv; int_part = s; sign = 1; if (*int_part == '+') int_part++; else if (*int_part == '-') { int_part++; sign = -1; } next = int_part; frac_part = strchr (next, '.'); frac_len = -1; rep_part = 0; rep_len = 0; esign = 1; if (frac_part) { frac_part++; next = frac_part; rep_part = strchr (next, '{'); if (rep_part) { frac_len = rep_part - frac_part; rep_part++; next = strchr (rep_part, '}'); if (!next) RETURN (Void); /* "can't" happen */ rep_len = next - rep_part; next = next + 1; } } exp_part = strchr (next, 'e'); if (!exp_part) exp_part = strchr (next, 'E'); if (exp_part) { if (frac_len < 0) frac_len = exp_part - frac_part; exp_part++; if (*exp_part == '+') exp_part++; else if (*exp_part == '-') { esign = -1; exp_part++; } } else if (frac_len < 0 && frac_part) frac_len = strlen(frac_part); v = atov (int_part, base); if (frac_part) { v = Plus (v, Divide (atov (frac_part, base), Pow (NewInt (base), NewInt (frac_len)))); } if (rep_part) { Value rep; rep = Divide (atov (rep_part, base), Minus (Pow (NewInt (base), NewInt (rep_len)), One)); if (frac_len) rep = Divide (rep, Pow (NewInt (base), NewInt (frac_len))); v = Plus (v, rep); } if (exp_part) { sv = Pow (NewInt (base), atov (exp_part, base)); if (esign > 0) v = Times (v, sv); else v = Divide (v, sv); } if (sign == -1) v = Negate (v); RETURN (v); } nickle_2.81.orig/mutex.5c0000664000175000000620000000407610722453513014504 0ustar keithpstaff/* * Mutexes * * Mutexes can be held by only one thread * at a time, the following exceptions may * be raised: * * exception deadlock (mutex m, thread self) * * Raised when a thread attempts to reacquire the mutex * * exception notowned (mutex m, thread self, mutex_owner owner) * * Raised when a thread attempts to release a mutex not owned by it. */ /* A mutex is either owned by a thread or nobody */ typedef union { thread owner; void nobody; } mutex_owner; public typedef struct { semaphore sem; mutex_owner owner; } mutex_struct; public typedef *mutex_struct mutex; namespace Mutex { public typedef *mutex_struct mutex; public exception deadlock (mutex m, thread self) /* * raised when attempting to lock a mutex locked by self */; public exception notowned (mutex m, thread self, mutex_owner owner) /* * raised when attempting to release a mutex which is not locked */; public bool acquire (mutex m) /* * Lock 'm' */ { if (m->owner == (mutex_owner.owner) Thread::current()) raise deadlock (m, Thread::current ()); Semaphore::wait(m->sem); m->owner = (mutex_owner.owner) Thread::current (); return true; } public bool try_acquire (mutex m) /* * If 'm' is unlocked, acquire (m) and return true * else return false */ { if (m->owner == (mutex_owner.owner) Thread::current()) raise deadlock (m, Thread::current()); bool ret = Semaphore::test (m->sem); if (ret) m->owner = (mutex_owner.owner) Thread::current(); return ret; } public void release (mutex m) /* * Unlock 'm' */ { if (m->owner != (mutex_owner.owner) Thread::current()) raise notowned (m, Thread::current (), m->owner); m->owner = mutex_owner.nobody; Semaphore::signal (m->sem); } public mutex_owner owner (mutex m) /* * Return owner of 'm' */ { return m->owner; } public mutex new () /* * Create new (unlocked) mutex */ { return reference ((mutex_struct) { .sem = Semaphore::new (1), .owner = mutex_owner.nobody }); } } nickle_2.81.orig/gram.y0000664000175000000620000014271313062257641014236 0ustar keithpstaff%{ /* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include /* * This grammar generates 1 shift/reduce conflict and 4 reduce/reduce: * * 2 reduce/reduce conflicts on: * * *int . func * **int . func * * Is the '*' a dereference operator or a pointer type modifier? * The grammar is ordered to make this a type modifier since * the other way is less common. Use parens when you want this. * * 2 reduce/reduce conflicts on: * * &int . func * &&int . func * * Is the '&' a reference operator or a reference type modifier? * The grammar is ordered to make this a type modifier since * the other way is less common. Use parens when you want this. * * shift/reduce conflict in ASSIGN in initializers * * That's because struct initializers look like assignment * expressions while array initializers permit any expression. * Shift yields struct initialization, so the effect is * to make assignment expressions invalid in array initializers. * (Of course, you can always enclose an assignment in parens.) * (I can't see any obvious way to use operator precedence to * get rid of this: seems like you'd need to duplicate simpleexpr * with different precedence. --BCM) * */ int ignorenl; int notCommand; int seeComment; NamespacePtr LexNamespace; int funcDepth; void ParseError (char *fmt, ...); void yyerror (char *msg); typedef enum _CanonTypeResult { CanonTypeUndefined, CanonTypeForward, CanonTypeDefined, } CanonTypeResult; static Expr * ParseCanonFor (Expr *expr); static CanonTypeResult ParseCanonType (TypePtr type, Bool forwardAllowed); static SymbolPtr ParseNewSymbol (Publish publish, Class class, Type *type, Atom name); %} %union { int ints; Value value; Class class; ArgType *argType; Type *type; Publish publish; ExprPtr expr; Atom atom; DeclListPtr declList; MemListPtr memList; Fulltype fulltype; ArgDecl argDecl; SymbolPtr symbol; NamespacePtr namespace; CodePtr code; Bool bool; AtomListPtr atomList; FuncDecl funcDecl; } %type fullname fullnames %type opt_rawnames rawname rawnames rawnamespace %type rawatom %type block opt_func_body func_body func_right catches catch %type statements statement simple_statement %type if_statement try_statement try_body_statement %type block_or_expr %type case_block cases case %type union_case_block union_cases union_case %type fulltype %type namespace %type comprehension compnames compname comparray %type atoms %type initnames typenames %type name opt_name %type func_decl func_name %type typename %type opt_init %type decl next_decl %type opt_type type subscripts subtype %type opt_stars stars dotdotdots %type basetype %type dims %type struct_members union_members %type class opt_class %type opt_publish publish publish_extend %type namespacename %type opt_argdecls argdecls %type argdecl %type opt_argdefines argdefines args %type argdefine %type opt_dotdotdot %type opt_expr for_exprs expr opt_exprs exprs simpleexpr %type opt_actuals actuals %type comma_expr %type assignop %type opt_integer integer %type doc_string opt_comment %type opt_arrayinit arrayinit arrayelts arrayelt %type opt_hashinit hashinit hashelts hashelt hashvalue %type structinit structelts structelt %type init %token VAR EXPR ARRAY STRUCT UNION ENUM COMP HASH %token SEMI MOD OC CC DOLLAR DOTDOTDOT ENDFILE %token GLOBAL AUTO STATIC CONST %token POLY INTEGER NATURAL RATIONAL REAL STRING FOREIGN %token FILET MUTEX SEMAPHORE CONTINUATION THREAD VOID BOOL %token FUNCTION FUNC EXCEPTION RAISE %token TYPEDEF IMPORT NEW ANONINIT %token NAMESPACE %token PUBLIC PROTECTED EXTEND %token WHILE DO FOR SWITCH %token BREAK CONTINUE RETURNTOK FORK CASE DEFAULT %token TWIXT %token NAME TYPENAME NAMESPACENAME COMMAND NAMECOMMAND %token TEN_NUM OCTAL0_NUM OCTAL_NUM BINARY_NUM HEX_NUM %token TEN_FLOAT OCTAL0_FLOAT OCTAL_FLOAT BINARY_FLOAT HEX_FLOAT %token CHAR_CONST STRING_CONST POLY_CONST THREAD_CONST %token COMMENT_CONST %token VOIDVAL BOOLVAL %token DARROW %token ISTYPE HASMEMBER %nonassoc POUND %right COMMA %right ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNTIMES ASSIGNDIVIDE ASSIGNDIV ASSIGNMOD ASSIGNPOW ASSIGNSHIFTL ASSIGNSHIFTR ASSIGNLXOR ASSIGNLAND ASSIGNLOR ASSIGNOR ASSIGNAND %right FORK %right QUEST COLON %left OR %left AND %left LOR %left LXOR %left LAND %left EQ NE %left LT GT LE GE %left SHIFTL SHIFTR %left PLUS MINUS %left TIMES DIVIDE DIV MOD %right POW STARSTAR POW2 POW3 %left UNIONCAST %right UMINUS BANG FACT LNOT INC DEC STAR AMPER THREADID %left OS CS DOT ARROW STAROS CALL OP CP %right POINTER %right COLONCOLON %left IF TRY NONL %left ELSE CATCH NL %% lines : lines pcommand | ; pcommand : command | error reset eend ; eend : NL { yyerrok; } | SEMI { yyerrok; } | ENDFILE { yyerrok; } ; /* * Sprinkled through the grammer to switch the lexer between reporting * and not reporting newlines */ ignorenl : { ignorenl++; } ; attendnl : { if (ignorenl > 0) ignorenl--; } ; reset : { ignorenl = 0; LexNamespace = 0; CurrentNamespace = TopNamespace; funcDepth = 0; notCommand = 0; lastThreadError = True; } ; /* * To make commands only recognized as the first token on a line, * this production precedes every top-level production in the grammar. * As the parser will look one token ahead, this cleverly makes only * the first token on the line match commands */ not_command : { notCommand = 1; } ; opt_nl : NL | %prec NONL ; opt_semi : SEMI | ; opt_comma : COMMA | ; /* * Interpreter command level */ command : not_command expr reset NL { ENTER (); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; e = BuildCall ("Command", "display", 1,NewExprTree (EXPR, $2, 0)); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); EXIT (); } | not_command expr POUND expr reset NL { ENTER (); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; e = BuildCall("Command", "display_base", 2, NewExprTree (EXPR, $2, 0), $4); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); EXIT (); } | not_command statement reset opt_nl { ENTER (); NamespacePtr s; FramePtr f; CodePtr c; Value t; GetNamespace (&s, &f, &c); t = NewThread (f, CompileStat ($2, c)); ThreadsRun (t, 0); EXIT (); } | not_command COMMAND opt_exprs reset opt_semi NL { ENTER(); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; CommandPtr cmd; cmd = CommandFind (CurrentCommands, $2); if (!cmd) ParseError ("Undefined command \"%s\"", AtomName ($2)); else { e = NewExprTree (OP, NewExprConst (POLY_CONST, cmd->func), $3); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); } EXIT (); } | not_command NAMECOMMAND opt_rawnames reset opt_semi NL { ENTER (); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; CommandPtr cmd; cmd = CommandFind (CurrentCommands, $2); if (!cmd) ParseError ("Undefined command \"%s\"", AtomName ($2)); else { e = NewExprTree (OP, NewExprConst (POLY_CONST, cmd->func), $3); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); } EXIT (); } | NL | ENDFILE ; opt_rawnames : rawnames | { $$ = 0; } ; rawnames : rawname COMMA rawnames { $$ = NewExprTree (COMMA, $1, $3); } | rawname { $$ = NewExprTree (COMMA, $1, 0); } ; rawname : rawnamespace rawatom { $$ = BuildRawname ($1, $2); } ; rawatom : NAME | NAMESPACENAME | TYPENAME ; rawnamespace : rawnamespace rawatom COLONCOLON { $$ = NewExprTree (COLONCOLON, $1, NewExprAtom ($2, 0, False)); } | { $$ = 0; } ; fulltype : namespace TYPENAME { $$ = BuildFullname ($1, $2); LexNamespace = 0; } | TYPENAME { $$ = BuildFullname (0, $1); LexNamespace = 0; } ; fullname : namespace namespacename { $$ = BuildFullname ($1, $2); LexNamespace = 0; } | namespacename { $$ = BuildFullname (0, $1); LexNamespace = 0; } ; fullnames : fullname { $$ = $1; } | fullname COMMA fullnames { $$ = NewExprTree (COMMA, $1, $3); } ; namespace : namespace NAMESPACENAME COLONCOLON { ExprPtr e; SymbolPtr symbol; e = BuildFullname ($1, $2); if (e->base.tag == COLONCOLON) symbol = e->tree.right->atom.symbol; else symbol = e->atom.symbol; if (!symbol) { ParseError ("non-existant namespace \"%A\"", $2); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", $2); YYERROR; } LexNamespace = symbol->namespace.namespace; $$ = e; } | NAMESPACENAME COLONCOLON { ExprPtr e; SymbolPtr symbol; e = BuildFullname (0, $1); if (e->base.tag == COLONCOLON) symbol = e->tree.right->atom.symbol; else symbol = e->atom.symbol; if (!symbol) { ParseError ("non-existant namespace \"%A\"", $1); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", $1); YYERROR; } LexNamespace = symbol->namespace.namespace; $$ = e; } ; namespacename : NAME | NAMESPACENAME ; /* * Statements */ namespace_start : { CurrentNamespace = NewNamespace (CurrentNamespace); } ; namespace_end : { CurrentNamespace = CurrentNamespace->previous; } ; block : block_start statements block_end { $$ = $2; } ; block_start : OC namespace_start ; block_end : namespace_end CC ; statements : statement statements { $$ = NewExprTree(OC, $1, $2); } | { $$ = NewExprTree(OC, 0, 0); } ; if_statement : IF ignorenl namespace_start OP expr CP statement %prec IF { $$ = NewExprTree(IF, $5, $7); } | IF ignorenl namespace_start OP expr CP statement ELSE statement { $$ = NewExprTree(ELSE, $5, NewExprTree(ELSE, $7, $9)); } statement: simple_statement | block ; simple_statement: if_statement namespace_end attendnl { $$ = $1; } | WHILE ignorenl namespace_start OP expr CP statement namespace_end attendnl { $$ = NewExprTree(WHILE, $5, $7); } | DO ignorenl namespace_start statement WHILE OP expr CP namespace_end attendnl { $$ = NewExprTree(DO, $4, $7); } | FOR ignorenl namespace_start OP for_exprs CP statement namespace_end attendnl { Expr *expr = ParseCanonFor($5); if (!expr) YYERROR; $$ = NewExprTree(FOR, expr, $7); } | SWITCH ignorenl namespace_start OP expr CP case_block namespace_end attendnl { $$ = NewExprTree (SWITCH, $5, $7); } | union_or_enum SWITCH ignorenl namespace_start OP expr CP union_case_block namespace_end attendnl { $$ = NewExprTree (UNION, $6, $8); } | BREAK SEMI { $$ = NewExprTree(BREAK, (Expr *) 0, (Expr *) 0); } | CONTINUE SEMI { $$ = NewExprTree(CONTINUE, (Expr *) 0, (Expr *) 0); } | RETURNTOK opt_expr SEMI { $$ = NewExprTree (RETURNTOK, (Expr *) 0, $2); } | expr SEMI { $$ = NewExprTree(EXPR, $1, (Expr *) 0); } | SEMI { $$ = NewExprTree(SEMI, (Expr *) 0, (Expr *) 0); } | func_decl doc_string opt_func_body namespace_end { DeclList *decl = $1.decl; SymbolPtr symbol = decl->symbol; Class class = $1.type.class; Publish publish = $1.type.publish; TypePtr type = $1.type.type; TypePtr ret = type->func.ret; ArgType *argType = type->func.args; if (symbol) { if ($3) { symbol->symbol.forward = False; ParseCanonType (ret, False); decl->init = NewExprCode (NewFuncCode (ret, argType, $3, $2), NewExprAtom (symbol->symbol.name, symbol, False)); } else symbol->symbol.forward = True; } $$ = NewExprDecl (FUNC, decl, class, type, publish); } | opt_publish EXCEPTION ignorenl NAME namespace_start opt_argdecls namespace_end doc_string SEMI attendnl { DeclListPtr decl; decl = NewDeclList ($4, 0, 0); decl->symbol = ParseNewSymbol ($1, class_exception, typePoly, $4); decl->symbol->exception.doc = $8; $$ = NewExprDecl (EXCEPTION, decl, class_exception, NewTypeFunc (typePoly, $6), $1); } | RAISE fullname OP opt_exprs CP SEMI { $$ = NewExprTree (RAISE, $2, $4); } | opt_publish TYPEDEF ignorenl typenames SEMI attendnl { DeclListPtr decl; for (decl = $4; decl; decl = decl->next) decl->symbol = ParseNewSymbol ($1, class_typedef, 0, decl->name); $$ = NewExprTree (TYPEDEF, NewExprDecl (TYPEDEF, $4, class_typedef, 0, $1), 0); } | opt_publish TYPEDEF ignorenl type typenames SEMI attendnl { DeclListPtr decl; for (decl = $5; decl; decl = decl->next) decl->symbol = ParseNewSymbol ($1, class_typedef, $4, decl->name); $$ = NewExprTree (TYPEDEF, NewExprDecl (TYPEDEF, $5, class_typedef, $4, $1), 0); } | publish_extend NAMESPACE ignorenl namespacename { SymbolPtr symbol; Publish publish = $1; /* * this is a hack - save the current namespace * on the parser stack to be restored after * the block is compiled. */ $2 = CurrentNamespace; if (publish == publish_extend) { symbol = NamespaceFindName (CurrentNamespace, $4, True); if (!symbol) { ParseError ("non-existant namespace %A", $4); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", $4); YYERROR; } else CurrentNamespace = symbol->namespace.namespace; } else { symbol = ParseNewSymbol ($1, class_namespace, 0, $4); CurrentNamespace = NewNamespace (CurrentNamespace); symbol->namespace.namespace = CurrentNamespace; } /* * Make all of the symbols visible while compiling within * the namespace */ if (CurrentNamespace != $2) CurrentNamespace->publish = publish_public; } OC statements CC attendnl { /* * close the namespace to non-public lookups */ if (CurrentNamespace != $2) CurrentNamespace->publish = publish_private; /* * Restore to the namespace saved on * the parser stack */ CurrentNamespace = $2; $$ = NewExprTree (NAMESPACE, NewExprAtom ($4, 0, False), $7); } | opt_publish IMPORT ignorenl fullnames SEMI attendnl { SymbolPtr symbol; ExprPtr p, e, n; p = $4; for (p = $4; p; p = n) { if (p->base.tag == COMMA) { e = p->tree.left; n = p->tree.right; } else { e = p; n = 0; } if (e->base.tag == COLONCOLON) e = e->tree.right; symbol = e->atom.symbol; if (!symbol) { ParseError ("non-existant namespace %A", e->atom.atom); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", e->atom.atom); YYERROR; } NamespaceImport (CurrentNamespace, symbol->namespace.namespace, $1); } $$ = NewExprTree (IMPORT, $4, NewExprDecl (IMPORT, 0, class_undef, 0, $1)); } | try_statement attendnl { $$ = $1; } | TWIXT ignorenl namespace_start OP opt_expr SEMI opt_expr CP statement namespace_end attendnl { $$ = NewExprTree (TWIXT, NewExprTree (TWIXT, $5, $7), NewExprTree (TWIXT, $9, 0)); } ; for_exprs : opt_expr SEMI for_exprs { $$ = NewExprTree(SEMI, $1, $3); } | opt_expr { $$ = NewExprTree(SEMI, $1, 0); } ; try_body_statement: simple_statement | OC statements CC { $$ = $2; } try_statement: TRY ignorenl try_body_statement catches { $$ = NewExprTree (CATCH, $4, $3); } ; catches : catches catch %prec TRY { $$ = NewExprTree (CATCH, $1, $2); } | { $$ = 0; } ; catch : CATCH fullname namespace_start args doc_string block namespace_end { $$ = NewExprCode (NewFuncCode (typePrim[rep_void], $4, $6, $5), $2); } ; opt_func_body : func_body | SEMI { $$ = 0; } ; func_body : { ++funcDepth; } block_or_expr { --funcDepth; $$ = $2; } ; block_or_expr : block { $$ = $1; } | attendnl ASSIGN simpleexpr SEMI { $$ = NewExprTree (OC, NewExprTree (RETURNTOK, 0, $3), NewExprTree (OC, 0, 0)); } ; union_or_enum : UNION | ENUM ; see_comment : { seeComment = 1; } ; doc_string : see_comment opt_comment { seeComment = 0; $$ = $2; } ; opt_comment : COMMENT_CONST | { $$ = Void; } ; case_block : block_start cases block_end { $$ = $2; } ; cases : case cases { $$ = NewExprTree (CASE, $1, $2); } | { $$ = 0; } ; case : CASE expr COLON statements { $$ = NewExprTree (CASE, $2, $4); } | DEFAULT COLON statements { $$ = NewExprTree (CASE, 0, $3); } ; union_case_block: block_start union_cases block_end { $$ = $2; } ; union_cases : union_case union_cases { $$ = NewExprTree (CASE, $1, $2); } | { $$ = 0; } ; union_case : CASE namespace_start NAME opt_name COLON statements namespace_end { SymbolPtr sym = $4; Atom sym_atom = sym ? sym->symbol.name : 0; ExprPtr name = 0; if (sym) name = NewExprAtom (sym_atom, sym, False); $$ = NewExprTree (CASE, NewExprTree (CASE, NewExprAtom ($3, 0, False), name), $6); } | DEFAULT COLON statements { $$ = NewExprTree (CASE, 0, $3); } ; opt_name : NAME { $$ = ParseNewSymbol (publish_private, class_undef, typePoly, $1); } | { $$ = 0; } ; /* * Identifiers */ atoms : NAME COMMA atoms { $$ = NewAtomList ($3, $1); } | NAME { $$ = NewAtomList (0, $1); } ; typenames : typename COMMA typenames { $$ = NewDeclList ($1, 0, $3); } | typename { $$ = NewDeclList ($1, 0, 0); } ; typename : TYPENAME | NAME ; /* * Ok, a few cute hacks to fetch the fulltype from the * value stack -- initnames always immediately follows a decl, * so $0 will be a fulltype. Note the cute trick to store the * type across the comma operator -- this means that name * will always find the fulltype at $0 as well */ initnames : name opt_init next_decl initnames { if ($1) { $$ = NewDeclList ($1->symbol.name, $2, $4); $$->symbol = $1; } else $$ = $4; } | name opt_init { if ($1) { $$ = NewDeclList ($1->symbol.name, $2, 0); $$->symbol = $1; } else $1 = 0; } ; name : NAME { $$ = ParseNewSymbol ($0.publish, $0.class, $0.type, $1); } ; /* * next_decl -- look backwards three entries on the stack to * find the previous type */ next_decl : COMMA { $$ = $-2; } ; /* * Declaration of a function */ func_decl : func_name namespace_start opt_argdefines CP { NamespacePtr save = CurrentNamespace; SymbolPtr symbol; Type *type = NewTypeFunc ($1.type.type, $3); /* * namespace_start pushed a new namespace, make sure * this symbol is placed in the original namespace */ CurrentNamespace = save->previous; symbol = NamespaceFindName (CurrentNamespace, $1.decl->name, True); if (symbol && symbol->symbol.forward) { if (!TypeIsSupertype (symbol->symbol.type, type)) { ParseError ("%A redefinition with different type", $1.decl->name); symbol = 0; } } else { symbol = ParseNewSymbol ($1.type.publish, $1.type.class, type, $1.decl->name); } CurrentNamespace = save; $$ = $1; $$.decl->symbol = symbol; $$.type.type = type; } ; func_name : decl NAME OP { $$.type = $1; $$.decl = NewDeclList ($2, 0, 0); } | decl FUNCTION NAME OP { $$.type = $1; $$.decl = NewDeclList ($3, 0, 0); } | FUNCTION ignorenl NAME OP { $$.type.publish = publish_private; $$.type.class = class_undef; $$.type.type = typePoly; $$.decl = NewDeclList ($3, 0, 0); } ; opt_init : ASSIGN simpleexpr { $$ = $2; } | ASSIGN init { $$ = $2; } | { $$ = 0; } ; /* * Full declaration including storage, type and publication */ decl : publish opt_class opt_type opt_nl { $$.publish = $1; $$.class = $2; $$.type = $3; } | class opt_type opt_nl { $$.publish = publish_private; $$.class = $1; $$.type = $2; } | type opt_nl { $$.publish = publish_private; $$.class = class_undef; $$.type = $1; } ; /* * Type declarations */ subscripts : opt_argdecls subscripts %prec CALL { $$ = NewTypeFunc ($2, $1); } | OS opt_stars CS subscripts { $$ = NewTypeArray ($4, $2, False); } | OS dotdotdots CS subscripts { $$ = NewTypeArray ($4, $2, True); } | OS dims CS subscripts { $$ = NewTypeArray ($4, $2, False); } | OS type CS subscripts { $$ = NewTypeHash ($4, $2); } | { $$ = 0; } ; type : subtype subscripts %prec CALL { Type *top = $2; Type *t, **bot = ⊤ /* * Walk down the type chain to hang the * base type off of the end. This * makes int[]() be an array of functions * rather than a function returning an array */ while ((t = *bot)) switch (t->base.tag) { case type_array: bot = &t->array.type; break; case type_hash: bot = &t->hash.type; break; case type_func: bot = &t->func.ret; break; default: assert(0); } *bot = $1; $$ = top; } | TIMES type %prec POINTER { $$ = NewTypeRef ($2, True); } | STARSTAR type %prec POINTER { $$ = NewTypeRef (NewTypeRef ($2, True), True); } | AND type %prec POINTER { $$ = NewTypeRef (NewTypeRef ($2, False), False); } | LAND type %prec POINTER { $$ = NewTypeRef ($2, False); } | type PLUS type { if (ParseCanonType ($1, False) != CanonTypeDefined) YYERROR; if (ParseCanonType ($3, False) != CanonTypeDefined) YYERROR; $$ = NewTypePlus ($1, $3); if (!$$) YYERROR; } ; subtype : basetype | STRUCT OC struct_members CC { AtomListPtr al; StructType *st; MemListPtr ml; int nelements; nelements = 0; for (ml = $3; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) nelements++; } st = NewStructType (nelements); nelements = 0; for (ml = $3; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) { AddBoxType (&st->types, ml->type); StructTypeAtoms(st)[nelements] = al->atom; nelements++; } } $$ = NewTypeStruct (st); } | UNION OC union_members CC { AtomListPtr al; StructType *st; MemListPtr ml; int nelements; nelements = 0; for (ml = $3; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) nelements++; } st = NewStructType (nelements); nelements = 0; for (ml = $3; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) { AddBoxType (&st->types, ml->type); StructTypeAtoms(st)[nelements] = al->atom; nelements++; } } $$ = NewTypeUnion (st, False); } | ENUM OC atoms CC { AtomListPtr al; StructType *st; int nelements; nelements = 0; for (al = $3; al; al = al->next) nelements++; st = NewStructType (nelements); nelements = 0; for (al = $3; al; al = al->next) { AddBoxType (&st->types, typePrim[rep_void]); StructTypeAtoms(st)[nelements] = al->atom; nelements++; } $$ = NewTypeUnion (st, True); } | OP type CP { $$ = $2; } | fulltype { $$ = NewTypeName ($1, 0); } ; opt_type : type | { $$ = typePoly; } ; basetype : POLY | INTEGER | RATIONAL | REAL | STRING | FILET | MUTEX | SEMAPHORE | CONTINUATION | THREAD | VOID | BOOL | FOREIGN ; opt_stars : stars | { $$ = 0; } ; stars : stars COMMA TIMES { $$ = NewExprTree (COMMA, 0, $1); } | TIMES { $$ = NewExprTree (COMMA, 0, 0); } ; dotdotdots : dotdotdots COMMA DOTDOTDOT { $$ = NewExprTree (COMMA, 0, $1); } | DOTDOTDOT { $$ = NewExprTree (COMMA, 0, 0); } ; dims : simpleexpr COMMA dims { $$ = NewExprTree (COMMA, $1, $3); } | simpleexpr { $$ = NewExprTree (COMMA, $1, 0); } ; /* * Structure member declarations */ struct_members : opt_type atoms SEMI struct_members { $$ = NewMemList ($2, $1, $4); } | { $$ = 0; } ; union_members : opt_type atoms SEMI union_members { $$ = NewMemList ($2, $1, $4); } | { $$ = 0; } ; /* * Declaration modifiers */ opt_class : class | { $$ = class_undef; } ; class : GLOBAL | AUTO | STATIC | CONST ; opt_publish : publish | { $$ = publish_private; } ; publish : PUBLIC | PROTECTED ; publish_extend : opt_publish | EXTEND ; /* * Arguments in function declarations */ opt_argdecls : OP argdecls CP { $$ = $2; } | OP CP { $$ = 0; } ; argdecls : argdecl COMMA argdecls { $$ = NewArgType ($1.type, False, $1.name, 0, $3); } | argdecl opt_dotdotdot { $$ = NewArgType ($1.type, $2, $1.name, 0, 0); } ; argdecl : type NAME { ParseCanonType ($1, False); $$.type = $1; $$.name = $2; } | type { ParseCanonType ($1, False); $$.type = $1; $$.name = 0; } ; /* * Arguments in function definitions */ args : OP opt_argdefines CP { $$ = $2; } ; opt_argdefines : ignorenl argdefines { ArgType *args; Type *type; for (args = $2; args; args = args->next) { type = args->type; if (ParseCanonType (type, False) != CanonTypeDefined) break; if (args->varargs) { type = NewTypeArray (type, NewExprTree (COMMA, NewExprConst (TEN_NUM, NewInt (0)), 0), False); } args->symbol = ParseNewSymbol (publish_private, class_arg, type, args->name); } $$ = $2; } | ignorenl { $$ = 0; } ; argdefines : argdefine COMMA argdefines { $$ = NewArgType ($1.type, False, $1.name, 0, $3); } | argdefine opt_dotdotdot { $$ = NewArgType ($1.type, $2, $1.name, 0, 0); } ; argdefine : opt_type NAME { $$.type = $1; $$.name = $2; } | type { $$.type = $1; $$.name = 0; } ; opt_dotdotdot : DOTDOTDOT { $$ = True; } | { $$ = False; } ; /* * Expressions, top level includes comma operator and declarations */ opt_expr : expr | { $$ = 0; } ; expr : comma_expr | decl initnames { DeclList *decl; for (decl = $2; decl; decl = decl->next) { if (decl->init) { if (!decl->init->base.type) decl->init->base.type = $1.type; } } $$ = NewExprDecl (VAR, $2, $1.class, $1.type, $1.publish); } ; comma_expr : simpleexpr | comma_expr COMMA simpleexpr { $$ = NewExprTree(COMMA, $1, $3); } ; /* * Expression list, different use of commas for function arguments et al. */ opt_exprs : exprs | { $$ = 0; } ; exprs : simpleexpr COMMA exprs { $$ = NewExprTree (COMMA, $1, $3); } | simpleexpr { $$ = NewExprTree (COMMA, $1, 0); } ; opt_actuals : actuals | { $$ = 0; } ; actuals : simpleexpr COMMA actuals { $$ = NewExprTree (COMMA, $1, $3); } | simpleexpr opt_dotdotdot { ExprPtr arg = $2 ? NewExprTree (DOTDOTDOT, $1, 0) : $1; $$ = NewExprTree (COMMA, arg, 0); } ; func_right : attendnl ASSIGN simpleexpr { $$ = NewExprTree (OC, NewExprTree (RETURNTOK, 0, $3), NewExprTree (OC, 0, 0)); } | { ++funcDepth; } block { --funcDepth; $$ = $2; } ; /* * Fundemental expression production */ simpleexpr : simpleexpr assignop simpleexpr %prec ASSIGN { if ($2 == ASSIGNPOW) $$ = NewExprTree (ASSIGNPOW, BuildName ("Math", "assign_pow"), NewExprTree (ASSIGNPOW, $1, $3)); else { ExprPtr left = $1; /* * Automatically declare names used in * simple assignements at the top level */ if ($2 == ASSIGN && funcDepth == 0 && left->base.tag == NAME && !(left->atom.symbol)) { $1->atom.symbol = ParseNewSymbol (publish_private, class_undef, typePoly, $1->atom.atom); } $$ = NewExprTree($2, $1, $3); } } | opt_type FUNC namespace_start args doc_string func_right namespace_end %prec ASSIGN { ParseCanonType ($1, False); $$ = NewExprCode (NewFuncCode ($1, $4, $6, $5), 0); } | MOD integer %prec THREADID { Value t; t = do_Thread_id_to_thread ($2); if (t == Void) { ParseError ("No thread %v", $2); YYERROR; } else $$ = NewExprConst(THREAD_CONST, t); } | TIMES simpleexpr %prec STAR { $$ = NewExprTree(STAR, $2, (Expr *) 0); } | STARSTAR simpleexpr %prec STAR { $$ = NewExprTree(STAR, NewExprTree (STAR, $2, 0), 0); } | LAND simpleexpr %prec AMPER { $$ = NewExprTree(AMPER, $2, (Expr *) 0); } | AND simpleexpr %prec AMPER { $$ = NewExprTree(AMPER, NewExprTree (AMPER, $2, (Expr *) 0), (Expr *) 0); } | MINUS simpleexpr %prec UMINUS { $$ = NewExprTree(UMINUS, $2, (Expr *) 0); } | LNOT simpleexpr { $$ = NewExprTree(LNOT, $2, (Expr *) 0); } | BANG simpleexpr { $$ = NewExprTree(BANG, $2, (Expr *) 0); } | simpleexpr BANG %prec FACT { $$ = NewExprTree(FACT, BuildName ("Math", "factorial"), $1); } | INC simpleexpr { $$ = NewExprTree(INC, $2, (Expr *) 0); } | simpleexpr INC { $$ = NewExprTree(INC, (Expr *) 0, $1); } | DEC simpleexpr { $$ = NewExprTree(DEC, $2, (Expr *) 0); } | simpleexpr DEC { $$ = NewExprTree(DEC, (Expr *) 0, $1); } | FORK simpleexpr { $$ = NewExprTree (FORK, (Expr *) 0, $2); } | simpleexpr PLUS simpleexpr { $$ = NewExprTree(PLUS, $1, $3); } | simpleexpr MINUS simpleexpr { $$ = NewExprTree(MINUS, $1, $3); } | simpleexpr TIMES simpleexpr { $$ = NewExprTree(TIMES, $1, $3); } | simpleexpr DIVIDE simpleexpr { $$ = NewExprTree(DIVIDE, $1, $3); } | simpleexpr DIV simpleexpr { $$ = NewExprTree(DIV, $1, $3); } | simpleexpr MOD simpleexpr { $$ = NewExprTree(MOD, $1, $3); } | simpleexpr STARSTAR simpleexpr %prec POW { $$ = NewExprTree(POW, BuildName ("Math", "pow"), NewExprTree (POW, $1, $3)); } | simpleexpr POW2 { $$ = NewExprTree (POW, BuildName("Math", "pow"), NewExprTree (POW, $1, NewExprConst (TEN_NUM, NewInt(2)))); } | simpleexpr POW3 { $$ = NewExprTree (POW, BuildName("Math", "pow"), NewExprTree (POW, $1, NewExprConst (TEN_NUM, NewInt(3)))); } | simpleexpr SHIFTL simpleexpr { $$ = NewExprTree(SHIFTL, $1, $3); } | simpleexpr SHIFTR simpleexpr { $$ = NewExprTree(SHIFTR, $1, $3); } | simpleexpr QUEST simpleexpr COLON simpleexpr { $$ = NewExprTree(QUEST, $1, NewExprTree(COLON, $3, $5)); } | simpleexpr LXOR simpleexpr { $$ = NewExprTree(LXOR, $1, $3); } | simpleexpr LAND simpleexpr { $$ = NewExprTree(LAND, $1, $3); } | simpleexpr LOR simpleexpr { $$ = NewExprTree(LOR, $1, $3); } | simpleexpr AND simpleexpr { $$ = NewExprTree(AND, $1, $3); } | simpleexpr OR simpleexpr { $$ = NewExprTree(OR, $1, $3); } | simpleexpr EQ simpleexpr { $$ = NewExprTree(EQ, $1, $3); } | simpleexpr NE simpleexpr { $$ = NewExprTree(NE, $1, $3); } | simpleexpr LT simpleexpr { $$ = NewExprTree(LT, $1, $3); } | simpleexpr GT simpleexpr { $$ = NewExprTree(GT, $1, $3); } | simpleexpr LE simpleexpr { $$ = NewExprTree(LE, $1, $3); } | simpleexpr GE simpleexpr { $$ = NewExprTree(GE, $1, $3); } | fullname | TEN_NUM { $$ = NewExprConst(TEN_NUM, $1); } | OCTAL_NUM { $$ = NewExprConst(OCTAL_NUM, $1); } | OCTAL0_NUM { $$ = NewExprConst(OCTAL0_NUM, $1); } | BINARY_NUM { $$ = NewExprConst(BINARY_NUM, $1); } | HEX_NUM { $$ = NewExprConst(HEX_NUM, $1); } | TEN_FLOAT { $$ = NewExprConst(TEN_FLOAT, $1); } | OCTAL_FLOAT { $$ = NewExprConst(OCTAL_FLOAT, $1); } | OCTAL0_FLOAT { $$ = NewExprConst(OCTAL0_FLOAT, $1); } | BINARY_FLOAT { $$ = NewExprConst(BINARY_FLOAT, $1); } | HEX_FLOAT { $$ = NewExprConst(HEX_FLOAT, $1); } | CHAR_CONST { $$ = NewExprConst(CHAR_CONST, $1); } | STRING_CONST { $$ = NewExprConst(STRING_CONST, $1); } | VOIDVAL { $$ = NewExprConst(VOIDVAL, $1); } | BOOLVAL { $$ = NewExprConst(BOOLVAL, $1); } | OS CS { $$ = BuildFullname (0, AtomId ("[]")); } | OP type CP namespace_start init namespace_end { ParseCanonType ($2, False); if ($5) $5->base.type = $2; $$ = NewExprTree (NEW, $5, 0); $$->base.type = $2; } | OP OS stars CS CP namespace_start arrayinit namespace_end { $7->base.type = NewTypeArray (typePoly, $3, True); ParseCanonType ($7->base.type, False); $$ = NewExprTree (NEW, $7, 0); $$->base.type = $7->base.type; } | OP OS dims CS CP namespace_start opt_arrayinit namespace_end { TypePtr t = NewTypeArray (typePoly, $3, False); ParseCanonType (t, False); $$ = NewExprTree (NEW, $7, 0); if ($7) $7->base.type = t; $$->base.type = t; } | OP OS type CS CP namespace_start opt_hashinit namespace_end { TypePtr t = NewTypeHash (typePoly, $3); ParseCanonType (t, False); $$ = NewExprTree (NEW, $7, 0); if ($7) $7->base.type = t; $$->base.type = t; } | type DOT NAME %prec UNIONCAST { ParseCanonType ($1, False); $$ = NewExprTree (UNION, NewExprAtom ($3, 0, False), 0); $$->base.type = $1; } | OP type DOT NAME CP simpleexpr %prec UNIONCAST { ParseCanonType ($2, False); $$ = NewExprTree (UNION, NewExprAtom ($4, 0, False), $6); $$->base.type = $2; } | DOLLAR opt_integer { $$ = BuildCall ("History", "fetch", 1, NewExprConst (TEN_NUM, $2)); } | DOT { $$ = NewExprTree (DOLLAR, 0, 0); } | OP expr CP { $$ = $2; } | OP block CP { $$ = $2; } | simpleexpr STAROS dims CS { $$ = NewExprTree (OS, NewExprTree (STAR, $1, (Expr *) 0), $3); } | simpleexpr OS dims CS { $$ = NewExprTree(OS, $1, $3); } | simpleexpr OP opt_actuals CP %prec CALL { $$ = NewExprTree (OP, $1, $3); } | ISTYPE OP simpleexpr COMMA type CP %prec CALL { TypePtr type = $5; ParseCanonType (type, False); $$ = NewExprType (ISTYPE, $3, type); } | HASMEMBER OP simpleexpr COMMA NAME CP %prec CALL { $$ = NewExprTree (HASMEMBER, $3, NewExprAtom($5, 0, False)); } | simpleexpr DOT NAME { $$ = NewExprTree(DOT, $1, NewExprAtom ($3, 0, False)); } | simpleexpr ARROW NAME { $$ = NewExprTree(ARROW, $1, NewExprAtom ($3, 0, False)); } ; opt_integer : integer | { $$ = Zero; } assignop : ASSIGNPLUS | ASSIGNMINUS | ASSIGNTIMES | ASSIGNDIVIDE | ASSIGNDIV | ASSIGNMOD | ASSIGNPOW | ASSIGNSHIFTL | ASSIGNSHIFTR | ASSIGNLXOR | ASSIGNLAND | ASSIGNLOR | ASSIGNOR | ASSIGNAND | ASSIGN ; integer : TEN_NUM | OCTAL_NUM | OCTAL0_NUM | BINARY_NUM | HEX_NUM ; /* * Array initializers */ opt_arrayinit : arrayinit | OC CC { $$ = 0; } | { $$ = 0; } ; arrayinit : OC arrayelts opt_comma opt_dotdotdot CC { ExprPtr elts = $2 ? ExprRehang ($2, 0) : 0; if ($4) { ExprPtr i = elts; while (i->tree.right) i = i->tree.right; i->tree.right = NewExprTree (COMMA, NewExprTree (DOTDOTDOT, 0, 0), 0); } $$ = NewExprTree (ARRAY, elts, 0); } | OC OS namespace_start compnames comparray CS comprehension namespace_end CC { $$ = NewExprTree (COMP, NewExprTree (COMP, $4, $5), $7); } ; comprehension : ASSIGN arrayelt { $$ = $2; } | block ; compnames : compname COMMA compnames { $$ = NewExprTree (COMMA, $1, $3); } | compname ; compname : NAME { SymbolPtr s; s = ParseNewSymbol (publish_private, class_arg, typePrim[rep_integer], $1); $$ = NewExprAtom ($1, s, False); } ; comparray : { SymbolPtr s; Atom a = AtomId("[]"); s = ParseNewSymbol (publish_private, class_undef, typePoly, a); $$ = NewExprAtom (a, s, False); } ; arrayelts : arrayelts COMMA arrayelt { $$ = NewExprTree (COMMA, $1, $3); } | arrayelt { $$ = NewExprTree (COMMA, 0, $1); } ; arrayelt : simpleexpr | init ; /* * Hash initializers */ opt_hashinit : hashinit | OC CC { $$ = 0; } | { $$ = 0; } ; hashinit : OC hashelts opt_comma CC { ExprPtr elts = $2 ? ExprRehang ($2, 0) : 0; $$ = NewExprTree (HASH, elts, 0); } ; hashelts : hashelts COMMA hashelt { $$ = NewExprTree (COMMA, $1, $3); } | hashelt { $$ = NewExprTree (COMMA, 0, $1); } ; hashelt : simpleexpr DARROW hashvalue { $$ = NewExprTree (DARROW, $1, $3); } | DARROW hashvalue { $$ = NewExprTree (DARROW, 0, $2); } ; hashvalue : simpleexpr | init ; /* * Structure initializers */ structinit : OC structelts opt_comma CC { $$ = NewExprTree (STRUCT, ExprRehang ($2, 0), 0); } ; structelts : structelts COMMA structelt { $$ = NewExprTree (COMMA, $1, $3); } | structelt { $$ = NewExprTree (COMMA, 0, $1); } ; structelt : NAME ASSIGN simpleexpr { $$ = NewExprTree (ASSIGN, NewExprAtom ($1, 0, False), $3); } | NAME ASSIGN init { $$ = NewExprTree (ASSIGN, NewExprAtom ($1, 0, False), $3); } | DOT NAME ASSIGN simpleexpr { $$ = NewExprTree (ASSIGN, NewExprAtom ($2, 0, False), $4); } | DOT NAME ASSIGN init { $$ = NewExprTree (ASSIGN, NewExprAtom ($2, 0, False), $4); } ; init : arrayinit | structinit | hashinit | OC CC { $$ = NewExprTree (ANONINIT, 0, 0); } ; %% static void DeclListMark (void *object) { DeclListPtr dl = object; MemReference (dl->next); MemReference (dl->init); } DataType DeclListType = { DeclListMark, 0, "DeclListType" }; DeclListPtr NewDeclList (Atom name, ExprPtr init, DeclListPtr next) { ENTER (); DeclListPtr dl; dl = ALLOCATE (&DeclListType, sizeof (DeclList)); dl->next = next; dl->name = name; dl->symbol = 0; dl->init = init; RETURN (dl); } static void MemListMark (void *object) { MemListPtr ml = object; MemReference (ml->next); MemReference (ml->type); MemReference (ml->atoms); } DataType MemListType = { MemListMark, 0, "MemListType" }; MemListPtr NewMemList (AtomListPtr atoms, Type *type, MemListPtr next) { ENTER (); MemListPtr ml; ml = ALLOCATE (&MemListType, sizeof (MemList)); ml->next = next; ml->type = type; ml->atoms = atoms; RETURN (ml); } extern NamespacePtr CurrentNamespace; FramePtr CurrentFrame; Value lookupVar (char *ns, char *n) { ENTER (); Value v; SymbolPtr symbol; NamespacePtr namespace; Bool search; search = True; namespace = CurrentNamespace; if (ns) { symbol = NamespaceFindName (CurrentNamespace, AtomId (ns), True); if (symbol && symbol->symbol.class == class_namespace) namespace = symbol->namespace.namespace; else namespace = 0; } if (namespace) symbol = NamespaceFindName (namespace, AtomId (n), search); else symbol = 0; if (symbol && symbol->symbol.class == class_global) v = BoxValue (symbol->global.value, 0); else v = Void; RETURN (v); } void setVar (NamespacePtr namespace, char *n, Value v, Type *type) { ENTER (); Atom atom; SymbolPtr symbol; atom = AtomId (n); symbol = NamespaceFindName (namespace, atom, True); if (!symbol) symbol = NamespaceAddName (namespace, NewSymbolGlobal (atom, type), publish_private); if (symbol->symbol.class == class_global) BoxValueSet (symbol->global.value, 0, v); EXIT (); } void GetNamespace (NamespacePtr *scope, FramePtr *fp, CodePtr *cp) { *scope = CurrentNamespace; *fp = CurrentFrame; if (CurrentFrame) *cp = CurrentFrame->function->func.code; else *cp = 0; } ExprPtr BuildName (char *ns, char *n) { ENTER (); SymbolPtr symbol, ns_symbol = 0; Atom atom, ns_atom = 0; Bool search = True; NamespacePtr namespace = CurrentNamespace; ExprPtr e; Bool ns_privateFound = False; Bool privateFound = False; if (ns) { ns_atom = AtomId (ns); ns_symbol = NamespaceFindName (namespace, ns_atom, search); if (ns_symbol && ns_symbol->symbol.class == class_namespace) namespace = ns_symbol->namespace.namespace; else { if (!ns_symbol) ns_privateFound = NamespaceIsNamePrivate (namespace, ns_atom, search); namespace = 0; } search = False; } atom = AtomId (n); if (namespace) { symbol = NamespaceFindName (namespace, atom, search); if (!symbol) privateFound = NamespaceIsNamePrivate (namespace, atom, search); } else symbol = 0; e = NewExprAtom (atom, symbol, privateFound); if (ns_atom) e = NewExprTree (COLONCOLON, NewExprAtom (ns_atom, ns_symbol, ns_privateFound), e); RETURN (e); } static Value AtomString (Atom id) { ENTER (); RETURN (NewStrString (AtomName (id))); } ExprPtr BuildRawname (ExprPtr colonnames, Atom name) { ENTER (); int len; Value array; ExprPtr e; len = 1; for (e = colonnames; e; e = e->tree.left) len++; array = NewArray (False, False, typePrim[rep_string], 1, &len); len--; ArrayValueSet (&array->array, len, AtomString (name)); e = colonnames; while (--len >= 0) { ArrayValueSet (&array->array, len, AtomString (e->tree.right->atom.atom)); e = e->tree.left; } e = NewExprConst (POLY_CONST, array); RETURN (e); } ExprPtr BuildFullname (ExprPtr left, Atom atom) { ENTER (); NamespacePtr namespace; SymbolPtr symbol; Bool search; ExprPtr nameExpr; Bool privateFound = False; if (left) { if (left->base.tag == COLONCOLON) symbol = left->tree.right->atom.symbol; else symbol = left->atom.symbol; if (symbol && symbol->symbol.class == class_namespace) namespace = symbol->namespace.namespace; else namespace = 0; search = False; } else { namespace = CurrentNamespace; search = True; } if (namespace) { symbol = NamespaceFindName (namespace, atom, search); if (!symbol) privateFound = NamespaceIsNamePrivate (namespace, atom, search); } else symbol = 0; nameExpr = NewExprAtom (atom, symbol, privateFound); if (left) nameExpr = NewExprTree (COLONCOLON, left, nameExpr); RETURN (nameExpr); } ExprPtr BuildCall (char *scope, char *name, int nargs, ...) { ENTER (); va_list alist; ExprPtr args, *prev; ExprPtr f; ExprPtr e; va_start (alist, nargs); prev = &args; args = 0; while (nargs--) { *prev = NewExprTree (COMMA, va_arg (alist, ExprPtr), 0); prev = &(*prev)->tree.right; } va_end (alist); f = BuildName (scope, name); e = NewExprTree (OP, f, args); #ifdef DEBUG printExpr (stdout, e, -1, 0); printf ("\n"); #endif RETURN (e); } /* * Walk for() loop arguments and normalize the list */ static Expr * ParseCanonFor (Expr *expr) { if (!expr || !expr->tree.right) { ParseError ("Too few exprs in for()\n"); return 0; } if (!expr->tree.right->tree.right) { /* 2-argument for() */ expr = NewExprTree(FOR, 0, expr); } if (expr->tree.right->tree.right->tree.right) { ParseError ("Too many exprs in for()\n"); return 0; } return expr; } /* * Walk a type structure and resolve any type names */ static CanonTypeResult ParseCanonType (TypePtr type, Bool forwardAllowed) { ArgType *arg; int n; CanonTypeResult ret = CanonTypeDefined, t; Bool anyResolved; if (!type) { ParseError ("Type missing inside compiler"); return False; } switch (type->base.tag) { case type_prim: break; case type_name: if (!TypeNameType(type)) { if (!type->name.name) { ExprPtr e; e = type->name.expr; if (e->base.tag == COLONCOLON) e = e->tree.right; type->name.name = e->atom.symbol; if (!type->name.name) { ParseError ("No typedef \"%A\" in namespace", e->atom.atom); ret = CanonTypeUndefined; break; } } if (type->name.name->symbol.class != class_typedef) { ParseError ("Symbol \"%A\" not a typedef", type->name.name->symbol.name); ret = CanonTypeUndefined; } else if (!TypeNameType(type)) { if (!forwardAllowed) ParseError ("Typedef \"%A\" not defined yet", type->name.name->symbol.name); ret = CanonTypeForward; } else { ret = ParseCanonType (TypeNameType(type), forwardAllowed); } } break; case type_ref: ret = ParseCanonType (type->ref.ref, True); if (ret == CanonTypeForward) ret = CanonTypeDefined; break; case type_func: if (type->func.ret) ret = ParseCanonType (type->func.ret, forwardAllowed); for (arg = type->func.args; arg; arg = arg->next) { t = ParseCanonType (arg->type, forwardAllowed); if (t < ret) ret = t; } break; case type_array: ret = ParseCanonType (type->array.type, forwardAllowed); break; case type_hash: ret = ParseCanonType (type->hash.type, forwardAllowed); t = ParseCanonType (type->hash.keyType, forwardAllowed); if (t < ret) ret = t; break; case type_struct: for (n = 0; n < type->structs.structs->nelements; n++) { StructType *st = type->structs.structs; t = ParseCanonType (BoxTypesElements(st->types)[n], forwardAllowed); if (t < ret) ret = t; } break; case type_union: anyResolved = False; for (n = 0; n < type->structs.structs->nelements; n++) { StructType *st = type->structs.structs; t = ParseCanonType (BoxTypesElements(st->types)[n], True); if (t < ret) ret = t; if (t == CanonTypeDefined) anyResolved = True; } if (ret == CanonTypeForward) { if (anyResolved) ret = CanonTypeDefined; else if (!forwardAllowed) ParseError ("No member of '%T' defined yet", type); } break; case type_types: break; } return ret; } static SymbolPtr ParseNewSymbol (Publish publish, Class class, Type *type, Atom name) { ENTER (); SymbolPtr s = 0; if (class == class_undef) class = funcDepth ? class_auto : class_global; if (class == class_namespace || (class == class_typedef && type == 0) || ParseCanonType (type, False) == CanonTypeDefined) { switch (class) { case class_const: s = NewSymbolConst (name, type); break; case class_global: s = NewSymbolGlobal (name, type); break; case class_static: s = NewSymbolStatic (name, type); break; case class_arg: s = NewSymbolArg (name, type); break; case class_auto: s = NewSymbolAuto (name, type); break; case class_exception: s = NewSymbolException (name, type, Void); break; case class_typedef: /* * Special case for typedefs -- * allow forward declaration of untyped * typedef names, then hook the * new type to the old name */ if (type) { s = NamespaceFindName (CurrentNamespace, name, False); if (s && s->symbol.class == class_typedef && !s->symbol.type) { s->symbol.type = type; RETURN (s); } } s = NewSymbolType (name, type); break; case class_namespace: s = NewSymbolNamespace (name, NewNamespace (CurrentNamespace)); break; case class_undef: break; } if (s) NamespaceAddName (CurrentNamespace, s, publish); } RETURN (s); } int yywrap (void) { if (LexInteractive()) printf ("\n"); if (CurrentFrame) { do_Debug_done (); return 0; } return 1; } extern char *yytext; void ParseError (char *fmt, ...) { va_list args; if (LexFileName ()) FilePrintf (FileStderr, "%A:%d: ", LexFileName (), LexFileLine ()); va_start (args, fmt); FileVPrintf (FileStderr, fmt, args); FilePrintf (FileStderr, "\n"); va_end (args); } void yyerror (char *msg) { ignorenl = 0; ParseError ("%s before %S", msg, yytext); } nickle_2.81.orig/COPYING0000664000175000000620000000245210414112462014131 0ustar keithpstaffCopyright © 1988-2004 Keith Packard and Bart Massey. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the names of the authors or their institutions shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. nickle_2.81.orig/main.c0000664000175000000620000001060611711436650014177 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * main.c * * main routine for nick */ #include "nickle.h" #include "gram.h" #include #define __USE_UNIX98 /* Get sigignore() and sigrelse() prototype for Linux */ #include #include #if HAVE_SYS_TIME_H #include #endif #if HAVE_SYS_RESOURCE_H #include #endif #if HAVE_LIBREADLINE #include #endif int stdin_interactive; static void setArgv (int argc, char **argv) { ENTER (); Value args; int i; args = NewArray (True, True, typePrim[rep_string], 1, &argc); for (i = 0; i < argc; i++) ArrayValueSet (&args->array, i, NewStrString (argv[i])); setVar (GlobalNamespace, "argv", args, NewTypeArray (typePrim[rep_string], NewExprTree (COMMA, 0, 0), False)); EXIT (); } static Bool try_nicklestart (void) { char *nicklestart; if ((nicklestart = getenv ("NICKLESTART")) == 0) nicklestart = NICKLELIBDIR "/builtin.5c"; return LexFile (nicklestart, True, False); } void intr(int), ferr(int); void stop (int), die (int), segv (int); static void ignoreSignal(int sig) { catchSignal (sig, SIG_IGN); } static void releaseSignal(int sig) { catchSignal (sig, SIG_DFL); } /*ARGSUSED*/ int main (int argc, char **argv) { #if HAVE_GETRLIMIT && HAVE_SETRLIMIT /* * Allow stack to grow as large as possible to avoid * crashes during recursive datastructure marking in the * garbage collector */ struct rlimit lim; if (getrlimit (RLIMIT_STACK, &lim) == 0) { lim.rlim_cur = lim.rlim_max; (void) setrlimit (RLIMIT_STACK, &lim); } #endif (void) catchSignal (SIGHUP, die); (void) catchSignal (SIGINT, intr); (void) catchSignal (SIGQUIT, die); (void) catchSignal (SIGILL, die); (void) catchSignal (SIGABRT, die); (void) catchSignal (SIGSEGV, segv); (void) ignoreSignal (SIGPIPE); (void) catchSignal (SIGTERM, die); (void) catchSignal (SIGTSTP, stop); (void) catchSignal (SIGTTIN, stop); (void) catchSignal (SIGTTOU, stop); stdin_interactive = isatty(0); init (); setArgv (argc - 1, argv + 1); if (!try_nicklestart()) { fprintf(stderr, "nickle: NICKLESTART environment var points at bad code\n"); exit(1); } (void) yyparse (); /* Wait for any running threads to execute */ ThreadsRun (0, 0); IoFini (); FileFini (); return lastThreadError; } void init (void) { MemInitialize (); TypeInit (); ValueInit (); IoInit (); LexInit (); NamespaceInit (); SymbolInit (); BuiltinInit (); ThreadInit (); TimerInit (); } void catchSignal (int sig, void (*func) (int sig)) { #ifdef HAVE_SIGACTION struct sigaction sa; memset (&sa, '\0', sizeof (struct sigaction)); sa.sa_handler = func; sa.sa_flags = SA_RESTART; sigaction (sig, &sa, 0); #else signal (sig, func); #endif } void resetSignal (int sig, void (*func) (int sig)) { #ifndef HAVE_SIGACTION signal (sig, func); #endif } volatile Bool signalInterrupt; void intr (int sig) { resetSignal (SIGINT, intr); if (signalInterrupt) { int ret = write(2,"Double interrupt, exiting\n", 26); (void) ret; #if HAVE_RL_CLEANUP_AFTER_SIGNAL if (stdin_in_readline) rl_cleanup_after_signal(); #endif exit(1); } SetSignalInterrupt (); } void stop (int sig) { sigset_t set, oset; #if HAVE_RL_CLEANUP_AFTER_SIGNAL printf ("stop %d\n", stdin_in_readline); if (stdin_in_readline) rl_cleanup_after_signal(); #endif sigfillset (&set); sigprocmask (SIG_SETMASK, &set, &oset); IoStop (); releaseSignal (sig); sigfillset (&set); sigdelset (&set, sig); sigprocmask (SIG_SETMASK, &set, &set); kill (getpid(), sig); sigprocmask (SIG_SETMASK, &oset, &set); IoStart (); catchSignal (sig, stop); #if HAVE_RL_RESET_AFTER_SIGNAL if (stdin_in_readline) rl_reset_after_signal(); #endif } void die (int sig) { IoStop (); #if HAVE_RL_CLEANUP_AFTER_SIGNAL if (stdin_in_readline) rl_cleanup_after_signal(); #endif _exit (sig); } void segv (int sig) { IoStop (); #if HAVE_RL_CLEANUP_AFTER_SIGNAL if (stdin_in_readline) rl_cleanup_after_signal(); #endif releaseSignal (SIGSEGV); /* return and reexecute the fatal instruction */ } nickle_2.81.orig/int.c0000664000175000000620000001365410770315535014055 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static Value IntPlus (Value av, Value bv, int expandOk) { int r = ValueInt(av) + ValueInt(bv); if (expandOk && NICKLE_INT_CARRIED(r)) return Plus (NewIntInteger (ValueInt(av)), NewIntInteger(ValueInt(bv))); return NewInt(r); } static Value IntMinus (Value av, Value bv, int expandOk) { int r = ValueInt(av) - ValueInt(bv); if (expandOk && NICKLE_INT_CARRIED(r)) return Minus (NewIntInteger (ValueInt(av)), NewIntInteger(ValueInt(bv))); return NewInt(r); } int logbase2(int a) { int log = 0; if (a < 0) a = -a; while (a & (~ 0xff)) { log += 8; a >>= 8; } if (a & (~0xf)) { log += 4; a >>= 4; } if (a & (~0x3)) { log += 2; a >>= 2; } if (a & (~0x1)) log += 1; return log; } #define HALF_BITS (NICKLE_INT_BITS>>1) #define HALF_MAX (1 << (NICKLE_INT_BITS>>1)) static Value IntTimes (Value av, Value bv, int expandOk) { int a = ValueInt(av), b = ValueInt(bv); signed_digit rd = (signed_digit) a * (signed_digit) b; if (rd > (signed_digit) MAX_NICKLE_INT || rd < (signed_digit) MIN_NICKLE_INT) return NewSignedDigitInteger (rd); return NewInt ((int) rd); } static Value IntDivide (Value av, Value bv, int expandOk) { ENTER (); int a = ValueInt(av), b = ValueInt(bv); Value ret; if (b == 0) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } if (expandOk && a % b != 0) ret = Divide (NewIntRational (a), NewIntRational (b)); else ret = NewInt (a/b); RETURN (ret); } static Value IntDiv (Value av, Value bv, int expandOk) { ENTER (); int a = ValueInt(av), b = ValueInt(bv); int d; Value ret; if (b == 0) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } switch (catagorize_signs (IntSign(a), IntSign(b))) { case BothPositive: d = a / b; break; case FirstPositive: d = - (a / -b); break; case SecondPositive: d = -(a / -b); if (a % -b) d--; break; case BothNegative: default: d = -a / -b; if (-a % -b) d++; break; } ret = NewInt (d); RETURN (ret); } /* * dividend * quotient + remainder = divisor * * IntSign(quotient) = IntSign (dividend) * IntSign (divisor) * 0 <= remainder < abs (dividend) */ static Value IntMod (Value av, Value bv, int expandOk) { ENTER (); int a = ValueInt(av), b = ValueInt(bv); int r; if (b == 0) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } switch (catagorize_signs (IntSign(a), IntSign(b))) { case BothPositive: r = a % b; break; case FirstPositive: r = a % -b; break; case SecondPositive: r = -a % b; if (r) r = b - r; break; case BothNegative: default: r = -a % -b; if (r) r = -b - r; break; } RETURN (NewInt (r)); } static Value IntEqual (Value av, Value bv, int expandOk) { int a = ValueInt(av), b = ValueInt(bv); if (a == b) return TrueVal; return FalseVal; } static Value IntLess (Value av, Value bv, int expandOk) { int a = ValueInt(av), b = ValueInt(bv); if (a < b) return TrueVal; return FalseVal; } static Value IntLand (Value av, Value bv, int expandOk) { ENTER (); int a = ValueInt(av), b = ValueInt(bv); RETURN (NewInt (a & b)); } static Value IntLor (Value av, Value bv, int expandOk) { ENTER (); int a = ValueInt(av), b = ValueInt(bv); RETURN (NewInt (a | b)); } static Value IntNegate (Value av, int expandOk) { ENTER (); int a = ValueInt(av); if (-(-a) != a) RETURN (Negate (NewIntInteger (a))); RETURN (NewInt (-a)); } static Value IntFloor (Value av, int expandOk) { return av; } static Value IntCeil (Value av, int expandOk) { return av; } static Bool IntPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { int a = ValueInt(av); int digit; int w; int fraction_width; char space[64], *s; char letter; int neg; long len; if ('A' <= format && format <= 'Z') letter = 'A'; else letter = 'a'; if (base == 0) base = 10; switch (format) { case 'c': space[StringPutChar (a, space)] = '\0'; s = space; break; default: s = space + sizeof (space); *--s = '\0'; neg = 0; if (a < 0) { a = -a; neg = 1; } if (!a) *--s = '0'; else { while (a) { digit = a % base; if (digit <= 9) digit = '0' + digit; else digit = letter + digit - 10; *--s = digit; a /= base; } if (neg) *--s = '-'; } } len = strlen (s); w = StringLength (s, len); fraction_width = 0; if (prec >= 0) { int avail_width; if (width > 0) avail_width = width; else avail_width = -width; fraction_width = prec + 1; if (avail_width > 0) { if (w + fraction_width > avail_width) { fraction_width = avail_width - w; if (fraction_width < 0) fraction_width = 0; } } } w += fraction_width; while (width > w) { FileOutchar (f, fill); width--; } FilePutsc (f, s, len); if (fraction_width) { FileOutput (f, '.'); --fraction_width; while (fraction_width) { FileOutput (f, '0'); --fraction_width; } } while (-width > w) { FileOutchar (f, fill); width++; } return True; } static HashValue IntHash (Value av) { return (HashValue) ValueInt (av);; } ValueRep IntRep = { { 0, 0, "IntRep" }, /* data */ rep_int, /* tag */ { /* binary */ IntPlus, IntMinus, IntTimes, IntDivide, IntDiv, IntMod, IntLess, IntEqual, IntLand, IntLor }, { IntNegate, IntFloor, IntCeil, }, 0, 0, IntPrint, 0, IntHash, }; int IntInit (void) { return 1; } nickle_2.81.orig/Makefile.am0000664000175000000620000001036213202404027015130 0ustar keithpstaff## Process this file with automake to produce Makefile.in ## Copyright © 1988-2005 Keith Packard and Bart Massey. ## All Rights Reserved. See the file COPYING in this directory ## for licensing information. AUTOMAKE_OPTIONS = foreign SUBDIRS = bench test examples doc RELEASE_DATE := @RELEASE_DATE@ NICKLEFILES = builtin.5c math.5c scanf.5c mutex.5c \ arc4.5c prng.5c command.5c abort.5c \ printf.5c history.5c ctype.5c string.5c socket.5c \ file.5c parse-args.5c svg.5c process.5c \ prime_sieve.5c factorial.5c gamma.5c sort.5c list.5c skiplist.5c \ json.5c DEBIAN = debian/changelog debian/compat \ debian/control debian/copyright debian/rules debian/lintian.override EXTRA_DIST = README.name README.release autogen.sh ChangeLog \ $(NICKLEFILES) $(DEBIAN) nickle.1.in nickle.spec.in MAINTAINERCLEANFILES=ChangeLog .PHONY: ChangeLog ChangeLog: (GIT_DIR=$(top_srcdir)/.git git log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \ (touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2) dist-hook: ChangeLog nickleincludedir=$(includedir)/nickle nickleinclude_HEADERS = \ builtin.h config.h mem.h nickle.h ref.h value.h \ builtin-namespaces.h gram.h memp.h opcode.h stack.h bin_PROGRAMS = nickle nickle_SOURCES = \ alarm.c array.c atom.c box.c compile.c debug.c \ divide.c edit.c error.c execute.c expr.c file.c float.c \ foreign.c frame.c func.c gcd.c hash.c int.c integer.c io.c \ main.c mem.c natural.c pretty.c profile.c rational.c ref.c \ refer.c sched.c scope.c stack.c string.c struct.c \ symbol.c sync.c type.c union.c util.c value.c \ mem.h memp.h nickle.h opcode.h ref.h stack.h value.h \ builtin-command.c builtin-debug.c builtin-environ.c \ builtin-file.c builtin-math.c builtin-namespaces.h \ builtin-semaphore.c builtin-sockets.c builtin-string.c \ builtin-thread.c builtin-toplevel.c builtin-pid.c \ builtin-date.c builtin.c builtin.h \ builtin-foreign.c gram.y lex.l nickle_LDFLAGS=$(NICKLE_LDFLAGS) pkgdata_DATA = $(NICKLEFILES) COPYING man_MANS = nickle.1 AM_YFLAGS = -d AM_CPPFLAGS = \ -DBUILD=\""$(RELEASE_DATE)"\" \ -DBUILD_VERSION=\""$(VERSION)"\" \ -DLOCAL_BUILD \ -DNICKLELIBDIR=\"@nicklelibdir@\" AM_CFLAGS = \ -D_FORTIFY_SOURCE=2 \ -Wall -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs -fno-strict-aliasing -fwrapv USES_GRAM_H = \ array.o \ compile.o \ error.o \ expr.o \ file.o \ lex.o \ main.o \ pretty.o \ type.o $(USES_GRAM_H): gram.h builtin.o main.o: Makefile TARFILE=$(PACKAGE)-$(VERSION).tar.gz DEBFILE=$(PACKAGE)_$(VERSION)-1_amd64.deb SRPMFILE=$(RPMDIR)/SRPMS/$(PACKAGE)-$(VERSION)-1.src.rpm RPMFILE=$(RPMDIR)/RPMS/$(PACKAGE)-$(VERSION)-1.x86_64.rpm RELEASE_FILES = $(TARFILE) $(DEBFILE) $(SRPMFILE) $(RPMFILE) DEB_TAR_DIR=$(PACKAGE)_$(VERSION).orig DEB_TAR=$(DEB_TAR_DIR).tar.gz debuild: $(DEBFILE) $(DEBFILE): $(DEB_TAR) $(TARFILE) tar xzf $(TARFILE) (cd $(distdir) && pdebuild --buildresult $(abs_top_builddir) --auto-debsign) debuild-unsigned: $(DEB_TAR) $(TARFILE) tar xzf $(distdir).tar.gz (cd $(distdir)/debian && debuild -us -uc) $(DEB_TAR): $(TARFILE) rm -f $(DEB_TAR) rm -rf $(DEB_TAR_DIR) tar xzf $(TARFILE) mv $(distdir) $(DEB_TAR_DIR) rm -rf $(DEB_TAR_DIR)/debian tar czf $(DEB_TAR) $(DEB_TAR_DIR) nickle.1: nickle.1.in config.h sed -e 's,@''VERSION@,$(VERSION),' \ -e 's,@''BUILD_DATE@,$(BUILD_DATE),' \ -e 's,@''pkgdatadir@,$(pkgdatadir),' $(top_srcdir)/nickle.1.in > $@ nickle.spec: nickle.spec.in config.h sed -e 's,@''VERSION@,$(VERSION),' \ -e 's,@''pkgdatadir@,$(pkgdatadir),' $(top_srcdir)/nickle.spec.in > $@ clean-local: rm -f nickle.1 nickle.spec # # This assumes you've got Mike Harris's rpmbuild-nonroot stuff installed # using the defaults # RPMDIR=$(HOME)/rpmbuild rpm: $(RPMFILE) $(SRPMFILE) $(RPMFILE): $(TARFILE) nickle.spec mkdir -p $(RPMDIR)/$(PACKAGE)-$(VERSION) cp $(TARFILE) $(RPMDIR)/$(PACKAGE)-$(VERSION) rpmbuild -ba nickle.spec $(SRPMFILE): $(RPMFILE) $(TARFILE): dist-gzip $(DISTFILES) touch $(TARFILE) echo $(TARFILE) ready release-files: $(RELEASE_FILES) release: $(RELEASE_FILES) scp $(RELEASE_FILES) nickle.org:/var/www/nickle/release .PHONY: debuild debuild-signed debuild-unsigned debuild-dirs rpm force nickle_2.81.orig/util.c0000664000175000000620000000336510414112462014223 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * util.c * * general purpose utilities */ #include "nickle.h" #ifdef notdef double dist (x0, y0, x1, y1) double x0, y0, x1, y1; { register double tx, ty; tx = x0 - x1; ty = y0 - y1; return sqrt (tx*tx + ty*ty); } #endif DataType TempType = { 0, 0, "TempType" }; void * AllocateTemp (int size) { DataType **b; b = ALLOCATE (&TempType, sizeof (DataType *) + size); return b + 1; } #include #include #ifdef HAVE_VPRINTF #include #include /* * Currently vfprintf() is required. It would * be easy to do a _doprnt() version if necessary, * and it would certainly be possible to develop * non-varargs versions of these. Contributed code welcome. */ static int wait_write (int fd, char *buf, int len) { int n; int w = 0; while (len) { n = write (fd, buf, len); if (n < 0) { if (errno == EINTR) { struct pollfd f; f.fd = fd; f.events = POLLOUT; (void) poll (&f, 1, -1); } else { if (w) return w; return -1; } } else { w += n; buf += n; len -= n; } } return w; } void debug (char *format, ...) { va_list ap; char buf[4096]; int len; va_start (ap, format); len = vsnprintf (buf, sizeof (buf), format, ap); va_end (ap); wait_write (2, buf, len); } void panic (char *format, ...) { va_list ap; char buf[4096]; int len; va_start (ap, format); len = vsnprintf (buf, sizeof (buf), format, ap); va_end (ap); wait_write (2, buf, len); abort (); } #endif nickle_2.81.orig/builtin-toplevel.c0000664000175000000620000005043213062260671016551 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * toplevel.c * * provide builtin functions for the Toplevel namespace */ #include #include #include #include "builtin.h" void import_Toplevel_namespace() { ENTER (); static const struct fbuiltin_0 funcs_0[] = { { do_time, "time", "i", "", "\n" " int time ()\n" "\n" " Return seconds since Jan 1, 1970 00:00 GMT\n" }, { do_millis, "millis", "i", "", "\n" " int millis ()\n" "\n" " Return time in milliseconds\n" }, { 0 } }; static const struct fbuiltin_1 funcs_1[] = { { do_abs, "abs", "R", "R", "\n" " real abs (real r)\n" "\n" " Return absolute value of 'r'.\n" }, { do_bit_width, "bit_width", "i", "i", "\n" " int bit_width (int i)\n" "\n" " Return width of binary representation of abs('i').\n" }, { do_ceil, "ceil", "i", "R", "\n" " int ceil (real r)\n" "\n" " Return the nearest integer no smaller than 'r'.\n" }, { do_denominator, "denominator", "i", "r", " int denominator (rational r)\n" "\n" " Return the denominator of 'r'\n" }, { do_dim, "dim", "i", "A*p", "\n" " int dim (poly[*] a)\n" "\n" " Return the dimension of 'a'.\n" }, { do_dims, "dims", "A*i", "Ap", "\n" " int[*] dims (poly[] a)\n" "\n" " Return an array containing the list of dimensions of 'a'.\n" }, { do_exit, "exit", "v", "i", "\n" " void exit (int i)\n" "\n" " Exit from the nickle environment with code 'i'.\n" }, { do_exponent, "exponent", "i", "R", "\n" " int exponent (real r)\n" "\n" " Return the exponent of the imprecise value 'r'.\n" }, { do_floor, "floor", "i", "R", "\n" " int floor (real r)\n" "\n" " Return the nearest integer no larger than 'r'.\n" }, { do_func_args, "func_args", "i", "p", "\n" " int func_args (poly f)\n" "\n" " Return the number of arguments required by function 'f'.\n" }, { do_is_array, "is_array", "b", "p", "\n" " bool is_array (poly v)\n" "\n" " Return whether 'v' is an array value.\n" }, { do_is_continuation, "is_continuation", "b", "p" , "\n" " bool is_continuation (poly v)\n" "\n" " Return whether 'v' is an continuation value.\n" }, { do_is_file, "is_file", "b", "p" , "\n" " bool is_file (poly v)\n" "\n" " Return whether 'v' is an file value.\n" }, { do_is_func, "is_func", "b", "p" , "\n" " bool is_func (poly v)\n" "\n" " Return whether 'v' is an func value.\n" }, { do_is_hash, "is_hash", "b", "p", "\n" " bool is_hash (poly v)\n" "\n" " Return whether 'v' is an hash value.\n" }, { do_is_int, "is_int", "b", "p" , "\n" " bool is_int (poly v)\n" "\n" " Return whether 'v' is an int value.\n" }, { do_is_number, "is_number", "b", "p" , "\n" " bool is_number (poly v)\n" "\n" " Return whether 'v' is an numeric value.\n" }, { do_is_rational, "is_rational", "b", "p" , "\n" " bool is_rational (poly v)\n" "\n" " Return whether 'v' is an rational value.\n" }, { do_is_ref, "is_ref", "b", "p" , "\n" " bool is_ref (poly v)\n" "\n" " Return whether 'v' is an ref value.\n" }, { do_is_semaphore, "is_semaphore", "b", "p" , "\n" " bool is_semaphore (poly v)\n" "\n" " Return whether 'v' is an semaphore value.\n" }, { do_is_string, "is_string", "b", "p" , "\n" " bool is_string (poly v)\n" "\n" " Return whether 'v' is an string value.\n" }, { do_is_struct, "is_struct", "b", "p" , "\n" " bool is_struct (poly v)\n" "\n" " Return whether 'v' is an struct value.\n" }, { do_is_thread, "is_thread", "b", "p" , "\n" " bool is_thread (poly v)\n" "\n" " Return whether 'v' is an thread value.\n" }, { do_is_bool, "is_bool", "b", "p" , "\n" " bool is_bool (poly v)\n" "\n" " Return whether 'v' is an bool value.\n" }, { do_is_void, "is_void", "b", "p" , "\n" " bool is_void (poly v)\n" "\n" " Return whether 'v' is an void value.\n" }, { do_is_uninit, "is_uninit", "b", "*p", "\n" " bool is_uninit (*poly r)\n" "\n" " Return whether 'r' references uninitialized storage.\n" }, { do_make_uninit, "make_uninit", "v", "*p", "\n" " void make_uninit (*poly r)\n" "\n" " Makes 'r' reference uninitialized storage.\n" }, { do_mantissa, "mantissa", "r", "R", "\n" " rational mantissa (real r)\n" "\n" " Return the mantissa of 'r' as a rational between 0 and 1.\n" }, { do_numerator, "numerator", "i", "r", "\n" " int numerator (rational r)\n" "\n" " Return the numerator of 'r'.\n" }, { do_precision, "precision", "i", "R", "\n" " int precision (real r)\n" "\n" " Return the number of bits in the\n" " representation of the mantissa of 'r'.\n" }, { do_profile, "profile", "b", "b", "\n" " bool profile (bool enable)\n" "\n" " Set profiling on/off.\n" " Returns previous profiling state.\n" }, { do_reference, "reference", "*p", "p", "\n" " *poly reference (poly value)\n" "\n" " Returns &value.\n" }, { do_sign, "sign", "i", "R", "\n" " int sign (real r)\n" " Return -1, 0, 1 for negative, zero or positive 'r'.\n" }, { do_sleep, "sleep", "v", "i", "\n" " void sleep (int milliseconds)\n" "\n" " Pause thread execution for 'milliseconds'.\n" }, { do_string_to_real, "string_to_real", "R", "s", "\n" " real string_to_real (string s)\n" "\n" " Parse a string representation of a numeric value.\n" }, { do_hash, "hash", "i", "p", "\n" " int hash (poly p)\n" "\n" " Return an integer based on 'p' such that any value equal\n" " to 'p' will return the same integer.\n" }, { do_hash_keys, "hash_keys", "Ap", "Hpp", "\n" " poly[] hash_keys (poly[poly] h)\n" "\n" " Return an array containing all of the key in 'h'.\n" " The order within the array is undefined.\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_gcd, "gcd", "i", "ii", "\n" " int gcd (int a, int b)\n" "\n" " Return the greatest common divisor of 'a' and 'b'.\n" }, { do_setjmp, "setjmp", "p", "*cp", "\n" " poly setjmp (*continuation c, poly v)\n" "\n" " On direct invocation, create a continuation and store\n" " that in *'c'. Then return 'v'.\n" " Subsequent invocations of longjmp with *'c' will appear\n" " to return from 'setjmp' with the value passed to longjmp.\n" }, { do_setdims, "setdims", "v", "ApA*i", "\n" " void setdims (poly[] a, int[*] dimensions)\n" "\n" " Set the dimensions of resizable array 'a' to 'dimensions'.\n" " dim(dimensionss) must be the same as dim(dims(a)).\n" }, { do_setdim, "setdim", "v", "A.pi", "\n" " void setdim (poly[...] a, int dimension)\n" "\n" " Set the dimension of 'a' to 'dimension'.\n" }, { do_hash_del, "hash_del", "v", "Hppp", "\n" " void hash_del (poly[poly] h, poly key)\n" "\n" " Delete any hash value in 'h' associated with 'key'.\n" }, { do_hash_test, "hash_test", "b", "Hppp", "\n" " bool hash_test (poly[poly] h, poly key)\n" "\n" " Return whether 'h' contains 'key'.\n" }, { 0 } }; static const struct fbuiltin_2j funcs_2j[] = { { do_longjmp, "longjmp", "v", "cp", "\n" " void longjmp (continuation c, poly v)\n" "\n" " Relocate execution to that saved in 'c', making the\n" " setjmp call there appear to return 'v'.\n" }, { 0 } }; static const struct fbuiltin_v funcs_v[] = { { do_imprecise, "imprecise", "R", "R.i", "\n" " real imprecise (real r)\n" " real imprecise (real r, int precision)\n" "\n" " Return an imprecise number.\n" " The precision will be 'precision' if supplied, else 256.\n" }, { do_string_to_integer, "string_to_integer", "i", "s.i", "\n" " int string_to_integer (string s)\n" " int string_to_integer (string s, int base)\n" "\n" " Parse 's' as an integer.\n" " Use 'base' if supplied, else autodetect.\n" }, { 0 } }; BuiltinFuncs0 (/*parent*/ 0, funcs_0); BuiltinFuncs1 (/*parent*/ 0, funcs_1); BuiltinFuncs2 (/*parent*/ 0, funcs_2); BuiltinFuncs2J (/*parent*/ 0, funcs_2j); BuiltinFuncsV (/*parent*/ 0, funcs_v); EXIT (); } Value do_gcd (Value a, Value b) { ENTER (); RETURN (Gcd (a, b)); } Value do_time (void) { ENTER (); RETURN (Reduce (NewInteger (Positive, NewDoubleDigitNatural ((double_digit) time(0))))); } Value do_string_to_integer (int n, Value *p) { ENTER (); char *s; int ibase; int negative = 0; Value ret = Zero; Value str = p[0]; Value base = Zero; switch(n) { case 1: break; case 2: base = p[1]; break; default: RaiseStandardException (exception_invalid_argument, 3, NewStrString ("string_to_integer: wrong number of arguments"), NewInt (2), NewInt (n)); RETURN(Void); } s = StringChars (&str->string); while (isspace ((int)(*s))) s++; switch (*s) { case '-': negative = 1; s++; break; case '+': s++; break; } ibase = IntPart (base, "string_to_integer: invalid base"); if (!aborting) { if (ibase == 0) { if (!strncmp (s, "0x", 2) || !strncmp (s, "0X", 2)) ibase = 16; else if (!strncmp (s, "0t", 2) || !strncmp (s, "0T", 2)) ibase = 10; else if (!strncmp (s, "0b", 2) || !strncmp (s, "0B", 2)) ibase = 2; else if (!strncmp (s, "0o", 2) || !strncmp (s, "0O", 2) || *s == '0') ibase = 8; else ibase = 10; } switch (ibase) { case 2: if (!strncmp (s, "0b", 2) || !strncmp (s, "0B", 2)) s += 2; break; case 8: if (!strncmp (s, "0o", 2) || !strncmp (s, "0O", 2)) s += 2; case 10: if (!strncmp (s, "0t", 2) || !strncmp (s, "0T", 2)) s += 2; break; case 16: if (!strncmp (s, "0x", 2) || !strncmp (s, "0X", 2)) s += 2; break; } ret = atov (s, ibase); if (!aborting) { if (negative) ret = Negate (ret); } } RETURN (ret); } Value do_string_to_real (Value str) { ENTER (); RETURN (aetov (StringChars (&str->string), 10)); } Value do_imprecise (int n, Value *p) { ENTER(); Value v; int prec; v = p[0]; if (n > 1) { prec = IntPart (p[1], "imprecise: invalid precision"); if (prec <= 0) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("imprecise: precision must be positive"), NewInt(0), p[1]); RETURN(v); } } else { Value float_prec; if (ValueIsFloat(v)) RETURN(v); prec = DEFAULT_FLOAT_PREC; float_prec = lookupVar(0, "float_precision"); if (float_prec) { int default_prec = ValueInt(float_prec); if (default_prec > 1) prec = default_prec; } } RETURN (NewValueFloat (v, prec)); } Value do_abs (Value a) { ENTER (); if (Negativep (a)) a = Negate (a); RETURN (a); } Value do_floor (Value a) { return Floor (a); } Value do_func_args (Value a) { ENTER (); if (!ValueIsFunc (a)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("func_args: argument must be function"), NewInt (0), a); RETURN (Void); } RETURN (NewInt (a->func.code->base.argc)); } Value do_ceil (Value a) { return Ceil (a); } Value do_exit (Value av) { ENTER (); int code; code = IntPart (av, "Illegal exit code"); if (aborting) RETURN (Void); IoFini (); FileFini (); exit (code); RETURN (Void); } Value do_dim(Value av) { ENTER(); Value ret; if (av->array.ndim != 1) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("dim: argument must be one-dimensional array"), NewInt (0), av); RETURN (Void); } ret = NewInt(ArrayLimits(&av->array)[0]); RETURN (ret); } Value do_dims(Value av) { ENTER(); Value ret; int i; int ndim = av->array.ndim; ret = NewArray(True, False, typePrim[rep_int], 1, &ndim); for (i = 0; i < ndim; i++) { Value d = NewInt(ArrayLimits(&av->array)[i]); ArrayValueSet(&ret->array, ndim - i - 1, d); } RETURN (ret); } Value do_setdims (Value av, Value dv) { ENTER (); Array *a = &av->array; Array *d = &dv->array; #define DIM_LOCAL 32 int dimLocal[DIM_LOCAL]; int *dims = a->ndim < DIM_LOCAL ? dimLocal : AllocateTemp (a->ndim * sizeof (int)); int i; if (a->ndim != ArrayNvalues(d)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("setdims: size of dimensions must match dimensionality of array"), NewInt (a->ndim), dv); RETURN (Void); } if (!av->array.resizable) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("setdims: array must be resizable"), av, Void); RETURN (Void); } for (i = 0; i < a->ndim; i++) { int j = a->ndim - 1 - i; dims[j] = IntPart (ArrayValue (d,i), "setdims: invalid dimension"); if (aborting) RETURN (Void); if (dims[j] < 0) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("setdims: dimensions must be non-negative"), NewInt (i), NewInt (dims[j])); RETURN (Void); } } ArraySetDimensions (av, dims); RETURN (Void); } Value do_setdim (Value av, Value dv) { ENTER (); int d = IntPart (dv, "setdim: invalid dimension"); if (aborting) RETURN (Void); if (d < 0) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("setdim: dimension must be non-negative"), dv, Void); RETURN (Void); } if (!av->array.resizable) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("setdim: array must be resizable"), av, Void); RETURN (Void); } ArrayResize (av, 0, d); RETURN (Void); } Value do_reference (Value av) { ENTER (); Value ret; ret = NewRef (NewBox (False, False, 1, typePoly), 0); RefValueSet (ret, Copy (av)); RETURN (ret); } Value do_precision (Value av) { ENTER (); unsigned prec; if (ValueIsFloat(av)) prec = av->floats.prec; else prec = 0; RETURN (NewInt (prec)); } Value do_sign (Value av) { ENTER (); if (Zerop (av)) av = Zero; else if (Negativep (av)) av = NewInt(-1); else av = One; RETURN (av); } Value do_exponent (Value av) { ENTER (); Value ret; if (!ValueIsFloat(av)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("exponent: argument must be imprecise"), NewInt (0), av); RETURN (Void); } ret = NewInteger (av->floats.exp->sign, av->floats.exp->mag); ret = Plus (ret, NewInt (FpartLength (av->floats.mant))); RETURN (ret); } Value do_mantissa (Value av) { ENTER (); Value ret; if (!ValueIsFloat(av)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("mantissa: argument must be imprecise"), NewInt (0), av); RETURN (Void); } ret = NewInteger (av->floats.mant->sign, av->floats.mant->mag); ret = Divide (ret, Pow (NewInt (2), NewInt (FpartLength (av->floats.mant)))); RETURN (ret); } Value do_numerator (Value av) { ENTER (); switch (ValueTag(av)) { case rep_int: case rep_integer: break; case rep_rational: av = NewInteger (av->rational.sign, av->rational.num); break; default: RaiseStandardException (exception_invalid_argument, 3, NewStrString ("numerator: argument must be precise"), NewInt (0), av); av = Void; break; } RETURN (av); } Value do_denominator (Value av) { ENTER (); switch (ValueTag(av)) { case rep_int: case rep_integer: av = One; break; case rep_rational: av = NewInteger (Positive, av->rational.den); break; default: RaiseStandardException (exception_invalid_argument, 3, NewStrString ("denominator: argument must be precise"), NewInt (0), av); av = Void; break; } RETURN (av); } Value do_bit_width (Value av) { ENTER (); switch (ValueTag(av)) { case rep_int: av = NewInt (IntWidth (ValueInt(av))); break; case rep_integer: av = NewInt (NaturalWidth (IntegerMag(av))); break; default: RaiseStandardException (exception_invalid_argument, 3, NewStrString ("bit_width: argument must be integer"), NewInt (0), av); av = Void; break; } RETURN (av); } Value do_is_int (Value av) { ENTER (); switch (ValueTag(av)) { case rep_int: case rep_integer: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_rational (Value av) { ENTER (); switch (ValueTag(av)) { case rep_int: case rep_integer: case rep_rational: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_number (Value av) { ENTER (); switch (ValueTag(av)) { case rep_int: case rep_integer: case rep_rational: case rep_float: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_string (Value av) { ENTER (); switch (ValueTag(av)) { case rep_string: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_file (Value av) { ENTER (); switch (ValueTag(av)) { case rep_file: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_thread (Value av) { ENTER (); switch (ValueTag(av)) { case rep_thread: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_semaphore (Value av) { ENTER (); switch (ValueTag(av)) { case rep_semaphore: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_continuation (Value av) { ENTER (); switch (ValueTag(av)) { case rep_continuation: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_bool (Value av) { ENTER (); switch (ValueTag(av)) { case rep_bool: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_void (Value av) { ENTER (); switch (ValueTag(av)) { case rep_void: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_uninit (Value av) { ENTER (); if (!av) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("do_is_uninit: invalid reference"), NewInt (0), av); av = Void; } else if (RefValueGet(av)) { av = FalseVal; } else { av = TrueVal; } RETURN (av); } Value do_make_uninit (Value av) { ENTER (); if (!av) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("do_make_uninit: invalid reference"), NewInt (0), av); } else { RefValueSet(av, 0); } RETURN (Void); } Value do_is_array (Value av) { ENTER (); switch (ValueTag(av)) { case rep_array: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_hash(Value av) { ENTER(); switch(ValueTag(av)) { case rep_hash: av = TrueVal; break; default: av = FalseVal; break; } RETURN(av); } Value do_is_ref (Value av) { ENTER (); switch (ValueTag(av)) { case rep_ref: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_struct (Value av) { ENTER (); switch (ValueTag(av)) { case rep_struct: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_is_func (Value av) { ENTER (); switch (ValueTag(av)) { case rep_func: av = TrueVal; break; default: av = FalseVal; break; } RETURN (av); } Value do_hash (Value a) { return ValueHash (a); } /* hash builtins (for testing) */ Value do_hash_new (void) { return NewHash (False, typePoly, typePoly); } Value do_hash_del (Value hv, Value key) { HashDelete (hv, key); return Void; } Value do_hash_test (Value hv, Value key) { return HashTest (hv, key); } Value do_hash_keys (Value hv) { return HashKeys (hv); } nickle_2.81.orig/arc4.5c0000664000175000000620000000246110414112462014160 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1999 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * Implementation of Alleged RC4 * * Bart 1999/2 * * Used primarily for PRNG, so interface is not too fancy */ namespace ARC4 { global int[256] state = {}; global int p1, p2; public void nsetkey(int nn, int k) /* * First argument is number of times to iterate the * initial scramble. 10 seems good for most apps. * Second argument is integer key: largest useful key is * 8 * 62 bits. */ { int i, j, n, ii; int[64] key = {}; key[0] = 13; key[1] = 17; for (n = 2; n < 64 && k > 0; n++) { key[n] = k & 0xff; k = k >> 8; } for (i = 0; i < 256; i++) state[i] = i; for (ii = 0; ii < nn; ii++) { j = 0; for (i = 0; i < 256; i++) { j = (j + state[i] + key[i % n]) & 0xff; int tmp = state[i]; state[i] = state[j]; state[j] = tmp; } } p1 = p2 = 0; } public int streambyte() /* * Get the next byte from the stream */ { p1 = (p1 + 1) & 0xff; p2 = (p2 + state[p1]) & 0xff; int tmp = state[p1]; state[p1] = state[p2]; state[p2] = tmp; int n = (state[p1] + state[p2]) & 0xff; return state[n]; } } nickle_2.81.orig/parse-args.5c0000664000175000000620000001512710414112462015376 0ustar keithpstaffnamespace ParseArgs { import File; import String; public typedef union { &bool arg_flag; &string arg_string; &int arg_int; &real arg_real; (void(string)) arg_lambda; } arg_var; public typedef struct { arg_var var; int abbr; string name; string expr_name; string desc; } arg; public typedef struct { arg_var var; void optional; string name; } posn_arg; public typedef struct { string prog_name; arg[*] args; posn_arg[*] posn_args; &int unknown; } argdesc; string arg_string(arg a) /* * Given an arg desc, produce * a printable representation */ { string stdarg() { if (is_uninit(&a.name)) return a.expr_name; string s = ""; if (!is_uninit(&a.abbr)) s += sprintf("-%c,", a.abbr); s += sprintf("--%s", a.name); return s; } union switch (a.var) { case arg_flag: return stdarg(); default: return sprintf("%s <%s>", stdarg(), a.expr_name); } abort("internal error: unknown arg type"); } public string basename(string path) /* * Return the filename part of 'path' */ { int p = rindex(path, "/"); if (p == -1) return path; return substr(path, p + 1, length(path) - p - 1); } /* * The argument description was defective, with * a reason string. */ public exception bad_argd(string reason); /* * Print a usage message on the given file. * XXX Valid only after parseargs() has been called. */ public void(file f) usage; public void parseargs(&argdesc argd, &(string[*]) argv) /* * Parse arguments in 'argv' according to 'argd' */ { /* * validate that any argd.posn_args * consists of mandatory followed by optional args */ if (!is_uninit(&argd.posn_args)) for (int i = 1; i < dim(argd.posn_args); i++) if (!is_uninit(&argd.posn_args[i - 1].optional) && is_uninit(&argd.posn_args[i].optional)) raise bad_argd("fixed after optional posn arg"); /* argument that is current focus */ int argind = 0; /* save program basename as needed */ if (is_uninit(&argd.prog_name)) { argd.prog_name = basename(argv[0]); argind++; } /* build hashes for flags */ arg[int] arg_abbr_hash = {}; arg[string] arg_name_hash = {}; if (!is_uninit(&argd.args)) { for (int i = 0; i < dim(argd.args); i++) { &arg d = &argd.args[i]; if (!is_uninit(&d.abbr)) arg_abbr_hash[d.abbr] = d; if (!is_uninit(&d.name)) arg_name_hash[d.name] = d; } } void usagef(file f) /* * Print a description of program usage on f */ { fprintf(f, "%s: usage: %s", argd.prog_name, argd.prog_name); if (!is_uninit(&argd.args)) { fprintf(f, " "); for (int i = 0; i < dim(argd.args); i++) if (is_uninit(&argd.args[i].name)) fprintf(f, " %s", arg_string(argd.args[i])); } if (!is_uninit(&argd.posn_args)) { for (int i = 0; i < dim(argd.posn_args); i++) if (is_uninit(&argd.posn_args[i].optional)) fprintf(f, " %s", argd.posn_args[i].name); else fprintf(f, " [%s]", argd.posn_args[i].name); } if (!is_uninit(&&argd.unknown)) fprintf(f, " [--] ..."); fprintf(f, "\n"); if (!is_uninit(&argd.args)) { for (int i = 0; i < dim(argd.args); i++) if (is_uninit(&argd.args[i].name)) fprintf(f, " %s %s\n", argd.args[i].expr_name, argd.args[i].desc); for (int i = 0; i < dim(argd.args); i++) if (!is_uninit(&argd.args[i].name)) fprintf(f, " %s %s\n", arg_string(argd.args[i]), argd.args[i].desc); } exit(1); } usage = usagef; void save_value(&arg_var a, string value) /* * convert and store the value * associated with an argument. * return number of args consumed */ { union switch(a) { case arg_string var: var = value; break; case arg_int var: var = string_to_integer(value); break; case arg_real var: var = string_to_real(value); break; case arg_lambda var: var(value); break; default: abort("save_value called on wrong var type"); } } void process_flag(&arg a) /* * Process a flag */ { argind++; union switch(a.var) { case arg_flag var: var = true; return; default: if (argind >= dim(argv)) { fprintf(stderr, "%s: missing value for --%s\n", argd.prog_name, a.name); usagef(stderr); } save_value(&a.var, argv[argind]); argind++; } } /* handle the help case first */ if (argind < dim(argv) && (argv[argind] == "--help" || argv[argind] == "--usage")) usagef(stdout); /* now walk the arguments */ while(argind < dim(argv)) { string a = argv[argind]; /* we're done on a "user stop" */ if (a == "--") { if (is_uninit(&&argd.unknown)) { fprintf(stderr, "%s: don't know what to do with arg \"%s\"\n", argd.prog_name, a); usagef(stderr); } break; } /* process abbreviated (old-style) flags (maybe grouped) */ if (a[0] == '-' && a[1] != '-') { for (int i = 1; i < length(a); i++) { if (!hash_test(arg_abbr_hash, a[i])) { fprintf(stderr, "%s: unknown flag char '-%c'\n", argd.prog_name, a[i]); usagef(stderr); } process_flag(&arg_abbr_hash[a[i]]); } continue; } /* process a long flag */ if (a[0] == '-' && a[1] == '-') { string argname = substr(a, 2, length(a) - 2); if (!hash_test(arg_name_hash, argname)) { fprintf(stderr, "%s: unknown flag \"--%s\"\n", argd.prog_name, argname); usagef(stderr); } process_flag(&arg_name_hash[argname]); continue; } /* maybe something will suck up remaining args */ if (!is_uninit(&argd.posn_args) || !is_uninit(&&argd.unknown)) break; fprintf(stderr, "%s: extra argument \"%s\"\n", argd.prog_name, argv[argind]); usagef(stderr); } /* process any positional arguments */ if (!is_uninit(&argd.posn_args)) { for (int i = 0; i < dim(argd.posn_args); i++) { if (argind >= dim(argv) || argv[argind] == "--") { if (!is_uninit(&argd.posn_args[i].optional)) break; fprintf(stderr, "%s: missing required argument %s\n", argd.prog_name, argd.posn_args[i].name); usagef(stderr); } save_value(&argd.posn_args[i].var, argv[argind]); argind++; } } /* process any unknown arguments */ if (argind < dim(argv)) { if (argv[argind] == "--") argind++; if (!is_uninit(&&argd.unknown)) { argd.unknown = argind; return; } if (argind < dim(argv)) { fprintf(stderr, "%s: unknown or extra argument \"%s\"\n", argd.prog_name, argv[argind]); usagef(stderr); } } } } nickle_2.81.orig/nickle.h0000664000175000000620000006301613202404777014532 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #if LOCAL_BUILD #include "config.h" #include "mem.h" #include "value.h" #include "opcode.h" #else #include #include #include #include #endif #include typedef struct _func *FuncPtr; typedef struct _namespace *NamespacePtr; typedef struct _command *CommandPtr; typedef struct _symbolBase { DataType *data; SymbolPtr next; Atom name; Class class; Type *type; Bool forward; /* forward declaration of a function */ } SymbolBase; typedef struct _symbolType { SymbolBase symbol; } SymbolType; typedef struct _symbolGlobal { SymbolBase symbol; BoxPtr value; } SymbolGlobal; typedef struct _symbolLocal { SymbolBase symbol; int element; Bool staticScope; /* dynamic scope equal to static */ CodePtr code; } SymbolLocal; typedef struct _symbolNamespace { SymbolBase symbol; NamespacePtr namespace; } SymbolNamespace; typedef struct _symbolException { SymbolBase symbol; Value doc; } SymbolException; typedef union _symbol { SymbolBase symbol; SymbolType type; SymbolGlobal global; SymbolLocal local; SymbolNamespace namespace; SymbolException exception; } Symbol; extern SymbolPtr NewSymbolType (Atom name, Type *type); extern SymbolPtr NewSymbolException (Atom name, Type *type, Value doc); extern SymbolPtr NewSymbolConst (Atom name, Type *type); extern SymbolPtr NewSymbolGlobal (Atom name, Type *type); extern SymbolPtr NewSymbolArg (Atom name, Type *type); extern SymbolPtr NewSymbolStatic (Atom name, Type *Rep); extern SymbolPtr NewSymbolAuto (Atom name, Type *type); extern SymbolPtr NewSymbolNamespace (Atom name, NamespacePtr namespace); static inline Type *_TypeNameType(TypePtr t) { if (t->name.name) return t->name.name->symbol.type; else return NULL; } #define TypeNameType(t) _TypeNameType(t) typedef struct _namelist *NamelistPtr; typedef struct _namelist { DataType *data; NamelistPtr next; SymbolPtr symbol; Publish publish; } Namelist; typedef struct _namespace { DataType *data; NamespacePtr previous; NamelistPtr names; Publish publish; } Namespace; NamespacePtr NewNamespace (NamespacePtr previous); SymbolPtr NamespaceFindName (NamespacePtr namespace, Atom atom, Bool search); Bool NamespaceIsNamePrivate (NamespacePtr namespace, Atom atom, Bool search); SymbolPtr NamespaceAddName (NamespacePtr namespace, SymbolPtr symbol, Publish publish); Bool NamespaceRemoveName (NamespacePtr namespace, Atom atom); void NamespaceImport (NamespacePtr namespace, NamespacePtr import, Publish publish); void NamespaceInit (void); extern NamespacePtr GlobalNamespace, TopNamespace, CurrentNamespace, DebugNamespace, LexNamespace; extern FramePtr CurrentFrame; typedef struct _command { DataType *data; CommandPtr previous; Atom name; Value func; Bool names; } Command; CommandPtr NewCommand (CommandPtr previous, Atom name, Value func, Bool names); CommandPtr CommandFind (CommandPtr command, Atom name); CommandPtr CommandRemove (CommandPtr command, Atom name); extern CommandPtr CurrentCommands; typedef struct _DeclList *DeclListPtr; typedef struct _DeclList { DataType *data; DeclListPtr next; Atom name; SymbolPtr symbol; ExprPtr init; } DeclList; extern DeclListPtr NewDeclList (Atom name, ExprPtr init, DeclListPtr next); typedef struct _MemList *MemListPtr; typedef struct _MemList { DataType *data; MemListPtr next; Type *type; AtomListPtr atoms; } MemList; extern MemListPtr NewMemList (AtomListPtr atoms, Type *type, MemListPtr next); typedef struct _Fulltype { Publish publish; Class class; Type *type; } Fulltype; typedef struct _funcDecl { Fulltype type; DeclList *decl; } FuncDecl; typedef struct _frame { DataType *data; FramePtr previous; FramePtr staticLink; Value function; BoxPtr frame; BoxPtr statics; InstPtr savePc; ObjPtr saveObj; } Frame; extern FramePtr NewFrame (Value function, FramePtr previous, FramePtr staticLink, BoxTypesPtr dynamics, BoxPtr statics); typedef struct _catch { Continuation continuation; SymbolPtr exception; } Catch; CatchPtr NewCatch (Value thread, SymbolPtr exception); typedef struct _twixt { Continuation continuation; InstPtr leave; int depth; } Twixt; TwixtPtr NewTwixt (ContinuationPtr continuation, InstPtr enter, InstPtr leave); InstPtr TwixtJump (Value thread, TwixtPtr twixt, Bool enter); static inline int TwixtDepth(Twixt *t) { if (t) return t->depth; else return 0; } TwixtPtr TwixtNext (TwixtPtr twixt, TwixtPtr last); # define NOTHING 0 # define CONT 1 # define BRK 2 # define RET 3 typedef struct _exprBase { DataType *data; int tag; Atom file; int line; NamespacePtr namespace; Type *type; double_digit ticks; double_digit sub_ticks; } ExprBase; typedef struct _exprTree { ExprBase expr; ExprPtr left; ExprPtr right; } ExprTree; typedef struct _exprConst { ExprBase expr; Value constant; } ExprConst; typedef struct _exprAtom { ExprBase expr; Atom atom; SymbolPtr symbol; Bool privateFound; /* used to clarify error message for missing names */ } ExprAtom; typedef struct _exprCode { ExprBase expr; CodePtr code; } ExprCode; typedef struct _exprDecls { ExprBase expr; DeclListPtr decl; Class class; Type *type; Publish publish; } ExprDecl; typedef struct _exprType { ExprBase expr; ExprPtr left; Type *type; } ExprType; typedef union _expr { ExprBase base; ExprTree tree; ExprConst constant; ExprAtom atom; ExprCode code; ExprDecl decl; ExprType type; } Expr; Expr *NewExprTree (int tag, Expr *left, Expr *right); Expr *NewExprComma (Expr *left, Expr *right); Expr *NewExprConst (int tag, Value val); Expr *NewExprAtom (Atom atom, SymbolPtr symbol, Bool privateFound); Expr *NewExprCode (CodePtr code, ExprPtr name); Expr *NewExprDecl (int tag, DeclListPtr decl, Class class, Type *type, Publish publish); Expr *NewExprType (int tag, Expr *left, Type *type); Expr *ExprRehang (Expr *expr, Expr *right); typedef struct _codeBase { DataType *data; Bool builtin; Type *type; int argc; Bool varargs; ArgType *args; ExprPtr name; CodePtr previous; CodePtr func; /* function context, usually self */ Value doc; /* documentation */ } CodeBase; /* * Static initializers: * * Two kinds: * static * global * * Static initializers are essentially parallel functions called when * the function is evaluated; the value resulting from this evaluation * contains a pointer to the function body along with a block of initialized * statics. They can therefore access any *static* variables in the * function scope as well as any other variables in *dynamic* scope * at the time of function evaluation, which means they can access * any name they can see *except* for dynamic variables in the function * scope. * * Global initializers are run in a global context, they can only access * variables which have global lifetime, that means only global variables. * When found inside a function context, they are placed in the static * initializer block of the enclosing function at global scope. * * * function foo() { * auto foo_a = 1; * static foo_s = 2; * global foo_g = 3; * * function bar() { * auto bar_a1 = 4; <- can touch any name in scope * global bar_g1 = foo_g; <- legal * global bar_g2 = foo_s; <- not legal * static bar_s1 = foo_g; <- legal * static bar_s2 = foo_s; <- legal * static bar_s3 = foo_a; <- legal * static bar_s4 = bar_a1; <- not legal * } * } */ typedef struct _funcBody { ObjPtr obj; BoxTypesPtr dynamics; } FuncBody, *FuncBodyPtr; typedef struct _funcCode { CodeBase base; ExprPtr code; FuncBody body; FuncBody staticInit; BoxTypesPtr statics; Bool inStaticInit; Bool inGlobalInit; } FuncCode, *FuncCodePtr; typedef union _builtinFunc { Value (*builtinN)(int, Value *); Value (*builtin0)(void); Value (*builtin1)(Value); Value (*builtin2)(Value,Value); Value (*builtin3)(Value,Value,Value); Value (*builtin4)(Value,Value,Value,Value); Value (*builtin5)(Value,Value,Value,Value,Value); Value (*builtin6)(Value,Value,Value,Value,Value,Value); Value (*builtin7)(Value,Value,Value,Value,Value,Value,Value); Value (*builtin8)(Value,Value,Value,Value,Value,Value,Value,Value); Value (*builtinNJ)(InstPtr *, int, Value *); Value (*builtin0J)(InstPtr *); Value (*builtin1J)(InstPtr *,Value); Value (*builtin2J)(InstPtr *,Value,Value); } BuiltinFunc; typedef struct _builtinCode { CodeBase base; Bool needsNext; BuiltinFunc b; } BuiltinCode, *BuiltinCodePtr; typedef union _code { CodeBase base; FuncCode func; BuiltinCode builtin; } Code; CodePtr NewFuncCode (Type *type, ArgType *args, ExprPtr code, Value doc); CodePtr NewBuiltinCode (Type *type, ArgType *args, int argc, BuiltinFunc func, Bool needsNext, char *doc); Value NewFunc (CodePtr, FramePtr); typedef struct _farJump { DataType *data; int inst; int twixt; int catch; int frame; } FarJump, *FarJumpPtr; FarJumpPtr NewFarJump (int inst, int twixt, int catch, int frame); Value FarJumpContinuation (ContinuationPtr continuation, FarJumpPtr farJump); #define InstPush 0x01 typedef struct _instBase { OpCode opCode; short flags; } InstBase; typedef struct _instBox { InstBase inst; BoxPtr box; } InstBox; typedef struct _instFrame { InstBase inst; short staticLink; short element; } InstFrame; typedef struct _instConst { InstBase inst; Value constant; } InstConst; typedef struct _instAtom { InstBase inst; Atom atom; } InstAtom; typedef struct _instInt { InstBase inst; int value; } InstInt; typedef struct _instStruct { InstBase inst; StructType *structs; } InstStruct; typedef struct _instArray { InstBase inst; short ndim; short resizable; TypePtr type; } InstArray; typedef enum _aInitMode { AInitModeStart, /* Build initialization data on stack */ AInitModeElement, /* Initialize one element */ AInitModeRepeat, /* Duplicate initialization values along row */ AInitModeFunc, /* Build stack frame for function call */ AInitModeTest, /* Check to see if the array is completely initialized */ AInitModeFuncDone /* Clean up */ } AInitMode; typedef struct _instAInit { InstBase inst; int dim; AInitMode mode; } InstAInit; typedef struct _instHash { InstBase inst; TypePtr type; } InstHash; typedef struct _instCode { InstBase inst; CodePtr code; } InstCode; typedef enum _branchMod { BranchModNone, BranchModBreak, BranchModContinue, BranchModReturn, BranchModReturnVoid, BranchModCatch } BranchMod; typedef struct _instBranch { InstBase inst; int offset; BranchMod mod; } InstBranch; typedef struct _instBinOp { InstBase inst; BinaryOp op; } InstBinOp; typedef struct _instBinFunc { InstBase inst; BinaryFunc func; } InstBinFunc; typedef struct _instUnOp { InstBase inst; UnaryOp op; } InstUnOp; typedef struct _instUnFunc { InstBase inst; UnaryFunc func; } InstUnFunc; typedef struct _instAssign { InstBase inst; Bool initialize; } InstAssign; typedef struct _instObj { InstBase inst; ObjPtr obj; } InstObj; typedef struct _instCatch { InstBase inst; int offset; SymbolPtr exception; } InstCatch; typedef struct _instRaise { InstBase inst; int argc; SymbolPtr exception; } InstRaise; typedef struct _instTwixt { InstBase inst; int enter; int leave; } InstTwixt; typedef struct _instTagCase { InstBase inst; int offset; Atom tag; } InstTagCase; typedef struct _instUnwind { InstBase inst; int twixt; int catch; } InstUnwind; typedef struct _instFarJump { InstBase inst; FarJumpPtr farJump; BranchMod mod; } InstFarJump; typedef struct _instIsType { InstBase inst; TypePtr type; } InstIsType; typedef union _inst { InstBase base; InstBox box; InstFrame frame; InstConst constant; InstAtom atom; InstInt ints; InstStruct structs; InstArray array; InstAInit ainit; InstHash hash; InstCode code; InstBranch branch; InstBinOp binop; InstBinFunc binfunc; InstUnOp unop; InstUnFunc unfunc; InstAssign assign; InstObj obj; InstCatch catch; InstRaise raise; InstTwixt twixt; InstTagCase tagcase; InstUnwind unwind; InstFarJump farJump; InstIsType isType; } Inst; /* * A structure used to process non-structured * control flow changes (break, continue, return) * within the presence of twixt/catch */ typedef enum _nonLocalKind { NonLocalControl, NonLocalTwixt, NonLocalTry, NonLocalCatch } NonLocalKind; #define NON_LOCAL_RETURN 0 #define NON_LOCAL_BREAK 1 #define NON_LOCAL_CONTINUE 2 typedef struct _nonLocal { DataType *data; struct _nonLocal *prev; NonLocalKind kind; /* kind of non local object */ int target; /* what kind of targets */ ObjPtr obj; } NonLocal, *NonLocalPtr; typedef struct _Stat { int inst; ExprPtr stat; } Stat, *StatPtr; typedef struct _obj { DataType *data; int size; int used; int size_stat; int used_stat; double_digit ticks; double_digit sub_ticks; Bool error; NonLocal *nonLocal; Inst insts[0]; } Obj; static inline InstPtr ObjCode(Obj *obj, int i) { return &(obj->insts[i]); } static inline int ObjLast(Obj *obj) { return obj->used - 1; } static inline StatPtr ObjStat(Obj *obj, int i) { StatPtr stats = (StatPtr) ObjCode(obj,obj->size); return &stats[i]; } ObjPtr CompileStat (ExprPtr expr, CodePtr code); ObjPtr CompileExpr (ExprPtr expr, CodePtr code); ExprPtr ObjStatement (ObjPtr obj, InstPtr inst); typedef enum _wakeKind { WakeAll, WakeOne } WakeKind; extern Bool lastThreadError; Value NewThread (FramePtr frame, ObjPtr code); void ThreadSleep (Value thread, Value sleep, int priority); void ThreadStepped (Value thread); void ThreadsWakeup (Value sleep, WakeKind wake); void ThreadsRun (Value thread, Value lex); void ThreadsInterrupt (void); void ThreadsSignal (Value signal); void ThreadsContinue (void); void ThreadFinish (Value thread, Bool error); void ThreadSetState (Value thread, ThreadState state); void ThreadInit (void); void TraceFunction (Value file, FramePtr frame, CodePtr code, ExprPtr name); void TraceFrame (Value file, FramePtr frame, ObjPtr obj, InstPtr pc, int depth); void ThreadStackDump (Value thread); void ThreadsBlock (void); typedef void (*NickleBlockHandler) (void *closure); void ThreadsRegisterBlockHandler (NickleBlockHandler handler, void *closure); void ThreadsUnregisterBlockHandler (NickleBlockHandler handler, void *closure); typedef struct _jump { DataType *data; TwixtPtr enter; TwixtPtr entering; TwixtPtr leave; TwixtPtr parent; ContinuationPtr continuation; Value ret; } Jump; Value JumpContinue (Value thread, InstPtr *next); InstPtr JumpStart (Value thread, ContinuationPtr continuation, Value ret); JumpPtr NewJump (TwixtPtr leave, TwixtPtr enter, TwixtPtr parent, ContinuationPtr continuation, Value ret); extern Value running; /* current thread */ extern Value stopped; /* stopped threads */ extern Bool complete; /* must complete current inst */ extern Bool profiling; /* profiling is active */ void InstDump (InstPtr inst, int indent, int i, int *branch, int maxbranch); void ObjDump (ObjPtr obj, int indent); void SymbolInit (void); extern NamespacePtr DebugNamespace; extern NamespacePtr FileNamespace; extern NamespacePtr MathNamespace; #ifdef BSD_RANDOM extern NamespacePtr BSDRandomNamespace; #endif extern NamespacePtr SemaphoreNamespace; extern NamespacePtr StringNamespace; extern NamespacePtr ThreadNamespace; extern NamespacePtr CommandNamespace; #ifdef GCD_DEBUG extern NamespacePtr GcdNamespace; #endif extern NamespacePtr EnvironNamespace; extern NamespacePtr DateNamespace; void BuiltinInit (void); Bool DebugSetFrame (Value continuation, int offset); void DebugStart (Value continuation); void DebugBreak (Value thread); void ProfileInterrupt (Value thread); typedef Bool (*TimerFunc) (void *closure); unsigned long TimeInMs (void); void TimerInsert (void *closure, TimerFunc func, unsigned long delta, unsigned long incr); void TimerInterrupt (void); void TimerInit (void); void IoInit (void); void IoStart (void); void IoStop (void); void IoFini (void); Bool IoTimeout (void *); void IoNoticeWriteBlocked (void); #ifdef NO_PIPE_SIGIO void IoNoticeReadBlocked (void); #endif void IoNoticeTtyUnowned (void); void IoInterrupt (void); void FileFini (void); void ProcessInterrupt (void); void *AllocateTemp (int size); typedef struct _ProfileData { double_digit sub; double_digit self; } ProfileData; void PrettyPrint (Value f, Publish publish, SymbolPtr name); void PrettyCode (Value f, CodePtr code, Atom name, Class class, Publish publish, int level, Bool nest); void PrettyStat (Value F, Expr *e, Bool nest); void PrettyExpr (Value f, Expr *e, int parentPrec, int level, Bool nest); void EditFunction (SymbolPtr name, Publish publish); void EditFile (Value file_name); Value lookupVar (char *ns, char *n); void setVar (NamespacePtr, char *, Value, Type *type); void GetNamespace (NamespacePtr *, FramePtr *, CodePtr *); Bool NamespaceLocate (Value names, NamespacePtr *s, SymbolPtr *symbol, Publish *publish, Bool complain); ExprPtr BuildName (char *ns_name, char *name); ExprPtr BuildCall (char *, char *, int, ...); ExprPtr BuildFullname (ExprPtr colonnames, Atom name); ExprPtr BuildRawname (ExprPtr colonnames, Atom name); Atom LexFileName (void); int LexFileLine (void); Bool LexInteractive (void); Bool LexResetInteractive (void); void LexInit (void); void NewLexInput (Value file, Atom name, Bool after, Bool interactive); #if HAVE_LIBREADLINE extern volatile int stdin_in_readline; #endif int yywrap (void); void yyerror (char *msg); void ParseError (char *fmt, ...); int yylex (void); Bool LexFile (char *file, Bool complain, Bool after); Value atov (char *, int), aetov (char *, int); extern int ignorenl; void skipcomment (void); Value lexdoc (void); void skipline (void); int lexEscape (int); extern void init (void); extern int yyparse (void); extern int stdin_interactive; void intr(int); void stop (int), die (int), segv (int); void catchSignal (int sig, void (*func) (int sig)); void resetSignal (int sig, void (*func) (int sig)); extern Value yyinput; /* Standard exceptions */ typedef enum _standardException { exception_none, exception_uninitialized_value, /* */ exception_invalid_argument, /* string integer poly */ exception_readonly_box, /* poly */ exception_invalid_array_bounds, /* poly poly */ exception_divide_by_zero, /* number number */ exception_invalid_struct_member,/* poly string */ exception_invalid_binop_values, /* poly poly */ exception_invalid_unop_value, /* poly */ exception_open_error, /* string integer string */ exception_io_error, /* string integer file */ exception_name_error, /* string integer string */ exception_signal, /* integer */ exception_system_error, /* string integer poly */ exception_io_eof, /* file */ _num_standard_exceptions } StandardException; void RaiseException (Value thread, SymbolPtr exception, Value ret, InstPtr *next); void RegisterStandardException (StandardException se, SymbolPtr sym); void RaiseStandardException (StandardException se, int argc, ...); SymbolPtr CheckStandardException (void); Value JumpStandardException (Value thread, InstPtr *next); static inline Value IntIncDec (Value av, BinaryOp operator) { int a = ValueInt(av); if (operator == PlusOp) a++; else a--; if (NICKLE_INT_CARRIED(a)) return NewIntInteger (a); return NewInt (a); } static inline Value ValueIncDec(Value v, BinaryOp o) { if (ValueIsInt(v)) return IntIncDec(v,o); else return BinaryOperate(v, One, o); } static inline Value BoxValue (BoxPtr box, int e) { Value v = BoxElements(box)[e]; if (!v) { RaiseStandardException (exception_uninitialized_value, 0); return (Void); } return v; } static inline Value Dereference (Value v) { if (!ValueIsRef(v)) { RaiseStandardException (exception_invalid_unop_value, 1, v); return Void; } v = RefValueGet(v); if (!v) { RaiseStandardException (exception_uninitialized_value, 0); return (Void); } return REFERENCE (v); } /* vararg builtins */ Value do_printf (int, Value *); Value do_fprintf (int, Value *); Value do_imprecise (int, Value *); Value do_Thread_kill (int, Value *); Value do_Thread_trace (int, Value *); Value do_Thread_trace (int, Value *); Value do_History_show (int, Value *); Value do_string_to_integer (int, Value *); Value do_Semaphore_new (int, Value *); Value do_Command_undefine (int, Value *); Value do_Command_pretty_print (int , Value *); /* zero argument builtins */ Value do_Thread_cont (void); Value do_Thread_current (void); Value do_Thread_list (void); Value do_time (void); Value do_File_string_write (void); Value do_Debug_up (void); Value do_Debug_down (void); Value do_Debug_done (void); Value do_Debug_collect (void); Value do_Debug_help (void); Value do_File_mkpipe (void); Value do_millis (void); /* one argument builtins */ Value do_sleep (Value); Value do_exit (Value); Value do_dim (Value); Value do_dims (Value); Value do_reference (Value); Value do_string_to_real (Value); Value do_abs (Value); Value do_floor (Value); Value do_func_args (Value); Value do_ceil (Value); Value do_exponent (Value); Value do_mantissa (Value); Value do_numerator (Value); Value do_denominator (Value); Value do_precision (Value); Value do_sign (Value); Value do_bit_width (Value); Value do_is_int (Value); Value do_is_rational (Value); Value do_is_number (Value); Value do_is_string (Value); Value do_is_file (Value); Value do_is_thread (Value); Value do_is_semaphore (Value); Value do_is_continuation (Value); Value do_is_array (Value); Value do_is_hash (Value); Value do_is_ref (Value); Value do_is_struct (Value); Value do_is_func (Value); Value do_is_bool (Value); Value do_is_void (Value); Value do_is_uninit (Value); Value do_make_uninit (Value); Value do_hash (Value); Value do_Thread_get_priority (Value); Value do_Thread_id_to_thread (Value); Value do_Thread_join (Value); Value do_Semaphore_signal (Value); Value do_Semaphore_count (Value); Value do_Semaphore_wait (Value); Value do_Semaphore_test (Value); Value do_File_close (Value); Value do_File_flush (Value); Value do_File_getb (Value); Value do_File_getc (Value); Value do_File_end (Value); Value do_File_error (Value); Value do_File_clear_error (Value); Value do_File_string_read (Value); Value do_File_string_string (Value); Value do_File_isatty (Value); Value do_File_status (Value); Value do_File_unlink (Value); Value do_File_rmdir (Value); Value do_String_length (Value); Value do_String_new (Value); Value do_Primitive_random (Value); Value do_Primitive_srandom (Value); Value do_Debug_dump (Value); Value do_Debug_dump_active (void); Value do_Command_delete (Value); Value do_Command_edit (Value); Value do_Command_display (Value); Value do_Command_valid_name (Value); Value do_Environ_check (Value); Value do_Environ_get (Value); Value do_Environ_unset (Value); Value do_profile (Value); /* two argument builtins */ Value do_Thread_set_priority (Value, Value); Value do_Thread_signal (Value, Value); Value do_File_open (Value, Value); Value do_gcd (Value, Value); Value do_xor (Value, Value); Value do_Math_pow (Value, Value); Value do_Math_assignpow (Value, Value); Value do_Math_popcount (Value); Value do_Math_factorial (Value); Value do_File_putb (Value, Value); Value do_File_putc (Value, Value); Value do_File_ungetb (Value, Value); Value do_File_ungetc (Value, Value); Value do_File_setbuf (Value, Value); Value do_File_rename (Value, Value); Value do_File_mkdir (Value, Value); Value do_String_index (Value, Value); Value do_setjmp (Value, Value); Value do_setdims (Value, Value); Value do_setdim (Value, Value); Value do_Command_new (Value, Value); Value do_Command_new_names (Value, Value); #ifdef GCD_DEBUG Value do_Gcd_bdivmod (Value, Value); Value do_Gcd_kary_reduction (Value, Value); #endif Value do_Environ_set (Value, Value); /* three argument builtins */ Value do_File_vfprintf (Value, Value, Value); Value do_String_substr (Value, Value, Value); Value do_File_reopen (Value, Value, Value); Value do_File_filter (Value file, Value argv, Value filev); /* four argument builtins */ Value do_Command_lex_input (Value file, Value name, Value after, Value interactive); /* seven argument builtins */ Value do_File_print (Value, Value, Value, Value, Value, Value, Value); /* two argument non-local builtins */ Value do_longjmp (InstPtr *, Value, Value); /* hash builtins (for testing) */ Value do_hash_new (void); Value do_hash_get (Value, Value); Value do_hash_del (Value, Value); Value do_hash_test (Value, Value); Value do_hash_set (Value, Value, Value); Value do_hash_keys (Value); nickle_2.81.orig/io.c0000664000175000000620000000500111711406551013650 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include #include #include #include #include "nickle.h" #include "ref.h" volatile Bool signalIo; Bool stdinOwned; Bool stdinPolling; Bool ioTimeoutQueued; Bool anyFileWriteBlocked; #ifdef HAVE_SIGACTION #define RESTART_SIGNAL(sig,func) #else #define RESTART_SIGNAL(sig,func) (void) signal (sig,func) #endif static void sigio (int sig) { resetSignal (SIGIO, sigio); SetSignalIo (); } void IoInterrupt (void) { FileCheckBlocked (False); } void IoStop (void) { if (stdin_interactive) { FileResetFd (0); stdinOwned = False; } } #ifdef GETPGRP_VOID #define GetPgrp() getpgrp() #else #define GetPgrp() getpgrp(0) #endif static Bool IoOwnTty (int fd) { int tpgrp; tpgrp = tcgetpgrp (fd); if (tpgrp == -1 || tpgrp == GetPgrp()) return True; return False; } void IoStart (void) { if (stdin_interactive) { stdinOwned = IoOwnTty (0); if (stdinOwned) { stdinPolling = False; FileSetFd (0); } } else stdinOwned = True; } void IoFini (void) { FileStdin->file.flags |= FileBlockWrites; FileClose (FileStdin); FileStdout->file.flags |= FileBlockWrites; FileClose (FileStdout); FileStderr->file.flags |= FileBlockWrites; FileClose (FileStderr); } Value FileStdin, FileStdout, FileStderr; Bool IoTimeout (void *closure) { if (!stdinOwned) IoStart (); FileCheckBlocked (False); if (anyFileWriteBlocked || (!stdinOwned && stdinPolling) #ifdef NO_PIPE_SIGIO || anyPipeReadBlocked #endif ) return True; ioTimeoutQueued = False; return False; } static void IoSetupTimeout (void) { if (!ioTimeoutQueued) { ioTimeoutQueued = True; TimerInsert (0, IoTimeout, 100, 100); } } void IoNoticeTtyUnowned (void) { if (!stdinOwned && !stdinPolling) { stdinPolling = True; IoSetupTimeout(); } } void IoNoticeWriteBlocked (void) { IoSetupTimeout (); } #ifdef NO_PIPE_SIGIO void IoNoticeReadBlocked (void) { IoSetupTimeout (); } #endif void IoInit (void) { ENTER (); catchSignal (SIGIO, sigio); FileStdin = FileCreate (0, FileReadable); FileStdout = FileCreate (1, FileWritable); FileStderr = FileCreate (2, FileWritable); MemAddRoot (FileStdin); MemAddRoot (FileStdout); MemAddRoot (FileStderr); IoStart (); EXIT (); } nickle_2.81.orig/gcd.c0000664000175000000620000004521111711555355014014 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * gcd.c * * compute gcd of two natural numbers * * The Accelerated Integer GCD Algorithm * * Kenneth Weber * Kent State University * ACM Transactions on Mathematical Software, Vol 21, No. 1 March 1995, Pages 111-122 */ #include "nickle.h" #undef CHECK #undef DEBUG_BMOD #undef DEBUG_BDIVMOD #undef DEBUG_GCD #undef DEBUG_KARY #undef DEBUG_RATMOD #undef DEBUG_FIX #undef DEBUG_POINTERS /* #define STATS */ #ifdef STATS #define START int steps = 0 #define STEP steps++ #define FINISH(op) FilePrintf (FileStdout, "%s %d steps\n", op, steps), steps = 0 #else #define START #define STEP #define FINISH(op) #endif #ifdef DEBUG_POINTERS #define GcdCheckPointer(a,b,c) MemCheckPointer(a,b,c) #else #define GcdCheckPointer(a,b,c) #endif static void NaturalRslInplace (Natural *v, int shift) { digit *vt, *rt; digit d1, d2; int length; int dshift; int index, last; #ifdef LLBASE2 dshift = (shift >> LLBASE2); shift = (shift & (LBASE2 - 1)); #else dshift = shift / LBASE2; shift = shift % LBASE2; #endif length = v->length - dshift; index = length; last = 1; if (length > 0 && (NaturalDigits(v)[v->length - 1] >> shift) == 0) { length--; last = 0; } if (length <= 0) { v->length = 0; return; } rt = NaturalDigits (v); vt = NaturalDigits (v) + dshift; v->length = length; if (shift) { d2 = *vt++; while (--index) { d1 = d2; d2 = *vt++; *rt++ = (d1 >> shift) | (d2 << (LBASE2 - shift)); } if (last) *rt++ = (d2 >> shift); } else { while (length--) { *rt++ = *vt++; } } } /* * compute u/v mod 2**s */ digit DigitBmod (digit u, digit v, int s) { int i; digit umask = 0; digit imask = 1; digit smask; digit m = 0; #ifdef DEBUG_BMOD FilePrintf (FileStdout, "DigitBmod (%u, %u, %d)\n", u, v, s); #endif if (s == DIGITBITS) smask = MAXDIGIT; else smask = (1 << s) - 1; for (i = 0; i < s; i++) { umask |= imask; if (u & umask) { u = (u - v) & smask; m = m | imask; } imask <<= 1; v <<= 1; } #ifdef DEBUG_BMOD FilePrintf (FileStdout, " = %u\n", m); #endif return m; } static int DigitWidth (digit i) #if DIGITBITS == 32 { int w; w = 0; if (i & 0xffff0000) w += 16; else i <<= 16; if (i & 0xff000000) w += 8; else i <<= 8; if (i & 0xf0000000) w += 4; else i <<= 4; if (i & 0xc0000000) w += 2; else i <<= 2; if (i & 0x80000000) w++; return w; } #endif #if DIGITBITS == 16 { int w; w = 0; if (i & 0xff00) w += 8; else i <<= 8; if (i & 0xf000) w += 4; else i <<= 4; if (i & 0xc000) w += 2; else i <<= 2; if (i & 0x8000) w++; return w; } #endif int NaturalWidth (Natural *u) { int w; if (NaturalZero (u)) return 0; w = NaturalLength (u) - 1; return DigitWidth (NaturalDigits (u)[w]) + (w << LLBASE2); } int IntWidth (int i) { int w; if (i < 0) i = -i; w = 0; while (i) { w++; i >>= 1; } return w; } int DoubleDigitWidth (double_digit i) { int w; w = 0; while (i) { w++; i >>= 1; } return w; } /* * Return multiplicative inverse of d in 2**DIGITBITS * * This is just d ** (2**DIGITBITS-1) */ static digit DigitInverse (digit d) { digit b = MAXDIGIT; digit result = 1; for (;;) { result = result * d; b >>= 1; if (!b) break; d = d * d; } return result; } static void NaturalBdivmodStepInplace (Natural *u, Natural *v, digit b, Bool shift) { double_digit quo; digit carry_mul; digit carry_sub; digit quo_d; digit d; digit r; digit *vd = NaturalDigits(v); digit *ud = NaturalDigits(u); digit *rd = ud; int i; carry_mul = 0; carry_sub = 0; for (i = 0; i < NaturalLength (v); i++) { quo = (double_digit) b * (double_digit) *vd++ + carry_mul; carry_mul = DivBase (quo); quo_d = ModBase (quo) + carry_sub; d = *ud++; if (quo_d) { carry_sub = 0; GcdCheckPointer (u, ud, sizeof (digit)); if ((r = d - quo_d) > d) carry_sub = 1; } else r = d; if (!shift || i) *rd++ = r; } carry_sub = carry_sub + carry_mul; while (carry_sub && i < NaturalLength (u)) { quo_d = carry_sub; carry_sub = 0; GcdCheckPointer (u, ud, sizeof (digit)); d = *ud++; if ((r = d - quo_d) > d) carry_sub = 1; if (!shift || i) *rd++ = r; i++; } while (i < NaturalLength (u)) { GcdCheckPointer (u, ud, sizeof (digit)); r = *ud++; if (!shift || i) *rd++ = r; i++; } /* * The caller must ensure that an extra digit space * is available for this operation */ if (carry_sub) { quo_d = carry_sub; carry_sub = 0; GcdCheckPointer (u, ud, sizeof (digit)); d = 0; if ((r = d - quo_d) > d) carry_sub = 1; if (!shift || i) *rd++ = r; i = rd - NaturalDigits(u); /* * Two's compliment negative results */ carry_sub = 1; rd = NaturalDigits (u); while (i--) { d = *rd; *rd++ = (~d) + carry_sub; if (d) carry_sub = 0; } } /* * Trim leading zeros */ while (--rd >= NaturalDigits (u) && *rd == 0) ; u->length = ((rd + 1) - NaturalDigits (u)); } static void NaturalBdivmodInplace (Natural *u, Natural *v, int bits) { digit v0_inv = DigitInverse (NaturalDigits(v)[0]); digit q0; #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "v0 %x v0_inv %x\n", NaturalDigits(v)[0], v0_inv); #endif while (bits >= DIGITBITS) { q0 = NaturalDigits(u)[0] * v0_inv; #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "u[0] %x q0 %x\n", NaturalDigits(u)[0], q0); #endif if (q0) NaturalBdivmodStepInplace (u, v, q0, True); else NaturalRslInplace (u, DIGITBITS); #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "bits %d u %N\n", bits, u); #endif bits -= DIGITBITS; } if (bits) { digit dmask = ((digit) 1 << bits) - 1; q0 = ((NaturalDigits(u)[0] & dmask) * v0_inv) & dmask; #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "u[0] %x q0 %x dmask %x\n", NaturalDigits(u)[0], q0, dmask); #endif if (q0) NaturalBdivmodStepInplace (u, v, q0, False); NaturalRslInplace (u, bits); #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "bits %d u %N\n", bits, u); #endif } } Natural * NaturalBdivmod (Natural *u_orig, Natural *v) { ENTER (); Natural *u; u = AllocNatural (u_orig->length + 2); NaturalCopy (u_orig, u); NaturalBdivmodInplace (u, v, NaturalWidth (u) - NaturalWidth (v) + 1); RETURN (u); } #if 0 static void oldNaturalBdivmodStepInplace (Natural *u, Natural *v, int bits, Bool shift) { double_digit quo; digit carry_mul; digit carry_sub; digit quo_d; digit d; digit b; digit r; digit *vd = NaturalDigits(v); digit *ud = NaturalDigits(u); digit *rd = ud; int i; b = DigitBmod (*ud, *vd, bits); carry_mul = 0; carry_sub = 0; for (i = 0; i < NaturalLength (v); i++) { quo = (double_digit) b * (double_digit) *vd++ + carry_mul; carry_mul = DivBase (quo); quo_d = ModBase (quo) + carry_sub; d = *ud++; if (quo_d) { carry_sub = 0; GcdCheckPointer (u, ud, sizeof (digit)); if ((r = d - quo_d) > d) carry_sub = 1; } else r = d; if (!shift || i) *rd++ = r; } carry_sub = carry_sub + carry_mul; while (carry_sub && i < NaturalLength (u)) { quo_d = carry_sub; carry_sub = 0; GcdCheckPointer (u, ud, sizeof (digit)); d = *ud++; if ((r = d - quo_d) > d) carry_sub = 1; if (!shift || i) *rd++ = r; i++; } while (i < NaturalLength (u)) { r = *ud++; if (!shift || i) *rd++ = r; i++; } /* * The caller must ensure that an extra digit space * is available for this operation */ if (carry_sub) { quo_d = carry_sub; carry_sub = 0; GcdCheckPointer (u, ud, sizeof (digit)); d = 0; if ((r = d - quo_d) > d) carry_sub = 1; if (!shift || i) *rd++ = r; i = rd - NaturalDigits(u); /* * Two's compliment negative results */ carry_sub = 1; rd = NaturalDigits (u); while (i--) { d = *rd; *rd++ = (~d) + carry_sub; if (d) carry_sub = 0; } } while (*--rd == 0) if (rd == NaturalDigits (u)) { NaturalLength (u) = 0; return; } NaturalLength (u) = (rd - NaturalDigits (u)) + 1; } static void oldNaturalBdivmodInplace (Natural *u, Natural *v, int d) { ENTER (); digit v0; digit dmask; v0 = NaturalDigits(v)[0]; while (d >= DIGITBITS) { #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "u[0] %x\n", NaturalDigits(u)[0]); #endif if (NaturalDigits(u)[0]) { oldNaturalBdivmodStepInplace (u, v, DIGITBITS, True); #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "d %d u %N\n", d, u); #endif } else { NaturalRslInplace (u, DIGITBITS); } d -= DIGITBITS; } if (d) { dmask = (((digit) 1) << d) - 1; if (NaturalDigits(u)[0] & dmask) { oldNaturalBdivmodStepInplace (u, v, d, False); #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "d %d u %N\n", d, u); #endif } if (NaturalLength (u)) NaturalRslInplace (u, d); } #ifdef DEBUG_BDIVMOD FilePrintf (FileStdout, "result u %N (shift %d)\n", u, d); #endif EXIT (); } static Natural * oldNaturalBdivmod (Natural *u_orig, Natural *v) { ENTER (); Natural *u; u = AllocNatural (u_orig->length + 2); NaturalCopy (u_orig, u); oldNaturalBdivmodInplace (u, v, NaturalWidth (u) - NaturalWidth (v) + 1); RETURN (u); } #define NaturalBdivmod oldNaturalBdivmod #define NaturalBdivmodInplace oldNaturalBdivmodInplace #endif #define Odd(n) (NaturalDigits(n)[0] & 1) static int NaturalZeroBits (Natural *u) { digit *ut = NaturalDigits (u); digit d; int z = 0; if (u->length) { while ((d = *ut++) == 0) z += LBASE2; while ((d & 1) == 0) { z++; d >>= 1; } } return z; } static void ReducedRatMod (Natural *x, Natural *y, digit *np, digit *dp) { digit n1, n2, nt, n2i; digit d1, d2, dt; digit c; int w2; c = DigitBmod (NaturalDigits(x)[0], NaturalDigits(y)[0], DIGITBITS); n1 = c; d1 = 1; n2 = -n1; d2 = -1; while ((w2 = DigitWidth (n2)) > DIGITBITS/2) { int i = DigitWidth (n1) - w2; while (n1 >= n2) { if (n1 >= (n2i = n2 << i)) { n1 = n1 - n2i; d1 = d1 - (d2 << i); } i--; } nt = n1; n1 = n2; n2 = nt; dt = d1; d1 = d2; d2 = dt; #ifdef DEBUG_RATMOD FilePrintf (FileStdout, "n1 %d n2 %d d1 %d d2 %d\n", n1, n2, d1, d2); #endif } *np = n2; *dp = d2; #ifdef DEBUG_RATMOD FilePrintf (FileStdout, "u %n v %n\n", x, y); FilePrintf (FileStdout, "c %u n %u d %u/%u\n", c, *np, *dp, d2); #endif } static void NaturalKaryReductionInplace (Natural *u, Natural *v) { ENTER (); digit n, d; digit *ud, *vd, *rd; double_digit qd, qv; digit carry_d, carry_v, carry; digit quo_d, quo_v, r; int i; Bool add; int lim; ReducedRatMod (u, v, &n, &d); add = False; if (d & (1 << DIGITBITS/2)) { add = True; d = -d & ((1 << DIGITBITS/2) - 1); #ifdef DEBUG_KARY FilePrintf (FileStdout, "d changed to %d\n", d); #endif } ud = NaturalDigits (u); vd = NaturalDigits (v); rd = NaturalDigits (u); carry = 0; carry_d = 0; carry_v = 0; lim = NaturalLength (v); if (lim > NaturalLength (u)) lim = NaturalLength (u); for (i = 0; i < lim; i++) { GcdCheckPointer (u, ud, sizeof (digit)); qd = (double_digit) d * (double_digit) *ud++ + carry_d; carry_d = DivBase (qd); quo_d = ModBase (qd); GcdCheckPointer (v, vd, sizeof (digit)); qv = (double_digit) n * (double_digit) *vd++ + carry_v; carry_v = DivBase (qv); quo_v = ModBase (qv); quo_v = quo_v + carry; if (quo_v) { carry = 0; if (add) { if ((r = quo_d + quo_v) < quo_d) carry = 1; } else { if ((r = quo_d - quo_v) > quo_d) carry = 1; } } else r = quo_d; GcdCheckPointer (u, rd, sizeof (digit)); if (i) *rd++ = r; } for (; i < NaturalLength (u); i++) { GcdCheckPointer (u, ud, sizeof (digit)); qd = (double_digit) d * (double_digit) *ud++ + carry_d; carry_d = DivBase (qd); quo_d = ModBase (qd); quo_v = carry_v + carry; carry_v = 0; if (quo_v) { carry = 0; if (add) { if ((r = quo_d + quo_v) < quo_d) carry = 1; } else { if ((r = quo_d - quo_v) > quo_d) carry = 1; } } else r = quo_d; GcdCheckPointer (u, rd, sizeof (digit)); if (i) *rd++ = r; } for (; i < NaturalLength (v); i++) { quo_d = carry_d; carry_d = 0; GcdCheckPointer (v, vd, sizeof (digit)); qv = (double_digit) n * (double_digit) *vd++ + carry_v; carry_v = DivBase (qv); quo_v = ModBase (qv); quo_v = quo_v + carry; if (quo_v) { carry = 0; if (add) { if ((r = quo_d + quo_v) < quo_d) carry = 1; } else { if ((r = quo_d - quo_v) > quo_d) carry = 1; } } else r = quo_d; GcdCheckPointer (u, rd, sizeof (digit)); if (i) *rd++ = r; } quo_d = carry_d; quo_v = carry_v + carry; if (quo_v) { carry = 0; if (add) { if ((r = quo_d + quo_v) < quo_d) carry = 1; } else { if ((r = quo_d - quo_v) > quo_d) carry = 1; } } else r = quo_d; *rd++ = r; if (carry) { if (add) abort (); else { /* * Two's compliment negative result */ i = rd - NaturalDigits (u); rd = NaturalDigits (u); carry = 1; while (i--) { r = *rd; *rd++ = (~r) + carry; if (r) carry = 0; } } } i = rd - NaturalDigits (u); while (i > 0 && *--rd == 0) i--; u->length = i; #ifdef DEBUG_KARY FilePrintf (FileStdout, "Reduction result %n\n", u); #endif EXIT (); } Natural * NaturalKaryReduction (Natural *u, Natural *v) { ENTER (); Natural *t; int len; len = NaturalLength (u); if (len < NaturalLength (v)) len = NaturalLength (v); t = AllocNatural (len + 1); NaturalCopy (u, t); NaturalKaryReductionInplace (t, v); RETURN (t); } /* * Allocate space and initialize for GCD. Extra space is needed for the * rational reduction step */ static Natural * NaturalGcdNormalize (Natural *u, int shift) { ENTER (); Natural *r; int dshift; digit d1, d2; digit *ut, *rt; int index; dshift = shift >> LLBASE2; shift = shift & (LBASE2 - 1); r = AllocNatural (NaturalLength (u) - dshift + 2); rt = NaturalDigits (r); ut = NaturalDigits (u) + dshift; index = NaturalLength (u) - dshift; if (shift) { d2 = *ut++; while (--index) { d1 = d2; d2 = *ut++; *rt++ = (d1 >> shift) | (d2 << (LBASE2 - shift)); } *rt++ = (d2 >> shift); } else { while (index--) *rt++ = *ut++; } while (*--rt == 0) ; r->length = rt - NaturalDigits (r) + 1; RETURN (r); } #ifdef CHECK static Natural * RegularGcd (Natural *u, Natural *v) { ENTER (); Natural *quo, *rem; while (v->length) { quo = NaturalDivide (u, v, &rem); u = v; v = rem; } RETURN (u); } #endif Natural * NaturalGcd (Natural *u0, Natural *v0) { ENTER (); #ifdef CHECK Natural *true = RegularGcd (u0, v0); #endif Natural *u, *v, *t; int normal; int u_zeros, v_zeros; int fix; if (NaturalZero (u0)) RETURN (zero_natural); if (NaturalZero (v0)) RETURN (zero_natural); u_zeros = NaturalZeroBits (u0); v_zeros = NaturalZeroBits (v0); normal = u_zeros; if (u_zeros > v_zeros) normal = v_zeros; u = NaturalGcdNormalize (u0, u_zeros); v = NaturalGcdNormalize (v0, v_zeros); if (NaturalLess (u, v)) { t = u; u = v; v = t; } if (NaturalLength (u) == 1 && NaturalLength (v) == 1) { digit ud = NaturalDigits(u)[0]; digit vd = NaturalDigits(v)[0]; digit td; START; while (vd) { while (!(vd&1)) vd >>= 1; if (vd < ud) { td = ud; ud = vd; vd = td; } vd -= ud; STEP; } NaturalDigits(u)[0] = ud; FINISH ("gcd1"); } else if (NaturalLength (u) <= 2 && NaturalLength (v) <= 2) { double_digit ud; double_digit vd; double_digit td; START; ud = NaturalDigits(u)[0]; if (NaturalLength (u) == 2) ud |= ((double_digit) NaturalDigits(u)[1]) << LBASE2; vd = NaturalDigits(v)[0]; if (NaturalLength (v) == 2) vd |= ((double_digit) NaturalDigits(v)[1]) << LBASE2; while (vd) { while (!(vd&1)) vd >>= 1; if (vd < ud) { td = ud; ud = vd; vd = td; } vd -= ud; STEP; } td = ud >> LBASE2; if (td) { if (NaturalLength (u) != 2) u = v; NaturalDigits(u)[1] = (digit) td; u->length = 2; } else u->length = 1; NaturalDigits(u)[0] = (digit) ud; FINISH ("gcd2"); } else { START; while (v->length) { if (aborting) RETURN (one_natural); #ifdef DEBUG_GCD FilePrintf (FileStdout, "u = %n;\n", u); FilePrintf (FileStdout, "v = %n;\n", v); #endif if (NaturalWidth (u) - NaturalWidth (v) > 10) { #ifdef DEBUG_GCD FilePrintf (FileStdout, "bdivmod\n"); #endif NaturalBdivmodInplace (u, v, NaturalWidth (u) - NaturalWidth (v) + 1); } else { #ifdef DEBUG_GCD FilePrintf (FileStdout, "kary\n"); #endif NaturalKaryReductionInplace (u, v); } u_zeros = NaturalZeroBits (u); if (u_zeros) NaturalRslInplace (u, u_zeros); t = u; u = v; v = t; STEP; } FINISH ("gcd_weber"); #ifdef DEBUG_FIX FilePrintf (FileStdout, "After weber:\n u: %n\n v: %n\n", u, v); #endif for (fix = 0; fix < 2; fix++) { v = u; if (fix) u = v0; else u = u0; #ifdef DEBUG_FIX FilePrintf (FileStdout, " fix %d\n u = %n;\n v = %n;\n", fix, u, v); #endif u = NaturalBdivmod (u, v); if (NaturalZero (u)) { u = v; continue; } while (v->length) { v_zeros = NaturalZeroBits (v); if (v_zeros) NaturalRslInplace (v, v_zeros); if (NaturalLess (v, u)) { t = u; u = v; v = t; } NaturalSubtractOffset (v, u, 0); STEP; } #ifdef DEBUG_FIX FilePrintf (FileStdout, " fix %n\n", u); #endif } FINISH ("gcd_fix"); } u = NaturalLsl (u, normal); #ifdef CHECK if (!NaturalEqual (u, true)) { FilePrintf (FileStdout, "gcd failure:\n"); FilePrintf (FileStdout, " u: %n\n v: %n\n gcd: %n\n got: %n\n", u0, v0, true, u); } #endif RETURN (u); } nickle_2.81.orig/lex.c0000664000175000000620000026517513064744550014064 0ustar keithpstaff #line 3 "lex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 1 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yynoreturn yy_fatal_error (yyconst char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 159 #define YY_END_OF_BUFFER 160 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[419] = { 0, 0, 0, 160, 158, 136, 63, 137, 135, 103, 158, 104, 53, 102, 105, 158, 64, 65, 94, 92, 52, 93, 56, 96, 140, 153, 132, 51, 116, 91, 117, 130, 157, 67, 68, 107, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 69, 106, 70, 108, 157, 157, 157, 136, 135, 2, 114, 0, 139, 0, 79, 122, 89, 0, 138, 0, 100, 73, 66, 110, 71, 112, 72, 57, 0, 156, 0, 1, 98, 75, 156, 140, 153, 0, 0, 0, 0, 131, 126, 118, 61, 113, 59, 120, 128, 157, 86, 157, 157, 157, 157, 157, 157, 10, 157, 157, 157, 157, 157, 157, 157, 157, 157, 11, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 90, 124, 109, 133, 134, 95, 97, 157, 157, 157, 157, 157, 157, 157, 157, 157, 0, 2, 139, 87, 138, 80, 54, 0, 77, 155, 156, 0, 0, 156, 0, 145, 0, 141, 0, 149, 82, 84, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 9, 157, 157, 157, 157, 24, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 19, 157, 157, 157, 157, 157, 88, 74, 76, 55, 101, 58, 60, 123, 125, 115, 119, 121, 62, 111, 127, 129, 99, 156, 0, 0, 148, 0, 148, 0, 144, 0, 144, 0, 152, 0, 152, 149, 3, 23, 157, 16, 157, 157, 157, 157, 12, 34, 157, 157, 157, 28, 157, 41, 40, 157, 157, 157, 157, 157, 22, 157, 157, 157, 157, 26, 157, 157, 157, 157, 157, 157, 157, 37, 157, 157, 157, 35, 157, 81, 83, 85, 78, 154, 0, 147, 148, 0, 0, 148, 0, 143, 144, 0, 0, 144, 152, 0, 151, 152, 152, 0, 0, 149, 149, 14, 20, 4, 157, 157, 157, 157, 38, 157, 157, 157, 157, 157, 157, 157, 157, 157, 45, 157, 157, 157, 157, 157, 157, 157, 157, 21, 157, 33, 8, 148, 0, 0, 144, 0, 0, 152, 152, 152, 0, 152, 152, 0, 152, 157, 157, 157, 48, 157, 157, 5, 157, 43, 157, 157, 157, 47, 157, 18, 157, 6, 27, 32, 13, 31, 157, 146, 142, 0, 150, 157, 17, 157, 36, 157, 157, 49, 157, 157, 157, 157, 39, 157, 15, 157, 7, 157, 157, 157, 25, 157, 157, 44, 157, 42, 46, 29, 157, 50, 157, 30, 0 } ; static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 24, 24, 25, 26, 27, 28, 29, 30, 1, 31, 31, 31, 31, 32, 31, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 35, 36, 37, 38, 1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 33, 48, 49, 50, 51, 52, 53, 33, 54, 55, 56, 57, 58, 59, 60, 61, 33, 62, 63, 64, 65, 1, 66, 33, 33, 33, 33, 33, 67, 68, 69, 70, 71, 33, 33, 33, 33, 33, 33, 72, 73, 33, 33, 33, 33, 74, 33, 33, 33, 33, 33, 33, 33, 33, 75, 76, 77, 33, 78, 79, 80, 81, 82, 33, 83, 84, 85, 33, 33, 33, 33, 33, 86, 87, 33, 33, 33, 88, 33, 33, 89, 33, 33, 90, 33, 33, 33, 33, 91, 92, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 93, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 } ; static yyconst YY_CHAR yy_meta[94] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 4, 1, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 5, 5, 6, 1, 1, 1, 1, 6, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } ; static yyconst flex_uint16_t yy_base[427] = { 0, 0, 92, 841, 842, 842, 842, 842, 842, 812, 88, 842, 842, 811, 85, 86, 842, 842, 84, 86, 842, 87, 85, 102, 105, 112, 813, 842, 111, 82, 91, 842, 0, 842, 842, 809, 779, 49, 102, 99, 101, 117, 786, 795, 116, 794, 116, 110, 103, 126, 781, 779, 784, 842, 115, 842, 842, 90, 105, 122, 192, 193, 842, 842, 151, 842, 174, 842, 801, 842, 172, 842, 187, 800, 842, 842, 842, 842, 842, 842, 842, 808, 189, 193, 842, 798, 842, 204, 216, 222, 234, 212, 241, 248, 842, 797, 842, 842, 842, 842, 842, 796, 0, 842, 767, 770, 778, 127, 769, 775, 0, 763, 760, 163, 767, 766, 760, 762, 760, 756, 0, 757, 753, 770, 757, 757, 753, 764, 173, 222, 753, 214, 755, 747, 216, 753, 746, 751, 750, 749, 842, 767, 0, 0, 0, 766, 765, 712, 202, 718, 200, 218, 719, 700, 207, 698, 293, 842, 195, 842, 264, 842, 842, 281, 842, 768, 285, 289, 297, 301, 264, 308, 293, 314, 337, 343, 842, 842, 734, 736, 745, 740, 741, 276, 742, 737, 729, 735, 734, 721, 732, 291, 733, 733, 734, 719, 0, 714, 726, 707, 711, 717, 710, 717, 714, 705, 722, 704, 161, 703, 715, 714, 0, 696, 712, 702, 711, 703, 842, 842, 842, 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 722, 721, 720, 306, 727, 349, 368, 320, 372, 332, 374, 380, 386, 398, 401, 428, 434, 446, 0, 0, 695, 0, 695, 682, 689, 673, 0, 0, 667, 662, 661, 0, 656, 0, 646, 662, 650, 643, 634, 639, 0, 650, 645, 644, 634, 0, 624, 623, 628, 623, 630, 629, 630, 0, 612, 625, 603, 0, 608, 842, 842, 842, 842, 842, 416, 628, 452, 322, 405, 425, 433, 627, 460, 464, 477, 483, 475, 488, 626, 502, 522, 527, 551, 557, 586, 0, 0, 0, 593, 594, 586, 595, 0, 582, 579, 575, 578, 564, 566, 564, 575, 569, 0, 557, 556, 560, 536, 518, 506, 511, 514, 0, 512, 0, 0, 320, 534, 539, 396, 528, 564, 591, 593, 447, 520, 617, 634, 641, 667, 479, 479, 474, 0, 466, 464, 0, 465, 0, 470, 469, 446, 0, 462, 0, 442, 0, 0, 0, 0, 0, 444, 842, 842, 394, 842, 349, 0, 424, 0, 424, 421, 0, 417, 414, 386, 377, 0, 342, 0, 305, 0, 257, 251, 207, 0, 199, 177, 0, 109, 0, 0, 0, 80, 0, 74, 0, 842, 711, 718, 721, 724, 729, 732, 737, 742 } ; static yyconst flex_int16_t yy_def[427] = { 0, 418, 1, 418, 418, 418, 418, 418, 418, 418, 419, 418, 418, 418, 418, 420, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 421, 418, 418, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 418, 418, 421, 421, 421, 418, 418, 418, 418, 419, 418, 419, 418, 418, 418, 420, 418, 420, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 421, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 419, 418, 420, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 422, 423, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 424, 418, 418, 418, 425, 418, 418, 418, 423, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 418, 418, 418, 418, 418, 424, 418, 418, 418, 425, 418, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 418, 418, 426, 418, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 0, 418, 418, 418, 418, 418, 418, 418, 418 } ; static yyconst flex_uint16_t yy_nxt[936] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 26, 27, 28, 29, 30, 31, 32, 32, 32, 33, 4, 34, 35, 32, 36, 37, 38, 39, 40, 41, 42, 43, 44, 32, 32, 32, 45, 32, 46, 47, 48, 49, 50, 51, 52, 32, 32, 53, 54, 55, 56, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 57, 58, 59, 60, 65, 68, 61, 71, 73, 62, 105, 76, 106, 81, 78, 82, 82, 82, 82, 98, 99, 74, 69, 77, 79, 80, 84, 75, 100, 101, 72, 85, 66, 87, 417, 88, 88, 88, 89, 86, 87, 416, 89, 89, 89, 89, 90, 95, 96, 97, 107, 109, 140, 90, 91, 130, 83, 90, 128, 111, 110, 112, 129, 108, 90, 114, 92, 65, 131, 120, 113, 132, 415, 115, 93, 121, 122, 125, 116, 126, 123, 133, 127, 117, 142, 143, 144, 141, 145, 134, 158, 181, 182, 71, 135, 66, 136, 147, 148, 149, 150, 151, 146, 156, 156, 152, 156, 156, 160, 157, 157, 65, 153, 187, 154, 155, 72, 281, 66, 82, 82, 82, 82, 163, 163, 163, 163, 282, 188, 202, 90, 72, 165, 414, 166, 166, 166, 166, 203, 66, 170, 90, 171, 171, 87, 90, 88, 88, 88, 89, 87, 413, 89, 89, 89, 89, 90, 90, 412, 168, 83, 168, 207, 90, 169, 169, 169, 169, 90, 172, 204, 173, 173, 173, 90, 167, 174, 208, 175, 175, 175, 175, 211, 222, 223, 71, 212, 205, 175, 175, 225, 226, 232, 233, 238, 238, 175, 175, 175, 175, 175, 175, 227, 411, 156, 228, 229, 156, 72, 410, 157, 163, 163, 163, 163, 166, 166, 166, 166, 237, 237, 237, 237, 242, 242, 242, 90, 169, 169, 169, 169, 169, 169, 169, 169, 239, 240, 90, 171, 171, 255, 256, 244, 264, 173, 173, 173, 90, 265, 241, 296, 296, 349, 349, 235, 245, 167, 300, 90, 300, 241, 241, 301, 301, 243, 409, 245, 246, 246, 246, 246, 248, 241, 175, 175, 175, 175, 246, 246, 237, 237, 237, 237, 175, 249, 246, 246, 246, 246, 246, 246, 175, 175, 175, 175, 249, 175, 399, 238, 238, 297, 400, 298, 298, 242, 242, 242, 408, 247, 241, 302, 302, 302, 241, 303, 245, 304, 304, 304, 314, 241, 314, 235, 306, 241, 306, 245, 245, 307, 307, 307, 246, 246, 246, 246, 301, 301, 245, 245, 239, 407, 246, 308, 299, 406, 243, 296, 296, 245, 246, 246, 246, 246, 308, 246, 301, 301, 305, 309, 309, 309, 309, 310, 302, 302, 302, 405, 404, 309, 309, 403, 314, 247, 314, 248, 312, 309, 309, 309, 309, 309, 309, 298, 298, 402, 401, 312, 316, 385, 347, 304, 304, 304, 241, 352, 352, 352, 398, 316, 385, 314, 245, 314, 397, 241, 313, 350, 307, 307, 307, 396, 395, 245, 307, 307, 307, 354, 394, 309, 309, 309, 309, 393, 299, 392, 391, 390, 354, 309, 309, 389, 305, 311, 311, 311, 311, 309, 309, 309, 309, 309, 309, 311, 312, 388, 387, 247, 314, 386, 314, 311, 311, 311, 311, 312, 311, 384, 359, 359, 359, 359, 355, 383, 358, 382, 381, 380, 359, 359, 349, 349, 379, 378, 313, 358, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 248, 377, 315, 315, 315, 315, 360, 360, 313, 352, 352, 352, 315, 316, 360, 360, 360, 360, 360, 360, 315, 315, 315, 315, 316, 315, 314, 347, 314, 248, 376, 375, 374, 314, 373, 314, 353, 353, 353, 353, 372, 371, 316, 370, 369, 368, 353, 354, 367, 354, 366, 365, 350, 316, 353, 353, 353, 353, 354, 353, 354, 364, 357, 357, 357, 357, 363, 362, 361, 356, 351, 348, 357, 358, 314, 346, 314, 247, 345, 247, 357, 357, 357, 357, 358, 357, 359, 359, 359, 359, 358, 344, 343, 342, 341, 340, 359, 359, 339, 338, 337, 358, 336, 313, 359, 359, 359, 359, 359, 359, 335, 334, 360, 360, 360, 360, 333, 332, 331, 330, 313, 329, 360, 360, 328, 327, 326, 325, 324, 355, 360, 360, 360, 360, 360, 360, 64, 323, 64, 64, 64, 64, 64, 70, 322, 70, 70, 70, 70, 70, 102, 102, 311, 311, 321, 311, 315, 315, 315, 353, 320, 353, 319, 353, 357, 318, 357, 317, 357, 360, 295, 360, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 280, 279, 278, 277, 276, 275, 274, 273, 272, 271, 270, 269, 268, 267, 266, 263, 262, 261, 260, 259, 258, 257, 254, 253, 252, 251, 250, 236, 234, 231, 230, 224, 221, 220, 219, 218, 217, 216, 215, 214, 213, 210, 209, 206, 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 186, 185, 184, 183, 180, 179, 178, 177, 176, 164, 162, 161, 159, 139, 138, 137, 124, 119, 118, 104, 103, 94, 67, 63, 418, 3, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418 } ; static yyconst flex_int16_t yy_chk[936] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 10, 14, 2, 15, 18, 2, 37, 19, 37, 22, 21, 22, 22, 22, 22, 29, 29, 18, 14, 19, 21, 21, 23, 18, 30, 30, 15, 23, 10, 24, 416, 24, 24, 24, 24, 23, 25, 414, 25, 25, 25, 25, 24, 28, 28, 28, 38, 39, 54, 25, 24, 48, 22, 24, 47, 40, 39, 40, 47, 38, 25, 41, 24, 64, 48, 44, 40, 48, 410, 41, 24, 44, 44, 46, 41, 46, 44, 49, 46, 41, 57, 57, 57, 54, 58, 49, 66, 107, 107, 70, 49, 64, 49, 59, 59, 59, 59, 59, 58, 60, 61, 59, 60, 61, 72, 60, 61, 158, 59, 113, 59, 59, 70, 208, 66, 82, 82, 82, 82, 83, 83, 83, 83, 208, 113, 128, 82, 72, 87, 408, 87, 87, 87, 87, 128, 158, 91, 82, 91, 91, 88, 87, 88, 88, 88, 88, 89, 407, 89, 89, 89, 89, 87, 88, 405, 90, 82, 90, 131, 89, 90, 90, 90, 90, 88, 92, 129, 92, 92, 92, 89, 87, 93, 131, 93, 93, 93, 93, 134, 148, 148, 160, 134, 129, 93, 93, 150, 150, 154, 154, 170, 170, 93, 93, 93, 93, 93, 93, 151, 404, 156, 151, 151, 156, 160, 403, 156, 163, 163, 163, 163, 166, 166, 166, 166, 167, 167, 167, 167, 172, 172, 172, 166, 168, 168, 168, 168, 169, 169, 169, 169, 170, 171, 166, 171, 171, 183, 183, 173, 191, 173, 173, 173, 235, 191, 171, 239, 239, 299, 299, 163, 173, 166, 241, 235, 241, 171, 347, 241, 241, 172, 401, 173, 174, 174, 174, 174, 175, 347, 175, 175, 175, 175, 174, 174, 237, 237, 237, 237, 175, 175, 174, 174, 174, 174, 174, 174, 175, 175, 175, 175, 175, 175, 387, 238, 238, 240, 387, 240, 240, 242, 242, 242, 399, 174, 238, 243, 243, 243, 240, 244, 242, 244, 244, 244, 385, 238, 385, 237, 245, 240, 245, 242, 244, 245, 245, 245, 246, 246, 246, 246, 300, 300, 350, 244, 238, 397, 246, 246, 240, 396, 242, 296, 296, 350, 246, 246, 246, 246, 246, 246, 301, 301, 244, 247, 247, 247, 247, 248, 302, 302, 302, 395, 394, 247, 247, 392, 249, 246, 249, 249, 248, 247, 247, 247, 247, 247, 247, 298, 298, 391, 389, 248, 249, 355, 296, 304, 304, 304, 298, 305, 305, 305, 382, 249, 355, 308, 304, 308, 376, 298, 248, 302, 306, 306, 306, 374, 372, 304, 307, 307, 307, 308, 371, 309, 309, 309, 309, 370, 298, 368, 366, 365, 308, 309, 309, 363, 304, 311, 311, 311, 311, 309, 309, 309, 309, 309, 309, 311, 311, 362, 361, 308, 312, 356, 312, 311, 311, 311, 311, 311, 311, 351, 313, 313, 313, 313, 309, 348, 312, 344, 342, 341, 313, 313, 349, 349, 340, 339, 311, 312, 313, 313, 313, 313, 313, 313, 314, 314, 314, 314, 315, 338, 315, 315, 315, 315, 314, 314, 312, 352, 352, 352, 315, 315, 314, 314, 314, 314, 314, 314, 315, 315, 315, 315, 315, 315, 316, 349, 316, 316, 337, 336, 335, 354, 333, 354, 353, 353, 353, 353, 332, 331, 316, 330, 329, 328, 353, 353, 327, 354, 326, 325, 352, 316, 353, 353, 353, 353, 353, 353, 354, 323, 357, 357, 357, 357, 322, 321, 320, 310, 303, 297, 357, 357, 358, 290, 358, 353, 288, 354, 357, 357, 357, 357, 357, 357, 359, 359, 359, 359, 358, 287, 286, 284, 283, 282, 359, 359, 281, 280, 279, 358, 278, 357, 359, 359, 359, 359, 359, 359, 276, 275, 360, 360, 360, 360, 274, 273, 271, 270, 358, 269, 360, 360, 268, 267, 266, 264, 262, 359, 360, 360, 360, 360, 360, 360, 419, 261, 419, 419, 419, 419, 419, 420, 260, 420, 420, 420, 420, 420, 421, 421, 422, 422, 257, 422, 423, 423, 423, 424, 256, 424, 255, 424, 425, 254, 425, 252, 425, 426, 236, 426, 234, 233, 232, 222, 217, 216, 215, 214, 213, 211, 210, 209, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 195, 194, 193, 192, 190, 189, 188, 187, 186, 185, 184, 182, 181, 180, 179, 178, 165, 155, 153, 152, 149, 147, 146, 145, 141, 139, 138, 137, 136, 135, 133, 132, 130, 127, 126, 125, 124, 123, 122, 121, 119, 118, 117, 116, 115, 114, 112, 111, 109, 108, 106, 105, 104, 101, 95, 85, 81, 73, 68, 52, 51, 50, 45, 43, 42, 36, 35, 26, 13, 9, 3, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "lex.l" #line 2 "lex.l" /* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "gram.h" #include "ref.h" #include #include #ifdef HAVE_LIBREADLINE #include #include #endif /* * Silence gcc by providing prototypes for these functions */ int yyget_lineno (void); FILE *yyget_in (void); FILE *yyget_out (void); int yyget_leng (void); char *yyget_text (void); void yyset_lineno (int); void yyset_in (FILE *); void yyset_out (FILE *); int yyget_debug (void); void yyset_debug (int); int yylex_destroy (void); typedef struct _lexInput { DataType data; struct _lexInput *next; Value file; Atom name; int lineno; Bool at_bol; Bool at_eof; Bool interactive; } LexInput; LexInput *lexInput; extern int ignorenl; extern int notCommand; extern int seeComment; #define FILE_END_CHAR -2 static void lexInputMark (void *object) { LexInput *lex = object; MemReference (lex->next); MemReference (lex->file); } static DataType lexInputType = { lexInputMark, 0, "lexInputType" }; void NewLexInput (Value file, Atom name, Bool after, Bool interactive) { ENTER (); LexInput *lex; lex = MemAllocate (&lexInputType, sizeof (*lex)); lex->file = file; lex->name = name; lex->lineno = 0; lex->at_bol = True; lex->at_eof = False; lex->interactive = interactive; if (after) { LexInput **prev; for (prev = &lexInput; *prev; prev = &(*prev)->next) ; lex->next = 0; *prev = lex; } else { lex->next = lexInput; lexInput = lex; } EXIT (); } #ifdef HAVE_LIBREADLINE volatile int stdin_in_readline; static void my_prep_terminal(int meta_flag) { stdin_in_readline = 1; rl_prep_terminal(meta_flag); } static void my_deprep_terminal(void) { rl_deprep_terminal(); stdin_in_readline = 0; } static int LexGetChar (void); static int ReadlineGetChar (FILE *f) { return LexGetChar (); } #endif ReferencePtr LexInputReference; void LexInit (void) { ENTER (); #if HAVE_LIBREADLINE rl_getc_function = ReadlineGetChar; rl_prep_term_function = my_prep_terminal; rl_deprep_term_function = my_deprep_terminal; rl_catch_signals = 0; #endif LexInputReference = NewReference ((void **) &lexInput); MemAddRoot (LexInputReference); EXIT (); } Atom LexFileName (void) { if (lexInput) return lexInput->name; return AtomId (""); } int LexFileLine (void) { if (lexInput) return lexInput->lineno; return 0; } Bool LexInteractive (void) { if (lexInput) return lexInput->interactive; return False; } Bool LexResetInteractive (void) { while (lexInput->next && !lexInput->interactive) { FileClose (lexInput->file); lexInput = lexInput->next; } if (lexInput->interactive) return True; return False; } Bool LexFile (char *s, Bool complain, Bool after) { Value f; int err; f = FileFopen (s, "r", &err); if (f == 0) { if (complain) (void) FilePrintf (FileStderr, "%s: %s\n", s, StringChars (&FileGetErrorMessage (err)->string)); return False; } (void) NewLexInput(f, AtomId (s), after, False); return True; } static int LexGetChar (void) { int c; for (;;) { c = FileInput (lexInput->file); if (c >= 0) return c; if (c == FileBlocked) ThreadsRun (0, lexInput->file); else { if (!lexInput->next) return FileEOF; lexInput->at_eof = True; return '\n'; } } } static Value prompt (void) { Value v; if (ignorenl) v = lookupVar (0, "prompt2"); else if (CurrentFrame) v = lookupVar (0, "prompt3"); else v = lookupVar (0, "prompt"); return v; } static int LexGetInteractiveChar (void) { #ifdef HAVE_LIBREADLINE static char *line, *line_base; int c; if (!line) { char *p; p = StrzPart (prompt (), "invalid prompt"); if (!p) p = "??? "; for (;;) { FileFlush (FileStdout, False); FileFlush (FileStderr, False); if (FileStdout->file.flags & FileOutputBlocked) ThreadsRun (0, FileStdout); else if (FileStderr->file.flags & FileOutputBlocked) ThreadsRun (0, FileStderr); else break; } rl_inhibit_completion = 1; line_base = readline (p); line = line_base; if (!line) return FileEOF; add_history (line_base); } c = (*line++) & 0xff; if (!c) { c = '\n'; free (line_base); line = 0; } return c; #else if (lexInput->at_bol) { Value v = prompt (); Print (FileStdout, v, 's', 0, 0, 0, ' '); FileFlush (FileStdout, True); } return LexGetChar (); #endif } #undef YY_INPUT #define YY_NO_UNPUT static int yy_input (char *buf, int max_size) { int c; int result = 0; while (result < max_size) { if (lexInput->at_eof) { FileClose (lexInput->file); lexInput = lexInput->next; } if (lexInput->interactive) c = LexGetInteractiveChar (); else c = LexGetChar (); if (lexInput->at_bol) { lexInput->lineno++; } lexInput->at_bol = False; if (c < 0) break; buf[result++] = c; if (c == '\n') { lexInput->at_bol = True; break; } } return result; } #define YY_INPUT(buf,result,max_size) ((result) = yy_input (buf, max_size)) #ifndef FLEX_SCANNER #undef input #undef unput int input (void) { char buf[1]; int r; YY_INPUT(buf, r, 1); if (r == 0) return 0; return buf[0]; } void unput (char c) { if (c == '\n') lexInput->lineno--; FileUnput (lexInput->file, c); } #endif #line 1135 "lex.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * _in_str ); FILE *yyget_out (void ); void yyset_out (FILE * _out_str ); int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput (int c,char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 336 "lex.l" #line 1358 "lex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 419 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 842 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 337 "lex.l" { if (seeComment) { yylval.value = lexdoc (); return COMMENT_CONST; } else skipcomment (); } YY_BREAK case 2: YY_RULE_SETUP #line 346 "lex.l" skipline(); YY_BREAK case 3: YY_RULE_SETUP #line 347 "lex.l" { yylval.class = class_auto; return AUTO; } YY_BREAK case 4: YY_RULE_SETUP #line 348 "lex.l" { yylval.class = class_const; return CONST; } YY_BREAK case 5: YY_RULE_SETUP #line 349 "lex.l" { yylval.class = class_global; return GLOBAL; } YY_BREAK case 6: YY_RULE_SETUP #line 350 "lex.l" { yylval.class = class_static; return STATIC; } YY_BREAK case 7: YY_RULE_SETUP #line 351 "lex.l" { yylval.type = typePrim[rep_void]; return FUNCTION; } YY_BREAK case 8: YY_RULE_SETUP #line 352 "lex.l" { yylval.ints = WHILE; return WHILE; } YY_BREAK case 9: YY_RULE_SETUP #line 353 "lex.l" { yylval.ints = FOR; return FOR; } YY_BREAK case 10: YY_RULE_SETUP #line 354 "lex.l" { yylval.ints = DO; return DO; } YY_BREAK case 11: YY_RULE_SETUP #line 355 "lex.l" { yylval.ints = IF; return IF; } YY_BREAK case 12: YY_RULE_SETUP #line 356 "lex.l" { yylval.ints = ELSE; return ELSE; } YY_BREAK case 13: YY_RULE_SETUP #line 357 "lex.l" { yylval.ints = SWITCH; return SWITCH; } YY_BREAK case 14: YY_RULE_SETUP #line 358 "lex.l" { yylval.ints = BREAK; return BREAK; } YY_BREAK case 15: YY_RULE_SETUP #line 359 "lex.l" { yylval.ints = CONTINUE; return CONTINUE; } YY_BREAK case 16: YY_RULE_SETUP #line 360 "lex.l" { yylval.ints = CASE; return CASE; } YY_BREAK case 17: YY_RULE_SETUP #line 361 "lex.l" { yylval.ints = DEFAULT; return DEFAULT; } YY_BREAK case 18: YY_RULE_SETUP #line 362 "lex.l" { yylval.ints = RETURNTOK; return RETURNTOK; } YY_BREAK case 19: YY_RULE_SETUP #line 363 "lex.l" { yylval.ints = TRY; return TRY; } YY_BREAK case 20: YY_RULE_SETUP #line 364 "lex.l" { yylval.ints = CATCH; return CATCH; } YY_BREAK case 21: YY_RULE_SETUP #line 365 "lex.l" { yylval.ints = TWIXT; return TWIXT; } YY_BREAK case 22: YY_RULE_SETUP #line 367 "lex.l" { yylval.type = typePoly; return POLY; } YY_BREAK case 23: YY_RULE_SETUP #line 368 "lex.l" { yylval.type = typePrim[rep_bool]; return BOOL; } YY_BREAK case 24: YY_RULE_SETUP #line 369 "lex.l" { yylval.type = typePrim[rep_integer]; return INTEGER; } YY_BREAK case 25: YY_RULE_SETUP #line 370 "lex.l" { yylval.type = typePrim[rep_rational]; return RATIONAL; } YY_BREAK case 26: YY_RULE_SETUP #line 371 "lex.l" { yylval.type = typePrim[rep_float]; return REAL; } YY_BREAK case 27: YY_RULE_SETUP #line 372 "lex.l" { yylval.type = typePrim[rep_string]; return STRING; } YY_BREAK case 28: YY_RULE_SETUP #line 373 "lex.l" { yylval.type = typePrim[rep_file]; return FILET; } YY_BREAK case 29: YY_RULE_SETUP #line 374 "lex.l" { yylval.type = typePrim[rep_semaphore]; return SEMAPHORE; } YY_BREAK case 30: YY_RULE_SETUP #line 375 "lex.l" { yylval.type = typePrim[rep_continuation]; return CONTINUATION; } YY_BREAK case 31: YY_RULE_SETUP #line 376 "lex.l" { yylval.type = typePrim[rep_thread]; return THREAD; } YY_BREAK case 32: YY_RULE_SETUP #line 377 "lex.l" { yylval.ints = STRUCT; return STRUCT; } YY_BREAK case 33: YY_RULE_SETUP #line 378 "lex.l" { yylval.ints = UNION; return UNION; } YY_BREAK case 34: YY_RULE_SETUP #line 379 "lex.l" { yylval.ints = ENUM; return ENUM; } YY_BREAK case 35: YY_RULE_SETUP #line 380 "lex.l" { yylval.type = typePrim[rep_void]; return VOID; } YY_BREAK case 36: YY_RULE_SETUP #line 381 "lex.l" { yylval.type = typePrim[rep_foreign]; return FOREIGN; } YY_BREAK case 37: YY_RULE_SETUP #line 382 "lex.l" { yylval.value = TrueVal; return BOOLVAL; } YY_BREAK case 38: YY_RULE_SETUP #line 383 "lex.l" { yylval.value = FalseVal; return BOOLVAL; } YY_BREAK case 39: YY_RULE_SETUP #line 385 "lex.l" { yylval.ints = TYPEDEF; return TYPEDEF; } YY_BREAK case 40: YY_RULE_SETUP #line 386 "lex.l" { yylval.ints = FUNC; return FUNC; } YY_BREAK case 41: YY_RULE_SETUP #line 387 "lex.l" { yylval.ints = FORK; return FORK; } YY_BREAK case 42: YY_RULE_SETUP #line 388 "lex.l" { yylval.ints = NAMESPACE; return NAMESPACE; } YY_BREAK case 43: YY_RULE_SETUP #line 389 "lex.l" { yylval.ints = IMPORT; return IMPORT; } YY_BREAK case 44: YY_RULE_SETUP #line 390 "lex.l" { yylval.ints = EXCEPTION; return EXCEPTION; } YY_BREAK case 45: YY_RULE_SETUP #line 391 "lex.l" { yylval.ints = RAISE; return RAISE; } YY_BREAK case 46: YY_RULE_SETUP #line 392 "lex.l" { yylval.publish = publish_protected; return PROTECTED; } YY_BREAK case 47: YY_RULE_SETUP #line 393 "lex.l" { yylval.publish = publish_public; return PUBLIC; } YY_BREAK case 48: YY_RULE_SETUP #line 394 "lex.l" { yylval.publish = publish_extend; return EXTEND; } YY_BREAK case 49: YY_RULE_SETUP #line 395 "lex.l" { yylval.ints = ISTYPE; return ISTYPE; } YY_BREAK case 50: YY_RULE_SETUP #line 396 "lex.l" { yylval.ints = HASMEMBER; return HASMEMBER; } YY_BREAK case 51: YY_RULE_SETUP #line 397 "lex.l" { yylval.ints = SEMI; return SEMI; } YY_BREAK case 52: YY_RULE_SETUP #line 398 "lex.l" { yylval.ints = COMMA; return COMMA; } YY_BREAK case 53: YY_RULE_SETUP #line 399 "lex.l" { yylval.ints = DOLLAR; return DOLLAR; } YY_BREAK case 54: YY_RULE_SETUP #line 400 "lex.l" { yylval.ints = DOTDOTDOT; return DOTDOTDOT; } YY_BREAK case 55: YY_RULE_SETUP #line 401 "lex.l" { yylval.ints = DOTDOTDOT; return DOTDOTDOT; } YY_BREAK case 56: YY_RULE_SETUP #line 402 "lex.l" { yylval.ints = DOT; return DOT; } YY_BREAK case 57: YY_RULE_SETUP #line 403 "lex.l" { yylval.ints = ARROW; return ARROW; } YY_BREAK case 58: YY_RULE_SETUP #line 404 "lex.l" { yylval.ints = ARROW; return ARROW; } YY_BREAK case 59: YY_RULE_SETUP #line 405 "lex.l" { yylval.ints = DARROW; return DARROW; } YY_BREAK case 60: YY_RULE_SETUP #line 406 "lex.l" { yylval.ints = DARROW; return DARROW; } YY_BREAK case 61: YY_RULE_SETUP #line 407 "lex.l" { yylval.value = Void; return VOIDVAL; } YY_BREAK case 62: YY_RULE_SETUP #line 408 "lex.l" { yylval.value = Void; return VOIDVAL; } YY_BREAK case 63: /* rule 63 can match eol */ YY_RULE_SETUP #line 409 "lex.l" { if (lexInput->at_eof) { strcpy (yytext, "EOF"); yylval.ints = ENDFILE; return ENDFILE; } if (!ignorenl) { yylval.ints = NL; return NL; } } YY_BREAK case 64: YY_RULE_SETUP #line 413 "lex.l" { yylval.ints = OP; ++ignorenl; return OP; } YY_BREAK case 65: YY_RULE_SETUP #line 414 "lex.l" { yylval.ints = CP; if (ignorenl > 0) --ignorenl; return CP; } YY_BREAK case 66: YY_RULE_SETUP #line 415 "lex.l" { yylval.ints = STAROS; ++ignorenl; return STAROS; } YY_BREAK case 67: YY_RULE_SETUP #line 416 "lex.l" { yylval.ints = OS; ++ignorenl; return OS; } YY_BREAK case 68: YY_RULE_SETUP #line 417 "lex.l" { yylval.ints = CS; if (ignorenl > 0) --ignorenl; return CS; } YY_BREAK case 69: YY_RULE_SETUP #line 418 "lex.l" { yylval.ints = OC; ++ignorenl; return OC; } YY_BREAK case 70: YY_RULE_SETUP #line 419 "lex.l" { yylval.ints = CC; if (ignorenl > 0) --ignorenl; return CC; } YY_BREAK case 71: YY_RULE_SETUP #line 420 "lex.l" { yylval.ints = ASSIGNPLUS; return ASSIGNPLUS; } YY_BREAK case 72: YY_RULE_SETUP #line 421 "lex.l" { yylval.ints = ASSIGNMINUS; return ASSIGNMINUS; } YY_BREAK case 73: YY_RULE_SETUP #line 422 "lex.l" { yylval.ints = ASSIGNTIMES; return ASSIGNTIMES; } YY_BREAK case 74: YY_RULE_SETUP #line 423 "lex.l" { yylval.ints = ASSIGNTIMES; return ASSIGNTIMES; } YY_BREAK case 75: YY_RULE_SETUP #line 424 "lex.l" { yylval.ints = ASSIGNDIVIDE; return ASSIGNDIVIDE; } YY_BREAK case 76: YY_RULE_SETUP #line 425 "lex.l" { yylval.ints = ASSIGNDIVIDE; return ASSIGNDIVIDE; } YY_BREAK case 77: YY_RULE_SETUP #line 426 "lex.l" { yylval.ints = ASSIGNDIV; return ASSIGNDIV; } YY_BREAK case 78: YY_RULE_SETUP #line 427 "lex.l" { yylval.ints = ASSIGNDIV; return ASSIGNDIV; } YY_BREAK case 79: YY_RULE_SETUP #line 428 "lex.l" { yylval.ints = ASSIGNMOD; return ASSIGNMOD; } YY_BREAK case 80: YY_RULE_SETUP #line 429 "lex.l" { yylval.ints = ASSIGNPOW; return ASSIGNPOW; } YY_BREAK case 81: YY_RULE_SETUP #line 430 "lex.l" { yylval.ints = ASSIGNPOW; return ASSIGNPOW; } YY_BREAK case 82: YY_RULE_SETUP #line 431 "lex.l" { yylval.ints = ASSIGNSHIFTL; return ASSIGNSHIFTL; } YY_BREAK case 83: YY_RULE_SETUP #line 432 "lex.l" { yylval.ints = ASSIGNSHIFTL; return ASSIGNSHIFTL; } YY_BREAK case 84: YY_RULE_SETUP #line 433 "lex.l" { yylval.ints = ASSIGNSHIFTR; return ASSIGNSHIFTR; } YY_BREAK case 85: YY_RULE_SETUP #line 434 "lex.l" { yylval.ints = ASSIGNSHIFTR; return ASSIGNSHIFTR; } YY_BREAK case 86: YY_RULE_SETUP #line 435 "lex.l" { yylval.ints = ASSIGNLXOR; return ASSIGNLXOR; } YY_BREAK case 87: YY_RULE_SETUP #line 436 "lex.l" { yylval.ints = ASSIGNAND; return ASSIGNAND; } YY_BREAK case 88: YY_RULE_SETUP #line 437 "lex.l" { yylval.ints = ASSIGNOR; return ASSIGNOR; } YY_BREAK case 89: YY_RULE_SETUP #line 438 "lex.l" { yylval.ints = ASSIGNLAND; return ASSIGNLAND; } YY_BREAK case 90: YY_RULE_SETUP #line 439 "lex.l" { yylval.ints = ASSIGNLOR; return ASSIGNLOR; } YY_BREAK case 91: YY_RULE_SETUP #line 440 "lex.l" { yylval.ints = ASSIGN; return ASSIGN; } YY_BREAK case 92: YY_RULE_SETUP #line 442 "lex.l" { yylval.ints = PLUS; return PLUS; } YY_BREAK case 93: YY_RULE_SETUP #line 443 "lex.l" { yylval.ints = MINUS; return MINUS; } YY_BREAK case 94: YY_RULE_SETUP #line 444 "lex.l" { yylval.ints = TIMES; return TIMES; } YY_BREAK case 95: YY_RULE_SETUP #line 445 "lex.l" { yylval.ints = TIMES; return TIMES; } YY_BREAK case 96: YY_RULE_SETUP #line 446 "lex.l" { yylval.ints = DIVIDE; return DIVIDE; } YY_BREAK case 97: YY_RULE_SETUP #line 447 "lex.l" { yylval.ints = DIVIDE; return DIVIDE; } YY_BREAK case 98: YY_RULE_SETUP #line 448 "lex.l" { yylval.ints = DIV; return DIV; } YY_BREAK case 99: YY_RULE_SETUP #line 449 "lex.l" { yylval.ints = DIV; return DIV; } YY_BREAK case 100: YY_RULE_SETUP #line 450 "lex.l" { yylval.ints = STARSTAR; return STARSTAR; } YY_BREAK case 101: YY_RULE_SETUP #line 451 "lex.l" { yylval.ints = STARSTAR; return STARSTAR; } YY_BREAK case 102: YY_RULE_SETUP #line 452 "lex.l" { yylval.ints = MOD; return MOD; } YY_BREAK case 103: YY_RULE_SETUP #line 453 "lex.l" { yylval.ints = BANG; return BANG; } YY_BREAK case 104: YY_RULE_SETUP #line 454 "lex.l" { yylval.ints = POUND; return POUND; } YY_BREAK case 105: YY_RULE_SETUP #line 455 "lex.l" { yylval.ints = LAND; return LAND; } YY_BREAK case 106: YY_RULE_SETUP #line 456 "lex.l" { yylval.ints = LOR; return LOR; } YY_BREAK case 107: YY_RULE_SETUP #line 457 "lex.l" { yylval.ints = LXOR; return LXOR; } YY_BREAK case 108: YY_RULE_SETUP #line 458 "lex.l" { yylval.ints = LNOT; return LNOT; } YY_BREAK case 109: YY_RULE_SETUP #line 459 "lex.l" { yylval.ints = LNOT; return LNOT; } YY_BREAK case 110: YY_RULE_SETUP #line 460 "lex.l" { yylval.ints = INC; return INC; } YY_BREAK case 111: YY_RULE_SETUP #line 461 "lex.l" { yylval.ints = INC; return INC; } YY_BREAK case 112: YY_RULE_SETUP #line 462 "lex.l" { yylval.ints = DEC; return DEC; } YY_BREAK case 113: YY_RULE_SETUP #line 463 "lex.l" { yylval.ints = EQ; return EQ; } YY_BREAK case 114: YY_RULE_SETUP #line 464 "lex.l" { yylval.ints = NE; return NE; } YY_BREAK case 115: YY_RULE_SETUP #line 465 "lex.l" { yylval.ints = NE; return NE; } YY_BREAK case 116: YY_RULE_SETUP #line 466 "lex.l" { yylval.ints = LT; return LT; } YY_BREAK case 117: YY_RULE_SETUP #line 467 "lex.l" { yylval.ints = GT; return GT; } YY_BREAK case 118: YY_RULE_SETUP #line 468 "lex.l" { yylval.ints = LE; return LE; } YY_BREAK case 119: YY_RULE_SETUP #line 469 "lex.l" { yylval.ints = LE; return LE; } YY_BREAK case 120: YY_RULE_SETUP #line 470 "lex.l" { yylval.ints = GE; return GE; } YY_BREAK case 121: YY_RULE_SETUP #line 471 "lex.l" { yylval.ints = GE; return GE; } YY_BREAK case 122: YY_RULE_SETUP #line 472 "lex.l" { yylval.ints = AND; return AND; } YY_BREAK case 123: YY_RULE_SETUP #line 473 "lex.l" { yylval.ints = AND; return AND; } YY_BREAK case 124: YY_RULE_SETUP #line 474 "lex.l" { yylval.ints = OR; return OR; } YY_BREAK case 125: YY_RULE_SETUP #line 475 "lex.l" { yylval.ints = OR; return OR; } YY_BREAK case 126: YY_RULE_SETUP #line 476 "lex.l" { yylval.ints = SHIFTL; return SHIFTL; } YY_BREAK case 127: YY_RULE_SETUP #line 477 "lex.l" { yylval.ints = SHIFTL; return SHIFTL; } YY_BREAK case 128: YY_RULE_SETUP #line 478 "lex.l" { yylval.ints = SHIFTR; return SHIFTR; } YY_BREAK case 129: YY_RULE_SETUP #line 479 "lex.l" { yylval.ints = SHIFTR; return SHIFTR; } YY_BREAK case 130: YY_RULE_SETUP #line 480 "lex.l" { yylval.ints = QUEST; return QUEST; } YY_BREAK case 131: YY_RULE_SETUP #line 481 "lex.l" { yylval.ints = COLONCOLON; return COLONCOLON; } YY_BREAK case 132: YY_RULE_SETUP #line 482 "lex.l" { yylval.ints = COLON; return COLON; } YY_BREAK case 133: YY_RULE_SETUP #line 483 "lex.l" { yylval.ints = POW2; return POW2; } YY_BREAK case 134: YY_RULE_SETUP #line 484 "lex.l" { yylval.ints = POW3; return POW3; } YY_BREAK case 135: YY_RULE_SETUP #line 485 "lex.l" ; YY_BREAK case 136: YY_RULE_SETUP #line 486 "lex.l" ; YY_BREAK case 137: YY_RULE_SETUP #line 487 "lex.l" ; YY_BREAK case 138: YY_RULE_SETUP #line 488 "lex.l" { ENTER (); char *s; long len = yyleng - 1; unsigned c; s = yytext + 1; s = StringNextChar (s, &c, &len); if (c == '\\') { if (!(s = StringNextChar (s, &c, &len))) c = 0; else if ('0' <= c && c <= '7') { unsigned ch; char *ps = s; c = c - '0'; while ((s = StringNextChar (s, &ch, &len)) && '0' <= ch && ch <= '7') { c = (c << 3) | (ch - '0'); ps = s; } s = ps; } else c = lexEscape (c); } yylval.value = NewInt (c); EXIT (); REFERENCE (yylval.value); return CHAR_CONST; } YY_BREAK case 139: YY_RULE_SETUP #line 522 "lex.l" { ENTER (); char *d, *s; unsigned c; long len = yyleng - 2; yylval.value = NewString (len); d = StringChars (&yylval.value->string); s = yytext + 1; while ((s = StringNextChar (s, &c, &len))) { if (c == '\\') { if (!(s = StringNextChar (s, &c, &len))) break; if ('0' <= c && c <= '7') { unsigned ch; char *ps = s; long plen = len; c = c - '0'; while ((s = StringNextChar (s, &ch, &len)) && '0' <= ch && ch <= '7') { c = (c << 3) | (ch - '0'); ps = s; plen = len; } s = ps; len = plen; } else c = lexEscape (c); } d += StringPutChar (c, d); } *d = '\0'; yylval.value->string.length = d - StringChars(&yylval.value->string); EXIT (); REFERENCE (yylval.value); return STRING_CONST; } YY_BREAK case 140: YY_RULE_SETUP #line 565 "lex.l" { yylval.value = atov(yytext+1, 8); if (yytext[1] == '\0') return TEN_NUM; else return OCTAL0_NUM; } YY_BREAK case 141: YY_RULE_SETUP #line 572 "lex.l" { yylval.value = atov(yytext+2, 8); return OCTAL_NUM; } YY_BREAK case 142: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 576 "lex.l" { yylval.value = aetov(yytext+2, 8); return OCTAL_FLOAT; } YY_BREAK case 143: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 580 "lex.l" { yylval.value = atov(yytext+2, 8); return OCTAL_NUM; } YY_BREAK case 144: YY_RULE_SETUP #line 584 "lex.l" { yylval.value = aetov (yytext+2, 8); return OCTAL_FLOAT; } YY_BREAK case 145: YY_RULE_SETUP #line 588 "lex.l" { yylval.value = atov(yytext+2, 2); return BINARY_NUM; } YY_BREAK case 146: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 592 "lex.l" { yylval.value = aetov(yytext+2, 2); return BINARY_FLOAT; } YY_BREAK case 147: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 596 "lex.l" { yylval.value = atov(yytext+2, 2); return BINARY_NUM; } YY_BREAK case 148: YY_RULE_SETUP #line 600 "lex.l" { yylval.value = aetov (yytext+2, 2); return BINARY_FLOAT; } YY_BREAK case 149: YY_RULE_SETUP #line 604 "lex.l" { yylval.value = atov(yytext+2, 16); return HEX_NUM; } YY_BREAK case 150: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 608 "lex.l" { yylval.value = aetov(yytext+2, 16); return HEX_FLOAT; } YY_BREAK case 151: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 612 "lex.l" { yylval.value = atov(yytext+2, 16); return HEX_NUM; } YY_BREAK case 152: YY_RULE_SETUP #line 616 "lex.l" { yylval.value = aetov (yytext+2, 16); return HEX_FLOAT; } YY_BREAK case 153: YY_RULE_SETUP #line 620 "lex.l" { yylval.value = atov(yytext, 10); return TEN_NUM; } YY_BREAK case 154: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 3; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 624 "lex.l" { yylval.value = aetov(yytext, 10); return TEN_FLOAT; } YY_BREAK case 155: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 2; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 628 "lex.l" { yylval.value = atov(yytext, 10); return TEN_NUM; } YY_BREAK case 156: YY_RULE_SETUP #line 632 "lex.l" { yylval.value = aetov (yytext, 10); return TEN_FLOAT; } YY_BREAK case 157: YY_RULE_SETUP #line 636 "lex.l" { CommandPtr c; SymbolPtr symbol; yylval.atom = AtomId (yytext); if (!notCommand && (c = CommandFind (CurrentCommands, yylval.atom))) { if (c->names) return NAMECOMMAND; return COMMAND; } if (LexNamespace) symbol = NamespaceFindName (LexNamespace, yylval.atom, False); else symbol = NamespaceFindName (CurrentNamespace, yylval.atom, True); if (symbol) { switch (symbol->symbol.class) { case class_namespace: return NAMESPACENAME; case class_typedef: return TYPENAME; default: break; } } return NAME; } YY_BREAK case 158: YY_RULE_SETUP #line 663 "lex.l" FilePrintf (FileStderr, "character \\%o ignored\n", *yytext & 0xff); YY_BREAK case 159: YY_RULE_SETUP #line 664 "lex.l" ECHO; YY_BREAK #line 2402 "lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 419 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; char *yy_cp = (yy_c_buf_p); YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 419 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; yy_is_jam = (yy_current_state == 418); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp ) { char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = (yy_n_chars) + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,(int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 664 "lex.l" int lexEscape (int c) { switch (c) { case '0': return '\0'; break; case 'b': return '\b'; break; case 'n': return '\n'; break; case 'r': return '\r'; break; case 't': return '\t'; break; case 'f': return '\f'; break; case 'v': return '\v'; break; default: return c; } } Value lexdoc (void) { int c; Value s = NewStrString (""); c = input(); if (lexInput->at_eof) { bail: yyerror ("Missing */ at end of file"); return Void; } for (;;) { Bool skip = False; while (c != EOF && c != '*') { if (skip && c != ' ' && c != '\t') skip = False; if (!skip) s = Plus (s, NewCharString (c)); if (c == '\n') skip = True; c = input(); if (c == EOF || lexInput->at_eof) goto bail; } c = input(); if (c == EOF || lexInput->at_eof) goto bail; if (c == '/') break; if (!skip) s = Plus (s, NewCharString ('*')); } return s; } void skipcomment (void) { int c; c = input(); if (lexInput->at_eof) { bail: yyerror ("Missing */ at end of file"); return; } for (;;) { while (c != EOF && c != '*') { c = input(); if (c == EOF || lexInput->at_eof) goto bail; } c = input(); if (c == EOF || lexInput->at_eof) goto bail; if (c == '/') return; } } void skipline (void) { int c; do { c = input(); } while (c != EOF && c != '\n'); } Value atov (char *s, int base) { ENTER (); Value result; Value b; char c; int i; b = NewInt (base); result = NewInt (0); for (;;) { c = *s++; if ('0' <= c && c <= '9') i = c - '0'; else if ('a' <= c && c <= 'z') i = c - 'a' + 10; else if ('A' <= c && c <= 'Z') i = c - 'A' + 10; else break; if (i >= base) break; result = Plus (NewInt (i), Times (result, b)); } RETURN (result); } Value aetov (char *s, int base) { ENTER (); char *int_part, *frac_part, *rep_part, *exp_part, *next; int sign, frac_len, rep_len, esign; Value v, sv; int_part = s; sign = 1; if (*int_part == '+') int_part++; else if (*int_part == '-') { int_part++; sign = -1; } next = int_part; frac_part = strchr (next, '.'); frac_len = -1; rep_part = 0; rep_len = 0; esign = 1; if (frac_part) { frac_part++; next = frac_part; rep_part = strchr (next, '{'); if (rep_part) { frac_len = rep_part - frac_part; rep_part++; next = strchr (rep_part, '}'); if (!next) RETURN (Void); /* "can't" happen */ rep_len = next - rep_part; next = next + 1; } } exp_part = strchr (next, 'e'); if (!exp_part) exp_part = strchr (next, 'E'); if (exp_part) { if (frac_len < 0) frac_len = exp_part - frac_part; exp_part++; if (*exp_part == '+') exp_part++; else if (*exp_part == '-') { esign = -1; exp_part++; } } else if (frac_len < 0 && frac_part) frac_len = strlen(frac_part); v = atov (int_part, base); if (frac_part) { v = Plus (v, Divide (atov (frac_part, base), Pow (NewInt (base), NewInt (frac_len)))); } if (rep_part) { Value rep; rep = Divide (atov (rep_part, base), Minus (Pow (NewInt (base), NewInt (rep_len)), One)); if (frac_len) rep = Divide (rep, Pow (NewInt (base), NewInt (frac_len))); v = Plus (v, rep); } if (exp_part) { sv = Pow (NewInt (base), atov (exp_part, base)); if (esign > 0) v = Times (v, sv); else v = Divide (v, sv); } if (sign == -1) v = Negate (v); RETURN (v); } nickle_2.81.orig/abort.5c0000664000175000000620000000160110675627422014451 0ustar keithpstaff/* $Header$ */ /* * Copyright © 2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ namespace Abort { public int trace_depth = 20; public exception aborting(string); public void abort(string reason, args ...) /* Print a stack trace and raise aborting exception with message */ { Debug::trace(Thread::current(), trace_depth); string reasonmsg = File::sprintf(reason, args ...); raise aborting(reasonmsg); } public void assert(bool ok, string failure, args ...) /* If 'ok' is false, abort (failure, args ...); */ { if (!ok) abort(failure, args ...); } public bool do_debug = true; public void debug(string fmt, args ...) /* Print to stderr, controlled by 'do_debug' global */ { if (do_debug) File::fprintf(stderr, fmt + "\n", args ...); } } nickle_2.81.orig/builtin.h0000664000175000000620000001310410751047004014714 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * builtin.h * * header shared across builtin implementation source files */ #if LOCAL_BUILD #include "nickle.h" #else #include #endif SymbolPtr BuiltinAddName (NamespacePtr *namespacep, SymbolPtr symbol); SymbolPtr BuiltinSymbol (NamespacePtr *namespacep, char *string, Type *type); SymbolPtr BuiltinNamespace (NamespacePtr *namespacep, char *string); void BuiltinSetUserdefType (Type *type, int n); SymbolPtr BuiltinException (NamespacePtr *namespacep, char *string, Type *type, char *doc); struct ebuiltin { char *name; StandardException exception; char *args; char *doc; }; void BuiltinAddException (NamespacePtr *namespacep, StandardException exception, char *name, char *format, char *doc); struct sbuiltin { char *value; char *name; NamespacePtr *namespace; }; #define BuiltinStrings(s) do { \ SymbolPtr sym; const struct sbuiltin *si; \ for (si = (s); si->name; si++) { \ sym = BuiltinSymbol (si->namespace, si->name, typePrim[rep_string]); \ BoxValueSet (sym->global.value, 0, NewStrString (si->value)); \ } } while (0) struct envbuiltin { #ifdef CENVIRON char *var; #endif char *def; char *name; NamespacePtr *namespace; }; struct ibuiltin { int value; char *name; NamespacePtr *namespace; }; #define BuiltinIntegers(s) do { \ SymbolPtr sym; const struct ibuiltin *ii; \ for (ii = (s); ii->name; ii++) { \ sym = BuiltinSymbol (ii->namespace ,ii->name, typePrim[rep_integer]); \ BoxValueSet (sym->global.value, 0, Reduce (NewIntInteger (ii->value))); \ } } while (0) struct filebuiltin { char *name; Value *value; NamespacePtr *namespace; }; void BuiltinAddFunction (NamespacePtr *namespacep, char *name, char *ret_format, char *format, BuiltinFunc f, Bool jumping, char *doc); #define BuiltinFuncStructDef(stype, functype) \ struct stype { \ functype func; \ char *name; \ char *ret; \ char *args; \ char *doc; \ } #define BuiltinExceptions(ns, e) do {\ const struct ebuiltin *ei; \ for (ei = (e); ei->name; ei++) { \ BuiltinAddException ((ns), ei->exception, ei->name, ei->args, ei->doc); \ } } while (0) #define BuiltinFuncsGeneric(ns, funcs, stype, bitem, jump) do { \ BuiltinFunc f; const struct stype *fi; \ for (fi = (funcs); fi->name; fi++) { \ f.bitem = fi->func; \ BuiltinAddFunction ((ns), fi->name, fi->ret, fi->args, f, jump, fi->doc); \ } } while (0) typedef Value (*fbuiltin_v_func) (int, Value *); BuiltinFuncStructDef(fbuiltin_v, fbuiltin_v_func); #define BuiltinFuncsV(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_v, builtinN, False) typedef Value (*fbuiltin_0_func) (void); BuiltinFuncStructDef(fbuiltin_0, fbuiltin_0_func); #define BuiltinFuncs0(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_0, builtin0, False) typedef Value (*fbuiltin_1_func) (Value); BuiltinFuncStructDef(fbuiltin_1, fbuiltin_1_func); #define BuiltinFuncs1(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_1, builtin1, False) typedef Value (*fbuiltin_2_func) (Value, Value); BuiltinFuncStructDef(fbuiltin_2, fbuiltin_2_func); #define BuiltinFuncs2(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_2, builtin2, False) typedef Value (*fbuiltin_3_func) (Value, Value, Value); BuiltinFuncStructDef(fbuiltin_3, fbuiltin_3_func); #define BuiltinFuncs3(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_3, builtin3, False) typedef Value (*fbuiltin_4_func) (Value, Value, Value, Value); BuiltinFuncStructDef(fbuiltin_4, fbuiltin_4_func); #define BuiltinFuncs4(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_4, builtin4, False) typedef Value (*fbuiltin_5_func) (Value, Value, Value, Value, Value); BuiltinFuncStructDef(fbuiltin_5, fbuiltin_5_func); #define BuiltinFuncs5(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_5, builtin5, False) typedef Value (*fbuiltin_6_func) (Value, Value, Value, Value, Value, Value); BuiltinFuncStructDef(fbuiltin_6, fbuiltin_6_func); #define BuiltinFuncs6(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_6, builtin6, False) typedef Value (*fbuiltin_7_func) (Value, Value, Value, Value, Value, Value, Value); BuiltinFuncStructDef(fbuiltin_7, fbuiltin_7_func); #define BuiltinFuncs7(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_7, builtin7, False) typedef Value (*fbuiltin_8_func) (Value, Value, Value, Value, Value, Value, Value, Value); BuiltinFuncStructDef(fbuiltin_8, fbuiltin_8_func); #define BuiltinFuncs8(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_8, builtin8, False) typedef Value (*fbuiltin_vj_func) (InstPtr *, int, Value *); BuiltinFuncStructDef(fbuiltin_vj, fbuiltin_vj_func); #define BuiltinFuncsVJ(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_vj, builtinNJ, True) typedef Value (*fbuiltin_0j_func) (InstPtr *); BuiltinFuncStructDef(fbuiltin_0j, fbuiltin_0j_func); #define BuiltinFuncs0J(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_0j, builtin0J, True) typedef Value (*fbuiltin_1j_func) (InstPtr *, Value); BuiltinFuncStructDef(fbuiltin_1j, fbuiltin_1j_func); #define BuiltinFuncs1J(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_1j, builtin1J, True) typedef Value (*fbuiltin_2j_func) (InstPtr *, Value, Value); BuiltinFuncStructDef(fbuiltin_2j, fbuiltin_2j_func); #define BuiltinFuncs2J(n, f) \ BuiltinFuncsGeneric(n, f, fbuiltin_2j, builtin2J, True) #if LOCAL_BUILD #include "builtin-namespaces.h" #else #include #endif nickle_2.81.orig/edit.c0000664000175000000620000000321111663765502014201 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * edit.c * * invoke the users editor (default /bin/ed) */ #include #include #include #include #include "nickle.h" #ifndef DEFAULT_EDITOR #define DEFAULT_EDITOR "ed" #endif static int edit (char *file_name) { char buf[1024]; char *editor; int ret; if (!(editor = getenv ("EDITOR"))) editor = DEFAULT_EDITOR; if (!file_name) file_name = ""; (void) sprintf (buf, "%s %s", editor, file_name); IoStop (); ret = system (buf); IoStart (); return ret; } void EditFunction (SymbolPtr symbol, Publish publish) { Value tmp; static const char template[] = "/tmp/nXXXXXX"; static const char exten[] = ".5c"; char tmpName[sizeof (template)]; char nickleName[sizeof (template) + sizeof (exten) + 2]; int fd; (void) strcpy (tmpName, template); fd = mkstemp (tmpName); if (fd < 0) return; strcpy (nickleName, tmpName); strcat (nickleName, exten); if (rename (tmpName, nickleName) < 0) { close (fd); unlink (tmpName); return; } tmp = FileCreate (fd, FileWritable); if (tmp) { PrettyPrint (tmp, publish, symbol); (void) FileClose (tmp); if (edit (nickleName) == 0) LexFile (nickleName, True, False); } (void) unlink (nickleName); } void EditFile (Value file_name) { if (!file_name) { edit (0); } else { char *name = StrzPart (file_name, "invalid filename"); if (name) edit (name); } } nickle_2.81.orig/list.5c0000664000175000000620000000351011716625403014310 0ustar keithpstaff/* * Copyright © 2012 Keith Packard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ namespace List { public typedef list_t; public typedef struct { *list_t prev; *list_t next; } list_t; public void init(*list_t l) { l->next = l; l->prev = l; } void add(*list_t entry, *list_t prev, *list_t next) { next->prev = entry; entry->next = next; entry->prev = prev; prev->next = entry; } void del(*list_t prev, *list_t next) { next->prev = prev; prev->next = next; } public bool is_empty(*list_t head) { return head->next == head; } public *list_t first(*list_t head) { assert(!is_empty(head), "empty list"); return head->next; } public *list_t last(*list_t head) { assert(!is_empty(head), "empty list"); return head->prev; } public void insert(*list_t entry, *list_t head) { add(entry, head, head->next); } public void append(*list_t entry, *list_t head) { add(entry, head->prev, head); } public void remove(*list_t entry) { del(entry->prev, entry->next); init(entry); } public iterate(*list_t head, bool (*list_t) f) { *list_t next; for (*list_t pos = head->next; pos != head; pos = next) { next = pos->next; if (!f(pos)) break; } } } nickle_2.81.orig/nickle.1.in0000664000175000000620000014351613062260671015051 0ustar keithpstaff.TH NICKLE 1 "@RELEASE_DATE@" .\" $Header$ .SH NAME nickle \- a desk calculator language .SH SYNOPSIS nickle [--help|--usage] [-f file] [-l library] [-e expr] [ script ] [--] [arg ...] .SH DESCRIPTION .PP \fINickle\fP is a desk calculator language with powerful programming and scripting capabilities. Nickle supports a variety of datatypes, especially arbitrary precision integers, rationals, and imprecise reals. The input language vaguely resembles C. Some things in C which do not translate easily are different, some design choices have been made differently, and a very few features are simply missing. .SH USAGE .PP An un-flagged argument is treated as a Nickle script, and replaces standard input. Any remaining arguments following the script are placed in the Nickle string array argv for programmatic inspection. When invoked without an expression or script argument, Nickle reads from standard input, and writes to standard output. .PP Options are as follows: .TP .B "--help,--usage" Print a help/usage message and exit. This is a built-in feature of Nickle's ParseArgs module, and thus will also be true of Nickle scripts that use this library. .TP .BI "-f,--file " file Load .I file into Nickle before beginning execution. .TP .BI "-l,--library " library Load .I library into Nickle before beginning execution. See below for a description of the library facility. .TP .BI "-e,--expr " expr Evaluate .I expr before beginning execution. .TP .B "--" Quit parsing arguments and pass the remainder, unevaluated, to .IR argv . .SH SYNTAX .PP To make the input language more useful in an interactive setting, \fBnewline\fP only terminates statements at ``reasonable'' times. \fBNewline\fP terminates either expressions or single statements typed by the user (with the exception of a few statements which require lookahead: notably if() and twixt(), which have an optional else part). Inside compound statements or function definitions, only a \fB;\fP terminates statements. This approach is convenient and does not appear to cause problems in normal use. .PP The syntax of Nickle programs is as follows. In this description, .B name denotes any sequence of letters, digits and _ characters not starting with a digit; .B E denotes any expression; .B S denotes any statement; and .B T denotes any type. The syntax .B "X,X,...,X" denotes one or more comma-separated Xs, unless otherwise indicated. .\" .LP .B "Comments:" .PP C-style comments are enclosed in /* and */, and shell-style comments are denoted by a leading # at the start of a line. .\" .LP .B "Operands:" .IP "real number" Can include exponent, need not include decimal point or sign. Will be treated as exact rationals. If a trailing decimal part contains an opening curly brace, the brace is silently ignored; if it contains a curly-bracketed trailing portion, it is treated as a repeating decimal. `Floating point'' constants are currently represented internally as rationals: for floating constants with a given precision (and an infinite-precision exponent), use the imprecise() builtin function described below. .IP "octal number" Start with a 0 (e.g., 014 is the same as 12). .IP "hexidecimal number" Start with "0x" (e.g., 0x1a is the same as 26). .IP string As in C. String constants are surrounded by double-quotes. Backslashed characters (including double-quotes) stand for themselves, except "\\n" stands for newline, "\\r" for carriage return, "\\b" for backspace, "\\t" for tab and "\\f" for formfeed. .IP name A variable reference. .IP "name() name(E,E,...,E)" A function call with zero or more arguments. Functions are fully call-by-value: arrays and structures are copied rather than being referenced as in C. .IP "desc name T name = value" Definition expressions: a new name is made available, with the value of the definition being the value of the initializer in the second form, and uninitialized in the first form. The descriptor desc is not optional: it consists of any combination of visibility, storage class or type (in that order). See QUALIFIERS immediately below for a description of these qualifiers. A structured value expression is also possible: see VALUES below. .IP In addition to being able to initialize a definition with a Nickle value, C-style array, structure, and union definitions are also allowed: For example, the following .nf int[*,*] name = {{0,1},{2,3}} int[2,2] name = {{0...}...} .fi are permitted with the obvious semantics. This is the context in which the dimensions in a type may be expressions: see the discussion of array types above. See the discussion of array and structure values for array and structure initializer syntax. .\" .SH QUALIFIERS .PP A declaration or definition may be qualified, as in C, to indicate details of programmatic behavior. Unlike in C, these qualifiers, while optional, must appear in the given order. .LP .B "Visibility:" .IP public Any definition expression (function definition, variable definition, type definition) can be qualified with public to indicate that the name being defined should be visible outside the current namespace, and should be automatically imported. See Namespaces below for further info. .IP protected Any definition expression (function definition, variable definition, type definition) can be qualified with protected to indicate that the name being defined should be visible outside the current namespace, but should not be made available by import declarations. See Namespaces below for further info. .LP .B "Lifetime:" .IP auto An auto object is local to a particular block: its lifetime is at least the lifetime of that block. An auto object with an initializer will be re-initialized each time it is evaluated. This is the default lifetime for local objects. .IP static A static object is local to a particular function definition: its lifetime is at least the lifetime of that definition. A new static object will be created each time its enclosing function definition is evaluated. .IP In Nickle, the keyword static has to do only with lifetime (like the use of static inside C functions), not with visibility (which is handled by separate qualifiers as described above, not like the use of static in global scope in C). .IP global A global object is global to the entire program: its lifetime is the lifetime of the program. A global object will be created and initialized when its definition is first seen. This is the default lifetime for global objects. .IP The distinction between static and global lifetime in Nickle is not possible in C, because C functions are not first class objects with nested scope. When deciding which to use in a Nickle program, think about what should happen if a definition is re-evaluated. .\" .SH OPERATORS .PP Here are the basic Nickle operators, grouped in order of decreasing precedence: .PP .IP "A[E,E,...,E]" Refers to the E'th element of the array expression A, or the E1'th/E2'th/etc element of a multi-dimensional array. Both arrays of arrays ala C and multidimensional arrays ala NAWK are possible. .IP "struct.tag" Structure dereference. .IP "struct->tag" Structure pointer dereference ala C. .IP "=============" .IP "++ --" Unary increment/decrement. May be either postfix or prefix. .IP "-" Unary negate .IP "! E" Logical negation. .IP "E !" Factorial. Requires a non-negative integer argument. .IP "* E" Pointer dereference. .IP "& E" Reference construction. .IP "=============" .IP "(U) E" Construct a value of union type with tag U and value E. .IP "=============" .IP "**" Exponentiation. Both operands may be fractional. The left operand must be non-negative unless the right operand is integer. The result type is the type of the left operand if the right operand is integer, and real otherwise. .IP This is the only known type-unsound feature of Nickle: an expression like 2 ** -3 will statically be of type integer, but dynamically will generate a rational result. This may cause a runtime type error later on: consider .br int x = 2 ** -3; .br .IP "=============" .IP "* / // %" Times, divide, integer divide, and remainder. The right operand of the last three operators must be nonzero. The result type of the division operator will always be at least rational: the result type of the integer division operator will always be int. This is a notable departure from C, where integer division is implied by integer operands. Integer division is defined by .br x // y == y > 0 ? floor (x / y) : ceil(x / y) .br The remainder is always non-negative and is defined by: by .br x % y = x - (x // y) * y .br .IP "=============" .IP "+ -" Addition and subtraction. .IP "=============" .IP "<< >>" Bitwise left and right shift with integer operands. Negative right operands work as expected. These operators are defined by .br x << y = x * 2 ** y .br x >> y = x // 2 ** y .br Another way to look at this is that negative left operands are considered to be in an infinite twos-complement representation (i.e., sign-extended to infinity), with right shift sign-extending its left operand. .IP "=============" .IP "<= >= < >" Relational operators. .IP "=============" .IP "== !=" Equality operators. .IP "=============" Finally, in order of decreasing precedence: .IP "&" Bitwise AND. Negative operands are considered to be in an infinite twos-complement representation (i.e., sign-extended to infinity). .IP "^" Bitwise XOR. Negative operands as in bitwise AND. .IP "|" Bitwise OR. Negative operands as in bitwise AND. .IP "&&" Short-circuit logical AND. .IP "||" Short-circuit logical OR. .IP "E ? E : E" Conditional expression: if first expression is logical true, value is second expression, else third. .IP "fork E" Create (and return) a thread. See Thread below for details. .IP "= += -= *= /= //= %= **= <<= >>= ^= &= |=" Assignment operators. Left-hand-side must be assignable. .BI "x " "=" " y" is equivalent to .BI "x " "=" " x " "" " y" .IP "E , E" Returns right-hand expression. .\" .SH TYPES .PP The type declaration syntax of Nickle more strongly resembles the ``left'' variant of the Java syntax than the C syntax. Essentially, a type consists of: .IP "poly integer rational real string continuation void" A base type of the language. Type void is actually only usable in certain contexts, notably function returns. It is currently implemented as a ``unit'' type ala ML, and thus has slightly different behavior than in C. Type poly is the supertype of all other types (i.e., it can be used to inhibit static type checking), and is the default type in most situations where a type need not appear. .IP "file semaphore thread" Also builtin base types, but integral to the File and Thread ADTs: see below. .LP .B "More About Types:" .PP \fINickle\fP supports polymorphic data: As an expresion is evaluated, a data type is chosen to fit the result. Any Nickle object may be statically typed, in which case bounds violations will be flagged as errors at compile time. Polymorphic variables and functions do not place restrictions on the assigned data type; this is the default type for all objects. .IP "poly" This describes the union of all datatypes. A variable with this type can contain any data value. .IP "int" Arbitrary precision integers. .IP "rational" Arbitrary precision rational numbers. .IP "real" Arbitrary exponent precision floating point numbers. As many computations cannot be carried out exactly as rational numbers, Nickle implements non-precise arithmetic using its own machine-independent representation for floating point numbers. The builtin function imprecise(n) generates a real number with 256 bits of precision from the number n, while imprecise(n,p) generates a real number with p bits of precision. .IP "T[]" An array of type T, of one or more dimensions. There are no zero-dimensional arrays in Nickle. .IP "T[*]" A one-dimensional array of type T. Unlike in C, the dimension of an array is never part of its type in Nickle. Further, arrays and pointers are unrelated types in Nickle. .IP "T[*,*,...,*]" A two or more dimensional array of type T. The stars ``*'' are not optional. As the previous paragraphs make clear, ``T[]'' is not a zero-dimensional array. .IP "T[E,E,...,E]" In definition contexts, integer values may be given for each dimension of an array context. These are strictly for value-creation purposes, and are not part of the type. An array type is determined only by the base type and number of dimensions of the array. .IP "T0() T0(T,T,...,T)" A function returning type T0. A function accepts 0 or more arguments. .IP "T0() T0(T,T,...,T \fB...\fP)" A function accepting zero or more required arguments, plus an arbitrary number of optional arguments. The second sequence of three dots (ellipsis) is syntax, not metasyntax: see the description of varargs functions for details. .IP "*T" A pointer to a location of type T. Pointer arithmetic in Nickle operates only upon pointers to arrays: the pointer must be of the correct type, and may never stray out of bounds. A pointer may either point to some location or be null (0). As in C, the precedence of ``*'' is lower than the precedence of ``[]'' or ``()'': use parenthesis as needed. .IP "struct {T name; T name; ...}" A structure with fields of the given name and type. The types T are optional: in their absence, the type of the field is poly. .IP "union {T name; T name; ...}" A ``disjoint union'' of the given types. This is more like the variant record type of Pascal or the datatype of ML than the C union type: the names are tags of the given type, exactly one of which applies to a given value at a given time. .IP "(T)" Parentheses for grouping. .LP .B "Typedef:" .PP As in C, new type names may be created with the typedef statement. The syntax is .br typedef T typename; .br where T is a Nickle type. The resulting typename may be used anywhere a type is expected. .\" .SH VALUES .PP Values of the base types of Nickle are as expected. See the syntax for constants above. Values of type file, semaphore, and continuation may currently be created only by calls to builtin functions: no Nickle constants of these types exist. .PP As noted in TYPES above, Nickle has several kinds of ``structured value'': arrays, functions, pointers, structures and disjoint unions. All of these have some common properties. When created, all of the component values are uninitialized (unless otherwise specified). Attempts to use an uninitialized value will result in either a compile-time error or a runtime exception. .LP .B "Arrays:" .IP "[E]" creates a (zero-based) array with E elements. E must be non-negative. .IP "[E]{V,V,...,V}" Creates an array with E elements, initialized to the Vs. If there are too few initializers, remaining elements will remain uninitialized. .IP "[E]{V,V,...,V\fI...\fP}" The second ellipsis (three dots) is syntax, not metasyntax. Create an array with E elements. The first elements in the array will be initialized according to the Vs, with any remaining elements receiving the same value as the last V. This syntax may be used in the obvious fashion with any of the array initializers below. .IP "[*]{V,V,...,V}" Creates an initialized array with exactly as many elements as initializers. There must be at least one initializer. .IP "[E,E,...,E] [*,*,...,*]" Creates multidimensional arrays. Integer expressions and "*" cannot be mixed: an array's dimensions are entirely either specified or unspecified by the definition. These arrays may also be created initialized: see next paragraph for initializer syntax. .IP "(T[E]) (T[E,E,...,E]) (T[E]){E,E,...,E}" .IP "(T[E,E,...,E]){{E,...},...,{E,...}}" Alternate syntax for creating arrays of type T. The initializers, in curly braces, are optional. The number of initializers must be less than or equal to the given number of elements in each dimension. For multidimensional arrays, the extra curly braces per dimension in the initializer are required; this is unlike C, where they are optional. .IP "(T[*]){E,E,...,E} (T[*,*,...,*]){{E,...},...,{E,...}}" Creates arrays of type T, with each dimension's size given by the maximum number of initializers in any subarray in that dimension. .LP .B "Pointers:" .IP 0 The null pointer, in contexts where a pointer is required. .IP "&V &A[E,E,...,E] &S.N" Creates a pointer to the given variable, array element, or structure member. The type of the pointer will be *T, where T is the type of the object pointed to. .IP "*P" The value pointed to by pointer P. This can be viewed or modified as in C. .LP .B "Functions:" .IP "(T func(){S;S;...S;}) (T func(T name,T name,...T name){S;S;...S;})" Function expression: denotes a function of zero or more formal parameters with the given types and names, returning the given result type. The function body is given by the curly-brace-enclosed statement list. All types are optional, and default to poly. As noted above, functions are strictly call-by-value: in particular, arrays and structures are copied rather than referenced. .IP "T function name(T name,T name,...,T name){S;S;...S;}" Defines a function of zero or more arguments. Syntactic sugar for .br T(T,T,...T) name = (T func(T name,T name,...T name){S;S;...S;}); .br .IP "T function name(T name, T name \fB...\fP)" The ellipsis here is syntax, not metasyntax: if the last formal argument to a function is followed by three dots, the function may be called with more actuals than formals. All ``extra'' actuals are packaged into the array formal of the given name, and typechecked against the optional type T of the last argument (default poly). .LP .B "Structures:" .IP "(struct { T name; T name; ...T name; }){name = E; name = E; ...name=E;}" Create a value of a structured type. The named fields are initialized to the given values, with the remainder uninitialized. As indicated, initialization is by label rather than positional as in C. .LP .B "Unions:" .IP "(union { T name; T name; ...T name; }.name) E" Create a value of the given union type, the variant given by .name, and the value given by E. E must be type-compatible with name. .\" .SH STATEMENTS The statement syntax very closely resembles that of C. Some additional syntax has been added to support Nickle's additional functionality. .IP "E;" Evaluates the expression. .IP "{S ... S}" Executes the enclosed statements in order. .IP "if (E) S" Basic conditional. .IP "if (E) S" Conditional execution. .IP "else S" Else is allowed, with the usual syntax and semantics. In particular, an else binds to the most recent applicable if() or twixt(). .IP "while (E) S" C-style while loop. .IP "do S while (E);" C-style do loop. .IP "for (opt-E; opt-E; opt-E) S" C-style for loop. .IP "switch (E) { case E: S-list case E: S-list ... default: S-list }" C-style case statement. The case expressions are not required to be constant expressions, but may be arbitrary. The first case evaluating to the switch argument is taken, else the default if present, else the switch body is skipped. .IP "twixt(opt-E; opt-E) S" .IP "twixt(opt-E; opt-E) S else S" If first argument expression evaluates to true, the body of the twixt() and then the second argument expression will be evaluated. If the first argument expression evaluates to false, the else statement will be executed if present. Otherwise, the entire twixt() statement will be skipped. .PP The twixt() statement guarantees that all of these events will happen in the specified order regardless of the manner in which the twixt() is entered (from outside) or exited, including exceptions, continuations, and break. (Compare with Java's ``finally'' clause.) .IP "try S;" .IP "try S catch name (T name, ...) { S; ... };" .IP "try S catch name (T name, ...) { S; ... } ... ;" Execute the first statement S. If an exception is raised during execution, and the name matches the name in a catch block, bind the formal parameters in the catch block to the actual parameters of the exception, and execute the body of the catch block. There may be multiple catch blocks per try. Zero catches, while legal, is relatively useless. After completion of a catch block, execution continues after the try clause. As with else, a catch binds to the most recent applicable try-catch block. .IP "raise name(name, name, ..., name)" Raise the named exception with zero or more arguments. .IP ";" The null statement .IP "break;" Discontinue execution of the nearest enclosing for/do/while/switch/twixt statement. The leave expression will be executed as the twixt statement is exited. .IP "continue;" Branch directly to the conditional test of the nearest enclosing for/do/while statement. .IP "return E;" Return value E from the nearest enclosing function. .\" .LP .B "Namespaces:" .PP Like Java and C++ Nickle has a notion of .IR namespace , a collection of names with partially restricted visibility. In Nickle, namespaces are created with the .I namespace command. .IP "opt-P namespace N { S ... }" Places all names defined in the statements S into a namespace named N. The optional qualifier P may be the keyword public, but beware: this merely indicates that the name N itself is visible elsewhere in the current scope, and has nothing to do with the visibility of items inside the namespace. .IP "extend namespace N { S ... }" Reopen the given namespace N, and extend it with the names defined as public in the given statements S. .IP Names defined inside the namespace are invisible outside the namespace unless they are qualified with the keyword public. Public names may be referred to using a path notation: .br namespace::namespace::...::namespace::name .br refers to the given name as defined inside the given set of namespaces. The double-colon syntax is unfortunate, as it is slightly different in meaning than in C++, but all the good symbols were taken, and it is believed to be a feature that the namespace separator is syntactically different than the structure operator. In Java, for example, the phrase .br name.name.name .br is syntactically ambiguous: the middle name may be either a structure or a namespace. .IP "import N;" The name N must refer to a namespace: all public names in this namespace are brought into the current scope (scoping out conflicting names). .\" .SH BUILTINS .PP \fINickle\fP has a collection of standard functions built in. Some of these are written in C, but many are written in Nickle. Several collections of functions have associated builtin datatypes: their namespaces, together with their types, should be viewed as ADTs. .LP .B "Top-Level Builtins:" .IP "int printf(string fmt, poly args...)" Calls File::fprintf(stdout, fmt, args ...) and returns its result. .IP "string function gets ()" Calls File::fgets(stdin) and returns its result. .IP "string function scanf (string fmt, *poly args...)" Calls File::vfscanf(stdin, fmt, args) and returns its result. .IP "string function vscanf (string fmt, (*poly)[*] args)" Calls File::vfscanf(stdin, fmt, args) and returns its result. .IP "real imprecise(rational value)" See the discussion of type real above. .IP "real imprecise(rational value, int prec)" See the discussion of type real above. .IP "int string_to_integer(string s)" .IP "int atoi(string s)" The argument s is a signed digit string, and the result is the integer it represents. If the string s is syntactically a hexadecimal, octal, binary, or explicit base-10 constant, treat it as such. .IP "int string_to_integer(string s, int base)" .IP "int atoi(string s, int base)" Treat s as a string of digits in the given base. A base of 0 acts as with no base argument. Otherwise, base specification syntax in the string is ignored. .IP "int putchar(int c)" Place the given character on the standard output using File::putc(c, stdout), and return its result. .IP "int sleep(int msecs)" Try to suspend the current thread for at least msecs milliseconds. Return 1 on early return, and 0 otherwise. .IP "int exit(int status)" Exit Nickle with the given status code. Do not return anything. .IP "int dim(poly[*] a)" Given a one-dimensional array a, dim() returns the number of elements of a. .IP "int[] dims(poly[] a) Given an arbitrary array a, dims() returns an array of integers giving the size of each dimension of a. Thus, dim(dims(a)) is the number of dimensions of a. .IP "*poly reference(poly v)" Given an arbitrary value v, ``box'' that value into storage and return a pointer to the box. .IP "rational string_to_real(string s)" .IP "rational atof(string s)" Convert the real constant string s into its associated real number. .IP "number abs(real v)" Return the absolute value of v. The result type chosen will match the given context. .IP "int floor(real v)" Return the largest integer less than or equal to v. This will fail if v is a real and the precision is too low. .IP "int ceil(real v)" Return the smallest integer greater than or equal to v. This will fail if v is a real and the precision is too low. .IP "int exponent(real v)" Return the exponent of the imprecise real v. .IP "rational mantissa(real v)" Return the mantissa of the imprecise real v, as a rational m with 0 <= m <= 0.5 . .IP "int numerator(rational v)" Return the numerator of the rational number v: i.e., if v = n/d in reduced form, return n. .IP "int denominator(rational v)" Return the denominator of the rational number v: i.e., if v = n/d in reduced form, return d. .IP "int precision(real v)" Return the number of bits of precision of the mantissa of the imprecise real number v. .IP "int sign(real v)" Return -1 or 1 as v is negative or nonnegative. .IP "int bit_width(int v)" Return the number of bits required to represent abs(v) internally. .IP "int is_int(poly v)" Type predicate. .IP "int is_rational(poly v)" Numeric type predicates are inclusive: e.g., is_rational(1) returns 1. .IP "int is_number(poly v)" Type predicate. .IP "int is_string(poly v)" Type predicate. .IP "int is_file(poly v)" Type predicate. .IP "int is_thread(poly v)" Type predicate. .IP "int is_semaphore(poly v)" Type predicate. .IP "int is_continuation(poly v)" Type predicate. .IP "int is_array(poly v)" Type predicate. .IP "int is_ref(poly v)" Type predicate: checks for pointer type. This is arguably a misfeature, and may change. .IP "int is_struct(poly v)" Type predicate. .IP "int is_func(poly v)" Type predicate. .IP "int is_void(poly v)" Type predicate. .IP "int gcd(int p, int q)" Return the GCD of p and q. The result is always positive. .IP "int xor(int a, int b)" Return a ^ b . This is mostly a holdover from before Nickle had an xor operator. .IP "poly setjmp(continuation *c, poly retval)" The setjmp() and longjmp() primitives together with the continuation type form an ADT useful for nearly arbitrary transfers of flow-of-control. The setjmp() and longjmp() builtins are like those of C, except that the restriction that longjmp() always jump upwards is removed(!): a continuation saved via setjmp() never becomes invalid during the program lifetime. .IP The setjmp() builtin saves the current location and context into its continuation pointer argument, and then returns its second argument. .IP "void longjmp(continuation c, poly retval)" The longjmp() builtin never returns to the call site, but instead returns from the setjmp() that created the continuation, with return value equal to the second argument of longjmp(). .IP "string prompt" The prompt printed during interactive use when at top-level. Default "> ". when waiting for the rest of a statement or expression, and when debugging, respectively. Default values are "> ", "+ ", and "- ". .IP "string prompt2" The prompt printed during interactive use when waiting for the rest of a statement or expression. Default "+ ". .IP "string prompt3" The prompt printed during interactive use when debugging. Default "- ". .IP "string format" The printf() format for printing top-level values. Default "%g". .IP "string version" The version number of the Nickle implementation currently being executed. .IP "string build" The build date of the Nickle implementation currently being executed, in the form "yyyy/mm/dd", or "?" if the build date is unknown for some reason. .IP "file stdin" Bound to the standard input stream. .IP "file stdout" Bound to the standard output stream. .IP "file stderr" Bound to the standard error stream. .LP .B "Exceptions:" .PP A few standard exceptions are predeclared and used internally by Nickle. .IP "exception uninitialized_value(string msg)" Attempt to use an uninitialized value. .IP "exception invalid_argument(string msg, int arg, poly val)" The arg-th argument to a builtin function had invalid value val. .IP "exception readonly_box(string msg, poly val)" Attempt to change the value of a read-only quantity to val. .IP "exception invalid_array_bounds(string msg, poly a, poly i)" Attempt to access array a at index i is out of bounds. .IP "exception divide_by_zero(string msg, real num, real den)" Attempt to divide num by den with den == 0. .IP "exception invalid_struct_member(string msg, poly struct, string name)" Attempt to refer to member name of the object struct, which does not exist. .IP "exception invalid_binop_values(string msg, poly arg1, poly arg2)" Attempt to evaluate a binary operator with args arg1 and arg2, where at least one of these values is invalid. .IP "exception invalid_unop_values(string msg, poly arg)" Attempt to evaluate a unary operator with invalid argument arg. .LP .B "Builtin Namespaces:" .IP Math The math functions available in the Math namespace are implemented in a fashion intended to be compatible with the C library. Please consult the appropriate manuals for further details. .IP "real pi" Imprecise constant giving the value of the circumference/diameter ratio of the circle to the default precision of 256 bits. .IP "protected real e" Imprecise constant giving the value of the base of natural logarithms to the default precision of 256 bits. Since e is protected, it must be referenced via Math::e, in order to avoid problems with using the fifth letter of the alphabet at top level. .IP "real function sqrt(real v)" Returns the square root of v. .IP "real function cbrt(real v)" Returns the cube root of v. .IP "real function exp(real v)" Returns e**v. .IP "real function log(real a)" Returns v such that e**v == a. Throws an invalid_argument exception if a is non-positive. .IP "real function log10(real a)" Returns v such that 10**v == a. Throws an invalid_argument exception if a is non-positive. .IP "real function log2(real a)" Returns v such that 2**v == a. Throws an invalid_argument exception if a is non-positive. .IP "real function pi_value(int prec)" Returns the ratio of the circumference of a circle to the diameter, with prec bits of precision. .IP "real function sin(real a)" Returns the ratio of the opposite side to the hypotenuse of angle a of a right triangle, given in radians. .IP "real function cos(real a)" Returns the ratio of the adjacent side to the hypotenuse of angle a of a right triangle, given in radians. .IP "void function sin_cos(real a, *real sinp, *real cosp)" Returns with sin(a) and cos(a) stored in the locations pointed to by sinp and cosp respectively. If either pointer is 0, do not store into that location. May be slightly faster than calling both trig functions independently. .IP "real function tan(real a)" Returns the ratio of the opposite side to the adjacent side of angle a of a right triangle, given in radians. Note that tan(pi/2) is not currently an error: it will return a very large number dependent on the precision of its input. .IP "real function asin(real v)" Returns a such that sin(a) == v. .IP "real function acos(real v)" Returns a such that cos(a) == v. .IP "real function atan(real v)" Returns a such that tan(a) == v. .IP "real function atan2(real x, y)" Returns a such that tan(a) == x / y. Deals correctly with y == 0. .IP "real function pow(real a, real b)" The implementation of the ** operator. .PP .IP File The namespace File provides operations on file values. .IP "int function fprintf(file f, string s, ....)" Print formatted values to a file, as with UNIX stdio library fprintf(). fprintf() and printf() accept a reasonable sub-set of the stdio library version: %c, %d, %e, %x, %o, %f, %s, %g work as expected, as does %v to smart-print a value. Format modifiers may be placed between the percent-sign and the format letter to modify formatting. There are a lot of known bugs with input and output formatting. .RS .LP .B "Format Letters:" .IP "%c" Requires a small integer argument (0..255), and formats as an ASCII character. .IP "%d" Requires an integer argument, and formats as an integer. .IP "%x" Requires an integer argument, and formats as a base-16 (hexadecimal) integer. .IP "%o" Requires an integer argument, and formats as a base-8 (octal) integer. .IP "%e" Requires a number argument, and formats in scientific notation. .IP "%f" Requires a number argument, and formats in fixed-point notation. .IP "%s" Requires a string argument, and emits the string literally. .IP "%g" Requires a number, and tries to pick a precise and readable representation to format it. .LP .B "Format Modifiers:" .IP "digits" All format characters will take an integer format modifier indicating the number of blanks in the format field for the data to be formatted. The value will be printed right-justified in this space. .IP "digits.digits" The real formats will take a pair of integer format modifiers indicating the field width and precision (number of chars after decimal point) of the formatted value. Either integer may be omitted. .IP "-" A precision value indicating infinite precision. .IP "*" The next argument to fprintf() is an integer indicating the field width or precision of the formatted value. .RE .IP "file function string_write()" Return a file which collects written values into a string. .IP "int function close(file f)" Close file f and return an indication of success. .IP "int function flush(file f)" Flush the buffers of file f and return an indication of success. .IP "int function getc(file f)" Get the next character from file f and return it. .IP "int function end(file f)" Returns true if file f is at EOF, else false. .IP "int function error(file f)" Returns true if an error is pending on file f, else false. .IP "int function clear_error(file f)" Clears pending errors on file f, and returns an indication of success. .IP "file function string_read(string s)" Returns a virtual file whose contents are the string s. .IP "string function string_string(file f)" Return the string previously written into the file f, which should have been created by string_read() or string_write(). Behavior on other files is currently undefined. .IP "file function open(string path, string mode)" Open the file at the given path with the given mode string, ala UNIX stdio fopen(). Permissible modes are as in stdio: "r", "w", "x", "r+", "w+" and "x+". .IP "integer function fputc(integer c, file f)" Output the character c to the output file f, and return an indication of success. .IP "integer function ungetc(integer c, file f)" Push the character c back onto the input file f, and return an indication of success. .IP "integer function setbuf(file f, integer n)" Set the size of the buffer associated with file f to n, and return n. .IP "string function fgets (file f)" Get a line of input from file f, and return the resulting string. .IP "file function pipe(string path, string[*] argv, string mode)" Start up the program at the given path, returning a file which is one end of a "pipe" to the given process. The mode argument can be "r" to read from the pipe or "w" to write to the pipe. The argv argument is an array of strings giving the arguments to be passed to the program, with argv[0] conventionally being the program name. .IP "int function print (file f, poly v, string fmt, int base, int width, int prec, string fill)" Print value v to file f in format fmt with the given base, width, prec, and fill. Used internally by File::fprintf(); .IP "int function fscanf(file f, string fmt, *poly args...)" Fill the locations pointed to by the array args with values taken from file f according to string fmt. The format specifiers are much as in UNIX stdio scanf(): the "%d", "%e", "%f", "%c" and "%s" specifiers are supported with the expected modifiers. .IP "int function vfscanf (file f, string fmt, (*poly)[*] args)" Given the file f, the format fmt, and the array of arguments args, fscanf() appropriately. .PP .IP Thread The namespace Thread supports various operations useful for programming with .IR threads , which provide concurrent flow of control in the shared address space. There is one piece of special syntax associated with threads. .RS .IP "fork(E)" Accepts an arbitrary expression, and evaluates it in a new child thread. The parent thread receives the thread as the value of the fork expression. .RE .IP The remainder of the Thread functions are fairly standard. .IP "int function kill(thread list...)" Kills every running thread in the array list. With no arguments, kills the currently running thread. Returns the number of threads killed. .IP "int function trace(poly list...)" Shows the state of every running thread in the array list. With no arguments, traces the default continuation. Returns the number of threads traced. .IP "int function cont()" Continues execution of any interrupted threads, and returns the number of continued threads. .IP "thread function current()" Return the current thread. .IP "int function list()" Reports the currently running thread to stdout. .IP "int function get_priority(thread t)" Reports the priority of the given thread. .IP "thread function id_to_thread(int id)" Returns the thread with the given id, if found, and 0 otherwise. .IP "poly function join(thread t)" Waits for thread t to terminate, and returns whatever it returns. .IP "int function set_priority(thread t, int i)" Attempts to set the priority of thread t to level i, and returns the new priority. Larger priorities mean more runtime: a task with higher priority will always run instead of a lower priority task. Threads of equal highest priority will be pre-emptively multitasked. .PP .IP Semaphore The Semaphore namespace encapsulates operations on the semaphore built-in ADT. A semaphore is used for thread synchronization. Each signal() operation on the semaphore awakens the least-recent thread to wait() on that semaphore. The ``count'' of waiting processes may be set at semaphore creation time. .IP "semaphore function new(int c)" Create a new semaphore with an initial count c of waiting processes. If c is positive, it means that c threads may wait on the semaphore before one blocks. If c is negative, it sets a count of threads which must be waiting on the semaphore before further waits will not block. .IP "semaphore function new()" Call semaphore(0) and return its result. .IP "int signal(semaphore s)" Increment semaphore s. If s is non-positive, and some thread is blocked on s, release the least-recently-blocked thread. Return 1 on success. .IP "int wait(semaphore s)" Decrement semaphore s. If s is negative, block until released. Return 1 on success. .IP "int test(semaphore s)" Test whether wait() on semaphore s would cause the current thread to block. If so, return 0. Otherwise, attempt to decrement s, and return 1 if successful. .PP .IP String The String namespace contains a few basic operations on the string ADT. .IP "int function length(string s)" Returns the number of characters in s. .IP "string function new(int c)" Returns as a string the single character c. .IP "string function new(int cv[*])" Returns a string comprised of the characters of cv. .IP "int function index(string t, string p)" Returns the integer index of the pattern string p in the target string t, or -1 if p is not a substring of t. .IP "string function substr(string s, int i, int l)" Returns the substring of string s starting with the character at offset i (zero-based) and continuing for a total of l characters. If l is negative, the substring will consist of characters preceding rather than succeeding i. .PP .IP PRNG The PRNG namespace provides pseudo-random number generation and manipulation. The core generator is the RC4 stream cipher generator, properly bootstrapped. This provide a stream of cryptographically-secure pseudo-random bits at reasonable amortized cost. (But beware, initialization is somewhat expensive.) .IP "void function srandom(int s)" Initialize the generator, using the (arbitrarily-large) integer as a seed. .IP "void function dev_srandom(int nbits)" Initialize the generator, using nbits bits of entropy obtained from some reasonable entropy source. On UNIX systems, this source is /dev/urandom. Asking for more initial entropy than the system has may lead either to bootstrapping (as on UNIX) or to hanging, so use cautiously. .IP "int function randbits(int n)" Returns an n-\fBbit\fP pseudo-random number, in the range \fI0..(2**n)-1\fP. Useful for things like RSA. .IP "int function randint(int n)" Returns a pseudo-random number in the range \fI0..n-1\fP. .IP "void function shuffle(*(poly[*]) a)" Performs an efficient in-place true shuffle (c.f. Knuth) of the array a. .PP .IP Command The Command namespace is used by the top-level commands as described below. It is also occasionally useful in its own right. .IP "string library_path" Contains the current library search path, a colon-separated list of directories to be searched for library files. .IP "int function undefine(string name)" Implements the top-level undefine command. Remove the name denoted by string name from the namespace. This removes all visible definitions of the name. .IP "int function undefine(string[*] names)" Remove each of the names in the array names from the namespace. This removes all visible definitions of each name. .IP "int function delete(string name)" Attempt to remove the command with the given string name from the top-level command list, and return 1 if successful. .IP "int function lex_file(string path)" Attempt to make the file at the given path the current source of Nickle code, and return 1 if successful. Note that this effectively ``includes'' the file by pushing it onto a stack of files to be processed. .IP "int function lex_library(string filename)" Like lex_file(), but searches the directories given by the .I library_path variable for the first file with the given filename. .IP "int function lex_string(string code)" Attempt to make the Nickle code contained in the string code be the next input. .IP "int function edit(string[*] names)" Implements the top-level edit command. The names in the array are a path of namespace names leading to the symbol name, which is last. .IP "int function new(string name, poly func)" Binds function func to the top-level command string name: i.e., makes it part of the top-level command vocabulary. .IP "int function new_names(string name, poly func)" Binds function func to the top-level command string name: i.e., makes it part of the top-level command vocabulary. Unlike new(), the string names given to func at the top level are passed unevaluated as an array of string names or as a single string name. .IP "int function pretty_print(file f, string[*] names)" Implements the top-level print command. Each of the passed name strings is looked up and the corresponding code printed to file f. .IP "int function display(string fmt, poly val)" Uses printf() to display the value val in format fmt. .PP .IP History Nickle maintains a top-level value history, useful as an adjunct to command-line editing when calculating. The History namespace contains functions to access this history. .IP "int function show(string fmt)" Implements the history top-level command with no arguments. Show the most recent history values with format fmt. .IP "int function show(string fmt, int count)" Implements the history top-level command with one argument. Show the last count history values with format fmt. .IP "int function show(string fmt, int first, int last)" Implements the history top-level command with two arguments. .IP "poly function insert(poly val)" Insert val in the history list, and return it. .PP .IP Environ Many operating systems have some notion of ``environment variables.'' The Environ namespace contains functions to manipulate these. .IP "int function check(string name)" Returns 1 if the variable with the given name is in the environment, and 0 otherwise. .IP "string function get(string name)" Attempts to retrieve and return the value of the environment variable with the given name. Throws an invalid_argument exception if the variable is not available. .IP "int function unset(string name)" Attempts to unset the environment variable with the given name, and returns an indication of success. .IP "string function set(string name, string value)" Attempts to set the environment variable with the given name to the given value, and returns an indication of success. .\" .SH COMMANDS .PP Nickle has a set of commands which may be given at the top level. .IP "quit" Exit Nickle. .IP "quit E" Exit Nickle with integer status code E. .IP "undefine NAME {,NAME}" Remove these names from the system. .IP "load E" Load a file given by the string name E. .IP "library E" Load a library given by the string name E. See the discussion of the NICKLEPATH environment variable in ENVIRONMENT below, and the discussion of Command::library_path above. .IP "E # E" Print expr1 in base expr2 . .IP "print NAME" Display a formatted version of the object denoted by NAME. Comments and original formating are lost. If NAME is a variable, print the type as well as the value. .IP "edit NAME" Invoke $EDITOR on the named object, and re-incorporate the results of the edit. This is most useful with functions. .IP "history" Display the 10 most recently printed values. They can be accessed with \fB$\fP\fIn\fP where \fIn\fP is the number displayed to the right of the value in this list. .IP "history \fIE\fP" Display the E most recent history values. .IP "history \fIE\fP,\fIE\fP" Display history values from the first integer E through the second. .\" .SH DEBUGGER When an unhandled exception reaches top level during execution, the user receives a dash prompt, indicating that debug mode is active. In this mode, the command-line environment is that in which the unhandled exception was raised. In addition a number of debugging commands are available to the user: .IP trace Get a stack backtrace showing the current state, as with the GDB where command. .IP up Move up the stack (i.e., toward the top-level expression) ala GDB. .IP down Move down the stack (i.e., toward the current context) ala GDB. .IP done Leave debugging mode, abandoning execution. .IP In addition, the Debug namespace is scoped in in debugging mode. This is primarily of use in debugging Nickle itself. .IP collect() Run the garbage collector. .IP dump(function) Print the compiled byte code for function. .\" .SH ENVIRONMENT .IP EDITOR The editor used by the edit command, described in COMMANDS above. .IP NICKLERC The location of the user's .nicklerc file, which will be loaded at the beginning of nickle execution if possible. .IP HOME Used to find the user's .nicklerc if NICKLERC is not set. .IP NICKLEPATH A colon-separated path whose elements are directories containing Nickle code. The library command and the -l flag, described above, search this path for a filename matching the given file. The default library path in the absence of this variable is @pkgdatadir@. .IP NICKLESTART The filename of the file that should be loaded as a bootstrap on Nickle startup. The default in the absence of this variable is to load @pkgdatadir@/builtin.5c. .\" .SH EXAMPLES .PP An example (taken from the \fIbc\fP manual: .nf real function exponent(real x) { real a = 1; int b = 1; real s = 1; int i = 1; while (1) { a = a * x; b = b * i; real c = a / b; if (abs(c) < 1e-6) return s; s = s + c; i++; } } .fi defines a function to compute an approximate value of the exponential function e ** x and .nf for (i = 1; i < 10; i++) printf ("%g\\n", exponent (i)); .fi prints approximate values of the exponential function of the first ten integers. .\" .SH VERSION .PP This document describes version 1.99.2 of nickle, as well as some newer features. It was distributed with version @VERSION@ of nickle. .SH BUGS .PP See the discussion of the type of the exponentiation operator ** above. .PP Due to a difficult-to-remove grammar ambiguity, it is not possible to use a bare assignment expression in an array initializer: it is confused with a structure initializer. For example: .nf > int x = 0; > (int[*]){x = 1} -> (int[*]) { x = 1 } Non array initializer .fi The workaround is to parenthesize the assignment expression: .nf > (int[*]){(x = 1)} [1]{1} .fi Because this is so rare, so hard to fix, and so easy to work around, this bug is unlikely to be fixed anytime soon. .PP There are a lot of known bugs with input and output formatting. The obvious stuff works, other stuff does not. .PP The semantics of division are unfortunately different from those of C. This is arguably because C is broken in this area: we cannot currently see any obvious fix. C allows automatic implicit coercion of floating to integral types, but we consider this a misfeature. .PP The implementation has not been thoroughly tested. .\" .SH AUTHOR \fINickle\fP is the work of Keith Packard and Bart Massey . .\" .PP Nickle is .br Copyright 1988-2006 Keith Packard and Bart Massey. All Rights Reserved. .PP Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: .PP The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. .PP THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .PP Except as contained in this notice, the names of the authors or their institutions shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. nickle_2.81.orig/type.c0000664000175000000620000010043111722535721014231 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * type.c * * manage datatype */ #include "nickle.h" #include "gram.h" Type *typePoly; Type *typeRefPoly; Type *typeArrayInt; Type *typePrim[rep_void + 1]; static void TypeNameMark (void *object) { TypeName *tn = object; MemReference (tn->name); } static void TypeRefMark (void *object) { TypeRef *tr = object; MemReference (tr->ref); } static void ArgTypeMark (void *object) { ArgType *at = object; MemReference (at->type); MemReference (at->next); } static void TypeFuncMark (void *object) { TypeFunc *tf = object; MemReference (tf->ret); MemReference (tf->args); } static void TypeArrayMark (void *object) { TypeArray *ta = object; MemReference (ta->type); MemReference (ta->dimensions); switch (ta->storage) { case DimStorageNone: break; case DimStorageGlobal: MemReference (ta->u.global); break; case DimStorageStatic: case DimStorageAuto: MemReference (ta->u.frame.code); break; } } static void TypeHashMark (void *object) { TypeHash *th = object; MemReference (th->type); MemReference (th->keyType); } static void TypeStructMark (void *object) { TypeStruct *ts = object; MemReference (ts->structs); MemReference (ts->left); MemReference (ts->right); } static void TypeTypesMark (void *object) { TypeTypes *type = object; MemReference (type->elt); } DataType TypePrimType = { 0, 0, "TypePrimType" }; DataType TypeNameType = { TypeNameMark, 0, "TypeNameType" }; DataType TypeRefType = { TypeRefMark, 0, "TypeRefType" }; DataType ArgTypeType = { ArgTypeMark, 0, "ArgTypeType" }; DataType TypeFuncType = { TypeFuncMark, 0, "TypeFuncType" }; DataType TypeArrayType = { TypeArrayMark, 0, "TypeArrayType" }; DataType TypeHashType = { TypeHashMark, 0, "TypeHashType" }; DataType TypeStructType = { TypeStructMark, 0, "TypeStructType" }; DataType TypeUnitType = { 0, 0, "TypeUnitType" }; DataType TypeTypesType = { TypeTypesMark, 0, "TypeTypesType" }; static Type * NewTypePrim (Rep prim) { ENTER (); Type *t; t = ALLOCATE (&TypePrimType, sizeof (TypePrim)); t->base.tag = type_prim; t->prim.prim = prim; RETURN (t); } Type * NewTypeName (ExprPtr expr, Symbol *name) { ENTER (); Type *t; t = ALLOCATE (&TypeNameType, sizeof (TypeName)); t->base.tag = type_name; t->name.expr = expr; t->name.name = name; RETURN (t); } Type * NewTypeRef (Type *ref, Bool pointer) { ENTER (); Type *t; if (!ref) RETURN (0); t = ALLOCATE (&TypeRefType, sizeof (TypeRef)); t->base.tag = type_ref; t->ref.ref = ref; t->ref.pointer = pointer; RETURN (t); } ArgType * NewArgType (Type *type, Bool varargs, Atom name, SymbolPtr symbol, ArgType *next) { ENTER (); ArgType *a; a = ALLOCATE (&ArgTypeType, sizeof (ArgType)); a->type = type; a->varargs = varargs; a->name = name; a->symbol = symbol; a->next = next; RETURN (a); } Type * NewTypeFunc (Type *ret, ArgType *args) { ENTER (); Type *t; t = ALLOCATE (&TypeFuncType, sizeof (TypeFunc)); t->base.tag = type_func; t->func.ret = ret; t->func.args = args; RETURN (t); } Type * NewTypeArray (Type *type, Expr *dimensions, Bool resizable) { ENTER (); Type *t; t = ALLOCATE (&TypeArrayType, sizeof (TypeArray)); t->base.tag = type_array; t->array.type = type; t->array.dimensions = dimensions; t->array.storage = DimStorageNone; t->array.resizable = resizable; RETURN (t); } Type * NewTypeHash (Type *type, Type *keyType) { ENTER (); Type *t; t = ALLOCATE (&TypeHashType, sizeof (TypeHash)); t->base.tag = type_hash; t->hash.type = type; t->hash.keyType = keyType; RETURN (t); } Type * NewTypeStruct (StructType *structs) { ENTER (); Type *t; t = ALLOCATE (&TypeStructType, sizeof (TypeStruct)); t->base.tag = type_struct; t->structs.structs = structs; t->structs.enumeration = False; t->structs.left = NULL; t->structs.right = NULL; RETURN (t); } Type * NewTypeUnion (StructType *structs, Bool enumeration) { ENTER (); Type *t; t = ALLOCATE (&TypeStructType, sizeof (TypeStruct)); t->base.tag = type_union; t->structs.structs = structs; t->structs.enumeration = enumeration; t->structs.left = NULL; t->structs.right = NULL; RETURN (t); } static Type * TypePlusPart (Type *type) { type = TypeCanon (type); switch (type->base.tag) { case type_struct: case type_union: break; default: ParseError ("Type '%T' not struct or union", type); return NULL; } return type; } static int AddPlusType (StructType *new, StructType *old, int pos) { int i; for (i = 0; i < old->nelements; i++) { AddBoxType (&new->types, BoxTypesElements (old->types)[i]); StructTypeAtoms (new)[pos] = StructTypeAtoms (old)[i]; pos++; } return pos; } Type * NewTypePlus (Type *left, Type *right) { ENTER (); Type *t, *l, *r;; StructType *st; int i; l = TypePlusPart (left); r = TypePlusPart (right); if (!l || !r) RETURN (NULL); if (l->base.tag != r->base.tag) { ParseError ("'%T' and '%T' are not the same type", left, right); RETURN (NULL); } st = NewStructType (l->structs.structs->nelements + r->structs.structs->nelements); i = AddPlusType (st, l->structs.structs, 0); if (i < 0) RETURN (NULL); i = AddPlusType (st, r->structs.structs, i); if (i < 0) RETURN (NULL); t = ALLOCATE (&TypeStructType, sizeof (TypeStruct)); t->base.tag = l->base.tag; t->structs.structs = st; t->structs.enumeration = l->structs.enumeration && r->structs.enumeration; t->structs.left = left; t->structs.right = right; RETURN (t); } Type * NewTypeTypes (TypeElt *elt) { ENTER (); Type *t; t = ALLOCATE (&TypeTypesType, sizeof (TypeTypes)); t->base.tag = type_types; t->types.elt = elt; RETURN (t); } SymbolPtr TypeNameName (Type *t) { ExprPtr e; if (t->base.tag == type_name) { e = t->name.expr; if (e->base.tag == COLONCOLON) e = e->tree.right; return e->atom.symbol; } return 0; } Bool TypeNumeric (Type *t) { if (t->base.tag != type_prim) return False; if (Numericp (t->prim.prim)) return True; return False; } Bool TypeIntegral (Type *t) { if (t->base.tag != type_prim) return False; if (Integralp (t->prim.prim)) return True; return False; } int TypeCountDimensions (ExprPtr dims) { int ndim = 0; while (dims) { ndim++; dims = dims->tree.right; } return ndim; } StackObject *TypeCheckStack; int TypeCheckLevel; /* * Return True if sup is a super type of sub */ Bool TypeIsSupertype (Type *super, Type *sub) { int n; Bool ret; StructType *super_st; StructType *sub_st; int super_dim; int sub_dim; if (super == sub) return True; if (!super || !sub) return False; /* resolve typedefs */ if (super->base.tag == type_name) return TypeIsSupertype (TypeNameType (super), sub); if (sub->base.tag == type_name) return TypeIsSupertype (super, TypeNameType (sub)); /* check bogus internal union types */ if (super->base.tag == type_types) { TypeElt *elt; for (elt = super->types.elt; elt; elt = elt->next) if (TypeIsSupertype (elt->type, sub)) return True; return False; } if (sub->base.tag == type_types) { TypeElt *elt; for (elt = sub->types.elt; elt; elt = elt->next) if (TypeIsSupertype (super, elt->type)) return True; return False; } /* poly is a supertype of all types */ if (TypePoly (super)) return True; if (super->base.tag != sub->base.tag) return False; switch (super->base.tag) { case type_prim: if (super->prim.prim == sub->prim.prim) return True; if (Numericp (super->prim.prim) && Numericp (sub->prim.prim)) return super->prim.prim >= sub->prim.prim; return False; case type_ref: /* * Avoid the infinite recursion, but don't unify type yet */ for (n = 0; n < TypeCheckLevel; n++) if (STACK_ELT(TypeCheckStack, n) == super) return True; STACK_PUSH (TypeCheckStack, super); ++TypeCheckLevel; /* XXX is this right? */ ret = TypeIsSupertype (super->ref.ref, sub->ref.ref); STACK_POP (TypeCheckStack); --TypeCheckLevel; return ret; case type_func: if (TypeIsSupertype (super->func.ret, sub->func.ret)) { ArgType *super_arg = super->func.args; ArgType *sub_arg = sub->func.args; while (super_arg || sub_arg) { if (!super_arg || !sub_arg) return False; if (super_arg->varargs != sub_arg->varargs) return False; if (!TypeIsSupertype (sub_arg->type, super_arg->type)) return False; super_arg = super_arg->next; sub_arg = sub_arg->next; } return True; } return False; case type_array: super_dim = TypeCountDimensions (super->array.dimensions); sub_dim = TypeCountDimensions (sub->array.dimensions); if (super_dim == 0 || sub_dim == 0 || super_dim == sub_dim) return TypeIsSupertype (super->array.type, sub->array.type); return False; case type_hash: return (TypeIsSupertype (super->hash.type, sub->hash.type) && TypeIsOrdered (super->hash.keyType, sub->hash.keyType)); case type_struct: case type_union: super_st = super->structs.structs; sub_st = sub->structs.structs; for (n = 0; n < super_st->nelements; n++) { Type *sub_mem; /* * Structs (or unions) are subtypes if they contain all * of the super type members and those members are subtypes */ sub_mem = StructMemType (sub_st, StructTypeAtoms(super_st)[n]); if (!sub_mem) return False; if (!TypeIsSupertype (BoxTypesElements(super_st->types)[n], sub_mem)) return False; } return True; case type_name: case type_types: abort (); } return False; } /* * Return True if a is a super or subtype of b */ Bool TypeIsOrdered (Type *a, Type *b) { return TypeIsSupertype (a, b) || TypeIsSupertype (b, a); } #if 0 /* * The above relationship isn't quite right -- * * real(real) x = int func(int a) { return a + 1; }; * * fails as int(int) is neither supertype nor subtype of real(real) * * We're trying to figure out what the right answer is, and for everything * aside from structures, it looks pretty easy. Structs are "hard"... */ /* * Return True if a is a "co-type" of b */ Bool TypeIsCotype (Type *a, Type *b) { int n; Bool ret; StructType *a_st; StructType *b_st; int a_dim; int b_dim; if (a == b) return True; if (!a || !b) return False; /* resolve typedefs */ if (a->base.tag == type_name) return TypeIsCotype (TypeNameType (a), b); if (b->base.tag == type_name) return TypeIsCotype (a, TypeNameType (b)); /* check bogus internal union types */ if (a->base.tag == type_types) { TypeElt *elt; for (elt = a->types.elt; elt; elt = elt->next) if (TypeIsCotype (elt->type, b)) return True; return False; } if (b->base.tag == type_types) { TypeElt *elt; for (elt = b->types.elt; elt; elt = elt->next) if (TypeIsCotype (a, elt->type)) return True; return False; } /* poly is a supertype of all types */ if (TypePoly (a) || TypePoly (b)) return True; if (a->base.tag != b->base.tag) return False; switch (a->base.tag) { case type_prim: if (a->prim.prim == b->prim.prim) return True; if (Numericp (a->prim.prim) && Numericp (b->prim.prim)) return True; return False; case type_ref: /* * Avoid the infinite recursion, but don't unify type yet */ for (n = 0; n < TypeCheckLevel; n++) if (STACK_ELT(TypeCheckStack, n) == a) return True; STACK_PUSH (TypeCheckStack, a); ++TypeCheckLevel; /* XXX is this right? */ ret = TypeIsCotype (a->ref.ref, b->ref.ref); STACK_POP (TypeCheckStack); --TypeCheckLevel; return ret; case type_func: if (TypeIsCotype (a->func.ret, b->func.ret)) { ArgType *a_arg = a->func.args; ArgType *b_arg = b->func.args; while (a_arg || b_arg) { if (!a_arg || !b_arg) return False; if (a_arg->varargs != b_arg->varargs) return False; if (!TypeIsCotype (b_arg->type, a_arg->type)) return False; a_arg = a_arg->next; b_arg = b_arg->next; } return True; } return False; case type_array: a_dim = TypeCountDimensions (a->array.dimensions); b_dim = TypeCountDimensions (b->array.dimensions); if (a_dim == 0 || b_dim == 0 || a_dim == b_dim) return TypeIsCotype (a->array.type, b->array.type); return False; case type_hash: return (TypeIsCotype (a->hash.type, b->hash.type) && TypeIsCotype (a->hash.keyType, b->hash.keyType)); case type_struct: case type_union: a_st = a->structs.structs; b_st = b->structs.structs; for (n = 0; n < a_st->nelements; n++) { Type *b_mem; /* * Structs (or unions) are subtypes if they contain all * of the a type members and those members are subtypes */ b_mem = StructMemType (b_st, StructTypeAtoms(a_st)[n]); if (!b_mem) return False; if (!TypeIsCotype (BoxTypesElements(a_st->types)[n], b_mem)) return False; } return True; case type_name: case type_types: abort (); } return False; } #endif /* * return the combined type for an operation * on a numeric type which is a group */ static Type * TypeBinaryGroup (Type *left, Type *right) { if (TypePoly (left)) { if (TypePoly (right) || TypeNumeric (right)) return typePrim[rep_float]; } else if (TypePoly (right)) { if (TypeNumeric (left)) return typePrim[rep_float]; } else if (TypeNumeric (left) && TypeNumeric (right)) { if (left->prim.prim < right->prim.prim) left = right; return left; } return 0; } /* * Return the least-upper bound for an integral computation */ static Type * TypeBinaryIntegral (Type *left, Type *right) { if (TypePoly (left)) left = typePrim[rep_integer]; if (TypePoly (right)) right = typePrim[rep_integer]; if (TypeIntegral (left) && TypeIntegral (right)) { if (left->prim.prim < right->prim.prim) left = right; return left; } else if (TypeNumeric (left) && TypeNumeric (right)) { return typePrim[rep_integer]; } return 0; } /* * return the combined type for an operation * on a set closed under addition and multiplication */ static Type * TypeBinaryField (Type *left, Type *right) { if (TypePoly (left)) { if (TypePoly (right) || TypeNumeric (right)) return typePrim[rep_float]; } else if (TypePoly (right)) { if (TypeNumeric (left)) return typePrim[rep_float]; } else if (TypeNumeric (left) && TypeNumeric (right)) { if (left->prim.prim < right->prim.prim) left = right; if (left->prim.prim < rep_rational) left = typePrim[rep_rational]; return left; } return 0; } /* * Return the type resuting from an div operator, * integral for numeric type */ static Type * TypeBinaryDiv (Type *left, Type *right) { if (TypePoly (left)) left = typePrim[rep_float]; if (TypePoly (right)) right = typePrim[rep_float]; if (TypeNumeric (left) && TypeNumeric (right)) { return typePrim[rep_integer]; } return 0; } /* * Return the type resuting from an exponentiation operator, * 'left' for integral 'right', float otherwise */ static Type * TypeBinaryPow (Type *left, Type *right) { if (TypePoly (left)) left = typePrim[rep_float]; if (TypePoly (right)) right = typePrim[rep_float]; if (TypeNumeric (left) && TypeNumeric (right)) { if (TypeIntegral (right)) return left; return typePrim[rep_float]; } return 0; } /* * Return string if both left and right are strings */ static Type * TypeBinaryString (Type *left, Type *right) { if (TypePoly (left)) left = typePrim[rep_string]; if (TypePoly (right)) right = typePrim[rep_string]; if (TypeString (left) && TypeString (right)) return left; return 0; } /* * Return reference type resulting from addition/subtraction */ static Type * TypeBinaryRefOff (Type *ref, Type *off) { if (TypePoly (ref)) ref = typeRefPoly; if (TypePoly (off)) off = typePrim[rep_integer]; if (ref->base.tag == type_ref && TypeIntegral (off)) return ref; return 0; } /* * Return reference type resulting from subtraction */ static Type * TypeBinaryRefMinus (Type *aref, Type *bref) { if (TypePoly (aref)) aref = typeRefPoly; if (TypePoly (bref)) bref = typeRefPoly; if (aref->base.tag == type_ref && bref->base.tag == type_ref) if (TypeIsOrdered (aref->ref.ref, bref->ref.ref)) return typePrim[rep_integer]; return 0; } /* * Return type referenced by ref */ static Type * TypeUnaryRef (Type *ref) { if (TypePoly (ref)) return typePoly; if (ref->base.tag == type_ref) return ref->ref.ref; return 0; } static Type * TypeUnaryGroup (Type *type) { if (TypePoly (type)) return typePrim[rep_float]; else if (TypeNumeric (type)) return type; return 0; } static Type * TypeUnaryIntegral (Type *type) { if (TypePoly (type)) return typePrim[rep_integer]; if (TypeIntegral (type)) return type; return 0; } /* * Indexing a string returns this type */ static Type * TypeUnaryString (Type *type) { if (TypePoly (type)) return typePrim[rep_string]; if (TypeString (type)) return typePrim[rep_integer]; return 0; } /* * Type of an array or hash reference */ static Type * TypeUnaryArray (Type *type) { if (TypePoly (type)) return typePoly; if (type->base.tag == type_array) return type->array.type; if (type->base.tag == type_hash) return type->hash.type; return 0; } /* * Comparison a logical operator type */ static Type * TypeUnaryBool (Type *type) { if (TypePoly (type)) return typePrim[rep_bool]; if (TypeBool (type)) return type; return 0; } /* * Return the least-upper bound for a boolean computation */ static Type * TypeBinaryBool (Type *left, Type *right) { if (TypePoly (left)) left = typePrim[rep_bool]; if (TypePoly (right)) right = typePrim[rep_bool]; if (TypeBool (left) && TypeBool (right)) return left; return 0; } static void TypeEltMark (void *object) { TypeElt *elt = object; MemReference (elt->next); MemReference (elt->type); } DataType TypeEltType = { TypeEltMark, 0, "TypeEltType" }; static TypeElt * NewTypeElt (Type *type, TypeElt *next) { ENTER (); TypeElt *elt; elt = ALLOCATE (&TypeEltType, sizeof (TypeElt)); elt->type = type; elt->next = next; RETURN (elt); } static Type * TypeAdd (Type *old, Type *new) { TypeElt **last; if (new->base.tag == type_types) { TypeElt *elt; for (elt = new->types.elt; elt; elt = elt->next) old = TypeAdd (old, elt->type); } else { if (!old) old = new; else if (old != new) { if (old->base.tag != type_types) old = NewTypeTypes (NewTypeElt (old, 0)); for (last = &old->types.elt; *last; last = &(*last)->next) if ((*last)->type == new) break; if (!*last) *last = NewTypeElt (new, 0); } } return old; } static Type * TypeCombineFlatten (Type *type) { ENTER (); if (type && type->base.tag == type_types) { TypeElt *n, **p, *m; /* * Remove obvious duplicates */ for (n = type->types.elt; n; n = n->next) { p = &n->next; while ((m = *p)) { if (m->type == n->type) *p = m->next; else p = &m->next; } } /* * Check for a single type and return just that */ if (!type->types.elt->next) type = type->types.elt->type; } RETURN(type); } Type * TypeCombineBinary (Type *left, int tag, Type *right) { ENTER (); Type *type; Type *ret = 0; if (!left || !right) RETURN(0); if (left->base.tag == type_name) RETURN (TypeCombineBinary (TypeNameType(left), tag, right)); if (right->base.tag == type_name) RETURN (TypeCombineBinary (left, tag, TypeNameType(right))); if (left->base.tag == type_types) { TypeElt *elt; for (elt = left->types.elt; elt; elt = elt->next) if ((type = TypeCombineBinary (elt->type, tag, right))) ret = TypeAdd (ret, type); } else if (right->base.tag == type_types) { TypeElt *elt; for (elt = right->types.elt; elt; elt = elt->next) if ((type = TypeCombineBinary (left, tag, elt->type))) ret = TypeAdd (ret, type); } else switch (tag) { case ASSIGN: if (TypeIsOrdered (left, right)) { if (TypePoly (left)) ret = TypeAdd (ret, right); else ret = TypeAdd (ret, left); } break; case PLUS: case ASSIGNPLUS: if ((type = TypeBinaryString (left, right))) ret = TypeAdd (ret, type); /* fall through ... */ case MINUS: case ASSIGNMINUS: if ((type = TypeBinaryRefOff (left, right))) ret = TypeAdd (ret, type); if (tag == MINUS && (type = TypeBinaryRefMinus (left, right))) ret = TypeAdd (ret, type); if ((tag == MINUS || tag == PLUS) && (type = TypeBinaryRefOff (right, left))) ret = TypeAdd (ret, type); /* fall through ... */ case TIMES: case MOD: case ASSIGNTIMES: case ASSIGNMOD: if ((type = TypeBinaryGroup (left, right))) ret = TypeAdd (ret, type); break; case DIV: case ASSIGNDIV: if ((type = TypeBinaryDiv (left, right))) ret = TypeAdd (ret, type); break; case POW: case ASSIGNPOW: if ((type = TypeBinaryPow (left, right))) ret = TypeAdd (ret, type); break; case DIVIDE: case ASSIGNDIVIDE: if ((type = TypeBinaryField (left, right))) ret = TypeAdd (ret, type); break; case SHIFTL: case SHIFTR: case LXOR: case LAND: case LOR: case ASSIGNSHIFTL: case ASSIGNSHIFTR: case ASSIGNLXOR: case ASSIGNLAND: case ASSIGNLOR: if ((type = TypeBinaryIntegral (left, right))) ret = TypeAdd (ret, type); break; case ASSIGNAND: case ASSIGNOR: if ((type = TypeBinaryBool (left, right))) ret = TypeAdd (ret, type); break; case COLON: if (TypePoly (left) || TypePoly (right)) ret = TypeAdd (ret, typePoly); else if (TypeIsSupertype (left, right)) ret = TypeAdd (ret, left); else if (TypeIsSupertype (right, left)) ret = TypeAdd (ret, right); break; case AND: case OR: if (TypeUnaryBool (left) && TypeUnaryBool (right)) ret = TypeAdd (ret, typePrim[rep_bool]); break; case EQ: case NE: case LT: case GT: case LE: case GE: if (TypeIsOrdered (left, right)) ret = TypeAdd (ret, typePrim[rep_bool]); break; } RETURN (TypeCombineFlatten (ret)); } Type * TypeCombineUnary (Type *type, int tag) { ENTER (); Type *ret = 0; Type *t; /* Avoid error cascade */ if (!type) RETURN(typePoly); if (type->base.tag == type_name) RETURN(TypeCombineUnary (TypeNameType(type), tag)); if (type->base.tag == type_types) { TypeElt *elt; for (elt = type->types.elt; elt; elt = elt->next) if ((t = TypeCombineUnary (elt->type, tag))) ret = TypeAdd (ret, t); } else switch (tag) { case STAR: if ((t = TypeUnaryRef (type))) ret = TypeAdd (ret, t); break; case LNOT: if ((t = TypeUnaryIntegral (type))) ret = TypeAdd (ret, t); break; case UMINUS: if ((t = TypeUnaryGroup (type))) ret = TypeAdd (ret, t); break; case BANG: if ((t = TypeUnaryBool (type))) ret = TypeAdd (ret, t); break; case FACT: if ((t = TypeUnaryIntegral (type))) ret = TypeAdd (ret, t); break; case OS: if ((t = TypeUnaryString (type))) ret = TypeAdd (ret, t); if ((t = TypeUnaryArray (type))) ret = TypeAdd (ret, t); break; } RETURN (TypeCombineFlatten (ret)); } Type * TypeCombineArray (Type *type, int ndim, Bool lvalue) { ENTER (); Type *ret = 0; Type *t; /* Avoid error cascade */ if (!type) RETURN(typePoly); if (type->base.tag == type_name) RETURN(TypeCombineArray (TypeNameType(type), ndim, lvalue)); if (type->base.tag == type_types) { TypeElt *elt; for (elt = type->types.elt; elt; elt = elt->next) if ((t = TypeCombineArray (elt->type, ndim, lvalue))) ret = TypeAdd (ret, t); } else { if ((t = TypeUnaryString (type))) ret = TypeAdd (ret, t); if (TypePoly (type)) ret = TypeAdd (ret, typePoly); if (type->base.tag == type_array) { int n = TypeCountDimensions (type->array.dimensions); if (n == 0 || n == ndim) ret = TypeAdd (ret, type->array.type); } else if (type->base.tag == type_hash) { if (ndim == 1) ret = TypeAdd (ret, type->hash.type); } } RETURN (TypeCombineFlatten (ret)); } Type * TypeCombineStruct (Type *type, int tag, Atom atom) { if (!type) return 0; if (TypePoly (type)) return typePoly; if (type->base.tag == type_name) return TypeCombineStruct (TypeNameType(type), tag, atom); switch (tag) { case DOT: if (type->base.tag == type_struct || type->base.tag == type_union) return StructMemType (type->structs.structs, atom); break; case ARROW: if (type->base.tag == type_ref) return TypeCombineStruct (type->ref.ref, DOT, atom); break; } return 0; } Type * TypeCombineReturn (Type *type) { if (TypePoly (type)) return typePoly; if (type->base.tag == type_name) return TypeCombineReturn (TypeNameType(type)); if (type->base.tag == type_func) return type->func.ret; return 0; } Type * TypeCombineFunction (Type *type) { if (TypePoly (type)) return typePoly; if (type->base.tag == type_name) return TypeCombineFunction (TypeNameType(type)); if (type->base.tag == type_func) return type; return 0; } /* * Check an assignment for type compatibility; Lvalues can assert * maximal domain for their values */ Bool TypeCompatibleAssign (TypePtr a, Value b) { int adim, bdim; int n; if (!a || !b) return True; if (a->base.tag == type_types) { TypeElt *elt; for (elt = a->types.elt; elt; elt = elt->next) if (TypeCompatibleAssign (elt->type, b)) return True; return False; } if (TypePoly (a)) return True; switch (a->base.tag) { case type_prim: if (a->prim.prim == ValueTag(b)) return True; if (Numericp (a->prim.prim) && Numericp (ValueTag(b))) { if (a->prim.prim >= ValueTag(b)) return True; } break; case type_name: return TypeCompatibleAssign (TypeNameType(a), b); case type_ref: if (ValueIsRef(b)) { if (RefValueGet (b)) return TypeCompatibleAssign (a->ref.ref, RefValueGet (b)); else return TypeIsOrdered (a->ref.ref, RefType (b)); } break; case type_func: if (ValueIsFunc(b)) { if (TypeIsOrdered (a->func.ret, b->func.code->base.type)) { ArgType *aarg = a->func.args, *barg = b->func.code->base.args; while (aarg || barg) { if (!barg || !aarg) return False; if (barg->varargs != aarg->varargs) return False; if (!TypeIsOrdered (barg->type, aarg->type)) return False; aarg = aarg->next; barg = barg->next; } return True; } } break; case type_array: if (ValueIsArray(b)) { adim = TypeCountDimensions (a->array.dimensions); bdim = b->array.ndim; if (adim == 0 || adim == bdim) { if (TypePoly (a->array.type)) return True; if (TypePoly (ArrayType(&b->array))) { int i; for (i = 0; i < ArrayNvalues(&b->array); i++) { Value v = ArrayValueGet (&b->array, i); if (v && !TypeCompatibleAssign (a->array.type, v)) { return False; } } return True; } else return TypeIsOrdered (a->array.type, ArrayType(&b->array)); } } break; case type_hash: if (ValueIsHash (b)) { if (TypePoly (a->hash.type)) return True; if (TypePoly (b->hash.type)) { HashValue h; Value *e = BoxElements (b->hash.elts); for (h = 0; h < b->hash.hashSet->size; h++) { if (!TypeCompatibleAssign (a->hash.type, HashEltValue(e))) { return False; } if (!TypeCompatibleAssign (a->hash.keyType, HashEltKey (e))) { return False; } HashEltStep (e); } return True; } else return (TypeIsOrdered (a->hash.type, b->hash.type) && TypeIsOrdered (a->hash.keyType, b->hash.keyType)); } case type_struct: case type_union: if ((ValueIsStruct(b) && a->base.tag == type_struct) || (ValueIsUnion(b) && a->base.tag == type_union)) { StructType *st = a->structs.structs; for (n = 0; n < st->nelements; n++) { Type *bt; bt = StructMemType (b->structs.type, StructTypeAtoms(st)[n]); if (!bt) break; if (!TypeIsOrdered (BoxTypesElements(st->types)[n], bt)) break; } if (n == st->nelements) return True; } break; default: break; } return False; } /* * Check to see if 'b' is a subtype of 'a' */ Bool ValueIsType (Value b, TypePtr a) { int adim, bdim; int n; if (!a || !b) return True; if (a->base.tag == type_types) { TypeElt *elt; for (elt = a->types.elt; elt; elt = elt->next) if (ValueIsType (b, elt->type)) return True; return False; } if (TypePoly (a)) return True; switch (a->base.tag) { case type_prim: if (a->prim.prim == ValueTag(b)) return True; if (Numericp (a->prim.prim) && Numericp (ValueTag(b))) { if (a->prim.prim >= ValueTag(b)) return True; } break; case type_name: return ValueIsType (b, TypeNameType(a)); case type_ref: if (ValueIsRef(b)) { if (RefValueGet (b)) return ValueIsType (RefValueGet (b), a->ref.ref); else return TypeIsSupertype (RefType(b), a->ref.ref); } break; case type_func: if (ValueIsFunc(b)) { if (TypeIsSupertype (b->func.code->base.type, a->func.ret)) { ArgType *aarg = a->func.args, *barg = b->func.code->base.args; while (aarg || barg) { if (!barg || !aarg) return False; if (barg->varargs != aarg->varargs) return False; if (!TypeIsSupertype (aarg->type, barg->type)) return False; aarg = aarg->next; barg = barg->next; } return True; } } break; case type_array: if (ValueIsArray(b)) { adim = TypeCountDimensions (a->array.dimensions); bdim = b->array.ndim; if (adim == 0 || adim == bdim) { if (TypePoly (a->array.type)) return True; if (TypePoly (ArrayType(&b->array))) { int i; for (i = 0; i < ArrayNvalues(&b->array); i++) { Value v = ArrayValueGet (&b->array, i); if (v && !ValueIsType (v, a->array.type)) { return False; } } return True; } else return TypeIsSupertype (ArrayType(&b->array), a->array.type); } } break; case type_hash: if (ValueIsHash (b)) { if (TypePoly (a->hash.type)) return True; if (TypePoly (b->hash.type)) { HashValue h; Value *e = BoxElements (b->hash.elts); for (h = 0; h < b->hash.hashSet->size; h++) { if (!ValueIsType (HashEltValue(e), a->hash.type)) { return False; } if (!ValueIsType (HashEltKey (e), a->hash.keyType)) { return False; } HashEltStep (e); } return True; } else return (TypeIsSupertype (b->hash.type, a->hash.type) && TypeIsSupertype (b->hash.keyType, a->hash.keyType)); } case type_struct: case type_union: if ((ValueIsStruct(b) && a->base.tag == type_struct) || (ValueIsUnion(b) && a->base.tag == type_union)) { StructType *st = a->structs.structs; for (n = 0; n < st->nelements; n++) { Type *bt; bt = StructMemType (b->structs.type, StructTypeAtoms(st)[n]); if (!bt) break; if (!TypeIsSupertype (bt, BoxTypesElements(st->types)[n])) break; } if (n == st->nelements) return True; } break; default: break; } return False; } Type * TypeCanon (Type *type) { if (type && type->base.tag == type_name) return TypeCanon (TypeNameType(type)); return type; } int TypeInit (void) { ENTER (); Rep t; for (t = rep_int; t <= rep_void; t++) { typePrim[t] = NewTypePrim (t); MemAddRoot (typePrim[t]); } typePoly = NewTypePrim(rep_undef); MemAddRoot (typePoly); typeRefPoly = NewTypeRef (typePoly, True); MemAddRoot (typeRefPoly); typeArrayInt = NewTypeArray (typePrim[rep_integer], 0, False); MemAddRoot (typeArrayInt); TypeCheckStack = StackCreate (); MemAddRoot (TypeCheckStack); TypeCheckLevel = 0; EXIT (); return 1; } nickle_2.81.orig/json.5c0000664000175000000620000001432313066263330014307 0ustar keithpstaff/* * Emit and parse JSON */ autoload Sort; autoload Ctype; namespace JSON { string quote(string a) { string result = "\""; for (int i = 0; i < String::length(a); i++) { int c = a[i]; switch (c) { case '"': case '\\': result = result + "\\" + String::new(c); break; case '\n': result = result + "\\n"; break; default: result = result + String::new(c); break; } } return result + "\""; } public string to_json(poly arg) { string do_indent(int indent) { string result = "\n"; for (int i = 0; i < indent; i++) result = result + "\t"; return result; } string json(poly arg, int indent); string json_hash(poly[string] a, int indent) { string[] keys = hash_keys(a); string result = "{"; bool first = true; Sort::qsort(&keys, bool func(poly a, poly b) { return a > b; }); for (int i = 0; i < dim(keys); i++) { string key = keys[i]; string value = json(a[key], indent+1); if (!first) result = result + ","; first = false; result = result + do_indent(indent+1); result = result + quote(key) + ": " + value; } result = result + do_indent(indent) + "}"; return result; } string json_array(poly[] a, int indent) { string result = "["; bool first = true; for (int i = 0; i < dim(a); i++) { if (!first) result = result + ","; first = false; result = result + do_indent(indent+1); result = result + to_json(a[i]); } result = result + do_indent(indent) + "]"; return result; } string json_string(string arg) { return quote(arg); } string json_int(int arg) { return sprintf ("%d", arg); } string json_float(real arg) { return sprintf("%.13g", arg); } json = string func(poly arg, int indent) { if (is_hash(arg)) return json_hash(arg, indent); if (is_array(arg)) return json_array(arg, indent); if (is_string(arg)) return json_string(arg); if (is_int(arg)) return json_int(arg); if (is_number(arg)) return json_float(arg); return ""; }; return json(arg, 0); } typedef enum { _string, _int, _float, _oc, _cc, _os, _cs, _comma, _colon, _end, _error } term_t; typedef struct { union { int ival; string sval; real fval; } val; term_t token; } token_t; typedef struct { file f; int line; string token; } json_input_t; json_input_t start_json(string s) { return (json_input_t) { .f = File::string_read(s), .line = 1 }; } token_t lex(*json_input_t f) { int ch() { int c = File::getc(f->f); if (c == '\n') f->line++; f->token = f->token + String::new(c); return c; } void unch(int c) { if (c == '\n') f->line--; f->token = String::substr(f->token, 0, String::length(f->token) - 1); File::ungetc(c, f->f); } bool is_int_char(int c) { if (Ctype::isdigit(c)) return true; if (c == '-') return true; return false; } bool is_float_char(int c) { if (Ctype::isdigit(c)) return true; if (c == '-') return true; if (c == '.') return true; if (c == 'e' || c == 'E') return true; return false; } try { f->token = ""; for (;;) { int c = ch(); switch (c) { case '\n': case ' ': case '\t': continue; case '{': return (token_t) { .token = term_t._oc }; case '}': return (token_t) { .token = term_t._cc }; case '[': return (token_t) { .token = term_t._os }; case ']': return (token_t) { .token = term_t._cs }; case ',': return (token_t) { .token = term_t._comma }; case ':': return (token_t) { .token = term_t._colon }; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': case '.': string nval = ""; bool has_float = false; while (is_float_char(c)) { nval = nval + String::new(c); if (!is_int_char(c)) has_float = true; if (File::end(f->f)) break; c = ch(); } unch(c); if (has_float) return (token_t) { .val = { .fval = atof(nval) }, .token = term_t._float }; return (token_t) { .val = { .ival = atoi(nval) }, .token = term_t._int }; case '"': string sval = ""; for (;;) { c = ch(); if (c == '"') break; if (c == '\\') { c = ch(); switch (c) { case 'n': c = '\n'; break; case 't': c = '\t'; break; default: break; } } sval = sval + String::new(c); } return (token_t) { .val = { .sval = sval }, .token = term_t._string }; default: break; } break; } } catch File::io_eof(file f) { return (token_t) { .token = term_t._end }; } return (token_t) { .token = term_t._error }; } public exception json_parse_error(int line, string token); public poly from_json(string arg) { json_input_t f = start_json(arg); token_t token; void next() { token = lex(&f); } void expect(term_t t) { if (token.token != t) raise json_parse_error(f.line, f.token); } poly value(); poly[string] hash() { poly[string] ret = {}; for (;;) { expect(term_t._string); string name = token.val.sval; next(); expect(term_t._colon); next(); poly val = value(); ret[name] = val; switch (token.token) { case term_t._comma: next(); continue; case term_t._cc: next(); return ret; default: raise json_parse_error(f.line, f.token); } } } poly[] array() { poly[...] ret = {}; for (;;) { poly val = value(); ret[dim(ret)] = val; switch (token.token) { case term_t._comma: next(); continue; case term_t._cs: next(); return ret; default: raise json_parse_error(f.line, f.token); } } } value = poly func() { switch (token.token) { case term_t._oc: next(); return hash(); case term_t._os: next(); return array(); case term_t._int: int ival = token.val.ival; next(); return ival; case term_t._float: real fval = token.val.fval; next(); return fval; case term_t._string: string sval = token.val.sval; next(); return sval; } }; next(); return value(); } } nickle_2.81.orig/foreign.c0000664000175000000620000000303413062261503014673 0ustar keithpstaff/* $Header$ */ /* * Copyright © 2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static Value ForeignEqual (Value av, Value bv, int expandOk) { if (av->foreign.data == bv->foreign.data) return TrueVal; return FalseVal; } static Bool ForeignPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePrintf (f, "foreign %s (0x%x)", av->foreign.id, av->foreign.data); return True; } static HashValue ForeignHash (Value av) { return (HashValue) (intptr_t) av->foreign.data; } static void ForeignMark (void *object) { Foreign *foreign = object; if (foreign->mark) (*foreign->mark) (foreign->data); } static int ForeignFree (void *object) { Foreign *foreign = object; if (foreign->free) (*foreign->free) (foreign->data); return 1; } ValueRep ForeignRep = { { ForeignMark, ForeignFree, "ForeignRep" }, /* data */ rep_foreign, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, ForeignEqual, 0, 0 }, { 0, 0, 0, }, 0, 0, ForeignPrint, 0, ForeignHash, }; int ForeignInit (void) { return 1; } Value NewForeign (const char *id, void *data, void (*mark) (void *data), void (*free) (void *data)) { ENTER (); Value ret; ret = ALLOCATE (&ForeignRep.data, sizeof (Foreign)); ret->foreign.id = id; ret->foreign.data = data; ret->foreign.free = free; ret->foreign.mark = mark; RETURN (ret); } nickle_2.81.orig/struct.c0000664000175000000620000001041111747625041014574 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" Value StructMemRef (Value sv, Atom name) { ENTER (); Struct *s = &sv->structs; StructType *st = s->type; int i; for (i = 0; i < st->nelements; i++) if (StructTypeAtoms(st)[i] == name) RETURN (NewRef (s->values, i)); RETURN (0); } Value StructMemValue (Value sv, Atom name) { ENTER (); Struct *s = &sv->structs; StructType *st = s->type; int i; for (i = 0; i < st->nelements; i++) if (StructTypeAtoms(st)[i] == name) RETURN (BoxValue (s->values, i)); RETURN (0); } Type * StructMemType (StructType *st, Atom name) { int i; for (i = 0; i < st->nelements; i++) if (StructTypeAtoms(st)[i] == name) return (BoxTypesElements(st->types)[i]); return (0); } static Bool StructPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { Struct *s = &av->structs; StructType *st = s->type; int i; Bool pretty = format == 'v' || format == 'g' || format == 'G'; char down_format = format == 'g' ? 'G' : format; if (pretty) FileOutput (f, '{'); for (i = 0; i < st->nelements; i++) { FilePuts (f, AtomName (StructTypeAtoms(st)[i])); if (format != 'G') { FilePuts (f, " = "); if (!Print (f, BoxValueGet (s->values, i), down_format, base, width, prec, fill)) return False; } if (i < st->nelements - 1) { if (pretty) FileOutput (f, ','); FileOutput (f, ' '); } } if (pretty) FileOutput (f, '}'); return True; } static void StructMark (void *object) { Struct *s = object; MemReference (s->type); MemReference (s->values); } static Value StructEqual (Value a, Value b, int expandOk) { int i; StructType *at = a->structs.type; if (at->nelements != b->structs.type->nelements) return FalseVal; for (i = 0; i < at->nelements; i++) { if (False (Equal (BoxValue (a->structs.values, i), StructMemValue (b, StructTypeAtoms(at)[i])))) return FalseVal; } return TrueVal; } static HashValue StructHash (Value a) { Struct *s = &a->structs; StructType *at = s->type; HashValue h = 0; int i; for (i = 0; i < at->nelements; i++) h = h ^ ValueInt (ValueHash (BoxValue (a->structs.values, i))); return h; } ValueRep StructRep = { { StructMark, 0, "StructRep" }, /* base */ rep_struct, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, StructEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, StructPrint, 0, StructHash, }; Value NewStruct (StructType *type, Bool constant) { ENTER (); Value ret; ret = ALLOCATE (&StructRep.data, sizeof (Struct)); ret->structs.type = type; ret->structs.values = 0; ret->structs.values = NewTypedBox (False, type->types); RETURN (ret); } static void StructTypeMark (void *object) { StructType *st = object; MemReference (st->types); } DataType StructTypeType = { StructTypeMark, 0, "StructTypeType" }; StructType * NewStructType (int nelements) { ENTER (); StructType *st; int i; Atom *atoms; st = ALLOCATE (&StructTypeType, sizeof (StructType) + nelements * sizeof (Atom)); st->nelements = nelements; st->types = NewBoxTypes (nelements); atoms = StructTypeAtoms(st); for (i = 0; i < nelements; i++) atoms[i] = 0; RETURN (st); } Value Elementless; StructType *ElementlessType; int StructInit (void) { ENTER (); ElementlessType = NewStructType (0); MemAddRoot (ElementlessType); Elementless = NewStruct (ElementlessType, True); MemAddRoot (Elementless); EXIT (); return 1; } Type * BuildStructType (int nelements, ...) { ENTER (); StructType *st; int i; char *name; Type *type; va_list ap; st = NewStructType (nelements); va_start (ap, nelements); for (i = 0; i < nelements; i++) { type = va_arg (ap, Type *); name = va_arg (ap, char *); AddBoxType (&st->types, type); StructTypeAtoms (st)[i] = AtomId (name); } va_end (ap); RETURN (NewTypeStruct (st)); } nickle_2.81.orig/execute.c0000664000175000000620000011357111766016323014723 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include #undef DEBUG_FRAME #define Stack(i) ((Value) STACK_ELT(thread->thread.continuation.stack, i)) #define CStack(i) ((Value) STACK_ELT(cstack, i)) /* * Instruction must be completed because changes have been * committed to storage. */ Bool complete; Bool signalFinished; /* current thread is finished */ Bool signalSuspend; /* current thread is suspending */ #define Arg(n) ((n) <= base ? CStack(base - (n)) : value) static FramePtr BuildFrame (Value thread, Value func, Value value, Bool staticInit, Bool tail, Bool varargs, int nformal, int base, int argc, InstPtr savePc, ObjPtr saveObj) { ENTER (); CodePtr code = func->func.code; FuncBodyPtr body = staticInit ? &code->func.staticInit : &code->func.body; StackObject *cstack = thread->thread.continuation.stack; int fe; FramePtr frame; #ifdef DEBUG_FRAME FilePrintf (FileStdout, "BuildFrame func %v value %v\n", func, value); ThreadStackDump (thread); FileFlush (FileStdout, True); #endif frame = thread->thread.continuation.frame; if (tail) frame = frame->previous; frame = NewFrame (func, frame, func->func.staticLink, body->dynamics, func->func.statics); for (fe = 0; fe < nformal; fe++) BoxValueSet (frame->frame, fe, Copy (Arg(fe))); if (varargs) { int extra = argc - nformal; Value array; array = NewArray (True, False, typePoly, 1, &extra); BoxValueSet (frame->frame, fe, array); for (; fe < argc; fe++) ArrayValueSet (&array->array, fe-nformal, Copy (Arg(fe))); } if (tail) { frame->savePc = thread->thread.continuation.frame->savePc; frame->saveObj = thread->thread.continuation.frame->saveObj; } else { frame->savePc = savePc; frame->saveObj = saveObj; } RETURN (frame); } static Value ThreadCall (Value thread, Bool tail, InstPtr *next, int *stack) { ENTER (); int argc = *stack; Value value = thread->thread.continuation.value; StackObject *cstack = thread->thread.continuation.stack; Value func; CodePtr code; FramePtr frame; ArgType *argt; int fe; int base; /* * Typecheck actuals */ fe = 0; base = argc - 2; if (argc < 0) { Value numvar = Arg(0); if (!ValueIsInt (numvar)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Incompatible argument"), NewInt(-1), Arg(0)); RETURN (Void); } argc = -argc - 1 + ValueInt(numvar); base = argc - 1; *stack = 1 + argc; /* count + args */ func = CStack(argc); } else func = argc ? CStack(argc-1) : value; if (!ValueIsFunc(func)) { ThreadStackDump (thread); RaiseStandardException (exception_invalid_unop_value, 1, func); RETURN (Void); } code = func->func.code; argt = code->base.args; while (fe < argc || (argt && !argt->varargs)) { if (!argt) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Too many arguments"), NewInt (argc), NewInt(code->base.argc)); RETURN (Void); } if (fe == argc) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Too few arguments"), NewInt (argc), NewInt(code->base.argc)); RETURN (Void); } if (!TypeCompatibleAssign (argt->type, Arg(fe))) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Incompatible argument"), NewInt (fe), Arg(fe)); RETURN (Void); } fe++; if (!argt->varargs) argt = argt->next; } if (code->base.builtin) { Value *values = 0; int formal; formal = code->base.argc; if (code->base.varargs) { formal = -1; values = AllocateTemp (argc * sizeof (Value)); for (fe = 0; fe < argc; fe++) values[fe] = Arg(fe); } if (code->builtin.needsNext) { /* * Let the non-local function handle the stack adjust */ *stack = 0; switch (formal) { case -1: value = (*code->builtin.b.builtinNJ)(next, argc, values); break; case 0: value = (*code->builtin.b.builtin0J)(next); break; case 1: value = (*code->builtin.b.builtin1J)(next, Arg(0)); break; case 2: value = (*code->builtin.b.builtin2J)(next, Arg(0), Arg(1)); break; } } else { switch (formal) { case -1: value = (*code->builtin.b.builtinN)(argc, values); break; case 0: value = (*code->builtin.b.builtin0)(); break; case 1: value = (*code->builtin.b.builtin1)(Arg(0)); break; case 2: value = (*code->builtin.b.builtin2)(Arg(0), Arg(1)); break; case 3: value = (*code->builtin.b.builtin3)(Arg(0), Arg(1), Arg(2)); break; case 4: value = (*code->builtin.b.builtin4)(Arg(0), Arg(1), Arg(2), Arg(3)); break; case 5: value = (*code->builtin.b.builtin5)(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4)); break; case 6: value = (*code->builtin.b.builtin6)(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), Arg(5)); break; case 7: value = (*code->builtin.b.builtin7)(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), Arg(5), Arg(6)); break; default: value = Void; break; } /* * For a tail call, drop the topmost frame */ if (tail && !aborting) { complete = True; thread->thread.continuation.obj = thread->thread.continuation.frame->saveObj; *next = thread->thread.continuation.frame->savePc; thread->thread.continuation.frame = thread->thread.continuation.frame->previous; } } } else { frame = BuildFrame (thread, func, value, False, tail, code->base.varargs, code->base.argc, base, argc, *next, thread->thread.continuation.obj); if (aborting) RETURN (value); complete = True; thread->thread.continuation.frame = frame; thread->thread.continuation.obj = code->func.body.obj; *next = ObjCode (code->func.body.obj, 0); } RETURN (value); } /* * Call the pseudo function to initialize static values */ static void ThreadStaticInit (Value thread, InstPtr *next) { ENTER (); Value value = thread->thread.continuation.value; CodePtr code = value->func.code; FramePtr frame; frame = BuildFrame (thread, value, Void, True, False, False, 0, 0, 0, *next, thread->thread.continuation.obj); if (aborting) return; complete = True; thread->thread.continuation.frame = frame; thread->thread.continuation.obj = code->func.staticInit.obj; *next = ObjCode (code->func.staticInit.obj, 0); EXIT (); } static inline void ThreadAssign (Value ref, Value v, Bool initialize) { ENTER (); if (!ValueIsRef (ref)) RaiseStandardException (exception_invalid_binop_values, 2, ref, v); else if (RefConstant(ref) && !initialize) RaiseStandardException (exception_readonly_box, 1, v); else if (ref->ref.element >= ref->ref.box->nvalues) RaiseStandardException (exception_invalid_array_bounds, 2, NewInt(ref->ref.element), v); else if (!TypeCompatibleAssign (RefType (ref), v)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Incompatible types in assignment"), NewInt(ref->ref.element), v); } else { if (!v) abort (); v = Copy (v); if (!aborting) { complete = True; RefValueSet (ref, v); } } EXIT (); } static Value ThreadArray (Value thread, Bool resizable, int ndim, Type *type) { ENTER (); int i; int *dims; dims = AllocateTemp (ndim * sizeof (int)); for (i = 0; i < ndim; i++) { Value d = Stack(i); dims[i] = IntPart (d, "Invalid array dimension"); if (dims[i] < 0) RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Negative array dimension"), NewInt (0), d); if (aborting) RETURN (0); } RETURN (NewArray (False, resizable, type, ndim, dims)); } static Value ThreadArrayInd (Value thread, Bool resizable, Value dim, Type *type) { ENTER (); Array *a = &dim->array; int i; int ndim = ArrayLimits(a)[0]; int *dims; dims = AllocateTemp (ndim * sizeof (int)); for (i = 0; i < ndim; i++) { Value d = ArrayValue (a, i); dims[i] = IntPart (d, "Invalid array dimension"); if (dims[i] < 0) RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Negative array dimension"), NewInt (0), d); if (aborting) RETURN (0); } RETURN (NewArray (False, resizable, type, ndim, dims)); } static int ThreadArrayIndex (Value array, Value thread, int ndim, Value last, int off, Bool except, Bool resize) { int i; int dim; int part; Value d; int *dims = ArrayDims (&array->array); int *limits = ArrayLimits (&array->array); i = 0; for (dim = ndim - 1; dim >= 0; dim--) { if (dim == 0) d = last; else d = Stack(dim + off - 1); if (!ValueIsInt(d) || (part = ValueInt(d)) < 0) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Array index not non-negative integer"), array, d); return 0; } if (limits[dim] <= part) { if (resize && array->array.resizable) { if (dims[dim] > part) limits[dim] = part + 1; else ArrayResize (array, dim, part + 1); } else if (except) { RaiseStandardException (exception_invalid_array_bounds, 2, array, d); return 0; } } i = i * dims[dim] + part; } return i; } /* * Array initialization * * Array initialization uses the stack to hold temporary index values while * the array is walked. The stack looks like: * * array * major-index * ... * minor-index * num-dimensions * * Each Element Repeat instruction indicates which dimension * is being stepped over. When the entire array has been walked, * a final Element inst with ndim set to the dimensionality of the * array is executed which pops the whole mess off the stack and * returns the completed array * * Repeat elements indicate along which dimension the repeat occurs. * The initial value for the repeat has already been stored in the * array, so the task is just to copy that first element to the end * of the dimension. */ static void ThreadArrayReplicate (Value thread, Value array, int dim, int start) { int dimsize = 1; int i; int total; Value *elements; assert (!array->array.resizable); for (i = 0; i < dim; i++) dimsize *= ArrayDims(&array->array)[i]; start = start - dimsize; total = ArrayDims(&array->array)[dim] * dimsize; elements = BoxElements (array->array.u.fix); for (i = start + dimsize; i % total; i += dimsize) memmove (elements + i, elements + start, dimsize * sizeof (elements[0])); } void ThreadStackDump (Value thread); static Value ThreadArrayInit (Value thread, Value value, AInitMode mode, int dim, int *stack, InstPtr *next) { ENTER (); Value array; int i; int ndim; if (aborting) RETURN(value); switch (mode) { case AInitModeStart: complete = True; STACK_PUSH (thread->thread.continuation.stack, value); for (i = 0; i < dim; i++) STACK_PUSH (thread->thread.continuation.stack, Zero); STACK_PUSH (thread->thread.continuation.stack, NewInt(dim)); break; case AInitModeRepeat: ndim = ValueInt(Stack(0)); array = Stack(ndim+1); if (ValueInt(Stack(dim+1)) == ArrayDims(&array->array)[dim]) break; /* fall through ... */ case AInitModeElement: ndim = ValueInt(Stack(0)); array = Stack(ndim+1); /* * Check and see if we're done */ if (dim == ndim) { *stack = ndim + 2; value = array; break; } /* * Initialize a single value? */ if (dim == 0) { if (!TypeCompatibleAssign (ArrayType(&array->array), value)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Incompatible types in array initialization"), array, value); break; } i = ThreadArrayIndex (array, thread, ndim, Stack(1), 2, True, False); if (aborting) break; complete=True; ArrayValueSet (&array->array, i, Copy (value)); } complete = True; /* * Step to the next element */ STACK_DROP(thread->thread.continuation.stack, dim+1); STACK_PUSH(thread->thread.continuation.stack, Plus (STACK_POP(thread->thread.continuation.stack), One)); /* * Reset remaining indices to zero */ for (i = 0; i < dim; i++) STACK_PUSH (thread->thread.continuation.stack, Zero); STACK_PUSH (thread->thread.continuation.stack, NewInt (ndim)); if (mode == AInitModeRepeat) { i = ThreadArrayIndex (array, thread, ndim, Stack(1), 2, False, False); ThreadArrayReplicate (thread, array, dim, i); } break; case AInitModeFunc: if (aborting) break; complete = True; /* * Fetch the function */ value = Stack(dim+2); /* * Push args. Tricky because the stack keeps growing */ i = dim + 1; while (--dim >= 0) { STACK_PUSH(thread->thread.continuation.stack, value); value = Stack(i); } break; case AInitModeFuncDone: ndim = ValueInt(Stack(0)); value = Stack(ndim+1); *stack = ndim + 3; break; case AInitModeTest: if (aborting) break; complete = True; ndim = ValueInt(Stack(0)); array = Stack(ndim+1); value = FalseVal; /* Done with this row? */ if (ValueInt(Stack(1)) == ArrayDims(&array->array)[0]) { /* Find dim with space */ for (dim = 1; dim < ndim; dim++) if (ValueInt(Stack(1+dim)) < ArrayDims(&array->array)[dim] - 1) break; /* All done? */ if (dim == ndim) { value = TrueVal; break; } /* * Step to the next element */ STACK_DROP(thread->thread.continuation.stack, dim+1); STACK_PUSH(thread->thread.continuation.stack, Plus (STACK_POP(thread->thread.continuation.stack), One)); /* * Reset remaining indices to zero */ while (--dim >= 0) STACK_PUSH (thread->thread.continuation.stack, Zero); STACK_PUSH (thread->thread.continuation.stack, NewInt (ndim)); } break; } RETURN (value); } #ifdef DEBUG_JUMP void ThreadCatches (Value thread) { CatchPtr catch; FilePrintf (FileStdout, "("); for (catch = thread->thread.continuation.catches; catch; catch = catch->continuation.catches) { FilePrintf (FileStdout, "%A ", catch->exception->symbol.name); } FilePrintf (FileStdout, ")\n"); } #endif static Value ThreadRaise (Value thread, Value value, int argc, SymbolPtr exception, InstPtr *next) { ENTER (); StackObject *cstack = thread->thread.continuation.stack; Value args; int i; int base = argc - 2; #ifdef DEBUG_JUMP FilePrintf (FileStdout, " Raise: %A ", exception->symbol.name); ThreadCatches (thread); #endif /* * Build and array to hold the arguments, this will end up * in the thread's value on entry to the catch block */ args = NewArray (False, False, typePoly, 1, &argc); for (i = 0; i < argc; i++) ArrayValueSet (&args->array, i, Arg(i)); if (!aborting) { RaiseException (thread, exception, args, next); if (!aborting) complete = True; } RETURN (args); } static void ThreadEndCatch (Value thread, int catches) { #ifdef DEBUG_JUMP FilePrintf (FileStdout, " EndCatch: %d ", catches); #endif while (catches--) thread->thread.continuation.catches = thread->thread.continuation.catches->continuation.catches; #ifdef DEBUG_JUMP ThreadCatches (thread); #endif } static Value ThreadExceptionCall (Value thread, InstPtr *next, int *stack) { ENTER (); Value args; Value ret; int argc; int i; /* * The compiler places a Noop with the push flag set * before the function is stuffed in the thread value, * this pushes the array of arguments carefully crafted * in ThreadRaise above. Fetch the argument array and * push all of them onto the stack. */ args = Stack(0); if (!ValueIsArray (args)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("exception call argument must be array"), NewInt (0), args); *stack = 1; RETURN (Void); } if (aborting) { *stack = 1; RETURN (Void); } complete = True; argc = ArrayLimits(&args->array)[0]; for (i = 0; i < argc; i++) { STACK_PUSH (thread->thread.continuation.stack, thread->thread.continuation.value); thread->thread.continuation.value = ArrayValue(&args->array, i); } /* * Call the function */ ret = ThreadCall (thread, False, next, &argc); /* * Account for the argument array */ *stack = 1 + argc; RETURN (ret); } static void ThreadFarJump (Value thread, Value ret, FarJumpPtr farJump, InstPtr *next) { ENTER (); Value continuation; /* * Build the continuation */ continuation = FarJumpContinuation (&thread->thread.continuation, farJump); /* * And jump */ if (!aborting) { complete = True; ContinuationJump (thread, &continuation->continuation, ret, next); } EXIT (); } static void ThreadUnwind (Value thread, int twixt, int catch) { while (twixt--) thread->thread.continuation.twixts = thread->thread.continuation.twixts->continuation.twixts; #ifdef DEBUG_JUMP FilePrintf (FileStdout, " Before unwind: "); ThreadCatches (thread); #endif while (catch--) { #ifdef DEBUG_JUMP FilePrintf (FileStdout, " Unwind: %A\n", thread->thread.continuation.catches->exception->symbol.name); #endif thread->thread.continuation.catches = thread->thread.continuation.catches->continuation.catches; } #ifdef DEBUG_JUMP FilePrintf (FileStdout, " After unwind: "); ThreadCatches (thread); #endif } #define ThreadBoxCheck(box,i) (BoxValueGet(box,i) == 0 ? ThreadBoxSetDefault(box,i,0) : 0) typedef struct _TypeChain { struct _TypeChain *prev; Type *type; } TypeChain; static void ThreadBoxSetDefault (BoxPtr box, int i, TypeChain *chain) { if (BoxValueGet (box, i) == 0) { Type *ctype = TypeCanon (BoxType (box, i)); StructType *st = ctype->structs.structs; TypeChain link, *c; /* * Check for recursion */ for (c = chain; c; c = c->prev) if (c->type == ctype) return; link.prev = chain; link.type = ctype; switch (ctype->base.tag) { case type_union: BoxValueSet (box, i, NewUnion (st, False)); break; case type_struct: BoxValueSet (box, i, NewStruct (st, False)); box = BoxValueGet (box, i)->structs.values; for (i = 0; i < st->nelements; i++) { if (BoxValueGet (box, i) == 0) ThreadBoxSetDefault (box, i, &link); } break; default: break; } } } static Value ThreadOpArray (Value thread, Value value, int stack, Bool fetch, Bool typeCheck) { Value v; char *s; int i; v = Stack(stack-1); switch (ValueTag(v)) { case rep_string: if (!fetch) { RaiseStandardException (exception_invalid_binop_values, 2, v, value); break; } if (stack != 1) { RaiseStandardException (exception_invalid_binop_values, 2, NewInt (stack), v); break; } i = IntPart (value, "Invalid string index"); if (aborting) break; s = StringChars (&v->string); if (i < 0 || StringLength (s, v->string.length) <= i) { RaiseStandardException (exception_invalid_binop_values, 2, v, value); break; } value = NewInt (StringGet (s, v->string.length, i)); break; case rep_array: if (stack != v->array.ndim) { RaiseStandardException (exception_invalid_binop_values, 2, NewInt (stack), v); break; } i = ThreadArrayIndex (v, thread, stack, value, 0, True, !fetch); if (!aborting) { BoxPtr box = ArrayValueBox (&v->array, i); int elt = ArrayValueElt (&v->array, i); if (typeCheck) ThreadBoxCheck (box, elt); if (fetch) value = BoxValue (box, elt); else value = NewRef (box, elt); } break; case rep_hash: if (stack != 1) { RaiseStandardException (exception_invalid_binop_values, 2, NewInt (stack), v); break; } if (fetch) value = HashGet (v, value); else value = HashRef (v, value); break; default: RaiseStandardException (exception_invalid_unop_value, 1, v); break; } return value; } static Value ThreadOpDot (Value thread, Value value, Atom atom, Bool fetch) { Value v; switch (ValueTag(value)) { default: RaiseStandardException (exception_invalid_unop_value, 1, value); break; case rep_struct: if (fetch) v = StructMemValue (value, atom); else v = StructMemRef (value, atom); if (!v) { RaiseStandardException (exception_invalid_struct_member, 2, value, NewStrString (AtomName (atom))); break; } value = v; break; case rep_union: if (fetch) v = UnionValue (value, atom); else v = UnionRef (value, atom); if (!v) { if (StructMemType (value->unions.type, atom)) RaiseStandardException (exception_invalid_struct_member, 2, value, NewStrString (AtomName (atom))); else RaiseStandardException (exception_invalid_struct_member, 2, value, NewStrString (AtomName (atom))); break; } value = v; break; } return value; } #include void ThreadStackDump (Value thread) { StackObject *cstack = thread->thread.continuation.stack; StackChunk *chunk; StackPointer stackPointer; int i = 0; chunk = cstack->current; stackPointer = STACK_TOP(cstack); while (chunk) { while (stackPointer < CHUNK_MAX(chunk)) { FilePrintf (FileStdout, "%d: %v\n", i++, (Value) *stackPointer++); } chunk = chunk->previous; stackPointer = CHUNK_MIN(chunk); } } #ifdef DEBUG_INST int dump_inst = 0; #endif #ifdef VALIDATE_EXECUTION extern DataType FrameType, BoxType, stackType, stackChunkType, ObjType; static void ObjValid(ObjPtr obj, InstPtr pc) { assert(obj->data == &ObjType); assert(0 <= obj->used && obj->used <= obj->size); assert(0 <= obj->used_stat && obj->used_stat <= obj->size_stat); assert(obj->insts <= pc && pc < &obj->insts[obj->used]); } static void FrameValid(FramePtr frame) { assert (frame->data == &FrameType); if (frame->previous) assert (frame->previous->data == &FrameType); if (frame->staticLink) assert (frame->staticLink->data == &FrameType); assert (ValueIsFunc(frame->function)); if (frame->frame) assert (frame->frame->data == &BoxType); if (frame->statics) assert (frame->statics->data == &BoxType); ObjValid(frame->saveObj, frame->savePc); } static void StackValid(StackObject *stack) { StackChunk *chunk; StackElement *stackPointer; assert(stack->type == &stackType); chunk = stack->current; if (chunk) { assert(chunk->type == &stackChunkType); if (chunk->previous) assert (chunk->previous->type == &stackChunkType); } stackPointer = stack->stackPointer; assert ((stackPointer == NULL) == (chunk == NULL)); if (stackPointer) { assert (&chunk->elements[0] <= stackPointer && stackPointer <= &chunk->elements[STACK_ENTS_PER_CHUNK]); } } static void ThreadValid(Value thread) { Thread *t; FramePtr frame; StackObject *stack; assert(thread->value.type == &ThreadRep); t = &thread->thread; /* Check to make sure object is valid */ ObjValid(t->continuation.obj, t->continuation.pc); /* Check for valid frame */ frame = t->continuation.frame; if (frame) FrameValid(frame); stack = t->continuation.stack; if (stack) StackValid(stack); } #define EXEC_HISTORY 256 Continuation exec_history[EXEC_HISTORY]; int exec_history_i; static inline void ExecRecord(Value thread) { exec_history[exec_history_i] = thread->thread.continuation; exec_history_i = (exec_history_i + 1) % EXEC_HISTORY; } #else #define ThreadValid(t) #define ExecRecord(t) #endif void ThreadsRun (Value thread, Value lex) { signalInterrupt = False; for (;;) { if (signaling) { signaling = False; aborting = False; /* * Check for pending external signals */ if (signalInterrupt) { signalInterrupt = False; ThreadsSignal (NewInt (SIGINT)); } if (signalTimer) { signalTimer = False; TimerInterrupt (); } if (signalIo) { signalIo = False; IoInterrupt (); } if (signalChild) { signalChild = False; ProcessInterrupt (); } if (lex && !(lex->file.flags & (FileInputBlocked|FileOutputBlocked))) break; } else if (thread && thread->thread.state == ThreadFinished) break; else if (!running) { /* when all threads are done, and all input is read, time to go */ if (!lex && !stopped) break; ThreadsBlock (); } else { ENTER (); Value thread = running; StackObject *cstack; InstPtr inst, next; FramePtr fp; int i, j; int stack; Value value, v, w; BoxPtr box; inst = thread->thread.continuation.pc; value = thread->thread.continuation.value; cstack = thread->thread.continuation.stack; for (j = 0; j < 10; j++) { ThreadValid(thread); ExecRecord(thread); stack = 0; next = inst + 1; complete = False; #ifdef DEBUG_INST if (dump_inst) { InstDump (inst, 1, 0, 0, 0); FileFlush (FileStdout, True); } #endif switch (inst->base.opCode) { case OpNoop: break; case OpBranch: next = inst + inst->branch.offset; break; case OpBranchFalse: if (!ValueIsBool(value)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("conditional expression not bool"), value, Void); break; } if (!True (value)) next = inst + inst->branch.offset; break; case OpBranchTrue: if (!ValueIsBool(value)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("conditional expression not bool"), value, Void); break; } if (True (value)) next = inst + inst->branch.offset; break; case OpCase: value = Equal (CStack(stack), value); if (True (value)) { next = inst + inst->branch.offset; stack++; } break; case OpDefault: next = inst + inst->branch.offset; stack++; break; case OpTagCase: if (!ValueIsUnion(value)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("union switch expression not union"), value, Void); break; } if (value->unions.tag == inst->tagcase.tag) { next = inst + inst->tagcase.offset; v = UnionValue (value, inst->tagcase.tag); if (!v) { if (StructMemType (value->unions.type, inst->atom.atom)) RaiseStandardException (exception_invalid_struct_member, 2, value, NewStrString (AtomName (inst->atom.atom))); else RaiseStandardException (exception_invalid_struct_member, 2, value, NewStrString (AtomName (inst->atom.atom))); break; } value = v; } break; case OpTagGlobal: box = inst->box.box; ThreadAssign (NewRef (inst->box.box, 0), value, True); break; case OpTagLocal: box = thread->thread.continuation.frame->frame; i = inst->frame.element; ThreadAssign (NewRef (box, i), value, True); break; case OpReturnVoid: value = Void; /* fall through */ case OpReturn: if (!thread->thread.continuation.frame) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("return outside of function"), Void, Void); break; } if (!TypeCompatibleAssign (thread->thread.continuation.frame->function->func.code->base.type, value)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Incompatible type in return"), value, Void); break; } if (aborting) break; complete = True; next = thread->thread.continuation.frame->savePc; thread->thread.continuation.obj = thread->thread.continuation.frame->saveObj; thread->thread.continuation.frame = thread->thread.continuation.frame->previous; break; case OpGlobal: ThreadBoxCheck (inst->box.box, 0); value = BoxValue (inst->box.box, 0); break; case OpGlobalRef: ThreadBoxCheck (inst->box.box, 0); /* fall through... */ case OpGlobalRefStore: value = NewRef (inst->box.box, 0); break; case OpStatic: case OpStaticRef: case OpStaticRefStore: for (i = 0, fp = thread->thread.continuation.frame; i < inst->frame.staticLink; i++) fp = fp->staticLink; box = fp->statics; i = inst->frame.element; if (inst->base.opCode != OpStaticRefStore) ThreadBoxCheck (box, i); if (inst->base.opCode == OpStatic) value = BoxValue (box, i); else value = NewRef (box, i); break; case OpLocal: case OpLocalRef: case OpLocalRefStore: for (i = 0, fp = thread->thread.continuation.frame; i < inst->frame.staticLink; i++) fp = fp->staticLink; box = fp->frame; i = inst->frame.element; if (inst->base.opCode != OpLocalRefStore) ThreadBoxCheck (box, i); if (inst->base.opCode == OpLocal) value = BoxValue (box, i); else value = NewRef (box, i); break; case OpFetch: value = Dereference (value); break; case OpConst: value = inst->constant.constant; break; case OpBuildArray: stack = inst->array.ndim; value = ThreadArray (thread, inst->array.resizable, stack, inst->array.type); break; case OpBuildArrayInd: value = ThreadArrayInd (thread, inst->array.resizable, value, inst->array.type); break; case OpInitArray: stack = 0; value = ThreadArrayInit (thread, value, inst->ainit.mode, inst->ainit.dim, &stack, &next); break; case OpBuildHash: value = NewHash (False, inst->hash.type->hash.keyType, inst->hash.type->hash.type); break; case OpInitHash: w = CStack (1); v = CStack (0); stack = 2; HashSet (w, v, value); value = w; break; case OpInitHashDef: v = CStack (0); stack = 1; HashSetDef (v, value); value = v; break; case OpBuildStruct: value = NewStruct (inst->structs.structs, False); break; case OpInitStruct: w = CStack(0); stack = 1; v = StructMemRef (w, inst->atom.atom); if (!v) { RaiseStandardException (exception_invalid_struct_member, 2, v, NewStrString (AtomName (inst->atom.atom))); break; } ThreadAssign (v, value, True); value = w; break; case OpBuildUnion: value = NewUnion (inst->structs.structs, False); break; case OpInitUnion: v = UnionRef (value, inst->atom.atom); if (!v) { RaiseStandardException (exception_invalid_struct_member, 2, value, NewStrString (AtomName (inst->atom.atom))); break; } w = CStack(0); stack = 1; ThreadAssign (v, w, True); break; case OpArray: case OpArrayRef: case OpArrayRefStore: stack = inst->ints.value; value = ThreadOpArray (thread, value, stack, inst->base.opCode == OpArray, inst->base.opCode != OpArrayRefStore); break; case OpVarActual: if (!ValueIsArray(value)) { RaiseStandardException (exception_invalid_unop_value, 1, value); break; } if (value->array.ndim != 1) { RaiseStandardException (exception_invalid_unop_value, 1, value); break; } for (i = 0; i < ArrayLimits(&value->array)[0]; i++) { STACK_PUSH (cstack, ArrayValue (&value->array, i)); if (aborting) { STACK_DROP (cstack, i + 1); break; } } if (i != ArrayLimits(&value->array)[0]) break; complete = True; value = NewInt (ArrayLimits(&value->array)[0]); break; case OpCall: case OpTailCall: stack = inst->ints.value; value = ThreadCall (thread, inst->base.opCode == OpTailCall, &next, &stack); break; case OpArrow: case OpArrowRef: case OpArrowRefStore: if (!ValueIsRef(value)) { RaiseStandardException (exception_invalid_unop_value, 1, value); break; } value = RefValueGet(value); /* fall through ... */ case OpDot: case OpDotRef: case OpDotRefStore: value = ThreadOpDot (thread, value, inst->atom.atom, inst->base.opCode == OpArrow || inst->base.opCode == OpDot); break; case OpObj: value = NewFunc (inst->code.code, thread->thread.continuation.frame); break; case OpStaticInit: /* Always follows OpObj so the function is sitting in value */ ThreadStaticInit (thread, &next); break; case OpStaticDone: if (!thread->thread.continuation.frame) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("StaticInitDone outside of function"), Void, Void); break; } if (aborting) break; complete = True; next = thread->thread.continuation.frame->savePc; thread->thread.continuation.obj = thread->thread.continuation.frame->saveObj; thread->thread.continuation.frame = thread->thread.continuation.frame->previous; /* Fetch the Obj from the stack */ value = CStack (0); stack = 1; break; case OpBinOp: value = BinaryOperate (CStack(0), value, inst->binop.op); stack = 1; break; case OpBinFunc: value = (*inst->binfunc.func) (CStack(0), value); stack = 1; break; case OpUnOp: value = UnaryOperate (value, inst->unop.op); break; case OpUnFunc: value = (*inst->unfunc.func) (value); break; case OpPreOp: v = Dereference (value); if (aborting) break; v = ValueIncDec (v, inst->binop.op); ThreadAssign (value, v, False); value = v; break; case OpPostOp: v = Dereference (value); if (aborting) break; ThreadAssign (value, ValueIncDec (v, inst->binop.op), False); value = v; break; case OpAssign: ThreadAssign (CStack(0), value, inst->assign.initialize); stack = 1; break; case OpAssignOp: v = BinaryOperate (CStack(0), value, inst->binop.op); ThreadAssign (CStack(1), v, False); stack = 2; value = v; break; case OpAssignFunc: v = (*inst->binfunc.func) (CStack(0), value); ThreadAssign (CStack(1), v, False); stack = 2; value = v; break; case OpFork: value = NewThread (thread->thread.continuation.frame, inst->obj.obj); break; case OpCatch: if (aborting) break; #ifdef DEBUG_JUMP FilePrintf (FileStdout, " Catch: %A ", inst->catch.exception->symbol.name); ThreadCatches (thread); #endif thread->thread.continuation.catches = NewCatch (thread, inst->catch.exception); complete = True; next = inst + inst->catch.offset; break; case OpEndCatch: if (aborting) break; ThreadEndCatch (thread, inst->ints.value); complete = True; break; case OpRaise: if (aborting) break; value = ThreadRaise (thread, value, inst->raise.argc, inst->raise.exception, &next); break; case OpExceptionCall: ThreadExceptionCall (thread, &next, &stack); break; case OpTwixt: if (aborting) break; thread->thread.continuation.twixts = NewTwixt (&thread->thread.continuation, inst + inst->twixt.enter, inst + inst->twixt.leave); complete = True; break; case OpTwixtDone: if (aborting) break; thread->thread.continuation.twixts = thread->thread.continuation.twixts->continuation.twixts; complete = True; break; case OpEnterDone: if (thread->thread.jump) { if (aborting) break; value = JumpContinue (thread, &next); if (next) complete = True; } break; case OpLeaveDone: if (thread->thread.jump) { if (aborting) break; value = JumpContinue (thread, &next); if (next) complete = True; } break; case OpFarJump: ThreadFarJump (thread, value, inst->farJump.farJump, &next); break; case OpUnwind: ThreadUnwind (thread, inst->unwind.twixt, inst->unwind.catch); break; case OpIsType: value = ValueIsType(value, inst->isType.type) ? TrueVal : FalseVal; break; case OpHasMember: if (ValueTag(value) != rep_struct) value = FalseVal; else { if (StructMemType(value->structs.type, inst->atom.atom)) value = TrueVal; else value = FalseVal; } break; case OpEnd: SetSignalFinished (); break; case OpDrop: stack = 1; break; default: break; } #if 0 assert (!next || (ObjCode (thread->thread.continuation.obj, 0) <= next && next <= ObjCode (thread->thread.continuation.obj, thread->thread.continuation.obj->used))); #endif if (aborting && !complete) { /* * Check for pending execution signals */ if (signalSuspend) { signalSuspend = False; if (thread->thread.state == ThreadRunning) ThreadSetState (thread, ThreadSuspended); } if (signalFinished) { signalFinished = False; ThreadFinish (thread, False); } if (signalException) { signalException = False; thread->thread.continuation.value = JumpStandardException (thread, &next); thread->thread.continuation.pc = next; } if (signalError) { signalError = False; } if (signalProfile) signalProfile = False; break; } /* have to do this before the pc is updated */ if (signalProfile) { signalProfile = False; ProfileInterrupt (running); } /* this instruction has been completely executed */ thread->thread.partial = 0; thread->thread.continuation.value = value; cstack = thread->thread.continuation.stack; if (stack) STACK_DROP (cstack, stack); if (inst->base.flags & InstPush) STACK_PUSH (cstack, value); inst = next; thread->thread.continuation.pc = inst; if (thread->thread.next) ThreadStepped (thread); ThreadValid(thread); if (running != thread) break; } EXIT (); } } } nickle_2.81.orig/ctype.5c0000664000175000000620000001033110700372663014457 0ustar keithpstaff/* * ctype routines * Bart 2002/7 * ASCII-only: Nickle is in the C locale */ namespace Ctype { public bool isascii(int ch) /* * As with C ctype.h, things outside the ASCII range * are not handled here. Unlike C ctype.h, we handle * this case cleanly. */ { return ch >= 0 && ch <= 127; } /* The characteristic vector of sets of Latin-1 chars. */ public typedef bool[256] charset; public charset make_charset(bool(int) cfun) /* * Make a characteristic vector from a characteristic function. */ { charset result; for (int i = 0; i < dim(result); i++) result[i] = cfun(i); return result; } public bool member(charset v, int ch) /* * Test whether a particular char is in a charset. */ { return ch >= 0 && ch < dim(v) && v[ch]; } /* * Now this machinery is used to implement the standard * C ctype.h tests in the obvious fasion. */ public bool isupper(int ch) /* * Return whether 'ch' is uppercase. */ { static bool cfun(int ch) { return (ch >= 'A' && ch <= 'Z' || ch >= 'À' && ch <= 'Þ'); } static charset v = make_charset(cfun); return member(v, ch); } public bool islower(int ch) /* * Return whether 'ch' is lowercase. */ { static bool cfun(int ch) { return (ch >= 'a' && ch <= 'z' || ch >= 'à' && ch <= 'þ'); } static charset v = make_charset(cfun); return member(v, ch); } public bool isdigit(int ch) /* * Return whether 'ch' is a digit */ { static bool cfun(int ch) { return ch >= '0' && ch <= '9'; } static charset v = make_charset(cfun); return member(v, ch); } public bool isblank(int ch) /* * Return whether 'ch' is a space or tab */ { return ch == ' ' || ch == '\t'; } public bool iscntrl(int ch) /* * Return whether 'ch' is a control character */ { static bool cfun(int ch) { return ch >= 0 && ch <= 31; } static charset v = make_charset(cfun); return member(v, ch); } public bool isgraph(int ch) /* * Return whether 'ch' is a visible character */ { static bool cfun(int ch) { return (ch > ' ' && ch < 127 || ch >= 'À' && ch <= 'þ'); } static charset v = make_charset(cfun); return member(v, ch); } public bool isprint(int ch) /* * Return whether 'ch' is a printable character */ { static bool cfun(int ch) { return (ch >= ' ' && ch < 127 || ch >= 'À' && ch <= 'þ'); } static charset v = make_charset(cfun); return member(v, ch); } public bool isspace(int ch) /* * Return whether 'ch' is whitespace */ { static bool cfun(int ch) { int[*] sc = {' ', '\f', '\n', '\r', '\t', '\v'}; for (int i = 0; i < dim(sc); i++) if (ch == sc[i]) return true; return false; } static charset v = make_charset(cfun); return member(v, ch); } public bool isalpha(int ch) /* * Return whether 'ch' is a latin letter */ { static bool cfun(int ch) { return islower(ch) || isupper(ch); } static charset v = make_charset(cfun); return member(v, ch); } public bool isalnum(int ch) /* * Return whether 'ch' is a letter or digit */ { static bool cfun(int ch) { return isalpha(ch) || isdigit(ch); } static charset v = make_charset(cfun); return member(v, ch); } public bool ispunct(int ch) /* * Return whether 'ch' is punctuation */ { static bool cfun(int ch) { return isgraph(ch) && !isalnum(ch); } static charset v = make_charset(cfun); return member(v, ch); } public int tolower(int ch) /* * If 'ch' is upper case, return the lower case version * else return 'ch' */ { if (isupper(ch)) return ch - 'A' + 'a'; return ch; } public int toupper(int ch) /* * If 'ch' is lower case, return the upper case version * else return 'ch' */ { if (islower(ch)) return ch - 'a' + 'A'; return ch; } public bool isxdigit(int ch) /* * Return whether 'ch' is a hexidecimal digit */ { static bool cfun(int ch) { if (isdigit(ch)) return true; int chl = tolower(ch); return chl >= 'a' && chl <= 'f'; } static charset v = make_charset(cfun); return member(v, ch); } } nickle_2.81.orig/config.h.in0000664000175000000620000001073613202542705015132 0ustar keithpstaff/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if the `getpgrp' function requires zero arguments. */ #undef GETPGRP_VOID /* Define to 1 if you have the `dlclose' function. */ #undef HAVE_DLCLOSE /* Define to 1 if you have the `dlerror' function. */ #undef HAVE_DLERROR /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN /* Define to 1 if you have the `dlsym' function. */ #undef HAVE_DLSYM /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* C compilers can extern program symbols */ #undef HAVE_EXTERN_SYMS /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `getrlimit' function. */ #undef HAVE_GETRLIMIT /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `hstrerror' function. */ #undef HAVE_HSTRERROR /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* support fancy command line editing */ #undef HAVE_LIBREADLINE /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Has rl_catch_signals */ #undef HAVE_RL_CATCH_SIGNALS /* Has rl_cleanup_after_signal */ #undef HAVE_RL_CLEANUP_AFTER_SIGNAL /* Has rl_reset_after_signal */ #undef HAVE_RL_RESET_AFTER_SIGNAL /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if you have the `setrlimit' function. */ #undef HAVE_SETRLIMIT /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* Define to 1 if you have the `sigignore' function. */ #undef HAVE_SIGIGNORE /* Define to 1 if you have the `sigrelse' function. */ #undef HAVE_SIGRELSE /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_STROPTS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Has uint64_t datatype */ #undef HAVE_UINT64_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT /* The size of `unsigned long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG /* The size of `unsigned long long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG_LONG /* The size of `unsigned short', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_SHORT /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER nickle_2.81.orig/TODO0000664000175000000620000000410410742535505013575 0ustar keithpstaffTO DO + Allow poll() as a substitute for select(). + Allow nick to be built without all the async IO and gettimeofday() and the like. + Build regression tests for everything on the DONE list. + Finish the manual. + Fix output formatting length problems. + Tagless GC. TO THINK ABOUT + Allow multiple instances of ARC4 or PRNG to run simultaneously (i.e. encapsulated generators)? + Too few array initializers is an error? + Array dimension types or something like them? + Remove as many 32-bit limits as possible + "Better" namespace seperator? + Move ellipses to other side of function formal? + Add a full scope operator? + Add true partial initializers? NOT TO DO + "public namespace" has a somewhat non-intuitive meaning. Fix? Too hard, don't know what to do. + Add array zeroing builtin? Use pattern initializer instead: much better. + * should be right unary operator? Should be, but won't :-). + Comments should not be allowed in interactive mode? Need to for intuition. + Make sure all comments are closed before the reader prints a prompt? Principle of least surprise: want to be able to paste code in. DONE + Build a small test suite. + Null-safe strings. + Move std math functions out of math, or import math. + Implement library autoload mechanism. + Write fixed position (scale=n) math library in nickle ala bc/dc. + Replace nick-in-C code (e.g. gcd.c) with nick library code. + "read" file should be "load" file. + Make sure all blocks and comments are closed when the reader leaves a file. + Finish exception handling. + typedef syntax. + : namespace separator. + Finish twixt handling. + Have '^' call math:pow function. + Better arctan. + Shift operators. + Bitwise operators. + Add log2 function. + XOR builtin. + Deeper typechecking on assignment (of all kinds). + Forward declarations of typenames. + Add file/line numbers to compile errors. + Add a PRNG. + Rename Strings to String. + Pattern-based initializers. + Array decl * syntax. + Add support + Remove mutex builtins. + Allow namespaces to be extended. + void type (as unit type). + GNU readline support. nickle_2.81.orig/AUTHORS0000664000175000000620000000011010414112462014133 0ustar keithpstaffKeith Packard Bart Massey nickle_2.81.orig/acinclude.m40000664000175000000620000000212510414112462015264 0ustar keithpstaffdnl Check for readline and get termcap lib as well AC_DEFUN([AC_LIB_READLINE],[ doit=yes AC_ARG_WITH(readline, [ --with-readline=DIR GNU readline library in DIR], doit=$with_readline) case $doit in no) ;; *) readline_header="readline" readline_libdir="" case $doit in yes) ;; *) readline_libdir="-L$doit/lib -R$doit/lib" readline_incdir="-I$doit/include" ;; esac AC_CHECK_LIB(ncurses,tparm,TERMLIB=-lncurses, AC_CHECK_LIB(termcap,tgetent,TERMLIB=-ltermcap)) saved_LIBS="$LIBS" LIBS="$LIBS $TERMLIB" saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $readline_libdir" saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $readline_incdir" AC_CHECK_LIB(readline,readline, [ AC_CHECK_HEADER(readline/readline.h, LIBS="$saved_LIBS -lreadline $TERMLIB" AC_DEFINE(HAVE_LIBREADLINE,1, [support fancy command line editing])) ], [ AC_MSG_RESULT([Cannot find readline. Build with --without-readline or set the readline path appropriately.]) exit 1 ]) ;; esac ]) nickle_2.81.orig/test/0002775000175000000620000000000013202543025014055 5ustar keithpstaffnickle_2.81.orig/test/hashtest.5c0000664000175000000620000000301610736265514016144 0ustar keithpstaffexception bad_result (string reason, poly[poly] h, poly key, poly value); poly[*][2] values = { { "hello", "world" }, { 1, "one" }, { (int[*]) { 1, 2, 3, 4 }, (struct { int x, y; }) { x = 1, y = 2 } }, }; void hash_tests () { poly[poly] h; /* * Test basic insert/find */ for (int i = 0; i < dim(values); i++) h[values[i][0]] = values[i][1]; for (int i = 0; i < dim(values); i++) if (h[values[i][0]] != values[i][1]) raise bad_result ("wrong value returned", h, values[i][0], values[i][1]); /* * check list of keys */ poly[*] keys = hash_keys (h); if (dim (keys) != dim (values)) raise bad_result ("wrong number of keys", h, dim(keys), dim (values)); for (int i = 0; i < dim (values); i++) { int j; for (j = 0; j < dim (keys); j++) if (keys[j] == values[i][0]) break; if (j == dim (keys)) raise bad_result ("missing key", h, values[i][0], â—Š); } /* * test delete */ for (int i = 0; i < dim (values); i++) hash_del (h, values[i][0]); if (dim (hash_keys(h)) != 0) raise bad_result ("couldn't delete all keys", h, â—Š, â—Š); /* * test mutable keys */ int[*] a = { 1, 2, 3 }; int[*] b = a; h[a] = "hello"; if (h[b] != "hello") raise bad_result ("couldn't find mutable key", h, a, "hello"); a[0] = 12; if (hash_test (h, a)) raise bad_result ("hash contains mutated key", h, a, h[a]); if (h[b] != "hello") raise bad_result ("couldn't find unmutated key", h, b, h[b]); } hash_tests (); nickle_2.81.orig/test/is_type.5c0000664000175000000620000000171511722540323015767 0ustar keithpstaffint errors = 0; void check (poly value, string type, bool got, bool want) { if (got != want) { printf ("is_type(%v, %s) = %v. should be %v\n", value, type, got, want); errors++; } } typedef struct { string a; } super_type; typedef super_type + struct { string b; } sub_type; super_type super_value = { .a = "a value" }; sub_type sub_value = { .a = "a value", .b = "b value" }; check(super_value, "super_type", is_type(super_value, super_type), true); check(super_value, "sub_type", is_type (super_value, sub_type), false); check(sub_value, "super_type", is_type (sub_value, super_type), true); check(sub_value, "sub_type", is_type (sub_value, sub_type), true); real real_value = pi; real int_value = 12; check(real_value, "real", is_type (real_value, real), true); check(real_value, "int", is_type (real_value, int), false); check(int_value, "real", is_type (int_value, real), true); check(int_value, "int", is_type(int_value, int), true); exit (errors); nickle_2.81.orig/test/modtest.5c0000664000175000000620000000103710727144150015771 0ustar keithpstaffvoid check(real n, real d) { real q = n // d; real r = n % d; assert(is_int(q), "non-integral quotient %v", q); assert(r >= 0, "negative remainder %v", r); assert(r < abs(d), "too-large remainder %v", r); real recons = q * d + r; assert(recons == n, "wrong reconstruction %v", recons); } void all_signs(real n, real d) { check(n, d); check(-n, d); check(n, -d); check(-n, -d); } all_signs(7, 3); all_signs(7 * (1<<32), 3 * (1<<32)); all_signs(7/2, 3/2); all_signs(imprecise(7/2), imprecise(3/2)); nickle_2.81.orig/test/Makefile.am0000664000175000000620000000105213202425321016103 0ustar keithpstaffcheck_SCRIPTS=\ scanf.5c \ gcdtest.5c \ inttest.5c \ optest.5c \ orderofoptest.5c \ rattest.5c \ reftest.5c \ modtest.5c \ hashtest.5c \ signal.5c \ round.5c \ math.5c \ factorial.5c \ is_type.5c \ jsontest.5c \ datetest.5c noinst_PROGRAMS=math-tables TABLES=math-tables.5c CLEANFILES=$(TABLES) TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir) TESTS=$(check_SCRIPTS) LOG_COMPILER=$(top_builddir)/nickle EXTRA_DIST=$(check_SCRIPTS) math.5c: $(TABLES) $(TABLES): math-tables ./math-tables > $(TABLES) nickle_2.81.orig/test/reftest.5c0000664000175000000620000000123010414112462015753 0ustar keithpstaff/* * Test various pointer and reference type combinations */ exception bad_result (poly a, poly b); int i = 7; string s = "hi"; &int ir = &i; i = 8; /* make sure references see changes to the underlying object */ if (i != ir) raise bad_result (i, ir); *int ip = &i; i = 9; /* make sure pointers see changes to the underlying object */ if (i != *ip) raise bad_result (i, *ip); if (ir != *ip) raise bad_result (ir, *ip); /* * Make sure function return values typecheck correctly */ typedef s; typedef struct { &s x; } s; s u() { s v; &v.x = reference(u()); return v; } s t() { s v; &v.x = &t(); return v; } nickle_2.81.orig/test/rattest.5c0000664000175000000620000000113610675627422016012 0ustar keithpstaffautoimport PRNG; exception bad_result (int u, rational v); void function rat_check (int u, int v) { if (((u/v) + (v/u)) * ((v*u) / (u**2 + v**2)) != 1) raise bad_result (u, v); } void function rat_random (int ubits, int vbits) { int u = randbits (ubits); int v = randbits (vbits); if (u == 0) u = 1; if (v == 0) v = 1; rat_check (u, v); } void function rat_test (int amin, int amax, int bmin, int bmax) { int a, b; for (a = amin; a <= amax; a += randint(200)) for (b = bmin; b <= bmax; b += randint(200)) rat_random (a, b); } rat_test (2,2000,2,2000); nickle_2.81.orig/test/optest.5c0000664000175000000620000001404410770315535015637 0ustar keithpstaff/* * Nickle Testing Suite v1.0 * Operator Testing Code * Written by Erin Chapman */ void check (poly value, poly correct) { if (is_number (value) && !is_rational (value)) { real error = abs (value - correct); if (error < abs(value) / 1e7) return; } if (value != correct) abort ("check failed (was %v, should be %v)", value, correct); } /* Assigns a value to x for testing. */ int x; check (x = 1, 1); /* Tests unary increment and decrememnt. */ check (++x, 2); check (x++, 2); check (x, 3); check (--x, 2); check (x--, 2); check (x, 1); /* Tests Unary negate */ check (-x, -1); /* Tests logical negation */ check (!true, false); /* Assigns a different value to x for testing. */ check (x = 4, 4); /* Test Factorial. */ check (x!, 24); /* Tests pointer construction and dereference. */ *int z; check (z = &x, &x); check (*z, 4); /* Tests construction and evaluation of a union. */ union {int a; string b;} test; check (sprintf ("%v", test), "{}") check (test.a = 1, 1); check (test, (union {int a;}) { .a = 1}); check (test.b = "hello", "hello"); check (test, (union {string b;}) { .b = "hello" }); check (bool func () { try { test.a; return false; } catch invalid_struct_member (poly test, string name) { return true; } return false; } (), true); /* Tests exponentiation. */ check (x**2, 16); check (x**.5, 2); check ((x/3)**2, 16/9); check ((x/3)**.5, 2 / sqrt (3)); check ((-x)**2, 16); check (bool func () { try { (-x)**.5; return false; } catch invalid_argument (msg, int i, poly value) { return true; } return false; } (), true); /* Tests multiplication. */ check (x*2, 8); /* Tests division. */ check (x/2, 2); /* Tests integer division. */ check (x//3, 1); check (x//3 == floor(x/3), true); check ((x//3)*3+(x%3) == x, true); /* Tests remainder. */ check (x%3, 1); /* Tests addition and subtraction. */ check (x+3, 7); check (x-3, 1); /* Tests bitwise left shift. */ check (x<<1, 8); check (x<<-1, 2); check (x<<1 == x*2**1, true); /* Tests bitwise right shift. */ check (x>>1, 2); check (x>>-1, 8); check (x>>1 == x//2**1, true); /* Tests relational operators. */ check (x<=10, true); check (x>=-10, true); check (x < 15, true); check (x > -15, true); /* Tests equality operators. */ check (x == x, true); check (x != x - 1, true); /* Tests bitwise AND. */ check (1&2, 0); check (2&3, 2); check (3&3, 3); /* Tests bitwsie XOR. */ check (1^2, 3); check (2^3, 1); check (3^3, 0); /* Tests bitwise OR. */ check (0|0, 0); check (0|1, 1); /* Tests short-circuit logical AND. */ check (true&&false, false); check (true&&true, true); check (false&&false, false); check (false&&true, false); /* Tests short-circuit logical OR. */ check (true||true, true); check (true||false, true); check (false||false, false); check (false||true, true); /* Assigns a value to y for testing. */ int y = 0; check (y, 0); /* Tests conditional expressions. */ check (y == 0 ? 1 : 2, 1); check (y == 1 ? 1 : 2, 2); /* Tests assignment operators. */ check (bool func () { try { x = 3; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Equals assignment failed (x = 3).\n"); return false; } return false; } (), true); check (x, 3); check (bool func () { try { x += 1; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Plus equals assignment failed (x += 1).\n"); return false; } return false; } (), true); check (x, 4); check (bool func () { try { x -= 1; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Minus equals assignment failed (x -= 1).\n"); return false; } return false; } (), true); check (x, 3); check (bool func () { try { x *= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Times equals assignment failed (x *= 2).\n"); return false; } return false; } (), true); check (x, 6); check (bool func () { try { x /= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Divide equals assignment failed (x /= 2).\n"); return false; } return false; } (), true); check (x, 3); check (bool func () { try { x //= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Integer divide equals assignment failed (x //= 2).\n"); return false; } return false; } (), true); check (x, 1); check (bool func () { try { x %= 3; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Remainder equals assignment failed (x %= 3).\n"); return false; } return false; } (), true); check (x, 1); check (x = 2, 2); check (bool func () { try { x **= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Exponentiation equals assignment failed (x **= 2).\n"); return false; } return false; } (), true); check (x, 4); check (bool func () { try { x <<= 1; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Bitwise left shift equals assignment failed (x <<= 1).\n"); return false; } return false; } (), true); check (x, 8); check (bool func () { try { x >>= 1; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Bitwise right shift equals assignment failed (x >>= 1).\n"); return false; } return false; } (), true); check (x, 4); check (bool func () { try { x ^= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Bitwise XOR equals assignment failed (x ^= 2).\n"); return false; } return false; } (), true); check (x, 6); check (bool func () { try { x &= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Bitwise AND equals assignment failed (x &= 2).\n"); return false; } return false; } (), true); check (x, 2); check (bool func () { try { x |= 2; return true; } catch invalid_argument (string msg, int i, poly value) { printf("Bitwise OR assignment failed (x |= 2).\n"); return false; } return false; } (), true); check (x, 2); quit nickle_2.81.orig/test/jsontest.5c0000664000175000000620000000132313066263330016162 0ustar keithpstaffautoimport JSON; exception bad_json(poly val, string json, poly got); void json_test_val(poly val, string match) { string json = to_json(val); poly t = from_json(json); /* Make sure the string representation is correct and parsing * matches the input */ if (json != match || val != t) raise bad_json(val, json, t); } json_test_val(1, "1"); json_test_val(1.1, "1.1000000000000"); json_test_val("hello world", "\"hello world\""); json_test_val((poly[string]) { "float" => 1.1, "hash" => (poly[string]) { "hashval" => 12 }, "int" => 10, "string" => "world" }, "{\n\t\"float\": 1.1000000000000,\n\t\"hash\": {\n\t\t\"hashval\": 12\n\t},\n\t\"int\": 10,\n\t\"string\": \"world\"\n}"); nickle_2.81.orig/test/datetest.5c0000664000175000000620000000274313202542656016140 0ustar keithpstaffimport Date; exception bad_seconds(int want, date_t date, int got); exception bad_date(date_t want, int seconds, date_t got); void test_round_seconds(int seconds) { date_t g = gmtime(seconds); date_t l = localtime(seconds); int sg = timegm(g); int sl = timelocal(l); if (seconds != sg) raise bad_seconds(seconds, g, sg); if (seconds != sl) raise bad_seconds(seconds, l, sl); } void test_round_date(date_t date) { int sg = timegm(date); int sl = timelocal(date); date_t g = gmtime(sg); date_t l = localtime(sl); if (g != date) raise bad_date(date, sg, g); if (l != date) raise bad_date(date, sl, l); } void test_utc_seconds(int seconds, date_t date) { date_t got_date = gmtime(seconds); int got_seconds = timegm(date); if (got_date != date) raise bad_date(date, seconds, got_date); if (got_seconds != seconds) raise bad_seconds(seconds, date, got_seconds); } test_round_seconds(0); test_round_seconds(time()); /* Epoch */ test_utc_seconds(0, (date_t) { .sec = 0, .min = 0, .hour = 0, .mday = 1, .mon = 1, .wday = 4, .yday = 0, .year = 1970, .isdst = false, .zone = "GMT" }); /* Try the largest possible time for 32-bit systems. Update * this test when glibc has been fixed for Y2038 */ test_utc_seconds(2**31-1, (date_t) {sec = 7, min = 14, hour = 3, mday = 19, mon = 1, year = 2038, wday = 2, yday = 18, isdst = false, zone = "GMT"}); nickle_2.81.orig/test/factorial.5c0000664000175000000620000000165711414642521016265 0ustar keithpstaff/* * Nickle test suite * * factorial tests */ int errors = 0; int fact(int n) { int r = 1; while (n > 1) { r *= n; n--; } return r; } void check_factorial(int max) { for (int n = 0; n < max; n++) { int is = n!; int should = fact(n); if (is != should) { printf ("check failed %d! (was %d should be %d)\n", n, is, should); ++errors; } } } real stirling (real n) { n = imprecise (n); return sqrt (2 * pi * n) * (n / Math::e) ** n; } void check_one_stirling(int v) { real s = stirling(v); real f = v!; real r = f/s; real e = 0.1/v; if (r < 1 || r > (1 + e)) { printf("check failed %d! (was %d should be close to %g)\n", v, f, s); ++errors; } } void check_stirling(int rep) { real v = 13; while (rep-- > 0) { int iv = floor(v); check_one_stirling(iv); v = v * 3 + 2; } } check_stirling(10); check_factorial(1000); exit (errors); nickle_2.81.orig/test/math-tables.c0000664000175000000620000000564011254531141016426 0ustar keithpstaff#include #include #include #define FMT "%25.17f" double print_val(double x) { if (isnan(x)) return 10000; if (x > 1e10) return 9999; if (x < -1e10) return 9999; if (fabs(x) < 1e-20) return 0; return x; } static void sin_cos_table(void) { double a; double r; printf ("/* %20.15f */\n", asin(-1)); printf ("typedef struct { real angle, sin, cos; } sin_cos_t;\n"); printf ("sin_cos_t[] sin_cos_table = {\n"); for (a = -800; a <= 800; a += 1) { double a_f = a / 100; printf ("\t{ .angle = " FMT ", .sin = " FMT ", .cos = " FMT " },\n", a_f, print_val(sin(a_f)), print_val(cos(a_f))); printf ("\t{ .angle = Ï€ * " FMT ", .sin = " FMT ", .cos = " FMT " },\n", a_f, print_val(sin(M_PI * a_f)), print_val(cos(M_PI * a_f))); } printf ("};\n"); printf ("typedef struct { real ratio, asin, acos; } asin_acos_t;\n"); printf ("asin_acos_t[] asin_acos_table = {\n"); for (r = -200; r <= 200; r += 1) { double r_f = r / 100; printf ("\t{ .ratio = " FMT ", .asin = " FMT ", .acos = " FMT " },\n", r_f, print_val(asin(r_f)), print_val(acos(r_f))); } printf ("};\n"); } static void tan_table(void) { double a; double r; double x, y; printf ("typedef struct { real angle, tan; } tan_t;\n"); printf ("tan_t[] tan_table = {\n"); for (a = -800; a <= 800; a += 1) { double a_f = a/100; printf ("\t{ .angle = " FMT ", .tan = " FMT " },\n", a_f, print_val(tan(a_f))); printf ("\t{ .angle = Ï€ * " FMT ", .tan = " FMT " },\n", a_f, print_val(tan(M_PI * a_f))); } printf ("};\n"); printf ("typedef struct { real ratio, atan; } atan_t;\n"); printf ("atan_t[] atan_table = {\n"); for (r = -1000; r <= 1000; r += 1) { double r_f = r / 10; printf ("\t{ .ratio = " FMT ", .atan = " FMT " },\n", r_f, print_val(atan(r_f))); } printf ("};\n"); printf ("typedef struct { real y, x, atan2; } atan2_t;\n"); printf ("atan2_t[] atan2_table = {\n"); for (y = -30; y <= 30; y += 1) { double y_f = y / 10; for (x = -30; x <= 30; x += 1) { double x_f = x/10; double v; /* * looks like glibc has a bug -- atan2(0,0) returns * Ï€/4 instead of 0 */ if (y_f == 0 && x_f == 0) v = 0; else v = atan2(y_f,x_f); printf ("\t{ .y = " FMT ", .x = " FMT ", .atan2 = " FMT " },\n", y_f, x_f, print_val(v)); } } printf ("};\n"); } void log_table(void) { double v; printf ("typedef struct { real in, log; } log_t;\n"); printf ("log_t[] log_table = {\n"); for (v = 1; v < 1e20; v *= 2) { double v_f = v/1e6; printf("\t{ .in = " FMT ", .log = " FMT " },\n", v_f, log(v_f)); } printf ("};\n"); printf ("typedef struct { real in, exp; } exp_t;\n"); printf ("exp_t[] exp_table = {\n"); for (v = -1000; v < 1000; v += 1) { double v_f = v/100; printf("\t{ .in = " FMT ", .exp = " FMT " },\n", v_f, exp(v_f)); } printf ("};\n"); } int main(int argc, char **argv) { sin_cos_table(); tan_table(); log_table(); exit(0); } nickle_2.81.orig/test/README0000664000175000000620000000054710770315533014751 0ustar keithpstaffThese files are used to make sure that everything in Nickle is working as it should be, or at least how we hope it should work. Each file tests specific items within Nickle such as order of operations. optest.5c - tests the operators to make sure they are calculating properly orderofoptest.5c - tests to make sure that Nickle evaluates in the correct ordernickle_2.81.orig/test/math.5c0000664000175000000620000000623111254531141015240 0ustar keithpstaff/* * Nickle test suite * * Trig operator tests */ load "math-tables.5c" int precision = 64; int errors = 0; real checked(real(real) f, real a) { try { real r = f(imprecise (a, precision)); if (r > 1e10) return 9999; if (r < -1e10) return 9999; return r; } catch invalid_argument(string type, int i, real v) { return 10000; } return 0; } real checked2(real(real, real) f, real a, real b) { try { real r = f(imprecise(a, precision), imprecise(b, precision)); /* Just return the same value for large magnitudes * as small variations in input cause the sign to flip */ if (r > 1e10) return 9999; if (r < -1e10) return 9999; return r; } catch invalid_argument(string type, int i, real v) { return 10000; } return 0; } void check(string op, real(real) f, real input, real correct) { real value = checked(f, input); if (is_number (value)) { real error = abs (value - correct); if (abs(correct) >= 1 && error < abs(correct) * 1e-8) return; if (abs(correct) < 1 && error < 1e-8) return; printf ("error %v value %v\n", error, value); } if (value != correct) { printf ("check failed %s(%v) (was %.-g, should be %.-g)", op, input, value, correct); errors++; } } void check2(string op, real(real, real) f, real input1, real input2, real correct) { real value = checked2(f, input1, input2); if (is_number (value)) { real error = abs (value - correct); if (abs(correct) >= 1 && error < abs(correct) * 1e-10) return; if (abs(correct) < 1 && error < 1e-10) return; printf ("error %v value %v\n", error, value); } if (value != correct) { printf ("check failed %s(%.-g, %.-g) (was %.-g, should be %.-g)", op, input1, input2, value, correct); errors++; } } void check_sin_cos() { for (int i = 0; i < dim(sin_cos_table); i++) { real angle = sin_cos_table[i].angle; real sin_value = sin_cos_table[i].sin; real cos_value = sin_cos_table[i].cos; check("sin", sin, angle, sin_value); check("cos", cos, angle, cos_value); } for (int i = 0; i < dim(asin_acos_table); i++) { real ratio = asin_acos_table[i].ratio; real asin_value = asin_acos_table[i].asin; real acos_value = asin_acos_table[i].acos; check("asin", asin, ratio, asin_value); check("acos", acos, ratio, acos_value); } } void check_tan() { for (int i = 0; i < dim(tan_table); i++) { real angle = tan_table[i].angle; real tan_value = tan_table[i].tan; check("tan", tan, angle, tan_value); } for (int i = 0; i < dim(atan_table); i++) { real ratio = atan_table[i].ratio; real atan_value = atan_table[i].atan; check("atan", atan, ratio, atan_value); } for (int i = 0; i < dim(atan2_table); i++) { real y = atan2_table[i].y; real x = atan2_table[i].x; real atan2_value = atan2_table[i].atan2; check2("atan2", atan2, y, x, atan2_value); } } void check_log() { for (int i = 0; i < dim(log_table); i++) { real in = log_table[i].in; real log_value = log_table[i].log; check("log", log, in, log_value); } for (int i = 0; i < dim(exp_table); i++) { real in = exp_table[i].in; real exp_value = exp_table[i].exp; check("exp", exp, in, exp_value); } } check_sin_cos(); check_tan(); check_log(); exit (errors); nickle_2.81.orig/test/Makefile.in0000664000175000000620000010307013202542702016122 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : noinst_PROGRAMS = math-tables$(EXEEXT) subdir = test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) math_tables_SOURCES = math-tables.c math_tables_OBJECTS = math-tables.$(OBJEXT) math_tables_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = math-tables.c DIST_SOURCES = math-tables.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ check_SCRIPTS = \ scanf.5c \ gcdtest.5c \ inttest.5c \ optest.5c \ orderofoptest.5c \ rattest.5c \ reftest.5c \ modtest.5c \ hashtest.5c \ signal.5c \ round.5c \ math.5c \ factorial.5c \ is_type.5c \ jsontest.5c \ datetest.5c TABLES = math-tables.5c CLEANFILES = $(TABLES) TESTS_ENVIRONMENT = NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir) TESTS = $(check_SCRIPTS) LOG_COMPILER = $(top_builddir)/nickle EXTRA_DIST = $(check_SCRIPTS) all: all-am .SUFFIXES: .SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) math-tables$(EXEEXT): $(math_tables_OBJECTS) $(math_tables_DEPENDENCIES) $(EXTRA_math_tables_DEPENDENCIES) @rm -f math-tables$(EXEEXT) $(AM_V_CCLD)$(LINK) $(math_tables_OBJECTS) $(math_tables_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/math-tables.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_SCRIPTS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? scanf.5c.log: scanf.5c @p='scanf.5c'; \ b='scanf.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) gcdtest.5c.log: gcdtest.5c @p='gcdtest.5c'; \ b='gcdtest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) inttest.5c.log: inttest.5c @p='inttest.5c'; \ b='inttest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) optest.5c.log: optest.5c @p='optest.5c'; \ b='optest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) orderofoptest.5c.log: orderofoptest.5c @p='orderofoptest.5c'; \ b='orderofoptest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) rattest.5c.log: rattest.5c @p='rattest.5c'; \ b='rattest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) reftest.5c.log: reftest.5c @p='reftest.5c'; \ b='reftest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) modtest.5c.log: modtest.5c @p='modtest.5c'; \ b='modtest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) hashtest.5c.log: hashtest.5c @p='hashtest.5c'; \ b='hashtest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) signal.5c.log: signal.5c @p='signal.5c'; \ b='signal.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) round.5c.log: round.5c @p='round.5c'; \ b='round.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) math.5c.log: math.5c @p='math.5c'; \ b='math.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) factorial.5c.log: factorial.5c @p='factorial.5c'; \ b='factorial.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) is_type.5c.log: is_type.5c @p='is_type.5c'; \ b='is_type.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) jsontest.5c.log: jsontest.5c @p='jsontest.5c'; \ b='jsontest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) datetest.5c.log: datetest.5c @p='datetest.5c'; \ b='datetest.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-generic clean-noinstPROGRAMS cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile math.5c: $(TABLES) $(TABLES): math-tables ./math-tables > $(TABLES) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/test/signal.5c0000664000175000000620000000046010751440613015566 0ustar keithpstaffint done = 0; void child () { try { while (true) sleep (100); } catch Thread::signal (int i) { done = i; } } void check () { thread t = fork child(); sleep (100); Thread::send_signal (t, 12); sleep (100); assert (done == 12, "signal not delivered"); } check (); nickle_2.81.orig/test/orderofoptest.5c0000664000175000000620000001513210414112462017204 0ustar keithpstaff/* * Nickle Testing Suite v1.0 * Order of Operations Testing Code * Written by Erin Chapman */ void check (poly value, poly correct) { if (is_number (value) && !is_rational (value)) { real error = abs (value - correct); if (error < abs(value) / 1e7) return; } if (value != correct) abort ("check failed (was %v, should be %v)", value, correct); } int x = 10; check(++x%x, 0); /* 11 */ check(x%++x, 11); /* 12 */ check(-++x, -13); /* 13 */ check((++x)!, 87178291200); /* 14 */ check(++x**2, 225); /* 15 */ check(2**++x, 65536); /* 16 */ check(++x*2, 34); /* 17 */ check(2*++x, 36); /* 18 */ check(++x/2, 9.5); /* 19 */ check(2/++x, 0.1); /* 20 */ check(++x//2, 10); /* 21 */ check(2//++x, 0); /* 22 */ check(++x%2, 1); /* 23 */ check(2%++x, 2); /* 24 */ check(++x-1, 24); /* 25 */ check(1-++x, -25); /* 26 */ check(++x+1, 28); /* 27 */ check(1+(++x), 29); /* 28 */ check(++x<<1, 58); /* 29 */ check(1<<++x, 1073741824); /* 30 */ check(++x>>1, 15); /* 31 */ check(1>>++x, 0); /* 32 */ check(++x==x, true); /* 33 */ check(x==++x, false); /* 34 */ check(++x!=x-1, true); /* 35 */ check(x-1!=++x, true); /* 36 */ check(++x&1, 1); /* 37 */ check(1&++x, 0); /* 38 */ check(++x^1, 38); /* 39 */ check(1^++x, 41); /* 40 */ check(++x|1, 41); /* 41 */ check(1|++x, 43); /* 42 */ check(++x==x ? 1 : 2, 1); /* 43 */ check(x+1==++x ? 1 : 2, 1); /* 44 */ check(true ? ++x : 2, 45); /* 45 */ check(false ? 1 : ++x, 46); /* 46 */ check(x++%x, 46); /* 47 */ check(x%x++, 0); /* 48 */ check(-x++, -48); /* 49 */ check(x++!, 608281864034267560872252163321295376887552831379210240000000000); check(x++**2, 2500); /* 51 */ check(2**x++, 2251799813685248); /* 52 */ check(x++*2, 104); /* 53 */ check(2*x++, 106); /* 54 */ check(x++/2, 27); /* 55 */ check(2/x++, 0.0{36}); /* 56 */ check(x++//2, 28); /* 57 */ check(2//x++, 0); /* 58 */ check(x++%2, 0); /* 59 */ check(2%x++, 2); /* 60 */ check(x++-1, 59); /* 61 */ check(1-x++, -60); /* 62 */ check(x+++1, 63); /* 63 */ check(1+x++, 64); /* 64 */ check(x++<<1, 128); /* 65 */ check(1<>1, 33); /* 67 */ check(1>>x++, 0); /* 68 */ check(x++==x-1, true); /* 69 */ check(x==x++, true); /* 70 */ check(x++!=x, true); /* 71 */ check(x-1!=x++, true); /* 72 */ check(x++&1, 0); /* 73 */ check(1&x++, 1); /* 74 */ check(x++^1, 75); /* 75 */ check(1^x++, 74); /* 76 */ check(x++|1, 77); /* 77 */ check(1|x++, 77); /* 78 */ check(x++==x-1 ? 1 : 2, 1); /* 79 */ check(true ? x++ : 2, 79); /* 80 */ check(false ? 1 : x++, 80); /* 81 */ check(--x%x, 0); /* 80 */ check(x%--x, 1); /* 79 */ check(-(--x), -78); /* 78 */ check((--x)!, 145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000); /* 77 */ check(--x**2, 5776); /* 76 */ check(2**--x, 37778931862957161709568); /* 75 */ check(--x*2, 148); /* 74 */ check(2*--x, 146); /* 73 */ check(--x/2, 36); /* 72 */ check(2/--x, 0.{0281690140845070422535211267605633802816901408450704225352112676056338}); /* 71 */ check(--x//2, 35); /* 70 */ check(2//--x, 0); /* 69 */ check(--x%2, 0); /* 68 */ check(2%--x, 2); /* 67 */ check(--x-1, 65); /* 66 */ check(1-(--x), -64); /* 65 */ check(--x+1, 65); /* 64 */ check(1+--x, 64); /* 63 */ check(--x<<1, 124); /* 62 */ check(1<<--x, 2305843009213693952); /* 61 */ check(--x>>1, 30); /* 60 */ check(1>>--x, 0); /* 59 */ check(--x==x, true); /* 58 */ check(x-1==--x, true); /* 57 */ check(--x!=x-1, true); /* 56 */ check(x!=--x, true); /* 55 */ check(--x&1, 0); /* 54 */ check(1&--x, 1); /* 53 */ check(--x^1, 53); /* 52 */ check(1^--x, 50); /* 51 */ check(--x|1, 51); /* 50 */ check(1|--x, 49); /* 49 */ check(--x==x ? 1 : 2, 1); /* 48 */ check(true ? --x : 2, 47); /* 47 */ check(false ? 1 : --x, 46); /* 46 */ check(x--%x, 1); /* 45 */ check(x%x--, 0); /* 44 */ check(-x--, -44); /* 43 */ check(x--!, 60415263063373835637355132068513997507264512000000000); /* 42 */ check(x--**2, 1764); /* 41 */ check(2**x--, 2199023255552); /* 40 */ check(x--*2, 80); /* 39 */ check(2*x--, 78); /* 38 */ check(x--/2, 19); /* 37 */ check(2/x--, 0.{054}); /* 36 */ check(x--//2, 18); /* 35 */ check(2//x--, 0); /* 34 */ check(x--%2, 0); /* 33 */ check(2%x--, 2); /* 32 */ check(x---1, 31); /* 31 */ check(1-x--, -30); /* 30 */ check(x--+1, 31); /* 29 */ check(1+x--, 30); /* 28 */ check(x--<<1, 56); /* 27 */ check(1<>1, 13); /* 25 */ check(1>>x--, 0); /* 24 */ check(x--==x+1, true); /* 23 */ check(x==x--, true); /* 22 */ check(x--!=x, true); /* 21 */ check(x+1!=x--, true); /* 20 */ check(x--&1, 0); /* 19 */ check(1&x--, 1); /* 18 */ check(x--^1, 19); /* 17 */ check(1^x--, 16); /* 16 */ check(x--|1, 17); /* 15 */ check(1|x--, 15); /* 14 */ check(x--==x+1 ? 1 : 2, 1); /* 13 */ check(true ? x-- : 2, 13); /* 12 */ check(false ? 1 : x--, 12); /* 11 */ bool y = true; check(y, true); check(!y==!y, true); check(!y==!!y, false); check(!!y==!y, false); check(!y!=!y, false); check(!y!=!!y, true); check(!!y!=!y, true); check(!y&&!y, false); check(!y&&!!y, false); check(!!y&&!y, false); check(!!y&&!!y, true); check(!y||!y, false); check(!y||!!y, true); check(!!y||!y, true); check(!!y||!!y, true); check(!y ? 1 : 2, 2); check(!!y ? 1 : 2, 1); check(true ? !y : y, false); check(false ? y : !y, false); check(x=5, 5); check(x!**2, 14400); check(2**x!, 1329227995784915872903807060280344576); check(x!*2, 240); check(2*x!, 240); check(x!/100, 6/5); check(100/x!, 5/6); check(x!//100, 1); check(100//x!, 0); check(x!%100, 20); check(100%x!, 100); check(x!+7, 127); check(7+x!, 127); check(x!-7, 113); check(7-x!, -113); check(x!>>1, 60); check(1>>x!, 0); check(x!<<1, 240); check(1<=x-x, true); check(x!+1>=x!, true); check(x!x-1, true); check(x!+1>x!, true); check((x!)==x!, true); check(x!!=x-1, true); check(x-1!=x!, true); check(x!&1, 0); check(1&x!, 0); check(x!^1, 121); check(1^x!, 121); check(x!|1, 121); check(1|x!, 121); check((x!)==x! ? 1 : 2, 1); check(true ? x! : 2, 120); check(false ? 1 : x!, 120); *int pntr; check(pntr=&x, &x); check(*pntr**2, 25); check(2***pntr, 32); check(*pntr*2, 10); check(2* *pntr, 10); check(*pntr/100, 1/20); check(100/ *pntr, 20); check(*pntr//100, 0); check(100//*pntr, 20); check(*pntr%100, 5); check(100%*pntr, 0); check(*pntr+7, 12); check(7+*pntr, 12); check(*pntr-7, -2); check(7-*pntr, 2); check(*pntr>>1, 2); check(1>>*pntr, 0); check(*pntr<<1, 10); check(1<<*pntr, 32); nickle_2.81.orig/test/gcdtest.5c0000664000175000000620000000156610740270416015756 0ustar keithpstaffint function gcd_euclid (int u, int v) { int steps = 0; if (u == 0 || v == 0) return 0; while (v > 0) { int t = u % v; u = v; v = t; steps++; } return u; } autoimport PRNG; bool gcd_verify = true; exception bad_gcd (int u, int v); void function gcd_check (int u, int v) { int weber = gcd (u,v); if (gcd_verify) { int euclid = gcd_euclid (u,v); if (weber != euclid) raise bad_gcd (u,v); } else for (int i = 0; i < 100; i++) int weber = gcd (u,v); } void function gcd_random (int ubits, int vbits) { int u = randbits (ubits); int v = randbits (vbits); gcd_check (u, v); } void function gcd_test (int amin, int amax, int bmin, int bmax) { int a, b; for (a = amin; a <= amax; a += randint(10)) for (b = bmin; b <= bmax; b += randint(10)) gcd_random (a, b); } gcd_test (2, 200, 2, 200) nickle_2.81.orig/test/scanf.5c0000664000175000000620000000233411720620067015405 0ustar keithpstaffint errors = 0; void check(string input, string format, int count, poly value) { poly got_value; int got_count = File::fscanf(File::string_read(input), format, &got_value); if (got_count != count) { printf ("got %d wanted %d. input %s format %s\n", got_count, count, input, format); errors++; return; } if (count != 0) { if (got_value != value) { printf ("read %v wanted %v. input %s format %s\n", got_value, value, input, format); errors++; } } } string[] int_formats={ "%b", "%o", "%d", "%x", "%e", "%f", "%g" }; for (int i = 0; i < dim(int_formats); i++) { check("0", int_formats[i], 1, 0); check(" 0", int_formats[i], 1, 0); check("1", "%x", 1, 1); check(" 1", "%x", 1, 1); check("", "%x", 0, 1); check(" ", "%x", 0, 1); } string[] real_formats={ "%e", "%f", "%g" }; typedef struct { string input; real value; } real_t; real_t[] real_tests = { { .input = ".{3}", .value = 1/3 }, { .input = "1.0e-30", value = 1e-30 }, { .input = "1e30", .value = 1e30 }, }; for (int i = 0; i < dim(real_formats); i++) { for (int t = 0; t < dim(real_tests); t++) { check(real_tests[t].input, real_formats[i], 1, real_tests[t].value); } } exit(errors); nickle_2.81.orig/test/round.5c0000664000175000000620000000227510737367727015470 0ustar keithpstaffexception bad_round (int num, int den, int round); autoimport PRNG; void floor_check (int num, int den, int floor) { if (num // den != floor) raise bad_round (num, den, floor); } void ceil_check (int num, int den, int ceil) { int compare; compare = num // den; if (num % den != 0) compare++; if (compare != ceil) raise bad_round (num, den, ceil); } void function round_random (int numbits, int denbits) { int num = randbits (numbits); int den = randbits (numbits); if (den == 0) return; floor_check (num, den, floor (num / den)); ceil_check (num, den, ceil (num / den)); floor_check (num, den, floor (imprecise (num / den))); ceil_check (num, den, ceil (imprecise (num / den))); floor_check (-num, den, floor (-num / den)); ceil_check (-num, den, ceil (-num / den)); floor_check (-num, den, floor (-imprecise (num / den))); ceil_check (-num, den, ceil (-imprecise (num / den))); } void function round_test (int amin, int amax, int bmin, int bmax) { int a, b; for (a = amin; a <= amax; a += randint(30)) for (b = bmin; b <= bmax; b += randint(30)) round_random (a, b); } round_test (2, 512, 2, 512) nickle_2.81.orig/test/inttest.5c0000664000175000000620000000106010675627422016012 0ustar keithpstaffautoimport PRNG; exception bad_result (int u, int v); void function int_check (int u, int v) { if (v * (u//v) + u%v - -v != u + v) raise bad_result (u, v); } void function int_random (int ubits, int vbits) { int u = randbits (ubits); int v = randbits (vbits); if (v == 0) v = 1; int_check (u, v); } void function int_test (int amin, int amax, int bmin, int bmax) { int a, b; for (a = amin; a <= amax; a += randint(200)) for (b = bmin; b <= bmax; b += randint(200)) int_random (a, b); } int_test(2,2000,2,2000) nickle_2.81.orig/install-sh0000755000175000000620000003546313064666316015130 0ustar keithpstaff#!/bin/sh # install - install a program, script, or datafile scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # $RANDOM is not portable (e.g. dash); use it when possible to # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so # create the $tmpdir first (and fail if unsuccessful) to make sure # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: nickle_2.81.orig/float.c0000664000175000000620000005674411711442776014403 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include "nickle.h" Fpart *zero_fpart, *one_fpart; #if 0 #define DebugV(s,v) FilePrintf (FileStdout, "%s %v\n", s, v) #define DebugN(s,n) FilePrintf (FileStdout, "%s %n\n", s, n) #define DebugFp(s,f) FilePrintf (FileStdout, "%s %s%n\n", s, \ (f)->sign == Negative ? "-" : "", \ (f)->mag) #define DebugF(s,f) { \ DebugFp(s,(f)->mant); \ DebugFp(" e ", (f)->exp); \ } #else #define DebugV(s,v) #define DebugN(s,n) #define DebugFp(s,f) #define DebugF(s,f) #endif static void FpartMark (void *object) { Fpart *f = object; MemReference (f->mag); } DataType FpartType = { FpartMark, 0, "FpartType" }; static Fpart * NewFpart (Sign sign, Natural *mag) { ENTER (); Fpart *ret; if (NaturalZero (mag)) sign = Positive; ret = ALLOCATE (&FpartType, sizeof (Fpart)); ret->sign = sign; ret->mag = mag; RETURN (ret); } static Fpart * NewIntFpart (int i) { ENTER (); Sign sign; unsigned long mag; if (i < 0) { sign = Negative; mag = -i; } else { sign = Positive; mag = i; } RETURN (NewFpart (sign, NewNatural (mag))); } static Fpart * NewValueFpart (Value v) { ENTER (); Fpart *ret; switch (ValueTag(v)) { case rep_int: ret = NewIntFpart (ValueInt(v)); break; case rep_integer: ret = NewFpart (IntegerSign(v), IntegerMag(v)); break; default: ret = zero_fpart; break; } RETURN (ret); } static Fpart * FpartAdd (Fpart *a, Fpart *b, Bool negate) { ENTER (); Fpart *ret; switch (catagorize_signs(a->sign, negate ? SignNegate (b->sign):b->sign)) { default: case BothPositive: ret = NewFpart (Positive, NaturalPlus (a->mag, b->mag)); break; case FirstPositive: if (NaturalLess (a->mag, b->mag)) ret = NewFpart (Negative, NaturalMinus (b->mag, a->mag)); else ret = NewFpart (Positive, NaturalMinus (a->mag, b->mag)); break; case SecondPositive: if (NaturalLess (a->mag, b->mag)) ret = NewFpart (Positive, NaturalMinus (b->mag, a->mag)); else ret = NewFpart (Negative, NaturalMinus (a->mag, b->mag)); break; case BothNegative: ret = NewFpart (Negative, NaturalPlus (a->mag, b->mag)); break; } RETURN (ret); } static Fpart * FpartMult (Fpart *a, Fpart *b) { ENTER (); Sign sign; sign = Positive; if (a->sign != b->sign) sign = Negative; RETURN (NewFpart (sign, NaturalTimes (a->mag, b->mag))); } static Fpart * FpartDivide (Fpart *a, Fpart *b) { ENTER (); Natural *rem; Natural *quo; Sign sign; sign = Positive; if (a->sign != b->sign) sign = Negative; quo = NaturalDivide (a->mag, b->mag, &rem); RETURN (NewFpart (sign, quo)); } static Fpart * FpartRsl (Fpart *a, int shift) { ENTER (); RETURN (NewFpart (a->sign, NaturalRsl (a->mag, shift))); } static Fpart * FpartLsl (Fpart *a, int shift) { ENTER (); RETURN (NewFpart (a->sign, NaturalLsl (a->mag, shift))); } static Bool FpartLess (Fpart *a, Fpart *b) { switch (catagorize_signs(a->sign, b->sign)) { default: case BothPositive: return NaturalLess (a->mag, b->mag); case FirstPositive: return False; case SecondPositive: return True; case BothNegative: return NaturalLess (b->mag, a->mag); } } static Bool FpartEqual (Fpart *a, Fpart *b) { switch (catagorize_signs(a->sign, b->sign)) { default: case BothPositive: case BothNegative: return NaturalEqual (a->mag, b->mag); case FirstPositive: return False; case SecondPositive: return False; } } static Bool FpartZero (Fpart *a) { return NaturalZero (a->mag); } unsigned FpartLength (Fpart *a) { unsigned bits; digit top; if (a->mag->length == 0) return 0; bits = (a->mag->length - 1) * LBASE2; top = NaturalDigits(a->mag)[a->mag->length - 1]; while (top) { bits++; top >>= 1; } return bits; } static unsigned FpartZeros (Fpart *a) { int i; int zeros = 0; digit top; if (a->mag->length == 0) return 0; for (i = 0; i < a->mag->length - 1; i++) { if (NaturalDigits(a->mag)[i] != 0) break; zeros += LBASE2; } top = NaturalDigits(a->mag)[i]; while ((top & 1) == 0) { zeros++; top >>= 1; } return zeros; } static Fpart * FpartNegate (Fpart *a) { ENTER (); RETURN (NewFpart (SignNegate (a->sign), a->mag)); } int FpartInit (void) { ENTER (); zero_fpart = NewFpart (Positive, zero_natural); MemAddRoot (zero_fpart); one_fpart = NewFpart (Positive, one_natural); MemAddRoot (one_fpart); EXIT (); return 1; } static Value FloatAdd (Value av, Value bv, int expandOk, Bool negate) { ENTER (); Value ret; Float *a = &av->floats, *b = &bv->floats; Fpart *dist; Fpart *amant, *bmant, *mant; Fpart *exp; int d; unsigned prec; int alen, blen; dist = FpartAdd (a->exp, b->exp, True); ret = 0; if (NaturalLess (dist->mag, max_int_natural)) { d = NaturalToInt (dist->mag); if (dist->sign == Negative) d = -d; amant = a->mant; bmant = b->mant; alen = FpartLength (amant); blen = FpartLength (bmant); prec = 0; exp = 0; if (d >= 0) { if (alen + d <= blen + a->prec) { amant = FpartLsl (amant, d); exp = b->exp; prec = b->prec; if (a->prec + d < prec) prec = a->prec + d; } } else { d = -d; if (blen + d <= alen + b->prec) { bmant = FpartLsl (bmant, d); exp = a->exp; prec = a->prec; if (b->prec + d < prec) prec = b->prec + d; } } if (prec) { mant = FpartAdd (amant, bmant, negate); ret = NewFloat (mant, exp, prec); } } if (!ret) { if (dist->sign == Negative) { ret = bv; if (negate) ret = NewFloat (NewFpart (SignNegate (bv->floats.mant->sign), bv->floats.mant->mag), bv->floats.exp, bv->floats.prec); } else ret = av; } RETURN (ret); } static Value FloatPlus (Value av, Value bv, int expandOk) { return FloatAdd (av, bv, expandOk, False); } static Value FloatMinus (Value av, Value bv, int expandOk) { return FloatAdd (av, bv, expandOk, True); } static Value FloatTimes (Value av, Value bv, int expandOk) { ENTER (); Float *a = &av->floats, *b = &bv->floats; Fpart *mant; Fpart *exp; unsigned prec; mant = FpartMult (a->mant, b->mant); exp = FpartAdd (a->exp, b->exp, False); if (a->prec < b->prec) prec = a->prec; else prec = b->prec; RETURN (NewFloat (mant, exp, prec)); } static Value FloatDivide (Value av, Value bv, int expandOk) { ENTER (); Float *a = &av->floats, *b = &bv->floats; Fpart *mant; Fpart *amant = a->mant, *bmant = b->mant; Fpart *exp; unsigned prec; unsigned iprec, alen; if (FpartZero (b->mant)) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } DebugF ("Dividend ", a); DebugF ("Divisor ", b); if (a->prec < b->prec) prec = a->prec; else prec = b->prec; iprec = prec + FpartLength (bmant) + 1; alen = FpartLength (amant); exp = b->exp; if (alen < iprec) { amant = FpartLsl (amant, iprec - alen); exp = FpartAdd (NewIntFpart (iprec-alen), exp, False); } exp = FpartAdd (a->exp, exp, True); DebugFp ("amant ", amant); DebugFp ("bmant ", bmant); mant = FpartDivide (amant, bmant); DebugFp ("mant ", mant); DebugFp ("exp ", exp); RETURN (NewFloat (mant, exp, prec)); } static Value FloatLess (Value av, Value bv, int expandOk) { ENTER (); Value ret; Float *a = &av->floats, *b = &bv->floats; if (FpartEqual (a->mant, zero_fpart)) { if (b->mant->sign == Positive && !FpartEqual (b->mant, zero_fpart)) ret = TrueVal; else ret = FalseVal; } else if (FpartEqual (b->mant, zero_fpart)) { if (a->mant->sign == Negative) ret = TrueVal; else ret = FalseVal; } else if (FpartEqual (a->exp, b->exp)) { ret = FalseVal; if (FpartLess (a->mant, b->mant)) ret = TrueVal; } else { av = FloatMinus (av, bv, expandOk); ret = FalseVal; if (av->floats.mant->sign == Negative) ret = TrueVal; } RETURN (ret); } static Value FloatEqual (Value av, Value bv, int expandOk) { ENTER (); Value ret; Float *a = &av->floats, *b = &bv->floats; if (FpartEqual (a->exp, b->exp)) { ret = FalseVal; if (FpartEqual (a->mant, b->mant)) ret = TrueVal; } else { av = FloatMinus (av, bv, expandOk); ret = FalseVal; if (NaturalZero (av->floats.mant->mag)) ret = TrueVal; } RETURN (ret); } static Value FloatNegate (Value av, int expandOk) { ENTER (); Float *a = &av->floats; RETURN (NewFloat (FpartNegate (a->mant), a->exp, a->prec)); } static Value FloatInteger (Value av) { ENTER (); Float *a = &av->floats; Natural *mag; int dist; if (a->exp->sign == Positive) { mag = a->mant->mag; dist = NaturalToInt (a->exp->mag); if (dist) mag = NaturalLsl (mag, dist); av = Reduce (NewInteger (a->mant->sign, mag)); } else { RaiseStandardException (exception_invalid_unop_value, 1, av); } RETURN (av); } static Value FloatFloor (Value av, int expandOk) { ENTER (); Float *a = &av->floats; Fpart *mant; Fpart *exp; int d; if (a->exp->sign == Positive) RETURN (FloatInteger (av)); if (NaturalLess (NewNatural (a->prec), a->exp->mag)) { if (a->mant->sign == Negative) RETURN (NewInt (-1)); RETURN (Zero); } d = NaturalToInt (a->exp->mag); mant = FpartRsl (a->mant, d); if (d && a->mant->sign == Negative) { mant = FpartAdd (mant, one_fpart, True); d--; } exp = zero_fpart; RETURN (FloatInteger (NewFloat (mant, exp, a->prec - d))); } static Value FloatCeil (Value av, int expandOk) { ENTER (); Float *a = &av->floats; Fpart *mant; Fpart *exp; int d; if (a->exp->sign == Positive) RETURN (FloatInteger (av)); if (NaturalLess (NewNatural (a->prec), a->exp->mag)) { if (a->mant->sign == Positive && !NaturalZero (a->mant->mag)) RETURN (One); RETURN (Zero); } d = NaturalToInt (a->exp->mag); mant = FpartRsl (a->mant, d); if (d && a->mant->sign == Positive) { mant = FpartAdd (mant, one_fpart, False); d--; } exp = zero_fpart; RETURN (FloatInteger (NewFloat (mant, exp, a->prec - d))); } static Value FloatPromote (Value av, Value bv) { ENTER (); int prec; if (!ValueIsFloat(av)) { prec = DEFAULT_FLOAT_PREC; if (bv && ValueIsFloat(bv)) { prec = bv->floats.prec; } else { Value float_prec = lookupVar(0, "float_precision"); if (float_prec) { int default_prec = ValueInt(float_prec); if (default_prec > 1) prec = default_prec; } } av = NewValueFloat (av, prec); } RETURN (av); } static Value FloatReduce (Value av) { return av; } /* * 1/2 <= value / 2^exp2 < 1 * 1/base <= value / base^expbase < 1 * * 2^(exp2-1) <= value < 2^exp2 * * assign value = 2^(exp2-1) * * then * * 1/base <= 2^(exp2-1) / base^expbase < 1 * * 1 <= 2^(exp2-1) / (base^(expbase-1)) < base * * -log(base) <= (exp2-1) * log(2) - expbase * log(base) < 1 * * ignoring the right inequality * * 0 <= (exp2 - 1) * log(2) - (expbase-1) * log(base) * (expbase - 1) * log(base) <= (exp2 - 1) * log(2) * (expbase - 1) <= (exp2 - 1) * log(2) / log(base); * expbase <= (exp2 - 1) * log(2) / log(base) + 1; * expbase = floor ((exp2 - 1) * log(2) / log(base) + 1); * * Depending on value, expbase may need an additional digit */ #if 0 static Bool NaturalBitSet (Natural *n, int i) { int d = i / LBASE2; int b = i & LBASE2; return d < NaturalLength (n) && (NaturalDigits(n)[d] & 1 << b); } #endif static Value FloatExp (Value exp2, Value *ratio, int ibase, unsigned prec) { ENTER (); double dscale; Value scale; Value r; Value min, max, mean, nmean; Value pow2; Value base_f; Value two; Value two_f; Bool done; DebugV ("exp2", exp2); two = NewInt (2); two_f = NewIntFloat (2, prec + 32); base_f = NewIntFloat (ibase, prec + 32); /* * Compute expbase, this is a bit tricky as log is only * available in floats */ dscale = log(2) / log(ibase) * MAX_NICKLE_INT; scale = Divide (NewInt ((int) dscale), NewInt (MAX_NICKLE_INT)); /* * min = floor (((exp2 - 1) * scale) + 1); */ min = Floor (Plus (Times (Minus (exp2, One), scale), One)); if (Negativep (min)) max = Div (min, two); else max = Times (min, two); /* * pow2 = 2 ** (exp2-1) */ pow2 = Pow (two_f, Minus (exp2, One)); mean = 0; done = False; do { if (aborting) { EXIT (); *ratio = Void; return Void; } nmean = Div (Plus (min, max), two); if (mean && True(Equal (nmean, mean))) { nmean = Plus (nmean, One); done = True; } mean = nmean; DebugV ("min ", min); DebugV ("mean", mean); DebugV ("max ", max); /* * r = 2 ** (exp2-1) / (base ** (mean - 1)) */ r = Divide (pow2, Pow (base_f, Minus (mean, One))); if (done) break; if (True (Less (One, r))) min = mean; else max = mean; } while (False (Equal (max, min))); mean = Minus (mean, One); /* r = Divide (pow2, Pow (base, Minus (mean, One)));*/ r = Divide (Pow (two_f, exp2), Pow (base_f, mean)); /* r = Divide (pow2, Pow (base, mean)); */ EXIT (); REFERENCE (mean); REFERENCE (r); *ratio = r; return mean; } static Bool FloatPrint (Value f, Value fv, char format, int base, int width, int prec, int fill) { ENTER (); Float *a = &fv->floats; Value expbase; Fpart *exp; Natural *int_n; Natural *frac_n; Value ratio; Value down; Value fratio; Value m; Value int_part; Value frac_part; unsigned length; int orig_prec = prec; int mant_prec; int frac_prec; int dig_max; int exp_width; int int_width; int frac_width; int print_width; Bool negative; char *int_buffer; char *int_string; char *frac_buffer; char *frac_string; char *exp_string = 0; Bool rounded = False; if (base <= 0) base = 10; if (prec == DEFAULT_OUTPUT_PRECISION) prec = 15; mant_prec = a->prec * log(2) / log(base); DebugFp ("mant", a->mant); DebugFp ("exp ", a->exp); length = FpartLength (a->mant); expbase = FloatExp (Plus (NewInt (length), NewInteger (a->exp->sign, a->exp->mag)), &ratio, base, a->prec); if (aborting) { EXIT (); return False; } DebugV ("expbase", expbase); DebugF ("ratio ", &ratio->floats); down = Pow (NewInt (2), NewInt ((int) length)); DebugV ("down ", down); fratio = Divide (ratio, down); DebugF ("fratio ", &fratio->floats); negative = a->mant->sign == Negative; m = NewInteger (Positive, a->mant->mag); m = Times (m, fratio); if (True (Less (m, One))) { m = Times (m, NewInt (base)); expbase = Minus (expbase, One); } else if (False (Less (m, NewInt (base)))) { m = Divide (m, NewInt (base)); expbase = Plus (expbase, One); } exp = NewValueFpart (expbase); switch (format) { case 'e': case 'E': case 'f': break; default: dig_max = prec; if ((exp->sign == Positive && !NaturalLess (exp->mag, NewNatural (dig_max))) || (exp->sign == Negative && NaturalLess (NewNatural (4), exp->mag))) { format = 'e'; } else { format = 'f'; } } if (format == 'f') { m = Times (m, Pow (NewInt (base), expbase)); exp_width = 0; if (prec == INFINITE_OUTPUT_PRECISION) { prec = mant_prec; if (ValueIsInt(expbase)) { if (ValueInt(expbase) < 0) prec -= ValueInt(expbase); else if (ValueInt(expbase) > prec) prec = ValueInt(expbase); } } } else { exp_string = NaturalSprint (0, exp->mag, base, &exp_width); if (aborting) { EXIT (); return True; } exp_width++; if (exp->sign == Negative) exp_width++; if (prec == INFINITE_OUTPUT_PRECISION) prec = mant_prec; } int_part = Floor (m); frac_part = Minus (m, int_part); try_again: if (ValueIsInteger(int_part)) int_n = IntegerMag(int_part); else int_n = NewNatural (ValueInt(int_part)); int_width = NaturalEstimateLength (int_n, base); if (negative) int_width++; int_buffer = malloc (int_width + 1); int_string = NaturalSprint (int_buffer + int_width + 1, int_n, base, &int_width); if (aborting) { EXIT (); return True; } frac_prec = mant_prec - int_width; if (*int_string == '0') frac_prec++; if (negative) { *--int_string = '-'; int_width++; } if (width) { if (width > 0) frac_width = width - int_width - exp_width; else frac_width = -width - int_width - exp_width; if (prec > 0) if (frac_width > prec + 1) frac_width = prec + 1; } else { if (prec == INFINITE_OUTPUT_PRECISION) frac_width = frac_prec + 1; else frac_width = prec + 1; } /* * Limit fraction to available precision */ if (frac_width > frac_prec + 1) frac_width = frac_prec + 1; if (frac_width < 2) frac_width = 0; /* * Round the fractional part up by 1/2 beyond the * last digit to be printed. */ if (!rounded) { int frac_digits = frac_width == 0 ? 0 : frac_width - 1; Value round = Times (Divide (One, NewInt (2)), Pow (NewInt (base), NewInt (-frac_digits))); frac_part = Plus (frac_part, round); /* * If the fractional overflowed, bump the integer part * and try again */ if (GreaterEqual (frac_part, One) == TrueVal) { frac_part = Minus (frac_part, One); int_part = Plus (int_part, One); rounded = True; free (int_buffer); goto try_again; } } frac_buffer = 0; frac_string = 0; if (frac_width) frac_part = Floor (Times (frac_part, Pow (NewInt (base), NewInt (frac_width - 1)))); if (frac_width && (!Zerop (frac_part) || orig_prec > 0)) { int frac_wrote; if (ValueIsInteger(frac_part)) frac_n = IntegerMag(frac_part); else frac_n = NewNatural (ValueInt(frac_part)); frac_buffer = malloc (frac_width + 1); frac_string = NaturalSprint (frac_buffer + frac_width + 1, frac_n, base, &frac_wrote); if (aborting) { EXIT (); return True; } while (frac_wrote < frac_width - 1) { *--frac_string = '0'; frac_wrote++; } *--frac_string = '.'; if (orig_prec < 0) while (frac_buffer[frac_width-1] == '0') frac_buffer[--frac_width] = '\0'; } else frac_width = 0; print_width = int_width + frac_width + exp_width; while (width > print_width) { FileOutchar (f, fill); width--; } FilePuts (f, int_string); if (frac_string) FilePuts (f, frac_string); if (exp_width) { FilePuts (f, "e"); if (exp->sign == Negative) FilePuts (f, "-"); FilePuts (f, exp_string); } while (-width > print_width) { FileOutchar (f, fill); width++; } free (int_buffer); if (frac_buffer) free (frac_buffer); EXIT (); return True; } static HashValue FloatHash (Value av) { Float *a = &av->floats; return (NaturalHash(a->mant->mag) ^ a->mant->sign ^ NaturalHash(a->exp->mag) ^ a->exp->sign); } static void FloatMark (void *object) { Float *f = object; MemReference (f->mant); MemReference (f->exp); } ValueRep FloatRep = { { FloatMark, 0, "FloatRep" }, /* base */ rep_float, /* tag */ { /* binary */ FloatPlus, FloatMinus, FloatTimes, FloatDivide, NumericDiv, NumericMod, FloatLess, FloatEqual, 0, 0, }, { /* unary */ FloatNegate, FloatFloor, FloatCeil, }, FloatPromote, FloatReduce, FloatPrint, 0, FloatHash, }; Value NewFloat (Fpart *mant, Fpart *exp, unsigned prec) { ENTER (); unsigned bits, dist; Value ret; DebugFp ("New mant", mant); DebugFp ("New exp ", exp); /* * Trim to specified precision */ bits = FpartLength (mant); if (bits > prec) { dist = bits - prec; exp = FpartAdd (exp, NewIntFpart (dist), False); mant = FpartRsl (mant, dist); } /* * Canonicalize by shifting to a 1 in the LSB */ dist = FpartZeros (mant); if (dist) { exp = FpartAdd (exp, NewIntFpart (dist), False); mant = FpartRsl (mant, dist); } bits = FpartLength (mant); if (bits == 0) exp = mant = zero_fpart; DebugFp ("Can mant", mant); DebugFp ("Can exp ", exp); ret = ALLOCATE (&FloatRep.data, sizeof (Float)); ret->floats.mant = mant; ret->floats.exp = exp; ret->floats.prec = prec; RETURN (ret); } Value NewIntFloat (int i, unsigned prec) { ENTER (); RETURN (NewFloat (NewIntFpart (i), zero_fpart, prec)); } Value NewIntegerFloat (Integer *i, unsigned prec) { ENTER (); Fpart *mant; mant = NewFpart (IntegerSign((Value) i), IntegerMag((Value) i)); RETURN (NewFloat (mant, zero_fpart, prec)); } Value NewNaturalFloat (Sign sign, Natural *n, unsigned prec) { ENTER (); Fpart *mant; mant = NewFpart (sign, n); RETURN (NewFloat (mant, zero_fpart, prec)); } Value NewRationalFloat (Rational *r, unsigned prec) { ENTER (); Value num, den; num = NewNaturalFloat (r->sign, r->num, prec); den = NewNaturalFloat (Positive, r->den, prec); RETURN (FloatDivide (num, den, 1)); } #define SCALE_BITS 52 #define SCALE 4503599627370496.0 /* 2 ** 52 */ Value NewDoubleFloat (double d) { ENTER (); int e; double m; Sign ms; double_digit dd; if (d == 0.0) RETURN (Zero); e = ilogb (d); m = significand (d); ms = Positive; if (m < 0) { ms = Negative; m = -m; } e = e - SCALE_BITS; dd = (double_digit) (m * SCALE + 0.5); RETURN (NewFloat (NewFpart (ms, NewDoubleDigitNatural (dd)), NewIntFpart (e), SCALE_BITS)); } Value NewValueFloat (Value av, unsigned prec) { ENTER (); switch (ValueTag(av)) { case rep_int: av = NewIntFloat (ValueInt(av), prec); break; case rep_integer: av = NewIntegerFloat (&av->integer, prec); break; case rep_rational: av = NewRationalFloat (&av->rational, prec); break; case rep_float: av = NewFloat (av->floats.mant, av->floats.exp, prec); break; default: break; } RETURN (av); } double DoublePart (Value av, char *error) { double mantissa; int i; int e; digit *mt; double div; av = NewValueFloat (av, 64); if (!ValueIsFloat (av)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString (error), NewInt (0), av); return 0.0; } if (NaturalLess (av->floats.exp->mag, max_int_natural)) e = NaturalToInt (av->floats.exp->mag); else e = MAX_NICKLE_INT; if (e > 1023) { if (av->floats.exp->sign == Negative) return 0.0; RaiseStandardException (exception_invalid_argument, 3, NewStrString (error), NewInt (0), av); return 0.0; } if (av->floats.exp->sign == Negative) e = -e; mantissa = 0.0; i = av->floats.mant->mag->length; e += DIGITBITS * i; mt = NaturalDigits (av->floats.mant->mag) + i; div = 1.0 / (double) BASE; while (i--) { mantissa = mantissa + (double) *--mt * div; div *= 1.0 / (double) BASE; } if (av->floats.mant->sign == Negative) mantissa = -mantissa; return mantissa * pow (2.0, (double) e); } nickle_2.81.orig/mem.h0000664000175000000620000000442510600331521014023 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #ifndef _MEM_H_ #define _MEM_H_ #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef MEM_TRACE typedef struct _DataType DataType; #else typedef const struct _DataType DataType; #endif #if LOCAL_BUILD #include "stack.h" #else #include #endif struct _DataType { void (*Mark) (void *); int (*Free) (void *); char *name; #ifdef MEM_TRACE int added; int total; int active; long long total_bytes; long long active_bytes; DataType *next; #endif }; struct bfree { DataType *type; struct bfree *next; }; typedef unsigned long PtrInt; struct block { struct block *next; int sizeIndex; }; /* make sure we can store doubles in blocks */ union block_round { struct block b; double round; }; # define MINHUNK (sizeof (struct bfree)) # define NUMSIZES 12 # define HUNKSIZE(i) (MINHUNK << (i)) # define MAXHUNK HUNKSIZE(NUMSIZES-1) # define HEADSIZE (sizeof (union block_round)) # define HUNKS(b) ((unsigned char *) (b) + HEADSIZE) struct bfree * MemAllocateHunk (int sizeIndex); struct bfree * MemAllocateHuge (int size); void *MemAllocate (DataType *type, int size); void *MemAllocateRef (DataType *type, int size); #ifdef MEM_TRACE void MemAddType (DataType *type); void MemActiveDump (void); #endif void MemInitialize (void); void MemAddRoot (void *object); void MemReference (void *object); int MemReferenceNoRecurse (void *object); void MemCollect (void); /* * These are used by the mem system and defined externally */ void debug (char *, ...); void panic (char *, ...); extern StackObject *MemStack; extern void *TemporaryData; extern struct bfree *freeList[NUMSIZES]; #define REFERENCE(o) STACK_PUSH(MemStack, (o)) #define ENTER() StackPointer __stackPointer = STACK_TOP(MemStack) #define ALLOCATE(type,size) MemAllocateRef(type,size) #define EXIT() STACK_RESET(MemStack, __stackPointer) #define RETURN(r) return (STACK_RETURN (MemStack, __stackPointer, (r))) #define NOREFRETURN(r) return (EXIT(), (r)) #endif /* _MEM_H_ */ nickle_2.81.orig/value.c0000664000175000000620000004332213202522675014370 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * operators accepting values */ #include "nickle.h" Value Void; Value TrueVal, FalseVal; volatile Bool aborting; volatile Bool signaling; #ifndef Numericp Bool Numericp (Rep t) { switch (t) { case rep_int: case rep_integer: case rep_rational: case rep_float: return True; default:; } return False; } #endif #ifndef Integralp Bool Integralp (Rep t) { switch (t) { case rep_int: case rep_integer: return True; default:; } return False; } #endif Bool Zerop (Value av) { switch (ValueTag(av)) { case rep_int: return ValueInt(av) == 0; case rep_integer: return IntegerMag(av)->length == 0; case rep_rational: return av->rational.num->length == 0; case rep_float: return av->floats.mant->mag->length == 0; default:; } return False; } Bool Negativep (Value av) { switch (ValueTag(av)) { case rep_int: return ValueInt(av) < 0; case rep_integer: return IntegerSign(av) == Negative; case rep_rational: return av->rational.sign == Negative; case rep_float: return av->floats.mant->sign == Negative; default:; } return False; } Bool Evenp (Value av) { switch (ValueTag(av)) { case rep_int: return (ValueInt(av) & 1) == 0; case rep_integer: return NaturalEven (IntegerMag(av)); default:; } return False; } int IntPart (Value av, char *error) { if (!ValueIsInt(av)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString (error), NewInt (0), av); return 0; } return ValueInt(av); } int BoolPart (Value av, char *error) { if (!ValueIsBool(av)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString (error), NewInt (0), av); return 0; } return av == TrueVal; } signed_digit SignedDigitPart(Value av, char *error) { if (ValueIsInt(av)) return ValueInt(av); if (ValueIsInteger(av) && IntegerFitsSignedDigit(&av->integer)) return IntegerToSignedDigit(&av->integer); RaiseStandardException (exception_invalid_argument, 3, NewStrString (error), NewInt (0), av); return 0; } Value BinaryOperate (Value av, Value bv, BinaryOp operator) { if (ValueIsInt(av) && ValueIsInt(bv)) { int a, b, r; signed_digit rd; switch (operator) { case PlusOp: r = ValueInt(av) + ValueInt(bv); if (NICKLE_INT_CARRIED(r)) return Plus (NewIntInteger (ValueInt(av)), NewIntInteger(ValueInt(bv))); return NewInt(r); case MinusOp: r = ValueInt(av) - ValueInt(bv); if (NICKLE_INT_CARRIED(r)) return Minus (NewIntInteger (ValueInt(av)), NewIntInteger(ValueInt(bv))); return NewInt(r); case TimesOp: a = ValueInt(av), b = ValueInt(bv); rd = (signed_digit) a * (signed_digit) b; if (rd > (signed_digit) MAX_NICKLE_INT || rd < (signed_digit) MIN_NICKLE_INT) return NewSignedDigitInteger (rd); return NewInt ((int) rd); case DivideOp: a = ValueInt(av), b = ValueInt(bv); if (b == 0) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); return Void; } if (a % b != 0) return Divide (NewIntRational (a), NewIntRational (b)); return NewInt (a/b); case DivOp: a = ValueInt(av), b = ValueInt(bv); if (b == 0) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); return Void; } switch (catagorize_signs (IntSign(a), IntSign(b))) { case BothPositive: r = a / b; break; case FirstPositive: r = - (a / -b); break; case SecondPositive: r = -(-a / b); if (-a % b) --r; break; case BothNegative: default: r = -a / -b; if (-a % -b) r++; break; } return NewInt (r); case ModOp: a = ValueInt(av), b = ValueInt(bv); if (b == 0) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); return Void; } switch (catagorize_signs (IntSign(a), IntSign(b))) { case BothPositive: r = a % b; break; case FirstPositive: r = a % -b; break; case SecondPositive: r = -a % b; if (r) r = b - r; break; case BothNegative: default: r = -a % -b; if (r) r = -b - r; break; } return NewInt (r); case EqualOp: return av == bv ? TrueVal : FalseVal; case LessOp: return ValueInt(av) < ValueInt(bv) ? TrueVal : FalseVal; case LandOp: return NewInt (ValueInt(av) & ValueInt(bv)); case LorOp: return NewInt (ValueInt(av) | ValueInt(bv)); case NumBinaryOp: ; } return Void; } else { ENTER (); Value ret; ValueRep *arep = ValueRep(av), *brep = ValueRep(bv); ValueRep *rep = 0; if (arep->typecheck) rep = (*arep->typecheck) (operator, av, bv, 1); else if (brep->typecheck) rep = (*brep->typecheck) (operator, av, bv, 1); else if (arep == brep) rep = arep; else if (Numericp (ValueTag(av)) && Numericp (ValueTag(bv))) { if (ValueTag(av) < ValueTag(bv)) av = (*brep->promote) (av, bv); else bv = (*arep->promote) (bv, av); rep = ValueRep(av); } else if (ValueIsUnion(av)) rep = arep; else if (ValueIsUnion(bv)) rep = brep; if (!rep || !rep->binary[operator]) { if (operator == EqualOp) RETURN (FalseVal); RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } if (aborting) RETURN (Void); ret = (*rep->binary[operator]) (av, bv, 1); rep = ValueRep(ret); if (rep->reduce) ret = (*rep->reduce) (ret); RETURN (ret); } } Value UnaryOperate (Value v, UnaryOp operator) { ENTER (); Value ret; ValueRep *rep = ValueRep(v); if (!rep->unary[operator]) { RaiseStandardException (exception_invalid_unop_value, 1, v); RETURN (Void); } if (aborting) RETURN (Void); ret = (*rep->unary[operator])(v, 1); rep = ValueRep(ret); if (rep->reduce) ret = (*rep->reduce) (ret); RETURN (ret); } Value Reduce (Value v) { ValueRep *rep = ValueRep(v); if (rep->reduce) v = (*rep->reduce) (v); return v; } Value NumericDiv (Value av, Value bv, int expandOk) { ENTER (); av = Divide (av, bv); if (Negativep (bv)) av = Ceil (av); else av = Floor (av); RETURN (av); } Value NumericMod (Value av, Value bv, int expandOk) { ENTER (); Value q; q = NumericDiv (av, bv, expandOk); av = Minus (av, Times (q, bv)); RETURN (av); } Value Negate (Value av) { return UnaryOperate (av, NegateOp); } Value Floor (Value av) { return UnaryOperate (av, FloorOp); } Value Ceil (Value av) { return UnaryOperate (av, CeilOp); } /* * non primitive functions */ Value Lnot (Value av) { ENTER (); RETURN (Minus (Negate (av), One)); } Value Lxor (Value av, Value bv) { ENTER (); RETURN (Land (Lnot (Land (av, bv)), Lor (av, bv))); } Value Not (Value av) { ENTER (); if (True (av)) av = FalseVal; else av = TrueVal; RETURN (av); } Value Greater (Value av, Value bv) { return Less (bv, av); } Value LessEqual (Value av, Value bv) { return Not (Less (bv, av)); } Value GreaterEqual (Value av, Value bv) { return Not (Less (av, bv)); } Value NotEqual (Value av, Value bv) { return Not (Equal (av, bv)); } Value Factorial (Value av) { ENTER (); Value tv; Value i; StackPointer iref, tvref; if (!Integralp (ValueTag(av)) || Negativep (av)) { RaiseStandardException (exception_invalid_unop_value, 1, av); RETURN (Void); } /* * A bit of reference magic here to avoid churning * through megabytes. Build a couple of spots * on the reference stack for the two intermediate * values and then reuse them after each iteration */ tv = One; i = One; REFERENCE (tv); tvref = STACK_TOP(MemStack); REFERENCE (i); iref = STACK_TOP(MemStack); for (;;) { ENTER (); if (aborting || False (Less (i, av))) { EXIT (); break; } i = Plus (i, One); tv = Times (i, tv); EXIT (); *iref = i; *tvref = tv; } RETURN (tv); } Value Truncate (Value av) { ENTER (); if (Negativep (av)) av = Ceil (av); else av = Floor (av); RETURN (av); } Value Round (Value av) { ENTER (); RETURN (Floor (Plus (av, NewRational (Positive, one_natural, two_natural)))); } Value Pow (Value av, Value bv) { ENTER (); Value result; if (!Numericp (ValueTag(av)) || !Numericp (ValueTag(bv))) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } switch (ValueTag(bv)) { case rep_int: { Value p; int i; int flip = 0; i = ValueInt(bv); if (i < 0) { i = -i; flip = 1; } p = av; result = One; while (i) { if (aborting) RETURN (Void); if (i & 1) result = Times (result, p); i >>= 1; if (i) p = Times (p, p); } if (flip) result = Divide (One, result); } break; case rep_integer: { Value p; Natural *i; Natural *two; Natural *rem; int flip = 0; i = IntegerMag(bv); if (IntegerSign(bv) == Negative) flip = 1; two = NewNatural (2); p = av; result = One; while (!NaturalZero (i)) { if (aborting) RETURN (Void); if (!NaturalEven (i)) result = Times (result, p); i = NaturalDivide (i, two, &rem); if (!NaturalZero (i)) p = Times (p, p); } if (flip) result = Divide (One, result); } break; default: RaiseStandardException (exception_invalid_binop_values, 2, av, bv); result = Void; break; } RETURN (result); } Value ShiftL (Value av, Value bv) { ENTER (); if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv))) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } if (Negativep (bv)) RETURN (ShiftR(av, Negate (bv))); if (Zerop (bv)) RETURN(av); if (ValueIsInt(bv)) { Sign sign = Positive; int b = ValueInt(bv); if (ValueIsInt (av) && b < NICKLE_INT_BITS) { signed_digit rd = (signed_digit) ValueInt (av) << b; if (rd > (signed_digit) MAX_NICKLE_INT || rd < (signed_digit) MIN_NICKLE_INT) av = NewSignedDigitInteger (rd); else av = NewInt ((int) rd); } else { if (Negativep (av)) sign = Negative; av = Reduce (NewInteger (sign, NaturalLsl (IntegerMag(IntegerRep.promote (av,0)), ValueInt(bv)))); } } else { av = Times (av, Pow (NewInt(2), bv)); } RETURN (av); } Value ShiftR (Value av, Value bv) { ENTER (); if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv))) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } if (Negativep (bv)) RETURN (ShiftL(av, Negate (bv))); if (Zerop (bv)) RETURN(av); if (ValueIsInt(bv)) { Sign sign = Positive; int b = ValueInt(bv); if (ValueIsInt (av) && b < NICKLE_INT_BITS) { av = NewInt (ValueInt (av) >> b); } else { if (Negativep (av)) { av = Minus (av, Minus (ShiftL (One, bv), One)); sign = Negative; } av = Reduce (NewInteger (sign, NaturalRsl (IntegerMag(IntegerRep.promote (av,0)), b))); } } else { av = Div (av, Pow (NewInt(2), bv)); } RETURN (av); } Value Gcd (Value av, Value bv) { ENTER (); if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv))) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } RETURN (Reduce (NewInteger (Positive, NaturalGcd (IntegerMag(IntegerRep.promote (av, 0)), IntegerMag(IntegerRep.promote (bv, 0)))))); } #ifdef GCD_DEBUG Value Bdivmod (Value av, Value bv) { ENTER (); if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv))) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } RETURN (Reduce (NewInteger (Positive, NaturalBdivmod (IntegerRep.promote (av, 0)->integer.mag, IntegerRep.promote (bv, 0)->integer.mag)))); } Value KaryReduction (Value av, Value bv) { ENTER (); if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv))) { RaiseStandardException (exception_invalid_binop_values, 2, av, bv); RETURN (Void); } RETURN (Reduce (NewInteger (Positive, NaturalKaryReduction (IntegerRep.promote (av, 0)->integer.mag, IntegerRep.promote (bv, 0)->integer.mag)))); } #endif StackObject *ValuePrintStack; int ValuePrintLevel; Bool Print (Value f, Value v, char format, int base, int width, int prec, int fill) { int i; Bool ret; ValueRep *rep; if (!v) { FilePuts (f, ""); return True; } rep = ValueRep(v); if (!rep->print) return True; for (i = 0; i < ValuePrintLevel; i++) { if (STACK_ELT(ValuePrintStack, i) == v) { FilePuts (f, ""); return True; } } STACK_PUSH (ValuePrintStack, v); ++ValuePrintLevel; ret = (*rep->print) (f, v, format, base, width, prec, fill); STACK_POP (ValuePrintStack); --ValuePrintLevel; return ret; } /* * Make a deep copy of 'v' */ Value CopyMutable (Value v) { ENTER (); Value nv; int i; BoxPtr box, nbox; int n; switch (ValueTag(v)) { case rep_array: if (!v->array.resizable && ArrayValueBox(&v->array,0)->constant) RETURN (v); nv = NewArray (False, v->array.resizable, ArrayType(&v->array), v->array.ndim, ArrayDims(&v->array)); for (i = 0; i < v->array.ndim; i++) ArrayLimits(&nv->array)[i] = ArrayLimits(&v->array)[i]; if (v->array.resizable) { BoxPtr *o, *n; int l = ArrayNvalues (&v->array); o = BoxVectorBoxes (v->array.u.resize); n = BoxVectorBoxes (nv->array.u.resize); for (i = 0; i < l; i++) { BoxValueSet (*n, 0, Copy (BoxValueGet (*o, 0))); n++; o++; } RETURN(nv); } else { box = v->array.u.fix; nbox = nv->array.u.fix; n = ArrayNvalues (&v->array); } break; case rep_struct: if (v->structs.values->constant) RETURN (v); nv = NewStruct (v->structs.type, False); box = v->structs.values; nbox = nv->structs.values; n = v->structs.type->nelements; break; case rep_union: if (v->unions.value->constant) RETURN (v); nv = NewUnion (v->unions.type, False); nv->unions.tag = v->unions.tag; box = v->unions.value; nbox = nv->unions.value; n = 1; break; case rep_hash: RETURN (HashCopy (v)); default: RETURN (v); } for (i = 0; i < n; i++) BoxValueSet (nbox, i, Copy (BoxValueGet (box, i))); RETURN (nv); } Value ValueEqual (Value a, Value b, int expandOk) { return a == b ? TrueVal : FalseVal; } Value ValueHash (Value v) { ValueRep *rep; if (!v) return Zero; rep = ValueRep(v); if (!rep->hash) return Zero; return NewInt ((*rep->hash) (v) & MAX_NICKLE_INT); } static Value UnitEqual (Value av, Value bv, int expandOk) { return TrueVal; } static Bool UnitPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePuts (f, "<>"); return True; } ValueRep UnitRep = { { 0, 0, "UnitRep" }, /* data */ rep_void, /* tag */ { 0, /* Plus */ 0, /* Minus */ 0, /* Times */ 0, /* Divide */ 0, /* Div */ 0, /* Mod */ 0, /* Less */ UnitEqual, /* Equal */ 0, /* Land */ 0, /* Lor */ }, /* binary */ { 0 }, /* unary */ 0, 0, UnitPrint, /* print */ }; static Value NewVoid (void) { ENTER (); Value ret; ret = ALLOCATE (&UnitRep.data, sizeof (BaseValue)); RETURN (ret); } static Value BoolEqual (Value av, Value bv, int expandOk) { return (av == TrueVal) == (bv == TrueVal) ? TrueVal : FalseVal; } static Bool BoolPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePuts (f, av == TrueVal ? "true" : "false"); return True; } ValueRep BoolRep = { { 0, 0, "BoolRep" }, /* data */ rep_bool, /* tag */ { 0, /* Plus */ 0, /* Minus */ 0, /* Times */ 0, /* Divide */ 0, /* Div */ 0, /* Mod */ 0, /* Less */ BoolEqual, /* Equal */ 0, /* Land */ 0, /* Lor */ }, /* binary */ { 0 }, /* unary */ 0, 0, BoolPrint, /* print */ }; static Value NewBool (void) { ENTER (); Value ret; ret = ALLOCATE (&BoolRep.data, sizeof (BaseValue)); RETURN (ret); } /* * This is a bit odd, but it's just a cache so * erase it at GC time */ static void DataCacheMark (void *object) { DataCache *dc = object; memset (DataCacheValues (dc), '\0', sizeof (void *) * dc->size); } static DataType DataCacheType = { DataCacheMark, 0, "DataCacheType" }; DataCachePtr NewDataCache (int size) { ENTER (); DataCachePtr dc; dc = (DataCachePtr) MemAllocate (&DataCacheType, sizeof (DataCache) + size * sizeof (void *)); dc->size = size; memset (DataCacheValues(dc), '\0', size * sizeof (Value)); MemAddRoot (dc); RETURN (dc); } int ValueInit (void) { if (!AtomInit ()) return 0; if (!ArrayInit ()) return 0; if (!FileInit ()) return 0; if (!HashInit ()) return 0; if (!IntInit ()) return 0; if (!NaturalInit ()) return 0; if (!IntegerInit ()) return 0; if (!RationalInit ()) return 0; if (!FpartInit ()) return 0; if (!RefInit ()) return 0; if (!StringInit ()) return 0; if (!StructInit ()) return 0; if (!ForeignInit ()) return 0; ValuePrintStack = StackCreate (); MemAddRoot (ValuePrintStack); Void = NewVoid (); MemAddRoot (Void); TrueVal = NewBool (); MemAddRoot (TrueVal); FalseVal = NewBool (); MemAddRoot (FalseVal); ValuePrintLevel = 0; return 1; } nickle_2.81.orig/expr.c0000664000175000000620000001125411722534012014222 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * expr.c * * handle expression trees */ #include "nickle.h" #include "gram.h" static void ExprTreeMark (void *object) { ExprTree *et = object; MemReference (et->expr.namespace); MemReference (et->expr.type); MemReference (et->left); MemReference (et->right); if (!profiling) et->expr.ticks = et->expr.sub_ticks = 0; } static void ExprConstMark (void *object) { ExprConst *ec = object; MemReference (ec->expr.namespace); MemReference (ec->expr.type); MemReference (ec->constant); if (!profiling) ec->expr.ticks = ec->expr.sub_ticks = 0; } static void ExprAtomMark (void *object) { ExprAtom *ea = object; MemReference (ea->expr.namespace); MemReference (ea->expr.type); MemReference (ea->symbol); if (!profiling) ea->expr.ticks = ea->expr.sub_ticks = 0; } static void ExprCodeMark (void *object) { ExprCode *ec = object; MemReference (ec->expr.namespace); MemReference (ec->expr.type); MemReference (ec->code); if (!profiling) ec->expr.ticks = ec->expr.sub_ticks = 0; } static void ExprDeclMark (void *object) { ExprDecl *ed = object; MemReference (ed->expr.namespace); MemReference (ed->expr.type); MemReference (ed->decl); MemReference (ed->type); if (!profiling) ed->expr.ticks = ed->expr.sub_ticks = 0; } static void ExprTypeMark (void *object) { ExprType *et = object; MemReference (et->expr.namespace); MemReference (et->expr.type); MemReference (et->left); MemReference (et->type); if (!profiling) et->expr.ticks = et->expr.sub_ticks = 0; } DataType ExprTreeType = { ExprTreeMark, 0, "ExprTreeType" }; DataType ExprConstType = { ExprConstMark, 0, "ExprConstType" }; DataType ExprAtomType = { ExprAtomMark, 0, "ExprAtomType" }; DataType ExprCodeType = { ExprCodeMark, 0, "ExprCodeType" }; DataType ExprDeclType = { ExprDeclMark, 0, "ExprDeclType" }; DataType ExprTypeType = { ExprTypeMark, 0, "ExprTypeType" }; static void ExprBaseInit (Expr *e, int tag) { e->base.tag = tag; e->base.file = LexFileName (); e->base.line = LexFileLine (); e->base.namespace = CurrentNamespace; e->base.type = 0; e->base.ticks = 0 ; e->base.sub_ticks = 0; } Expr * NewExprTree(int tag, Expr *left, Expr *right) { ENTER (); Expr *e; e = ALLOCATE (&ExprTreeType, sizeof (ExprTree)); ExprBaseInit (e, tag); if (left) { if (left->base.file == e->base.file && left->base.line < e->base.line) e->base.line = left->base.line; } else if (right) { if (right->base.file == e->base.file && right->base.line < e->base.line) e->base.line = right->base.line; } e->tree.left = left; e->tree.right = right; RETURN ((Expr *) e); } Expr * NewExprComma (Expr *left, Expr *right) { return NewExprTree (COMMA, left, right); } Expr * NewExprConst (int tag, Value val) { ENTER (); Expr *e; e = ALLOCATE (&ExprConstType, sizeof (ExprConst)); ExprBaseInit (e, tag); e->constant.constant = val; RETURN (e); } Expr * NewExprAtom (Atom atom, SymbolPtr symbol, Bool privateFound) { ENTER (); Expr *e; e = ALLOCATE (&ExprAtomType, sizeof (ExprAtom)); ExprBaseInit (e, NAME); e->atom.atom = atom; e->atom.symbol = symbol; e->atom.privateFound = privateFound; RETURN (e); } Expr * NewExprCode (CodePtr code, ExprPtr name) { ENTER (); Expr *e; e = ALLOCATE (&ExprCodeType, sizeof (ExprCode)); ExprBaseInit (e, FUNC); e->code.code = code; code->base.name = name; RETURN (e); } Expr * NewExprDecl (int tag, DeclListPtr decl, Class class, Type *type, Publish publish) { ENTER (); Expr *e; e = ALLOCATE (&ExprDeclType, sizeof (ExprDecl)); ExprBaseInit (e, tag); e->decl.decl = decl; e->decl.class = class; e->decl.type = type; e->decl.publish = publish; RETURN (e); } Expr * NewExprType (int tag, ExprPtr left, Type *type) { ENTER (); Expr *e; e = ALLOCATE (&ExprTypeType, sizeof (ExprType)); ExprBaseInit (e, tag); e->type.left = left; e->type.type = type; RETURN (e); } /* * LALR grammars like to build things right to left, but * sometimes we like the resulting data structure to be left to right */ Expr* ExprRehang (Expr *e, Expr *right) { if (e->tree.left) { Expr *t, *left; left = e->tree.right; t = ExprRehang (e->tree.left, e); e->tree.left = left; e->tree.right = right; return t; } else { e->tree.left = e->tree.right; e->tree.right = right; return e; } } nickle_2.81.orig/depcomp0000755000175000000620000005601613064666316014476 0ustar keithpstaff#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: nickle_2.81.orig/alarm.c0000664000175000000620000000637211721047753014357 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2001 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "ref.h" #include #include volatile Bool signalTimer; /* Timer signal received */ typedef struct _sleepQ { DataType *data; struct _sleepQ *next; unsigned long ms; unsigned long incr; void *closure; TimerFunc func; } SleepQ, *SleepQPtr; SleepQPtr sleeping; static void SleepQMark (void *object) { SleepQPtr sleep = object; MemReference (sleep->next); MemReference (sleep->closure); } DataType SleepQType = { SleepQMark, 0, "SleepQType" }; unsigned long TimeInMs (void) { struct timeval tv; struct timezone tz; gettimeofday (&tv, &tz); return tv.tv_sec * 1000 + tv.tv_usec / 1000; } static void _TimerSet (unsigned long when, unsigned long now) { long delta; struct itimerval it, ot; delta = when - now; if (delta < 0) delta = 1; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; it.it_value.tv_sec = delta / 1000; it.it_value.tv_usec = (delta % 1000) * 1000; setitimer (ITIMER_REAL, &it, &ot); } static void _TimerInsert (SleepQPtr new, unsigned long now) { SleepQPtr *prev, s; for (prev = &sleeping; (s = *prev); prev = &s->next) if (s->ms > new->ms) break; new->next = *prev; *prev = new; if (prev == &sleeping) _TimerSet (new->ms, now); } void TimerInsert (void *closure, TimerFunc func, unsigned long delta, unsigned long incr) { ENTER (); unsigned long now, ms; SleepQPtr self; self = ALLOCATE (&SleepQType, sizeof (SleepQ)); now = TimeInMs (); ms = now + delta; self->next = 0; self->ms = ms; self->incr = incr; self->closure = closure; self->func = func; _TimerInsert (self, now); EXIT (); } void TimerInterrupt (void) { ENTER (); unsigned long now; SleepQPtr s; now = TimeInMs (); while ((s = sleeping) && (int) (now - s->ms) >= 0) { sleeping = s->next; if ((*s->func) (s->closure) && s->incr) { s->ms += s->incr; _TimerInsert (s, now); } } if (sleeping) _TimerSet (sleeping->ms, now); EXIT (); } static Bool _sleepDone (void *closure) { Value thread = closure; if (thread->thread.state == ThreadSuspended) ThreadSetState (thread, ThreadRunning); return False; } Value do_sleep (Value ms) { ENTER (); int delta; if (running->thread.partial) RETURN (Void); delta = IntPart (ms, "Invalid sleep value"); /* don't queue if instruction is aborting */ if (aborting) RETURN (Void); TimerInsert (running, _sleepDone, delta, 0); /* This primitive has been partially executed */ running->thread.partial = 1; SetSignalSuspend(); RETURN (Void); } Value do_millis (void) { ENTER(); RETURN(NewInt(TimeInMs())); } ReferencePtr SleepingReference; static void _CatchAlarm (int sig) { resetSignal (SIGALRM, _CatchAlarm); SetSignalTimer(); } void TimerInit (void) { ENTER (); SleepingReference = NewReference ((void **) &sleeping); MemAddRoot (SleepingReference); catchSignal (SIGALRM, _CatchAlarm); EXIT (); } nickle_2.81.orig/test-driver0000755000175000000620000001104013064665461015303 0ustar keithpstaff#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2013-07-13.22; # UTC # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: nickle_2.81.orig/history.5c0000664000175000000620000000175210414112462015032 0ustar keithpstaff/* $Header$*/ /* * Copyright © 2002 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ namespace History { poly[...] hist = {}; public void insert (poly v) /* * Insert 'v' in the history list */ { hist[dim(hist)] = v; } public poly fetch (int id) /* * Fetch history element 'id' */ { if (dim(hist) == 0) return <>; if (id <= 0) return hist[dim(hist)+id-1]; else return hist[id-1]; } public void show (string format, int args...) /* * show history elements */ { int from = 10, to = dim(hist); int id; if (dim(hist) == 0) return; if (dim(args) >= 1) from = args[0]; if (dim(args) >= 2) to = args[1]; else { from = dim(hist) - from; if (from < 1) from = 1; } for (id = from; id <= to; id++) { printf ("$%-4d\t", from); printf (format, fetch (id)); printf ("\n"); from++; } } } nickle_2.81.orig/mem.c0000664000175000000620000002116211641024421014017 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * mem.c * * interface: * * void *MemAllocate (DataType *type, int size) * - returns a hunk of at least "size" bytes * void MemReference (void *object) * - marks the indicated object as referenced * void MemAddRoot (void *object) * - adds the indicated object as a root * void MemCollect (void) * - sweeps the entire heap freeing unused storage * */ #include #include #define MEM_NEED_ALLOCATE 1 #include "mem.h" #include "memp.h" #include static struct block *head; struct bfree *freeList[NUMSIZES]; static int garbageTime; static int sinceGarbage; StackObject *MemStack; void *TemporaryData; static void **Roots; static int RootCount; static int RootSize; #ifdef DEBUG int GCdebug; int totalBytesFree; int totalBytesUsed; int totalObjectsFree; int totalObjectsUsed; int useMap[NUMSIZES+1]; #endif /* * Allocate a new block */ static struct block * newBlock (int sizeIndex) { struct block *b; int size; if (sizeIndex < NUMSIZES) size = BLOCKSIZE; else size = sizeIndex + HEADSIZE; if (++sinceGarbage >= garbageTime) { MemCollect (); if (sizeIndex < NUMSIZES && freeList[sizeIndex]) return 0; } b = (struct block *) malloc (size); if (!b) { MemCollect (); if (sizeIndex < NUMSIZES && freeList[sizeIndex]) return 0; b = (struct block *) malloc (size); if (!b) panic ("Out of memory\n"); } b->sizeIndex = sizeIndex; b->next = head; head = b; return b; } /* * Allocate a small block of memory */ struct bfree * MemAllocateHunk (int sizeIndex) { struct block *b; struct bfree *new; b = newBlock (sizeIndex); if (b) { unsigned char *data = HUNKS (b); int n = NUMHUNK(sizeIndex); /* * put the contents on the free list */ while (--n) { unsigned char *next = data + HUNKSIZE(sizeIndex); ((struct bfree *) data)->type = 0; ((struct bfree *) data)->next = (struct bfree *) next; data = next; } ((struct bfree *) data)->type = 0; ((struct bfree *) data)->next = freeList[sizeIndex]; freeList[sizeIndex] = (struct bfree *) HUNKS(b); } new = freeList[sizeIndex]; freeList[sizeIndex] = new->next; return new; } void * MemAllocate (DataType *type, int size) { int sizeIndex = 0; struct bfree *new; #if NUMSIZES > 15 bad NUMSIZES #endif #ifdef MEM_TRACE if (!type->added) MemAddType (type); type->total++; type->total_bytes += size; type->active++; type->active_bytes += size; #endif if (size > HUNKSIZE(7)) sizeIndex += 8; if (size > HUNKSIZE(sizeIndex+3)) sizeIndex += 4; if (size > HUNKSIZE(sizeIndex+1)) sizeIndex += 2; if (size > HUNKSIZE(sizeIndex)) sizeIndex += 1; if (sizeIndex >= NUMSIZES) new = MemAllocateHuge (size); else if ((new = freeList[sizeIndex])) freeList[sizeIndex] = new->next; else new = MemAllocateHunk (sizeIndex); new->type = type; return new; } void * MemAllocateRef (DataType *type, int size) { struct bfree *new = MemAllocate (type, size); new->type = 0; REFERENCE (new); new->type = type; return (void *) new; } /* * Allocate a large block of memory */ struct bfree * MemAllocateHuge (int size) { return (struct bfree *) HUNKS (newBlock (size)); } #ifdef MEM_TRACE /* * Allocation tracing. Track usage of each type of object */ static DataType *allDataTypes; void MemAddType (DataType *type) { DataType **prev; for (prev = &allDataTypes; *prev; prev =&(*prev)->next) if (strcmp ((*prev)->name, type->name) >= 0) break; type->next = *prev; type->added = 1; *prev = type; } static void activeReference (DataType *type, int size) { type->active++; type->active_bytes += size; } static void activeReset (void) { DataType *type; for (type = allDataTypes; type; type = type->next) { type->active = 0; type->active_bytes = 0; } } void MemActiveDump (void) { DataType *type; debug ("Active memory dump\n"); debug ("%20.20s: %9s %12s %9s %12s\n", "name", "total", "bytes", "active", "bytes"); for (type = allDataTypes; type; type = type->next) { debug ("%20.20s: %9d %12lld %9d %12lld\n", type->name, type->total, type->total_bytes, type->active, type->active_bytes); } } #endif /* * Initialize the allocator */ void MemInitialize (void) { #ifdef DEBUG if (getenv ("NICKLE_MEM_DEBUG")) GCdebug=1; #endif if (!MemStack) { MemStack = StackCreate (); MemAddRoot (MemStack); } garbageTime = GARBAGETIME; } /* * Add a root to the memory system, objects * referenced through this will be marked as busy */ void MemAddRoot (void *object) { void **roots; if (RootCount == RootSize) { if (RootSize == 0) RootSize = 128; else RootSize *= 2; roots = malloc (sizeof (void *) * RootSize); if (!roots) panic ("Out of memory\n"); memcpy (roots, Roots, RootCount * sizeof (void *)); if (Roots) free (Roots); Roots = roots; } Roots[RootCount++] = object; } /* * Mark an object as referenced, recurse through * the Mark routine for the type to mark referenced objects */ void MemReference (void *object) { DataType *type; if (!object) return; if (PtrToInt(object) & 3) return; if (!isReferenced (object)) { type = TYPE(object); setReference(object); if (type && type->Mark) (*type->Mark) (object); } } /* * Mark an object but don't recurse, returning * whether the object was previously referenced or not */ int MemReferenceNoRecurse (void *object) { if (!object) return 1; if (PtrToInt (object) & 3) return 1; if (isReferenced (object)) return 1; setReference (object); return 0; } /* * mark: walk roots marking referenced memory */ static void mark (void) { int rootCount = RootCount; void **roots = Roots; while (rootCount--) MemReference (*roots++); if (TemporaryData) MemReference (TemporaryData); } static inline int busy (unsigned char *data) { DataType *type; if (isReferenced (data)) return 1; type = TYPE(data); if (!type) return 0; if (!type->Free) return 0; if ((*type->Free) (data)) return 0; return 1; } /* * sweep: rebuild the free lists from unused data */ static void sweep (void) { struct block *b, **p; /* Erase free list */ memset (freeList, '\0', NUMSIZES * sizeof(freeList[0])); /* * Walk all blocks */ for (p = &head; (b = *p); ) { int sizeIndex = b->sizeIndex; int n = NUMHUNK_ALL(sizeIndex); int size = HUNKSIZE_ALL(sizeIndex); unsigned char *data = HUNKS(b); struct bfree *first = 0; struct bfree **prev = &first; int anybusy = 0; while (n--) { if (busy (data)) { clrReference(data); anybusy = 1; #ifdef MEM_TRACE activeReference (TYPE(data), size); #endif #ifdef DEBUG totalObjectsUsed++; useMap[sizeIndex]++; totalBytesUsed += size; #endif } else { TYPE(data) = 0; *prev = (struct bfree *) data; prev = &((struct bfree *) data)->next; #ifdef DEBUG totalBytesFree += size; totalObjectsFree++; #endif } data += size; } if (anybusy) { if (sizeIndex < NUMSIZES) { *prev = freeList[sizeIndex]; freeList[sizeIndex] = first; } p = &b->next; } else { *p = b->next; free (b); } } } /* * Garbage collect */ void MemCollect (void) { #ifdef DEBUG if (GCdebug) debug ("GC:\n"); memset (useMap, '\0', sizeof useMap); totalBytesFree = 0; totalObjectsFree = 0; totalBytesUsed = 0; totalObjectsUsed = 0; #endif sinceGarbage = 0; #ifdef MEM_TRACE activeReset (); #endif /* * Mark */ #ifdef DEBUG if (GCdebug) debug ("GC: mark objects\n"); #endif mark (); /* * Sweep */ #ifdef DEBUG if (GCdebug) debug ("GC: sweep objects\n"); #endif sweep (); /* * Set the garbage collection time */ garbageTime = GARBAGETIME/* - (totalBytesFree / BLOCKSIZE) */; if (garbageTime < 10) garbageTime = 10; #ifdef DEBUG if (GCdebug) { int i; debug ("GC: used: bytes %7d objects %7d\n", totalBytesUsed, totalObjectsUsed); debug ("GC: free: bytes %7d objects %7d\n", totalBytesFree, totalObjectsFree); for (i = 0; i <= NUMSIZES; i++) debug ("used %5d: %7d\n", i == NUMSIZES ? 0 : HUNKSIZE(i), useMap[i]); debug ("GC: garbageTime set to %d\n", garbageTime); } #endif } nickle_2.81.orig/rational.c0000664000175000000620000005457011711574502015073 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * rational.c * * operationalns on rationals */ #include "nickle.h" #include int RationalInit (void) { return 1; } #if 0 static Value natural_to_rational (Natural *n) { ENTER (); RETURN (NewRational (Positive, n, one_natural)); } #endif static Value RationalPlusHelper (Sign sign, Rational *a, Rational *b) { ENTER (); RETURN (NewRational (sign, NaturalPlus (NaturalTimes (a->num, b->den), NaturalTimes (b->num, a->den)), NaturalTimes (a->den, b->den))); } static Value RationalMinusHelper (Rational *a, Rational *b) { ENTER (); Natural *ra, *rb, *t; Sign sign = Positive; ra = NaturalTimes (a->num, b->den); rb = NaturalTimes (b->num, a->den); if (NaturalLess (ra, rb)) { sign = Negative; t = ra; ra = rb; rb = t; } RETURN (NewRational (sign, NaturalMinus (ra, rb), NaturalTimes (a->den, b->den))); } static Value RationalPlus (Value av, Value bv, int expandOk) { ENTER (); Rational *a = &av->rational, *b = &bv->rational; Value ret; switch (catagorize_signs(a->sign, b->sign)) { case BothPositive: case BothNegative: ret = RationalPlusHelper (a->sign, a, b); break; case FirstPositive: ret = RationalMinusHelper (a, b); break; case SecondPositive: ret = RationalMinusHelper (b, a); break; default: abort(); } RETURN (ret); } static Value RationalMinus (Value av, Value bv, int expandOk) { ENTER (); Rational *a = &av->rational, *b = &bv->rational; Value ret; switch (catagorize_signs(a->sign, b->sign)) { case BothPositive: ret = RationalMinusHelper (a, b); break; case FirstPositive: case SecondPositive: ret = RationalPlusHelper (a->sign, a, b); break; case BothNegative: ret = RationalMinusHelper (b, a); break; default: abort(); } RETURN (ret); } static Value RationalTimes (Value av, Value bv, int expandOk) { ENTER (); Rational *a = &av->rational, *b = &bv->rational; Sign sign; sign = Positive; if (a->sign != b->sign) sign = Negative; RETURN (NewRational (sign, NaturalTimes (a->num, b->num), NaturalTimes (a->den, b->den))); } static Value RationalDivide (Value av, Value bv, int expandOk) { ENTER (); Rational *a = &av->rational, *b = &bv->rational; Sign sign; if (NaturalZero (b->num)) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } sign = Positive; if (a->sign != b->sign) sign = Negative; RETURN (NewRational (sign, NaturalTimes (a->num, b->den), NaturalTimes (a->den, b->num))); } /* * Modulus for rational values. * * Sorta like for integers: * * c/d * (a/b | c/d) + a/b % c/d = a/b * * 0 <= a/b % c/d < abs (c/d) * a/b | c/d is an integer * * To calculate modulus (e/f): * * c/d * n + e/f = a/b * e/f = a/b - c/d * n * (e * b * d) / f = a * d - c * b * n * * therefore (e * b * d) / f is integer * * c * b * n + (e * b * d) / f = a * d * (e * b * d) / f = (a * d) % (c * b) * e / f = ((a * d) % (c * b)) / (b * d) */ static Value RationalMod (Value av, Value bv, int expandOk) { ENTER (); Rational *a = &av->rational, *b = &bv->rational; Natural *rem, *div; if (NaturalZero (b->num)) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } div = NaturalTimes (b->num, a->den); (void) NaturalDivide (NaturalTimes (a->num, b->den), div, &rem); if (a->sign == Negative && !NaturalZero (rem)) rem = NaturalMinus (div, rem); RETURN (NewRational (Positive, rem, NaturalTimes (a->den, b->den))); } static Value RationalLess (Value av, Value bv, int expandOk) { ENTER (); Rational *a = &av->rational, *b = &bv->rational; Rational *t; int ret; switch (catagorize_signs (a->sign, b->sign)) { case BothNegative: t = a; a = b; b = t; case BothPositive: if (!NaturalEqual (a->den, b->den)) ret = NaturalLess (NaturalTimes (a->num, b->den), NaturalTimes (b->num, a->den)); else ret = NaturalLess (a->num, b->num); break; case FirstPositive: ret = 0; break; case SecondPositive: ret = 1; break; default: abort(); } RETURN (ret ? TrueVal : FalseVal); } static Value RationalEqual (Value av, Value bv, int expandOk) { Rational *a = &av->rational, *b = &bv->rational; if (a->sign == b->sign && NaturalEqual (a->num, b->num) && NaturalEqual (a->den, b->den)) { return TrueVal; } return FalseVal; } static Value RationalNegate (Value av, int expandOk) { ENTER (); Rational *a = &av->rational; RETURN (NewRational (SignNegate (a->sign), a->num, a->den)); } static Value RationalFloor (Value av, int expandOk) { ENTER (); Rational *a = &av->rational; Natural *quo, *rem; quo = NaturalDivide (a->num, a->den, &rem); if (!NaturalZero (rem) && a->sign == Negative) quo = NaturalPlus (quo, one_natural); RETURN (NewInteger (a->sign, quo)); } static Value RationalCeil (Value av, int expandOk) { ENTER (); Rational *a = &av->rational; Natural *quo, *rem; quo = NaturalDivide (a->num, a->den, &rem); if (!NaturalZero (rem) && a->sign == Positive) quo = NaturalPlus (quo, one_natural); RETURN (NewInteger (a->sign, quo)); } static Value RationalPromote (Value av, Value bv) { ENTER (); switch (ValueTag(av)) { case rep_int: av = NewIntRational (ValueInt(av)); break; case rep_integer: av = NewIntegerRational (&av->integer); break; default: break; } RETURN (av); } static Value RationalReduce (Value av) { ENTER (); Rational *a = &av->rational; if (NaturalEqual (a->den, one_natural)) av = Reduce (NewInteger (a->sign, a->num)); RETURN (av); } static HashValue RationalHash (Value av) { Rational *a = &av->rational; return NaturalHash (a->den) ^ NaturalHash(a->num) ^ a->sign; } extern ValueRep IntegerRep; extern Natural *NaturalFactor (Natural *, Natural *); extern Natural *NaturalSqrt (Natural *); extern Natural *NaturalIntPow (Natural *, int); extern Natural *NaturalPow (Natural *, Natural *); extern Natural *NaturalPowMod (Natural *, Natural *, Natural *); extern Natural *two_natural; static Natural * NaturalPsi(Natural *a, Natural *max) { ENTER (); Natural *p; int n; Natural *ret; Natural *rem; Natural *next; Natural *pow; Natural *fact; ret = one_natural; while (!NaturalEqual (a, one_natural)) { p = NaturalFactor (a, max); if (!p) { ret = 0; break; } n = 0; for (;;) { next = NaturalDivide (a, p, &rem); if (!NaturalZero (rem)) break; a = next; n++; } pow = NaturalIntPow (p, n-1); fact = NaturalMinus (NaturalTimes (pow, p), pow); ret = NaturalTimes (ret, fact); if (max && NaturalLess (max, fact)) break; } RETURN (ret); } #if 0 static int IntSqrt (int a) { int l, h, m; l = 2; h = a/2; while ((h-l) > 1) { m = (h+l) >> 1; if (m * m < a) l = m; else h = m; } return h; } static int IntFactor (int a) { int v, lim; if (!a) return 0; if ((a & 1) == 0) return 2; lim = IntSqrt (a); for (v = 3; v <= lim; v += 2) { if (a % v == 0) return v; } return a; } static int IntPow (int a, int p) { int result; result = 1; while (p) { if (p & 1) result = result * a; p >>= 1; if (p) a = a * a; } return result; } static int IntPowMod (int a, int p, int m) { int result; if (m >= 32767) { #if DIGITBITS == 32 signed_digit la = a, lm = m, lr; lr = 1; while (p) { if (p & 1) lr = (lr * la) % lm; p >>= 1; if (p) la = (la * la) % lm; } result = (int) lr; #else ENTER (); result = NaturalToInt (NaturalPowMod (NewNatural (a), NewNatural (p), NewNatural (m))); EXIT (); #endif } else { result = 1; while (p) { if (p & 1) result = (result * a) % m; p >>= 1; if (p) a = (a * a) % m; } } return result; } static int IntPsi (int a) { int p; int n; int ret; ret = 1; while (a != 1) { p = IntFactor (a); n = 0; do { n++; a /= p; } while (a % p == 0); ret = ret * (IntPow (p, n-1) * (p - 1)); } return ret; } #endif typedef struct _partial { DataType *data; struct _partial *down; Natural *partial; int power; } Partial, *PartialPtr; static void PartialMark (void *object) { PartialPtr p = object; MemReference (p->partial); MemReference (p->down); } DataType PartialType = { PartialMark, 0, "PartialType" }; static PartialPtr NewPartial (Natural *partial) { ENTER (); PartialPtr p; if (!partial) RETURN (0); p = ALLOCATE (&PartialType, sizeof (Partial)); p->down = 0; p->partial = partial; p->power = 0; RETURN (p); } typedef struct _factor { DataType *data; struct _factor *next; Natural *prime; int power; PartialPtr partials; } Factor, *FactorPtr; static void FactorMark (void *object) { FactorPtr f = object; MemReference (f->prime); MemReference (f->next); MemReference (f->partials); } DataType FactorType = { FactorMark, 0, "FactorType" }; static FactorPtr NewFactor (Natural *prime, int power, FactorPtr next) { ENTER (); FactorPtr f; f = ALLOCATE (&FactorType, sizeof (Factor)); f->next = next; f->prime = prime; f->power = power; f->partials = 0; f->partials = NewPartial (prime); f->partials->power = 0; RETURN (f); } static FactorPtr GenerateFactors (Natural *n, Natural *max) { ENTER (); FactorPtr f = 0; Natural *p; Natural *largest; Natural *d, *rem; p = 0; largest = NaturalSqrt (n); while (!NaturalEqual (n, one_natural)) { int power = 1; for (;;) { if (!p) p = two_natural; else if (NaturalEqual (p, two_natural)) p = NewNatural (3); else p = NaturalPlus (p, two_natural); d = NaturalDivide (n, p, &rem); if (NaturalZero (rem)) break; if (max && NaturalLess (max, p)) RETURN(f); if (NaturalLess (largest, p)) RETURN (NewFactor (n, 1, f)); } n = d; for (;;) { d = NaturalDivide (n, p, &rem); if (!NaturalZero (rem)) break; n = d; power++; } f = NewFactor (p, power, f); largest = NaturalSqrt (n); } RETURN (f); } static Natural * FactorBump (FactorPtr f) { PartialPtr p, minp; Natural *factor; ENTER (); if (!f) RETURN(0); p = f->partials; if (!p) RETURN(0); minp = p; while (p->power) { if (!p->down) p->down = NewPartial (FactorBump (f->next)); p = p->down; if (!p) break; if (NaturalLess (p->partial, minp->partial)) minp = p; } if (!minp) RETURN(0); factor = minp->partial; if (minp->power < f->power) { minp->partial = NaturalTimes (minp->partial, f->prime); minp->power++; } else { f->partials = minp->down; } RETURN (factor); } static int RationalRepeatLength (int prec, Natural *nden, int ibase) { ENTER (); Natural *nbase; Natural *ndigits; FactorPtr factors; Natural *factor; int digits; Natural *max = 0; if (NaturalEqual (nden, one_natural)) return 0; if (prec > 0) max = NewNatural (prec); nbase = NewNatural (ibase); ndigits = NaturalPsi (nden, max); if (!ndigits) { factor = one_natural; for (factor = one_natural;; factor = NaturalPlus (factor, one_natural)) { if (NaturalEqual (NaturalPowMod (nbase, factor, nden), one_natural)) break; if (aborting) break; if (NaturalLess (max, factor)) { EXIT (); return -1; } } } else { factors = GenerateFactors (ndigits, max); if (aborting) return 0; factor = one_natural; while (factor) { if (NaturalEqual (NaturalPowMod (nbase, factor, nden), one_natural)) break; if (aborting) break; factor = FactorBump (factors); if (max && factor && NaturalLess (max, factor)) { EXIT (); return -1; } } } if (!factor) factor = ndigits; if (NaturalLess (max_int_natural, factor)) factor = max_int_natural; digits = NaturalToInt (factor); EXIT (); return digits; } static void CheckDecimalLength (int prec, Natural *nden, int ibase, int *initial, int *repeat) { ENTER (); Natural *rem; Natural *nbase; Natural *g; int offset; int rep; nbase = NewNatural (ibase); offset = 0; while (!NaturalEqual ((g = NaturalGcd (nden, nbase)), one_natural)) { if (aborting) { EXIT (); return; } offset++; if (prec >= 0 && offset > prec) break; nden = NaturalDivide (nden, g, &rem); } if (prec >= 0 && offset >= prec) { if (offset > prec) offset = -prec; else offset = prec; rep = 0; } else if (NaturalEqual (nden, one_natural)) { rep = 0; } else { if (prec >= 0) prec -= offset; rep = RationalRepeatLength (prec, nden, ibase); } *initial = offset; *repeat = rep; EXIT (); } static Bool RationalDecimalPrint (Value f, Value rv, char format, int base, int width, int prec, int fill) { ENTER (); Rational *r = &rv->rational; Natural *quo; Natural *partial; Natural *rep, *init; Natural *dig; int exponent = 0; int exponent_width = 0; char *initial = 0, *in; char *repeat = 0, *re; char *whole; int initial_width, repeat_width = 0; int frac_width; int rep_width, brace_width = 0, dot_width = 0; int whole_width; int fraction_width; int print_width; int min_prec; Bool use_braces = True; min_prec = 0; if (format == 'f' || format == 'e' || format == 'g') { min_prec = prec; use_braces = False; } if (prec == DEFAULT_OUTPUT_PRECISION) { min_prec = 0; prec = 15; } else if (prec == INFINITE_OUTPUT_PRECISION) prec = -1; dig = NewNatural (base); /* * Check for small numbers for 'e' format */ if (NaturalLess (r->num, r->den) && !NaturalZero(r->num)) { Natural *quo, *rem; Natural *mag; int bits; if (format == 'e' || (format == 'g' && prec > 0)) { quo = NaturalDivide (r->den, r->num, &rem); bits = NaturalWidth (quo); exponent = (int) ((double) bits / (log ((double) base) / log (2.0))); if (exponent < 0) exponent = 0; mag = NaturalIntPow (dig, exponent); while (NaturalLess (mag, quo)) { mag = NaturalTimes (mag, dig); exponent++; } if (format == 'g' && prec > 0) if (prec - exponent < 3) format = 'e'; if (format == 'e') { int ev; rv = RationalTimes (rv, NewRational (Positive, mag, one_natural), True); r = &rv->rational; exponent_width = 3; ev = exponent; while (ev >= base) { exponent_width++; ev /= base; } exponent = -exponent; } else exponent = 0; } else exponent = 0; } CheckDecimalLength (prec, r->den, base, &initial_width, &repeat_width); if (aborting) { EXIT (); return False; } if ((rep_width = repeat_width)) { /* * When using %f format, just fill the * result with digits */ if (!use_braces && prec != -1) { initial_width = -prec; repeat_width = 0; rep_width = 0; } else { if (repeat_width < 0) rep_width = prec - initial_width; } } if (initial_width) { Natural *half_digit; if (initial_width < 0) { initial_width = -initial_width; half_digit = NaturalTimes (NaturalIntPow (dig, initial_width), two_natural); rv = RationalPlusHelper (r->sign, r, &NewRational (Positive, one_natural, half_digit)->rational); r = &rv->rational; } else { if (!repeat_width && initial_width < min_prec) initial_width = min_prec; } initial = malloc (initial_width + 1); if (!initial) { EXIT (); return False; } } quo = NaturalDivide (r->num, r->den, &partial); whole = NaturalSprint (0, quo, base, &whole_width); brace_width = 0; if (repeat_width) { brace_width++; if (repeat_width > 0) brace_width++; } dot_width = 0; if (initial_width + rep_width) dot_width = 1; /* * Compute how much space is available for the fractional part */ if (width) { if (width < 0) fraction_width = -width; else fraction_width = width; fraction_width = fraction_width - (whole_width + exponent_width); if (fraction_width < 0) fraction_width = 0; if (prec > 0 && fraction_width > prec + dot_width) fraction_width = prec + dot_width; } else if (prec > 0) fraction_width = prec + dot_width; else fraction_width = -1; /* * Start paring down parts of the output to fit the desired size */ while (fraction_width >= 0 && (frac_width = dot_width + initial_width + rep_width + brace_width) && frac_width > fraction_width) { if (rep_width) { if (brace_width > 1) { brace_width = 1; repeat_width = -repeat_width; } rep_width = fraction_width - (dot_width + initial_width + brace_width); if (rep_width < 0) { rep_width = 0; } } else if (brace_width) brace_width = 0; else if (initial_width) { initial_width = fraction_width - dot_width; if (initial_width < 0) initial_width = 0; } else dot_width = 0; } if (initial_width) { init = NaturalDivide (NaturalTimes (partial, NaturalIntPow (dig, initial_width)), r->den, &partial); if (aborting) { free (initial); EXIT (); return False; } in = NaturalSprint (initial + initial_width + 1, init, base, &initial_width); if (!in) { free (initial); EXIT (); return False; } while (in > initial) { *--in = '0'; ++initial_width; } } if (rep_width) { #define MAX_SENSIBLE 10000000 if (rep_width > MAX_SENSIBLE) { repeat_width = -1; rep_width = MAX_SENSIBLE; } /* * allocate the output buffer; keep trying until this works */ while (!(repeat = malloc (rep_width + 1))) { repeat_width = -1; rep_width >>= 1; } rep = NaturalDivide (NaturalTimes (partial, NaturalIntPow (dig, rep_width)), r->den, &partial); if (aborting) { free (initial); free (repeat); EXIT (); return False; } re = NaturalSprint (repeat + rep_width + 1, rep, base, &rep_width); if (!re) { free (initial); free (repeat); EXIT (); return False; } while (re > repeat) { *--re = '0'; ++rep_width; } if (use_braces) { rep_width++; /* open { */ if (repeat_width > 0) rep_width++; /* close } */ } } fraction_width = initial_width + rep_width; print_width = whole_width + 1 + fraction_width + exponent_width; if (r->sign == Negative) print_width = print_width + 1; while (width > print_width) { FileOutchar (f, fill); width--; } if (r->sign == Negative) FileOutput (f, '-'); FilePuts (f, whole); FileOutput (f, '.'); if (initial_width) { FilePuts (f, initial); free (initial); } if (rep_width) { if (use_braces) FileOutput (f, '{'); FilePuts (f, repeat); free (repeat); if (use_braces && repeat_width > 0) FileOutput (f, '}'); } if (exponent) { FilePrintf (f, "e%d", exponent); } while (-width > print_width) { FileOutchar (f, fill); width++; } EXIT (); return True; } static Bool RationalPrint (Value f, Value rv, char format, int base, int width, int prec, int fill) { Rational *r = &rv->rational; char *num, *num_base, *den, *den_base; int num_width, den_width; int print_width; Bool ret = True; if (base == 0) base = 10; switch (format) { case 'v': num_width = NaturalEstimateLength (r->num, base); num_base = malloc (num_width); num = NaturalSprint (num_base + num_width, r->num, base, &num_width); if (!num) { free (num_base); ret = False; break; } den_width = NaturalEstimateLength (r->den, base); den_base = malloc (den_width); den = NaturalSprint (den_base + den_width, r->den, base, &den_width); if (!den) { free (num_base); free (den_base); ret = False; break; } print_width = 1 + num_width + 1 + den_width + 1; if (r->sign == Negative) print_width++; while (width > print_width) { FileOutchar (f, fill); width--; } FileOutput (f, '('); if (r->sign == Negative) FileOutput (f, '-'); FilePuts (f, num); FileOutput (f, '/'); FilePuts (f, den); FileOutput (f, ')'); free (num_base); free (den_base); while (-width > print_width) { FileOutchar (f, fill); width++; } break; default: ret = RationalDecimalPrint (f, rv, format, base, width, prec, fill); break; } return ret; } static void RationalMark (void *object) { Rational *rational = object; MemReference (rational->num); MemReference (rational->den); } ValueRep RationalRep = { { RationalMark, 0, "RationalRep" }, /* base */ rep_rational, /* tag */ { /* binary */ RationalPlus, RationalMinus, RationalTimes, RationalDivide, NumericDiv, RationalMod, RationalLess, RationalEqual, 0, 0, }, { /* unary */ RationalNegate, RationalFloor, RationalCeil, }, RationalPromote, RationalReduce, RationalPrint, 0, RationalHash, }; Value NewRational (Sign sign, Natural *num, Natural *den) { ENTER (); Value ret; Natural *g; Natural *rem; if (NaturalZero (num)) den = one_natural; else { if (NaturalLength(den) != 1 || NaturalDigits(den)[0] != 1) { g = NaturalGcd (num, den); if (NaturalLength (g) != 1 || NaturalDigits(g)[0] != 1) { num = NaturalDivide (num, g, &rem); den = NaturalDivide (den, g, &rem); } } } ret = ALLOCATE (&RationalRep.data, sizeof (Rational)); ret->rational.sign = sign; ret->rational.num = num; ret->rational.den = den; RETURN (ret); } Value NewIntRational (int i) { ENTER (); if (i < 0) RETURN (NewRational (Negative, NewNatural ((unsigned) -i), one_natural)); else RETURN (NewRational (Positive, NewNatural ((unsigned) i), one_natural)); } Value NewIntegerRational (Integer *i) { ENTER (); RETURN (NewRational (IntegerSign((Value) i), IntegerMag((Value) i), one_natural)); } nickle_2.81.orig/hash.c0000664000175000000620000002335410770315535014204 0ustar keithpstaff/* $Header$ */ /* * Copyright © 2003 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" /* * From Knuth -- a good choice for hash/rehash values is p, p-2 where * p and p-2 are both prime. These tables are sized to have an extra 10% * free to avoid exponential performance degradation as the hash table fills */ static HashSetRec hashSets[] = { { 2, 5, 3 }, { 4, 7, 5 }, { 8, 13, 11 }, { 16, 19, 17 }, { 32, 43, 41 }, { 64, 73, 71 }, { 128, 151, 149 }, { 256, 283, 281 }, { 512, 571, 569 }, { 1024, 1153, 1151 }, { 2048, 2269, 2267 }, { 4096, 4519, 4517 }, { 8192, 9013, 9011 }, { 16384, 18043, 18041 }, { 32768, 36109, 36107 }, { 65536, 72091, 72089 }, { 131072, 144409, 144407 }, { 262144, 288361, 288359 }, { 524288, 576883, 576881 }, { 1048576, 1153459, 1153457 }, { 2097152, 2307163, 2307161 }, { 4194304, 4613893, 4613891 }, { 8388608, 9227641, 9227639 }, { 16777216, 18455029, 18455027 }, { 33554432, 36911011, 36911009 }, { 67108864, 73819861, 73819859 }, { 134217728, 147639589, 147639587 }, { 268435456, 295279081, 295279079 }, { 536870912, 590559793, 590559791 }, { 1073741824, 1181116273, 1181116271}, { 2147483648ul, 2362232233ul, 2362232231ul} }; #define NHASHSETS (sizeof(hashSets)/sizeof(hashSets[0])) static Value * Find (HashTablePtr ht, Value hash, Value key) { HashSetPtr hs = ht->hashSet; HashValue size = hs->size; HashValue h = ValueInt (hash); HashValue elt = h % size; HashValue step = 0; Value *elts = BoxElements (ht->elts); Value *er, *del = 0; for (;;) { er = &elts[elt * HashEltSize]; if (!HashEltKey(er)) { /* check for a deleted entry */ if (HashEltValue (er)) { /* save first deleted entry found */ if (!del) del = er; else if (er == del) break; } else { /* pull reference as far forward on the chain as posible */ if (del) er = del; break; } } else if (HashEltHash(er) == hash && Equal(HashEltKey(er), key) == TrueVal) { break; } if (!step) { step = h % hs->rehash; if (!step) step = 1; } elt += step; if (elt >= size) elt -= size; } return er; } static void Rehash (BoxPtr old, HashTablePtr ht) { Value *o, *n; HashValue h; o = BoxElements (old); ht->count = 0; for (h = old->nvalues / HashEltSize; h > 0; h--) { if (HashEltValid (o)) { /* XXX must rewrite references */ n = Find (ht, HashEltHash(o), HashEltKey(o)); HashEltCopy (n, o); ht->count++; } HashEltStep (o); } } static void Resize (HashTablePtr ht, const HashSetPtr hs) { ENTER (); BoxPtr old; if (ht->hashSet == hs) return; old = ht->elts; ht->elts = NewBox (False, False, hs->size * HashEltSize, ht->type); ht->hashSet = hs; if (old) Rehash (old, ht); EXIT (); } #if HAVE_STDINT_H typedef uint32_t crc32_t; #else typedef unsigned int crc32_t; #endif static crc32_t crc32_table[256]; static void generate_crc32_table(void) { crc32_t c, p; int n, m; p = 0xedb88320; for (n = 0; n < 256; n++) { c = n; for (m = 0; m < 8; m++) c = (c >> 1) ^ ((c & 1) ? p : 0); crc32_table[n] = c; } } HashValue HashCrc32 (unsigned char *bytes, int nbytes) { crc32_t crc32 = ~0; if (crc32_table[1] == 0) abort (); while (nbytes--) crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *bytes++) & 0xff]; return (HashValue) ~crc32; } int HashInit (void) { generate_crc32_table (); return 1; } static Value HashEqual (Value av, Value bv, int expandOk) { HashTable *at = &av->hash; HashTable *bt = &bv->hash; HashValue i; Value *ae, *be; /* if they have different numbers of valid elements, they're not equal */ if (at->count != bt->count) return FalseVal; ae = BoxElements (at->elts); for (i = 0; i < at->hashSet->size; i++) { if (HashEltValid (ae)) { be = Find (bt, HashEltHash(ae), HashEltKey (ae)); if (!be || !HashEltValid (be)) return FalseVal; if (Equal (HashEltValue (be), HashEltValue (ae)) != TrueVal) return FalseVal; } HashEltStep (ae); } return TrueVal; } static Bool HashPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { HashTable *ht = &av->hash; HashValue h; Value *e; Bool first = True; Bool pretty = format == 'v' || format == 'g'; if (pretty) { FilePuts (f, "("); FilePutBaseType (f, ht->type, False); FilePuts (f, " "); FilePuts (f, "["); FilePutType (f, ht->keyType, False); FilePuts (f, "]"); FilePutSubscriptType (f, ht->type, False); FilePuts (f, ") {"); } e = BoxElements (ht->elts); for (h = ht->hashSet->size; h-- > 0; ) { if (HashEltValid (e)) { if (pretty) { if (!first) FilePuts (f, ", "); else FilePuts (f, " "); Print (f, HashEltKey (e), format, base, width, prec, fill); FilePuts (f, " => "); } else if (!first) FilePuts (f, " "); Print (f, HashEltValue (e), format, base, width, prec, fill); first = False; } HashEltStep (e); } if (pretty) { if (ht->def) { if (!first) FilePuts (f, ","); FilePuts (f, " => "); Print (f, ht->def, format, base, width, prec, fill); first = False; } if (!first) FilePuts (f, " "); FilePuts (f, "}"); } return True; } static HashValue HashHash (Value av) { HashTable *ht = &av->hash; HashValue h; Value *e; HashValue hash = 0; e = BoxElements (ht->elts); for (h = ht->hashSet->size; h-- > 0; ) { if (HashEltValue (e)) hash ^= ValueInt (HashEltHash (e)); HashEltStep (e); } return hash; } static void HashMark (void *object) { HashTable *ht = (HashTable *) object; MemReference (ht->type); MemReference (ht->keyType); MemReference (ht->elts); MemReference (ht->def); } ValueRep HashRep = { { HashMark, 0, "HashRep" }, rep_hash, { 0, 0, 0, 0, 0, 0, 0, HashEqual, 0, 0, }, { 0, }, 0, 0, HashPrint, 0, HashHash, }; Value NewHash (Bool constant, TypePtr keyType, TypePtr type) { ENTER (); Value ret = ALLOCATE (&HashRep.data, sizeof (HashTable)); ret->hash.hashSet = 0; ret->hash.count = 0; ret->hash.type = type; ret->hash.keyType = keyType; ret->hash.elts = 0; ret->hash.def = 0; Resize (&ret->hash, &hashSets[0]); RETURN (ret); } Value HashGet (Value hv, Value key) { HashTablePtr ht = &hv->hash; Value hash = ValueHash (key); Value *he; Value value; he = Find (ht, hash, key); if (!HashEltValid (he)) { if (!ht->def) { RaiseStandardException (exception_uninitialized_value, 0); return (Void); } if (ht->count >= ht->hashSet->entries && ht->hashSet != &hashSets[NHASHSETS - 1]) { Resize (ht, ht->hashSet + 1); } ht->count++; HashEltHash(he) = hash; HashEltKey(he) = Copy (key); HashEltValue(he) = Copy(ht->def); } value = HashEltValue (he); if (!value) { RaiseStandardException (exception_uninitialized_value, 0); return (Void); } return value; } void HashSet (Value hv, Value key, Value value) { HashTablePtr ht = &hv->hash; Value hash = ValueHash (key); Value *he; if (ht->count >= ht->hashSet->entries && ht->hashSet != &hashSets[NHASHSETS - 1]) { Resize (ht, ht->hashSet + 1); } he = Find (ht, hash, key); if (!HashEltValid (he)) ht->count++; HashEltHash (he) = hash; HashEltKey (he) = Copy (key); HashEltValue (he) = Copy (value); } void HashSetDef (Value hv, Value def) { HashTablePtr ht = &hv->hash; ht->def = Copy(def); } Value HashRef (Value hv, Value key) { ENTER (); HashTablePtr ht = &hv->hash; Value *he; Value hash = ValueHash (key); if (ht->count == ht->hashSet->entries && ht->hashSet != &hashSets[NHASHSETS - 1]) { Resize (ht, ht->hashSet + 1); } he = Find (ht, hash, key); if (!HashEltValid (he)) { ht->count++; HashEltHash (he) = hash; HashEltKey (he) = Copy (key); if (ht->def) HashEltValue (he) = Copy(ht->def); } RETURN (NewRef (ht->elts, &HashEltValue(he) - BoxElements (ht->elts))); } Value HashTest (Value hv, Value key) { HashTablePtr ht = &hv->hash; Value *he; Value hash = ValueHash (key); he = Find (ht, hash, key); return HashEltValid (he) ? TrueVal : FalseVal; } void HashDelete (Value hv, Value key) { HashTablePtr ht = &hv->hash; Value *he; Value hash = ValueHash (key); he = Find (ht, hash, key); if (HashEltValid (he)) { /* mark this entry as deleted -- value Void, key NULL */ HashEltHash (he) = 0; HashEltKey (he) = 0; HashEltValue (he) = Void; --ht->count; } } Value HashKeys (Value hv) { ENTER (); HashTablePtr ht = &hv->hash; int dim = ht->count; Value keys = NewArray (False, True, ht->keyType, 1, &dim); HashValue h; int i = 0; Value *e = BoxElements (ht->elts); for (h = ht->hashSet->size; h > 0; h--) { if (HashEltValid (e)) { ArrayValueSet (&keys->array, i, HashEltKey (e)); i++; } HashEltStep (e); } if (i != dim) ArrayResize (keys, 0, i); RETURN (keys); } Value HashCopy (Value hv) { ENTER (); Value new = NewHash (False, hv->hash.keyType, hv->hash.type); new->hash.def = hv->hash.def; Resize (&new->hash, hv->hash.hashSet); Rehash (hv->hash.elts, &new->hash); RETURN (new); } nickle_2.81.orig/skiplist.5c0000664000175000000620000001152211716630063015177 0ustar keithpstaff/* $Header$ */ /* * Copyright © 2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ autoload PRNG; namespace Skiplist { public typedef bool (poly a, poly b) Greater; public typedef void (poly a) Visit; public exception not_found (poly missing); /* * Private representation of an element */ typedef Element; typedef union { *Element element; void nil; } ElementPtr; const MaxLevel = 16; typedef struct { poly value; ElementPtr[*] forward; } Element; typedef struct { int level; Greater greater; Element header; } SkipRec; public typedef *SkipRec Skip; int random_level () /* * This uses a fixed probability of 1/4 for each level */ { int bits = PRNG::randbits(MaxLevel * 2); int level = 0; while (++level < MaxLevel) { if ((bits & 3) != 0) break; bits >>= 2; } return level; } public Skip new (Greater greater) /* * Allocate a new list with 'greater' as the ordering function */ { return &(SkipRec) { .level = 0, .greater = greater, .header = { .forward = (ElementPtr[MaxLevel]) { [i] = ElementPtr.nil }, .value = <> } }; } public poly search (Skip list, poly value) /* * Search 'list' for 'value', returning a * matching value in the list else Raise 'not_found'. */ { ElementPtr x = (ElementPtr.element) &list->header; for (int i = list->level; --i >= 0; ) { while (x.element->forward[i] != ElementPtr.nil && list->greater (value, x.element->forward[i].element->value)) x = x.element->forward[i]; } x = x.element->forward[0]; if (x == ElementPtr.nil || list->greater (x.element->value, value)) raise not_found (value); return x.element->value; } public void insert (Skip list, poly value) /* * Insert 'value' into 'list' */ { ElementPtr[MaxLevel] update = {}; ElementPtr x = (ElementPtr.element) &list->header; for (int i = list->level; --i >= 0;) { while (x.element->forward[i] != ElementPtr.nil && list->greater (value, x.element->forward[i].element->value)) x = x.element->forward[i]; update[i] = x; } x = x.element->forward[0]; int level = random_level (); if (level > list->level) { level = list->level + 1; list->level = level; update[level-1] = (ElementPtr.element) &list->header; } /* * Allocate new list entry */ ElementPtr new = (ElementPtr.element) &(Element) { .value = value, .forward = (ElementPtr[level]) {} }; for (int i = 0; i < level; i++) { new.element->forward[i] = update[i].element->forward[i]; update[i].element->forward[i] = new; } } public void delete (Skip list, poly value) /* * delete entry matching 'value' from 'list', else * raise not_found. */ { ElementPtr[MaxLevel] update = {}; ElementPtr x = (ElementPtr.element) &list->header; for (int i = list->level; --i >= 0;) { while (x.element->forward[i] != ElementPtr.nil && list->greater (value, x.element->forward[i].element->value)) x = x.element->forward[i]; update[i] = x; } x = x.element->forward[0]; if (x == ElementPtr.nil || list->greater (x.element->value, value)) raise not_found (value); for (int i = 0; i < list->level && update[i].element->forward[i] == x; i++) { update[i].element->forward[i] = x.element->forward[i]; } while (list->level > 0 && list->header.forward[list->level-1] == ElementPtr.nil) list->level--; } public void walk (Skip list, Visit visit) /* * Invoke 'visit' for each element of 'list'. * Operations on */ { for (ElementPtr e = list->header.forward[0]; e != ElementPtr.nil; e = (ElementPtr next)) { next = e.element->forward[0]; visit (e.element->value); } } public bool (&poly) iterate (Skip list) { ElementPtr e = list->header.forward[0]; bool next (&poly value) { if (e == ElementPtr.nil) return false; value = e.element->value; e = e.element->forward[0]; return true; } return next; } public int length (Skip list) { int len = 0; for (ElementPtr e = list->header.forward[0]; e != ElementPtr.nil; e = e.element->forward[0]) { len++; } return len; } public int storage (Skip list, poly value) { ElementPtr x = (ElementPtr.element) &list->header; for (int i = list->level; --i >= 0;) { while (x.element->forward[i] != ElementPtr.nil && list->greater (value, x.element->forward[i].element->value)) x = x.element->forward[i]; } x = x.element->forward[0]; if (x == ElementPtr.nil || list->greater (x.element->value, value)) raise not_found (value); return dim (x.element->forward); } } namespace Sortlist { public import Skiplist; } nickle_2.81.orig/builtin-sockets.c0000664000175000000620000003324313202404005016356 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * sockets.c * * provide builtin functions for the Socket namespace */ #include #include #include #include #include #ifndef SUN_LEN #define SUN_LEN(ptr) \ (sizeof(*(ptr)) - sizeof((ptr)->sun_path) + strlen((ptr)->sun_path) + 1) #endif #include #include #include #include #include "builtin.h" #include NamespacePtr SocketNamespace; Type *typeSockaddr; Value do_Socket_create (int num, Value *args); Value do_Socket_connect (int num, Value *args); Value do_Socket_bind (int numb, Value *args); Value do_Socket_listen (Value s, Value backlog); Value do_Socket_accept (Value s); Value do_Socket_shutdown (Value s, Value how); Value do_Socket_gethostname (void); Value do_Socket_getsockname (Value s); void import_Socket_namespace() { ENTER (); static const struct fbuiltin_0 funcs_0[] = { { do_Socket_gethostname, "gethostname", "s", "", "\n" " string gethostname ()\n" "\n" " Get the current hostname.\n" }, { 0 }, }; static const struct fbuiltin_1 funcs_1[] = { { do_Socket_accept, "accept", "f", "f", "\n" " file accept (file listen)\n" "\n" " Return a socket for the next connection on 'listen'.\n" }, { do_Socket_getsockname, "getsockname", "a", "f", "\n" " sockaddr getsockname (file socket)\n" "\n" " Returns the address and port of 'socket'.\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_Socket_listen, "listen", "v", "fi", "\n" " void listen (file socket, int length)\n" "\n" " Establish a listen queue on 'f' of length 'i' (max 5).\n" }, { do_Socket_shutdown, "shutdown", "v", "fi", "\n" " void shutdown (file socket, int dir)\n" "\n" " Shut communication in 'dir' direction:\n" " SHUT_RD: shut down reading.\n" " SHUT_WR: shut down writing.\n" " SHUT_RDWR: shut down reading and writing.\n" }, { 0 } }; static const struct fbuiltin_v funcs_v[] = { { do_Socket_create, "create", "f", ".i", "\n" " file create ([int family], int type)\n" "\n" " Create a socket where the optional 'family' is one of:\n" " AF_UNIX: Local communication.\n" " AF_INET (default): IPv4 Internet protocols.\n" " AF_INET6: IPv6 Internet protocols.\n" " and where 'type' is one of:\n" " SOCK_STREAM: a stream socket.\n" " SOCK_DGRAM: a datagram socket.\n" }, { do_Socket_bind, "bind", "v", "f.p", "\n" " void bind (file socket, string host, string port)\n" " void bind (file socket, string host, int port)\n" "\n" " Bind AF_INET 'socket' to 'host', 'port'.\n" "\n" " void bind (file socket, string local_socket)\n" "\n" " Bind AF_UNIX 'socket' to 'localhost'.\n" }, { do_Socket_connect, "connect", "v", "f.p", "\n" " void connect (file socket, string host, string port)\n" " void connect (file socket, string host, int port)\n" "\n" " Connect AF_INET 'socket' to 'host', 'port'.\n" "\n" " void connect (file socket, string local_socket)\n" "\n" " Connect AF_UNIX 'socket' to 'local_socket'.\n" }, { 0 } }; static const struct ibuiltin ivars[] = { { AF_UNIX, "AF_UNIX", &SocketNamespace }, { AF_INET, "AF_INET", &SocketNamespace }, #ifdef AF_INET6 { AF_INET6, "AF_INET6", &SocketNamespace }, #endif { SOCK_STREAM, "SOCK_STREAM", &SocketNamespace }, { SOCK_DGRAM, "SOCK_DGRAM", &SocketNamespace }, { SHUT_RD, "SHUT_RD", &SocketNamespace }, { SHUT_WR, "SHUT_WR", &SocketNamespace }, { SHUT_RDWR, "SHUT_RDWR", &SocketNamespace }, { 0 } }; static const struct sbuiltin svars[] = { { "0.0.0.0", "INADDR_ANY", &SocketNamespace }, { "127.0.0.1", "INADDR_LOOPBACK", &SocketNamespace }, { "255.255.255.255", "INADDR_BROADCAST", &SocketNamespace }, { 0 } }; SymbolPtr sym; Type *type; SocketNamespace = BuiltinNamespace (/*parent*/ 0, "Socket")->namespace.namespace; type = BuildStructType (2, typePrim[rep_integer], "addr", typePrim[rep_integer], "port"); sym = NewSymbolType (AtomId ("sockaddr"), type); typeSockaddr = NewTypeName (NewExprAtom (AtomId ("sockaddr"), 0, False), sym); NamespaceAddName (SocketNamespace, sym, publish_public); BuiltinFuncs0 (&SocketNamespace, funcs_0); BuiltinFuncs1 (&SocketNamespace, funcs_1); BuiltinFuncs2 (&SocketNamespace, funcs_2); BuiltinFuncsV (&SocketNamespace, funcs_v); BuiltinIntegers (ivars); BuiltinStrings (svars); EXIT (); } /* File::file do_Socket_create ({SOCK_STREAM,SOCK_DGRAM} type); */ Value do_Socket_create (int num, Value *args) { ENTER (); int ifamily, itype, type_index, s; Value ret; if (num == 0 || num > 2) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("create must have one or two arguments"), NewInt (0), NewInt (num)); RETURN (Void); } if (num > 1) { ifamily = IntPart (args[0], "Illegal address family"); type_index = 1; } else { ifamily = AF_INET; type_index = 0; } itype = IntPart (args[type_index], "Illegal socket type"); if (aborting) RETURN (Void); s = socket (ifamily, itype, 0); if (s == -1) RETURN (Void); ret = FileCreate (s, FileReadable|FileWritable); ret->file.sock_family = ifamily; RETURN (ret); } #ifdef PATH_MAX #define UN_SOCK_MAX PATH_MAX #else #define UN_SOCK_MAX 4096 #endif typedef union { struct sockaddr_in in; struct sockaddr_un un; struct sockaddr addr; struct { struct sockaddr_un un; char path[UN_SOCK_MAX]; } align; } sockaddr_all_t; #define VerifyArgumentCount(arg, condition, error) \ if (! (condition)) { \ RaiseStandardException (exception_invalid_argument, 3, \ NewStrString (error), NewInt (0), NewInt (arg)); \ } /* Supports the following args from both bind and connect: * (File::file s, String local_socket) */ static Bool address_lookup_af_unix (int num, Value *args, struct sockaddr_un *addr, socklen_t *len) { char *local_socket; Value s = args[0]; VerifyArgumentCount (num, num == 2, "must have 2 arguments for an AF_UNIX socket"); if (aborting) return False; local_socket = StrzPart (args[1], "invalid local_socket"); if (!local_socket || *local_socket == '\0') return False; if (strlen (local_socket) > UN_SOCK_MAX) return False; addr->sun_family = s->file.sock_family; strcpy (addr->sun_path, local_socket); *len = SUN_LEN (addr); return True; } /* Supports the following args from both bind and connect: * (File::file s, String host, String port) * (File::file s, String host, int port) */ static Bool address_lookup_af_inet (int num, Value *args, struct sockaddr_in *addr, socklen_t *len) { Value host, port; char *hostchars; struct hostent *hostent; long int portnum; struct servent *portent; char *endptr; Value s = args[0]; VerifyArgumentCount (num, num == 3, "must have 3 arguments for an AF_INET socket"); if (aborting) return False; host = args[1]; port = args[2]; hostchars = StrzPart (host, "invalid hostname"); if (!hostchars || *hostchars == '\0') return False; if (ValueIsString (port)) { char *portchars = StrzPart (port, "invalid port string"); if (!portchars || *portchars == '\0') return False; portnum = strtol (portchars, &endptr, /* base */ 10); if (*endptr != '\0') /* non-numeric port specification */ { /* FIXME: this should not always be "tcp"! */ portent = getservbyname (portchars, "tcp"); if (portent == 0) return False; /* FIXME: more here? */ addr->sin_port = portent->s_port; } if (portnum <= 0 || portnum >= (1 << 16)) return False; /* FIXME: more here? */ } else { portnum = IntPart (port, "invalid port value"); if (portnum <= 0 || portnum >= (1 << 16)) return False; /* FIXME: more here? */ } addr->sin_family = s->file.sock_family; addr->sin_port = htons (portnum); /* host lookup */ hostent = gethostbyname (hostchars); if (hostent == 0) { return False; /* FIXME: more here? */ } *len = sizeof (*addr); memcpy (&addr->sin_addr.s_addr, hostent->h_addr_list[0], sizeof (addr->sin_addr.s_addr)); return True; } /* Supports the following args from both bind and connect: * * (File::file s, String host, String port) * (File::file s, String host, int port) * (File::file s, String local_socket) */ static Bool address_lookup (int num, Value *args, sockaddr_all_t *addr, socklen_t *len) { Value s = args[0]; switch (s->file.sock_family) { case AF_UNIX: return address_lookup_af_unix (num, args, &addr->un, len); case AF_INET: return address_lookup_af_inet (num, args, &addr->in, len); #ifdef AF_INET6 case AF_INET6: /* FIXME */ #endif default: return False; } } /* void do_Socket_connect (File::file s, String host, String port); * void do_Socket_connect (File::file s, String host, int port); * void do_Socket_connect (File::file s, String local_socket; */ Value do_Socket_connect (int num, Value *args) { ENTER (); sockaddr_all_t addr; socklen_t len; Value s = args[0]; if (!address_lookup (num, args, &addr, &len)) RETURN (Void); if (!running->thread.partial) { int flags = fcntl (s->file.fd, F_GETFL); int n, err; flags |= O_NONBLOCK; fcntl (s->file.fd, F_SETFL, flags); #ifdef SO_BROADCAST { int one = 1; setsockopt (s->file.fd, SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof (int)); } #endif n = connect (s->file.fd, &addr.addr, len); flags &= ~O_NONBLOCK; fcntl (s->file.fd, F_SETFL, flags); err = errno; if (n == -1) { if (err == EWOULDBLOCK || err == EINPROGRESS) { FileSetBlocked (s, FileOutputBlocked); running->thread.partial = 1; } else { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (err), FileGetError (err), s); RETURN (Void); } } } if (s->file.flags & FileOutputBlocked) { ThreadSleep (running, s, PriorityIo); RETURN (Void); } complete = True; RETURN (Void); } /* void do_Socket_bind (File::file s, String host, String port); * void do_Socket_bind (File::file s, String host, int port); * void do_Socket_bind (File::file s, String local_socket; */ Value do_Socket_bind (int num, Value *args) { ENTER (); sockaddr_all_t addr; socklen_t len; Value s = args[0]; if (!address_lookup (num, args, &addr, &len)) RETURN (Void); #ifdef SO_REUSEADDR { int one = 1; setsockopt (s->file.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (int)); } #endif if (bind (s->file.fd, &addr.addr, len) == -1) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (errno), FileGetError (errno), s); RETURN (Void); } RETURN (Void); } /* void do_Socket_listen (File::file s, int backlog); */ Value do_Socket_listen (Value s, Value backlog) { ENTER (); int ibacklog; ibacklog = IntPart (backlog, "Illegal backlog length"); if (aborting) RETURN (Void); if (listen (s->file.fd, ibacklog) == -1) { RETURN (Void); /* FIXME: more here? */ } RETURN (Void); } /* File::file do_Socket_accept (File::file s); */ Value do_Socket_accept (Value s) { ENTER (); int f, err; int flags = fcntl (s->file.fd, F_GETFL); flags |= O_NONBLOCK; fcntl (s->file.fd, F_SETFL, flags); f = accept (s->file.fd, 0, 0); flags &= ~O_NONBLOCK; fcntl (s->file.fd, F_SETFL, flags); err = errno; if (f == -1) { if (err == EWOULDBLOCK || err == EAGAIN) { FileSetBlocked (s, FileInputBlocked); running->thread.partial = 1; } else { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (err), FileGetError (err), s); RETURN (Void); } } if (s->file.flags & FileInputBlocked) { ThreadSleep (running, s, PriorityIo); RETURN (Void); } complete = True; RETURN (FileCreate (f, FileReadable|FileWritable)); } /* void do_Socket_shutdown (File::file s, {SHUT_RD,SHUT_WR,SHUT_RDWR} how); */ Value do_Socket_shutdown (Value s, Value how) { ENTER (); int ihow; ihow = IntPart (how, "Illegal socket shutdown request"); if (aborting) RETURN (Void); if (shutdown (s->file.fd, ihow) == -1) { RETURN (Void); /* FIXME: more here? */ } RETURN (Void); } Value do_Socket_gethostname (void) { ENTER (); #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 255 #endif char hostname[HOST_NAME_MAX+1]; if (gethostname (hostname, sizeof (hostname)) == -1) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (errno), FileGetError (errno), Void); RETURN (Void); } /* null termination is not promised */ hostname[HOST_NAME_MAX] = '\0'; RETURN (NewStrString (hostname)); } Value do_Socket_getsockname (Value s) { ENTER (); struct sockaddr_in addr; socklen_t len = sizeof (addr); Value ret; BoxPtr box; if (getsockname (s->file.fd, (struct sockaddr *) &addr, &len) == -1) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (errno), FileGetError (errno), s); RETURN (Void); } ret = NewStruct (TypeCanon (typeSockaddr)->structs.structs, False); box = ret->structs.values; BoxValueSet (box, 0, NewInteger (Positive, NewNatural (ntohl (addr.sin_addr.s_addr)))); BoxValueSet (box, 1, NewInt (ntohs (addr.sin_port))); RETURN (ret); } nickle_2.81.orig/README.name0000664000175000000620000000666710414112462014711 0ustar keithpstaffThe Naming Of Nickle Keith Packard's original calculator language of 15 years ago was called "ic", for "interpreted C", based on his earlier "ec" inline compiler and runtime for arbitrary-precision rationals integrable with C code. At some point, the language name was upgraded to "Nick" (whether for "New IC of Keith's" or just because he liked the name, we cannot recall). That name was retained throughout our ongoing work, until our upcoming first public release. At that point, we decided we needed a name which was more descriptive of the nature of the current language. Nickle is designed to support one more major upgrade (to handle parametric type inference). The name nickle, for "nick <=", was chosen partly to denote this state. In addition (in no particular order), we note that: + The progression to longer names built around the same core is inline with the evolution of program naming in UNIX generally. ic -> nick -> nickle is two characters per iteration, which we believe to be about right. + There is a weak tradition of "materials based" names for scripting languages, most notably the "PERL" family of languages and successors like "Ruby". + There is a tradition of "materials-man" standards draft names as well. Our language standard is currently much more than a "strawman," but a little less than an "iron man": "nickle man" appears to be about right. + The term "nickle" (with this spelling) was apparently a common abbreviation among the Mattel Intellivision processor team for a 5-bit field. (The term may have a longer and broader history.) We figure the language is worth about 5 bits (i.e. $0.625 US), and are amused to note that this cannot be accurately represented to two decimal places. (Thanks to Dan Flynn for the correction.) + The word "nickle" probably actually originates from the Germanic name "Nicholas", i.e. "Nick", as a short form of the German "Kupfernickel" or "copper demon", for the deceptive copper color of nickle ore. (Note that this is also the origin of the term "Old Nick" to denote the Christian Satan. Sources tell us that the cute little BSD daemon is named "Chuck". We think "Nick" would be a better choice.) + Recall the famous joke about little-language designer Nickle's Worth. ("Europeans call him by name, but Americans call him by value.") Niklaus Wirth was easily the single biggest influence on my development of interest in and understanding of programming languages and language design. + Several programming language researchers are named "Nickle" or "Nickel". Hopefully, they will feel flattered and supportive. + Remember the famous Dilbertian "condescending UNIX computer user" from Scott Adams' "Computer Holy Wars" series? "Here's a nickle, kid: buy yourself a better computer." Finally, a note about the spelling. "Nickel" appears to be the preferred spelling for both the metal and the U.S. coin. The New American Heritage Dictionary does not allow the variant "nickle", although the Merriam Webster Collegiate Dictionary does. A Google search reveals a vast predominance of the former spelling over the latter. However, for a variety of reasons, some noted above, we have chosen the more problematic variant. As the old gag goes, you can call it anything you like. Just call it. --- Copyright © 1988-2004 Keith Packard and Bart Massey. All Rights Reserved. See the file COPYING in this directory for licensing information. nickle_2.81.orig/ref.h0000664000175000000620000000040410414112462014016 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ typedef struct _reference *ReferencePtr; ReferencePtr NewReference (void **object); nickle_2.81.orig/array.c0000664000175000000620000002140713062261355014371 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "gram.h" int ArrayInit (void) { return 1; } static int ArrayNextI (Array *a, int i) { int step = 1; int sub_size = 1; int d; int dim, lim; int j = i + 1; for (d = 0; d < a->ndim - 1; d++) { dim = ArrayDims(a)[d]; lim = ArrayLimits(a)[d]; if (dim != lim && j % dim == lim) step += (dim - lim) * sub_size; sub_size *= ArrayDims(a)[d]; j /= dim; } return i + step; } static int ArrayLimit (Value av) { Array *a = &av->array; int *limits = ArrayLimits(a); int *dims = ArrayDims(a); int d; int limit; limit = limits[a->ndim-1]; for (d = 0; d < a->ndim - 1; d++) limit *= dims[d]; return limit; } static Value ArrayEqual (Value av, Value bv, int expandOk) { Array *a = &av->array, *b = &bv->array; int ai, bi; int alimit = ArrayLimit (av), blimit = ArrayLimit (bv); int d; if (a->ndim != b->ndim) return FalseVal; for (d = 0; d < a->ndim; d++) if (ArrayLimits(a)[d] != ArrayLimits(b)[d]) return FalseVal; ai = 0; bi = 0; while (ai < alimit && bi < blimit) { if (False (Equal ( ArrayValue (a, ai), ArrayValue (b, bi)))) return FalseVal; ai = ArrayNextI (a, ai); bi = ArrayNextI (b, bi); } return TrueVal; } static Bool ArrayPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { ENTER (); Array *a = &av->array; int *limits = ArrayLimits(a); int *dims = ArrayDims(a); int i, j, k; int ndone; int limit = ArrayLimit (av); Bool ret = True; Bool pretty = format == 'v' || format == 'g' || format == 'G'; char down_format = format == 'g' ? 'G' : format; if (pretty) { FilePuts (f, "("); if (!TypePoly (ArrayType(a))) { FilePutBaseType (f, ArrayType (a), False); FilePuts (f, " "); } FilePuts (f, "["); for (i = a->ndim - 1; i >= 0; i--) { if (a->resizable) FilePuts (f, "..."); else FilePutInt (f, limits[i]); if (i) FilePuts (f, ", "); } FilePuts (f, "]"); if (!TypePoly (ArrayType(a))) { FilePutSubscriptType (f, ArrayType (a), False); } FilePuts (f, ") "); if (format != 'G') { for (i = 0; i < a->ndim; i++) FileOutput (f, '{'); } } if (format != 'G') { i = 0; while (i < limit) { if (!Print (f, ArrayValueGet (a, i), down_format, base, width, prec, fill)) { ret = False; break; } i = ArrayNextI (a, i); if (i < limit) { ndone = 0; if (pretty) { j = i; k = 0; while (k < a->ndim - 1 && j % dims[k] == 0) { ndone++; j = j / dims[k]; k++; } for (k = 0; k < ndone; k++) FileOutput (f, '}'); FileOutput (f, ','); } FileOutput (f, ' '); if (pretty) for (k = 0; k < ndone; k++) FileOutput (f, '{'); } } if (pretty) for (i = 0; i < a->ndim; i++) FileOutput (f, '}'); } EXIT (); return ret; } #define hrot(i) (((i) << 1) | ((i) >> (sizeof (HashValue) * 8 - 1))) static HashValue ArrayHash (Value av) { Array *a = &av->array; int i; HashValue h = 0; int limit = ArrayLimit (av); for (i = 0; i < limit; i = ArrayNextI (a, i)) h = hrot(h) ^ ValueInt (ValueHash (ArrayValueGet (a, i))); return h; } static void ArrayMark (void *object) { Array *array = object; if (array->resizable) MemReference (array->u.resize); else MemReference (array->u.fix); } ValueRep ArrayRep = { { ArrayMark, 0, "ArrayRep" }, rep_array, { 0, 0, 0, 0, 0, 0, 0, ArrayEqual, 0, 0, }, { 0, }, 0, 0, ArrayPrint, 0, ArrayHash, }; static void BoxVectorMark (void *object) { BoxVectorPtr bv = object; int i; BoxPtr *boxes = BoxVectorBoxes (bv); MemReference (bv->type); for (i = 0; i < bv->nvalues; i++) MemReference (boxes[i]); } DataType BoxVectorType = { BoxVectorMark, 0, "BoxVectorType" }; static BoxVectorPtr NewBoxVector (int nvalues, TypePtr type) { ENTER (); BoxVectorPtr bv = ALLOCATE (&BoxVectorType, sizeof (BoxVector) + nvalues * sizeof (BoxPtr)); int i; BoxPtr *boxes = BoxVectorBoxes (bv); bv->nvalues = nvalues; bv->type = type; for (i = 0; i < nvalues; i++) boxes[i] = 0; RETURN (bv); } static void FillBoxVector (BoxVectorPtr bv, BoxPtr *boxes, int n) { ENTER(); while (n--) *boxes++ = NewBox (False, False, 1, bv->type); EXIT (); } Value NewArray (Bool constant, Bool resizable, TypePtr type, int ndim, int *dims) { ENTER (); Value ret; int ents; int dim; if (ndim) { ents = 1; for (dim = 0; dim < ndim; dim++) ents *= dims[dim]; } else ents = 0; ret = ALLOCATE (&ArrayRep.data, sizeof (Array) + (ndim * 2) * sizeof (int)); ret->array.ndim = ndim; for (dim = 0; dim < ndim; dim++) ArrayLimits(&ret->array)[dim] = ArrayDims(&ret->array)[dim] = dims[dim]; ret->array.resizable = resizable; if (resizable) { ret->array.u.resize = 0; ret->array.u.resize = NewBoxVector (ents, type); FillBoxVector (ret->array.u.resize, BoxVectorBoxes (ret->array.u.resize), ents); } else { ret->array.u.fix = 0; ret->array.u.fix = NewBox (constant, True, ents, type); } RETURN (ret); } void ArrayResize (Value av, int dim, int size) { ENTER (); Array *a = &av->array; int *dims = ArrayDims(a); int *limits = ArrayLimits(a); int odim = dims[dim]; int ents; int d; int stride; /* size of each chunk */ int nchunk; /* number of chunks */ int c; int unit; int good; BoxPtr *b; assert (av->array.resizable); if (size == limits[dim]) return; ents = a->u.resize->nvalues; stride = 1; for (d = 0; d <= dim; d++) stride *= dims[d]; if (stride) nchunk = ents / stride; else nchunk = 1; /* * Resize if necessary. */ if (dims[dim] < size || dims[dim] > size * 2) { int ostride = stride; int nstride = stride; BoxVectorPtr nboxes; BoxPtr *o, *n; if (odim < size) { /* was empty */ if (odim == 0) { odim = 1; ents = 1; nstride = 1; for (d = 0; d < a->ndim; d++) dims[d] = 1; } /* bigger */ while (odim < size) { odim <<= 1; ents <<= 1; nstride <<= 1; } good = ostride; } else if (size > 0) { /* smaller */ while (odim > size * 2) { odim >>= 1; ents >>= 1; nstride >>= 1; } good = nstride; } else { /* empty */ ents = 0; nstride = 0; odim = 0; size = 0; nchunk = 0; for (d = 0; d < a->ndim; d++) { dims[d] = 0; limits[d] = 0; } good = 0; } nboxes = NewBoxVector (ents, a->u.resize->type); o = BoxVectorBoxes (a->u.resize); n = BoxVectorBoxes (nboxes); for (c = 0; c < nchunk; c++) { memcpy (n, o, good * sizeof (BoxPtr)); if (nstride > good) FillBoxVector (nboxes, n + good, nstride - good); o += ostride; n += nstride; } a->u.resize = nboxes; dims[dim] = odim; limits[dim] = size; stride = nstride; } /* * When shrinking the array, replace the * now discarded entries with new boxes. * This leaves growing trivial; all unused * elements of the array have clean boxes */ if (limits[dim] > size) { b = BoxVectorBoxes (a->u.resize); unit = stride / dims[dim]; good = size * unit; for (c = 0; c < nchunk; c++) { FillBoxVector (a->u.resize, b + good, stride - good); b += stride; } } limits[dim] = size; EXIT (); } void ArraySetDimensions (Value av, int *dims) { Array *a = &av->array; int i; for (i = 0; i < a->ndim; i++) ArrayResize (av, i, dims[i]); } Type * BuildArrayType (Type *subtype, int ndim, ...) { ENTER (); Expr *dims = 0; int i; int dim; va_list ap; Type *type; Value dimArray; dimArray = NewArray (True, False, typePrim[rep_integer], 1, &ndim); va_start (ap, ndim); for (i = 0; i < ndim; i++) { dim = va_arg (ap, int); ArrayValueSet(&dimArray->array, i, NewInt (dim)); dims = NewExprTree (COMMA, NewExprConst (TEN_FLOAT, NewInt (dim)), dims); } va_end (ap); type = NewTypeArray (subtype, dims, False); /* * Create an array to hold the dimension information and * fill it in */ type->array.storage = DimStorageGlobal; type->array.u.global = NewBox (True, False, 1, typeArrayInt); BoxValueSet (type->array.u.global, 0, dimArray); RETURN (type); } nickle_2.81.orig/atom.c0000664000175000000620000000412210414112462014176 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" typedef struct _atom { DataType *data; struct _atom *next; } AtomEntry; #define AtomEntryName(ae) ((char *) ((ae) + 1)) static void AtomEntryMark (void *object) { ; } DataType AtomEntryType = { AtomEntryMark, 0, "AtomEntryType" }; # define HASHSIZE 63 typedef struct _atomTable { DataType *data; AtomEntry *hash[HASHSIZE]; } AtomTable; static void AtomTableMark (void *object) { AtomTable *table = object; int i; AtomEntry *atom; for (i = 0; i < HASHSIZE; i++) for (atom = table->hash[i]; atom; atom = atom->next) MemReference (atom); } DataType AtomTableType = { AtomTableMark, 0, "AtomTableType" }; AtomTable *atomTable; int AtomInit (void) { ENTER (); atomTable = ALLOCATE (&AtomTableType, sizeof (AtomTable)); memset (atomTable->hash, '\0', sizeof (atomTable->hash)); MemAddRoot (atomTable); EXIT (); return 1; } static int hash (char *name) { int h; h = 0; while (*name) h += *name++; if (h < 0) h = -h; return h % HASHSIZE; } Atom AtomId (char *name) { AtomEntry **bucket = &atomTable->hash[hash(name)]; AtomEntry *atomEntry; for (atomEntry = *bucket; atomEntry; atomEntry = atomEntry->next) if (!strcmp (name, AtomEntryName(atomEntry))) break; if (!atomEntry) { ENTER (); atomEntry = ALLOCATE (&AtomEntryType, sizeof (AtomEntry) + strlen (name) + 1); atomEntry->next = *bucket; *bucket = atomEntry; strcpy (AtomEntryName(atomEntry), name); EXIT(); } return AtomEntryName (atomEntry); } static void AtomListMark (void *object) { AtomListPtr al = object; MemReference (al->next); } DataType AtomListType = { AtomListMark, 0, "AtomListType" }; AtomListPtr NewAtomList (AtomListPtr next, Atom atom) { ENTER (); AtomListPtr al; al = ALLOCATE (&AtomListType, sizeof (AtomList)); al->next = next; al->atom = atom; RETURN (al); } nickle_2.81.orig/process.5c0000664000175000000620000000620410414112462015004 0ustar keithpstaff/* * Copyright © 2005 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * Implementation of process manipulation functions. */ namespace Process { import File, Thread; public void system(string cmd, string args ...) /* Fork a separate process. The string cmd is the actual command to be executed, whereas args forms the argument vector. */ { file[3] descs = {stdin, stdout, stderr}; int pid = filter(cmd, args, descs); } public void copy(file readfd, file writefd) /* Generic copy-input-to-output sometimes useful in process manipulation. */ { while (!end(readfd)) putb(getb(readfd), writefd); } public typedef void(file) agent; public void run_process(agent writer, agent reader, string cmd, string args ...) /* Run a separate process, invoking an extra thread so that the process can be concurrently written to and read from. The writer should accept a file descriptor suitable for writing, the reader a file descriptor suitable for reading. The string cmd is the actual command to be executed, whereas args forms the argument vector. Return when both the writer and reader have returned. */ { file[*] inpipe = mkpipe(); file[*] outpipe = mkpipe(); file[3] descs = {inpipe[0], outpipe[1], stderr}; int pid = filter(cmd, args, descs); close(inpipe[0]); close(outpipe[1]); thread t = fork(reader(outpipe[0])); writer(inpipe[1]); close(inpipe[1]); join(t); close(outpipe[0]); } public typedef enum { read, write } popen_direction; public file popen(popen_direction d, bool nullf, string cmd, string args ...) /* Return a file descriptor suitable for reading (when d = read) or writing (when d = write) a separate process. If nullf is true, the unused descriptor will be connected to /dev/null. Otherwise, it will be connected to standard input (when d = read) or standard output (when d = write). The string cmd is the actual command to be executed, whereas args forms the argument vector. */ { switch(nullf) { case true: switch(d) { case popen_direction.read: twixt(file[*] pipe = mkpipe(); close(pipe[1])) { twixt(file nullf = open("/dev/null", "r"); close(nullf)) { file[3] descs = {nullf, pipe[1], stderr}; filter(cmd, args, descs); } return pipe[0]; } case popen_direction.write: twixt(file[*] pipe = mkpipe(); close(pipe[0])) { twixt(file nullf = open("/dev/null", "w"); close(nullf)) { file[3] descs = {pipe[0], nullf, stderr}; filter(cmd, args, descs); } return pipe[1]; } } break; case false: switch(d) { case popen_direction.read: twixt(file[*] pipe = mkpipe(); close(pipe[1])) { file[3] descs = {stdin, pipe[1], stderr}; filter(cmd, args, descs); return pipe[0]; } case popen_direction.write: twixt(file[*] pipe = mkpipe(); close(pipe[0])) { file[3] descs = {pipe[0], stdout, stderr}; filter(cmd, args, descs); return pipe[1]; } } break; } abort("bad popen state"); } } nickle_2.81.orig/pretty.c0000664000175000000620000005562211735351503014610 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * pretty.c * * pretty print a function */ #include #include "nickle.h" #include "gram.h" #define PRETTY_NUM_WIDTH 10 static int PrettyNumWidth (unsigned long i) { int w = 1; while (i >= 10) { w++; i /= 10; } return w; } static void PrettyProfNum (Value f, unsigned long i, int pad_left) { int spaces = PRETTY_NUM_WIDTH - PrettyNumWidth (i); if (pad_left) while (spaces-- > 0) FilePuts (f, " "); FilePrintf (f, "%d", i); if (!pad_left) while (spaces-- > 0) FilePuts (f, " "); } static void PrettyParameters (Value f, Expr *e, Bool nest); static void PrettyArrayInit (Value f, Expr *e, int level, Bool nest); static void PrettyStatement (Value f, Expr *e, int level, int blevel, Bool nest); static void PrettyBody (Value f, CodePtr code, int level, Bool nest); static void PrettyDoc (Value f, int level, Value doc); static void PrettyIndent (Value f, Expr *e, int level) { int i; if (profiling) { if (e) { PrettyProfNum (f, e->base.sub_ticks + e->base.ticks, 1); FilePuts (f, " "); PrettyProfNum (f, e->base.ticks, 1); } else FilePuts (f, " "); FilePuts (f, ": "); } for (i = 0; i < level-1; i += 2) FileOutput (f, '\t'); if (i < level) FilePuts (f, " "); } static void PrettyBlock (Value f, Expr *e, int level, Bool nest) { while (e->tree.left) { PrettyStatement (f, e->tree.left, level, level, nest); e = e->tree.right; } } static int tokenToPrecedence (int token) { switch (token) { case COMMA: return 0; case ASSIGN: case ASSIGNPLUS: case ASSIGNMINUS: case ASSIGNTIMES: case ASSIGNDIVIDE: case ASSIGNMOD: case ASSIGNDIV: case ASSIGNPOW: case ASSIGNSHIFTL: case ASSIGNSHIFTR: case ASSIGNLXOR: case ASSIGNLAND: case ASSIGNLOR: case ASSIGNAND: case ASSIGNOR: return 1; case QUEST: case COLON: return 2; case OR: return 3; case AND: return 4; case LOR: return 5; case LAND: return 6; case LXOR: return 7; case EQ: case NE: return 8; case LT: case GT: case LE: case GE: return 9; case SHIFTL: case SHIFTR: return 10; case PLUS: case MINUS: return 11; case TIMES: case DIVIDE: case MOD: case DIV: return 12; case POW: return 13; case UMINUS: case BANG: case FACT: case LNOT: return 14; case INC: case DEC: return 15; case STAR: case AMPER: return 16; case OS: case CS: return 17; default: return 18; } } static void PrettyParameters (Value f, Expr *e, Bool nest) { while (e) { if (e->tree.left->base.tag == DOTDOTDOT) { PrettyExpr (f, e->tree.left->tree.left, -1, 0, nest); FilePuts (f, "..."); } else { PrettyExpr (f, e->tree.left, -1, 0, nest); } e = e->tree.right; if (e) FilePuts (f, ", "); } } static void PrettyArrayInit (Value f, Expr *e, int level, Bool nest); static void PrettyArrayInits (Value f, Expr *e, int level, Bool nest) { while (e) { if (e->tree.left) PrettyArrayInit (f, e->tree.left, 0, nest); e = e->tree.right; if (e) { if (e->tree.left->base.tag == DOTDOTDOT) FilePuts (f, " "); else FilePuts (f, ", "); } } } static void PrettyArrayInit (Value f, Expr *e, int level, Bool nest) { switch (e->base.tag) { case OC: FilePuts (f, "{ "); PrettyArrayInits (f, e->tree.left, level, nest); FilePuts (f, " }"); break; case DOTDOTDOT: FilePuts (f, "..."); break; default: PrettyExpr (f, e, -1, level, nest); break; } } static void PrettyHashInit (Value f, Expr *e, int level, Bool nest) { while (e) { PrettyExpr (f, e->tree.left->tree.left, -1, level, nest); FilePuts (f, " => "); PrettyExpr (f, e->tree.left->tree.right, -1, level, nest); e = e->tree.right; if (e) FilePuts (f, ", "); } } static void PrettyStructInit (Value f, Expr *e, int level, Bool nest) { while (e) { FilePuts (f, AtomName (e->tree.left->tree.left->atom.atom)); FilePuts (f, " = "); PrettyExpr (f, e->tree.left->tree.right, -1, level, nest); e = e->tree.right; if (e) FilePuts (f, ", "); } } static void PrettyChar (Value f, int c) { FileOutput (f, '\''); if (c < ' ' || '~' < c) switch (c) { case '\n': FilePuts (f, "\\n"); break; case '\r': FilePuts (f, "\\r"); break; case '\b': FilePuts (f, "\\b"); break; case '\t': FilePuts (f, "\\t"); break; case '\f': FilePuts (f, "\\f"); break; default: FileOutput (f, '\\'); Print (f, NewInt (c), 'o', 8, 3, 0, '0'); break; } else if (c == '\'') FilePuts (f, "\\'"); else FileOutchar (f, c); FileOutput (f, '\''); } static void PrettyDecl (Value f, Expr *e, int level, Bool nest) { DeclListPtr decl; /* PrettyProf (f, e);*/ FilePutPublish (f, e->decl.publish, True); switch (e->decl.class) { case class_const: FilePuts (f, "const"); if (e->decl.type) FilePutType (f, e->decl.type, False); break; case class_global: if (e->decl.type) FilePutType (f, e->decl.type, False); else FilePuts (f, "global"); break; case class_auto: if (e->decl.type) FilePutType (f, e->decl.type, False); else FilePuts (f, "auto"); break; case class_static: case class_typedef: case class_namespace: FilePutClass (f, e->decl.class, e->decl.type && !TypePoly (e->decl.type)); if (e->decl.type && !TypePoly (e->decl.type)) FilePutType (f, e->decl.type, False); break; case class_undef: case class_arg: FilePutType (f, e->decl.type, False); break; case class_exception: FilePutClass (f, e->decl.class, False); break; } for (decl = e->decl.decl; decl; decl = decl->next) { FileOutput (f, ' '); FilePuts (f, AtomName (decl->name)); if (decl->init) { FilePuts (f, " = "); PrettyExpr (f, decl->init, -1, level, nest); } if (decl->next) FilePuts (f, ","); } if (e->decl.class == class_exception) { FilePutArgType (f, e->decl.type->func.args); } } void PrettyExpr (Value f, Expr *e, int parentPrec, int level, Bool nest) { int selfPrec; if (!e) return; selfPrec = tokenToPrecedence (e->base.tag); if (selfPrec < parentPrec) FilePuts (f, "("); switch (e->base.tag) { case NAME: FilePuts (f, AtomName (e->atom.atom)); break; case VAR: PrettyDecl (f, e, level, nest); break; case OP: PrettyExpr (f, e->tree.left, selfPrec, level, nest); FilePuts (f, " ("); if (e->tree.right) PrettyParameters (f, e->tree.right, nest); FilePuts (f, ")"); break; case OS: PrettyExpr (f, e->tree.left, selfPrec, level, nest); FilePuts (f, "["); PrettyParameters (f, e->tree.right, nest); FilePuts (f, "]"); break; case NEW: FilePrintf (f, "(%T)", e->base.type); if (e->tree.left) { FilePuts (f, " "); PrettyExpr (f, e->tree.left, selfPrec, level, nest); } break; case ARRAY: FilePuts (f, "{ "); PrettyArrayInits (f, e->tree.left, level, nest); FilePuts (f, " }"); break; case COMP: FilePuts (f, "{ "); FilePuts (f, "["); PrettyExpr (f, e->tree.left->tree.left, selfPrec, level, nest); FilePuts (f, "] "); if (e->tree.right->base.tag == OC) PrettyStatement (f, e->tree.right, level + 1, level, nest); else { FilePuts (f, "= "); PrettyExpr (f, e->tree.right, selfPrec, level, nest); } FilePuts (f, " }"); break; case HASH: FilePuts (f, "{ "); PrettyHashInit (f, e->tree.left, level, nest); FilePuts (f, " }"); break; case ANONINIT: FilePuts (f, "{}"); break; case STRUCT: FilePuts (f, "{ "); PrettyStructInit (f, e->tree.left, level, nest); FilePuts (f, " }"); break; case UNION: if (e->tree.right) { FilePrintf (f, "(%T.%A) ", e->base.type, e->tree.left->atom.atom); PrettyExpr (f, e->tree.right, selfPrec, level, nest); } else { FilePrintf (f, "%T.%A", e->base.type, e->tree.left->atom.atom); } break; case OCTAL_NUM: case OCTAL0_NUM: case OCTAL_FLOAT: case OCTAL0_FLOAT: FilePrintf (f, "0o"); Print (f, e->constant.constant, 'o', 8, 0, DEFAULT_OUTPUT_PRECISION, ' '); break; case BINARY_NUM: case BINARY_FLOAT: FilePrintf (f, "0b"); Print (f, e->constant.constant, 'b', 2, 0, DEFAULT_OUTPUT_PRECISION, ' '); break; case HEX_NUM: case HEX_FLOAT: FilePrintf (f, "0x"); Print (f, e->constant.constant, 'x', 16, 0, DEFAULT_OUTPUT_PRECISION, ' '); break; case TEN_NUM: case TEN_FLOAT: case STRING_CONST: case POLY_CONST: case THREAD_CONST: case VOIDVAL: case BOOLVAL: FilePrintf (f, "%v", e->constant.constant); break; case CHAR_CONST: PrettyChar (f, IntPart (e->constant.constant, "malformed character constant")); break; case FUNC: PrettyCode (f, e->code.code, 0, class_undef, publish_private, level + 1, nest); break; case POW: case ASSIGNPOW: e = e->tree.right; /* fall through */ case PLUS: case MINUS: case TIMES: case DIVIDE: case MOD: case DIV: case SHIFTL: case SHIFTR: case LXOR: case LAND: case LOR: case EQ: case NE: case LT: case GT: case LE: case GE: case AND: case OR: case ASSIGN: case ASSIGNPLUS: case ASSIGNMINUS: case ASSIGNTIMES: case ASSIGNDIVIDE: case ASSIGNMOD: case ASSIGNSHIFTL: case ASSIGNSHIFTR: case ASSIGNLXOR: case ASSIGNLAND: case ASSIGNLOR: case ASSIGNAND: case ASSIGNOR: case COMMA: PrettyExpr (f, e->tree.left, selfPrec, level, nest); switch (e->base.tag) { case PLUS: FilePuts (f, " + "); break; case MINUS: FilePuts (f, " - "); break; case TIMES: FilePuts (f, " * "); break; case DIVIDE: FilePuts (f, " / "); break; case MOD: FilePuts (f, " % "); break; case DIV: FilePuts (f, " // "); break; case POW: FilePuts (f, " ** "); break; case SHIFTL: FilePuts (f, " << "); break; case SHIFTR: FilePuts (f, " >> "); break; case LXOR: FilePuts (f, " ^ "); break; case LAND: FilePuts (f, " & "); break; case LOR: FilePuts (f, " | "); break; case EQ: FilePuts (f, " == "); break; case NE: FilePuts (f, " != "); break; case LT: FilePuts (f, " < "); break; case GT: FilePuts (f, " > "); break; case LE: FilePuts (f, " <= "); break; case GE: FilePuts (f, " >= "); break; case AND: FilePuts (f, " && "); break; case OR: FilePuts (f, " || "); break; case ASSIGN: FilePuts (f, " = "); break; case ASSIGNPLUS:FilePuts (f, " += "); break; case ASSIGNMINUS:FilePuts (f, " -= "); break; case ASSIGNTIMES:FilePuts (f, " *= "); break; case ASSIGNDIVIDE:FilePuts (f, " /= "); break; case ASSIGNMOD: FilePuts (f, " %= "); break; case ASSIGNDIV: FilePuts (f, " //= "); break; case ASSIGNPOW: FilePuts (f, " **= "); break; case ASSIGNSHIFTL:FilePuts (f, " <<= "); break; case ASSIGNSHIFTR:FilePuts (f, " >>= "); break; case ASSIGNLXOR:FilePuts (f, " ^= "); break; case ASSIGNLAND:FilePuts (f, " &= "); break; case ASSIGNLOR: FilePuts (f, " |= "); break; case ASSIGNAND:FilePuts (f, " &&= "); break; case ASSIGNOR: FilePuts (f, " ||= "); break; case COMMA: FilePuts (f, ", "); break; } PrettyExpr (f, e->tree.right, selfPrec, level, nest); break; case FACT: PrettyExpr (f, e->tree.right, selfPrec, level, nest); FilePuts (f, "!"); break; case LNOT: case UMINUS: case BANG: case INC: case DEC: if (e->tree.right) PrettyExpr (f, e->tree.right, selfPrec, level, nest); switch (e->base.tag) { case LNOT: FilePuts (f, "~"); break; case UMINUS: FilePuts (f, "-"); break; case BANG: FilePuts (f, "!"); break; case INC: FilePuts (f, "++"); break; case DEC: FilePuts (f, "--"); break; } if (e->tree.left) PrettyExpr (f, e->tree.left, selfPrec, level, nest); break; case STAR: FilePuts (f, "*"); PrettyExpr (f, e->tree.left, selfPrec, level, nest); break; case AMPER: FilePuts (f, "&"); PrettyExpr (f, e->tree.left, selfPrec, level, nest); break; case COLONCOLON: PrettyExpr (f, e->tree.left, selfPrec, level, nest); FilePuts (f, "::"); FilePuts (f, AtomName (e->tree.right->atom.atom)); break; case DOT: PrettyExpr (f, e->tree.left, selfPrec, level, nest); FileOutput (f, '.'); FilePuts (f, AtomName (e->tree.right->atom.atom)); break; case ARROW: PrettyExpr (f, e->tree.left, selfPrec, level, nest); FilePuts (f, "->"); FilePuts (f, AtomName (e->tree.right->atom.atom)); break; case QUEST: PrettyExpr (f, e->tree.left, selfPrec, level, nest); FilePuts (f, " ? "); PrettyExpr (f, e->tree.right->tree.left, selfPrec, level, nest); FilePuts (f, " : "); PrettyExpr (f, e->tree.right->tree.right, selfPrec, level, nest); break; case DOLLAR: if (e->tree.left) { FilePuts (f, "$"); PrettyExpr (f, e->tree.left, selfPrec, level, nest); } else FilePuts (f, "."); break; case EXPR: PrettyExpr (f, e->tree.left, selfPrec, level, nest); break; } if (selfPrec < parentPrec) FilePuts (f, ")"); } static void _PrettyCatch (Value f, Expr *e, int level, Bool nest) { CodePtr catch; if (!e) return; _PrettyCatch (f, e->tree.left, level, nest); if (nest) PrettyIndent (f, 0, level); e = e->tree.right; catch = e->code.code; FilePuts (f, "catch "); PrettyExpr (f, catch->base.name, 0, level, nest); FilePuts (f, " "); PrettyBody (f, catch, level, nest); FilePuts (f, "\n"); } static void PrintArgs (Value f, ArgType *args); void PrettyStatement (Value f, Expr *e, int level, int blevel, Bool nest) { switch (e->base.tag) { case EXPR: PrettyIndent (f, e, level); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, ";\n"); break; case IF: PrettyIndent (f, e, level); FilePuts (f, "if ("); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, ")\n"); if (nest) PrettyStatement (f, e->tree.right, level+1, level, nest); break; case ELSE: PrettyIndent (f, e, level); FilePuts (f, "if ("); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, ")\n"); if (nest) { PrettyStatement (f, e->tree.right->tree.left, level+1, level, nest); PrettyIndent (f, 0, level); FilePuts (f, "else\n"); PrettyStatement (f, e->tree.right->tree.right, level+1, level, nest); } break; case WHILE: PrettyIndent (f, e, level); FilePuts (f, "while ("); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, ")\n"); if (nest) PrettyStatement (f, e->tree.right, level+1, level, nest); break; case OC: PrettyIndent (f, 0, blevel); FilePuts (f, "{\n"); PrettyBlock (f, e, blevel + 1, nest); PrettyIndent (f, 0, blevel); FilePuts (f, "}\n"); break; case DO: PrettyIndent (f, 0, level); FilePuts (f, "do\n"); if (nest) PrettyStatement (f, e->tree.left, level+1, level, nest); PrettyIndent (f, e, level); FilePuts (f, "while ("); PrettyExpr (f, e->tree.right, -1, level, nest); FilePuts (f, ");\n"); break; case FOR: PrettyIndent (f, e, level); FilePuts (f, "for ("); if (e->tree.left->tree.left) PrettyExpr (f, e->tree.left->tree.left, -1, level, nest); if (e->tree.left->base.tag == SEMI) FilePuts (f, ";"); if (e->tree.left->tree.right->tree.left) { if (e->tree.left->base.tag == SEMI) FilePuts (f, " "); PrettyExpr (f, e->tree.left->tree.right->tree.left, -1, level, nest); } FilePuts (f, ";"); if (e->tree.left->tree.right->tree.right->tree.left) { FilePuts (f, " "); PrettyExpr (f, e->tree.left->tree.right->tree.right->tree.left, -1, level, nest); } FilePuts (f, ")\n"); if (nest) PrettyStatement (f, e->tree.right, level+1, level, nest); break; case SWITCH: case UNION: PrettyIndent (f, e, level); if (e->base.tag == SWITCH) FilePuts (f, "switch ("); else FilePuts (f, "union switch ("); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, ")"); if (nest) { ExprPtr block = e->tree.right; FilePuts (f, " {\n"); while (block) { PrettyIndent (f, 0, level); if (block->tree.left->tree.left) { FilePuts (f, "case "); PrettyExpr (f, block->tree.left->tree.left, -1, level, nest); } else FilePuts (f, "default"); FilePuts (f, ":\n"); PrettyBlock (f, block->tree.left->tree.right, level+1, nest); block = block->tree.right; } PrettyIndent (f, 0, level); FilePuts (f, "}"); } FilePuts (f, "\n"); break; case SEMI: PrettyIndent (f, e, level); FilePuts (f, ";\n"); break; case BREAK: PrettyIndent (f, e, level); FilePuts (f, "break;\n"); break; case CONTINUE: PrettyIndent (f, e, level); FilePuts (f, "continue;\n"); break; case RETURNTOK: PrettyIndent (f, e, level); FilePuts (f, "return "); PrettyExpr (f, e->tree.right, -1, level, nest); FilePuts (f, ";\n"); break; case FUNC: PrettyIndent (f, e, level); { DeclListPtr decl = e->decl.decl; ExprPtr init = decl->init; if (init) { CodePtr code = init->code.code; PrettyCode (f, code, decl->name, e->decl.class, e->decl.publish, level, nest); } else { Type *t = e->decl.type; FilePrintf (f, "%p%k%T %A ", e->decl.publish, e->decl.class, t->func.ret, decl->name); PrintArgs (f, t->func.args); FilePuts (f, ";"); } } FilePuts (f, "\n"); break; case TYPEDEF: e = e->tree.left; /* fall through */ case VAR: PrettyIndent (f, e, level); PrettyDecl (f, e, level, nest); FilePuts (f, ";\n"); break; case NAMESPACE: PrettyIndent (f, e, level); FilePuts (f, "namespace "); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, "\n"); PrettyStatement (f, e->tree.right, level + 1, level, nest); break; case IMPORT: PrettyIndent (f, e, level); FilePrintf (f, "%pimport ", e->tree.right->decl.publish); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, ";\n"); break; case TWIXT: PrettyIndent (f, e, level); FilePuts (f, "twixt ("); PrettyExpr (f, e->tree.left->tree.left, -1, level, nest); FilePuts (f, "; "); PrettyExpr (f, e->tree.left->tree.right, -1, level, nest); FilePuts (f, ")\n"); if (nest) PrettyStatement (f, e->tree.right->tree.left, level+1, level, nest); break; case CATCH: PrettyIndent (f, e, level); FilePuts (f, "try"); if (nest) { FilePuts (f, "\n"); PrettyStatement (f, e->tree.right, level+1, level, nest); } else FilePuts (f, " "); _PrettyCatch (f, e->tree.left, level, nest); break; case RAISE: PrettyIndent (f, e, level); FilePrintf (f, "raise %A (", e->tree.left->atom.atom); if (e->tree.right) PrettyParameters (f, e->tree.right, nest); FilePuts (f, ");\n"); break; case DOLLAR: PrettyIndent (f, e, level); PrettyExpr (f, e->tree.left, -1, level, nest); FilePuts (f, "\n"); break; } } static void PrintArgs (Value f, ArgType *args) { FilePuts (f, "("); for (; args; args = args->next) { FilePutType (f, args->type, args->name != 0); if (args->name) FilePuts (f, AtomName (args->name)); if (args->varargs) FilePuts (f, " ..."); if (args->next) FilePuts (f, ", "); } FilePuts (f, ")"); } static void PrettyDoc (Value f, int level, Value doc) { char *s = StringChars (&doc->string); long len = doc->string.length; unsigned c; Bool newline = False; PrettyIndent (f, 0, level); FilePuts (f, "/""*"); while ((s = StringNextChar (s, &c, &len))) { if (newline) { PrettyIndent (f, 0, level); FilePuts (f, " *"); newline = False; } FileOutchar (f, c); if (c == '\n') newline = True; } if (newline) { PrettyIndent (f, 0, level); FileOutput (f, ' '); } FilePuts (f, "*""/"); } static void PrettyBody (Value f, CodePtr code, int level, Bool nest) { PrintArgs (f, code->base.args); if (code->base.doc != Void) { FilePuts (f, "\n"); PrettyDoc (f, level + 1, code->base.doc); } if (nest) { if (code->base.builtin) { FilePuts (f, " "); } else { FilePuts (f, "\n"); PrettyIndent (f, 0, level); FilePuts (f, "{\n"); PrettyBlock (f, code->func.code, level + 1, nest); PrettyIndent (f, 0, level); FilePuts (f, "}"); } } else FilePuts (f, ";"); } void PrettyCode (Value f, CodePtr code, Atom name, Class class, Publish publish, int level, Bool nest) { if (name) FilePrintf (f, "%p%k%T %A ", publish, class, code->base.type, name); else FilePrintf (f, "%tfunc", code->base.type); PrettyBody (f, code, level, nest); if (!code->base.builtin && nest && profiling) { double_digit sub = 0, self = 0; if (code->func.body.obj) { sub += code->func.body.obj->sub_ticks; self += code->func.body.obj->ticks; } if (code->func.staticInit.obj) { sub += code->func.staticInit.obj->sub_ticks; self += code->func.staticInit.obj->ticks; } FilePuts (f, "\n---------------------\n"); PrettyProfNum (f, sub + self, 1); FilePuts (f, " "); PrettyProfNum (f, self, 1); if (name) FilePrintf (f, ": %A\n", name); else FilePrintf (f, ": %tfunc\n", code->base.type); } } void PrettyStat (Value f, Expr *e, Bool nest) { PrettyStatement (f, e, 1, 1, nest); } void doPrettyPrint (Value f, Publish publish, SymbolPtr symbol, int level, Bool nest); static void PrintNames (Value f, NamelistPtr names, int level) { if (!names) return; PrintNames (f, names->next, level); if (names->publish != publish_private) doPrettyPrint (f, names->publish, names->symbol, level, False); } static void PrintNamespace (Value f, NamespacePtr namespace, int level) { PrintNames (f, namespace->names, level); } void doPrettyPrint (Value f, Publish publish, SymbolPtr symbol, int level, Bool nest) { Value v; if (!symbol) return; if (profiling) FilePuts (f, " total(ms) self(ms)\n"); PrettyIndent (f, 0, level); switch (symbol->symbol.class) { case class_const: case class_global: v = BoxValueGet (symbol->global.value, 0); if (v && ValueIsFunc(v)) { PrettyCode (f, v->func.code, symbol->symbol.name, class_undef, publish, level, nest); } else { FilePrintf (f, "%p%k%t%A = %v;", publish, symbol->symbol.class, symbol->symbol.type, symbol->symbol.name, v); } FilePuts (f, "\n"); break; case class_namespace: FilePrintf (f, "%p%C %A", publish, symbol->symbol.class, symbol->symbol.name); if (nest) { FilePuts (f, " {\n"); PrintNamespace (f, symbol->namespace.namespace, level + 1); PrettyIndent (f, 0, level); FilePuts (f, "}\n"); } else FilePuts (f, ";\n"); break; case class_exception: FilePrintf (f, "%p%C %A ", publish, symbol->symbol.class, symbol->symbol.name); PrintArgs (f, symbol->symbol.type->func.args); if (symbol->exception.doc != Void) { FilePuts (f, "\n"); PrettyDoc (f, level + 1, symbol->exception.doc); } FilePuts (f, ";\n"); break; default: FilePrintf (f, "%p%k%t%A;\n", publish, symbol->symbol.class, symbol->symbol.type, symbol->symbol.name); break; } } void PrettyPrint (Value f, Publish publish, SymbolPtr name) { if (!name) PrintNamespace (f, TopNamespace, 0); else doPrettyPrint (f, publish, name, 0, True); } nickle_2.81.orig/config.h0000664000175000000620000001143513202542704014521 0ustar keithpstaff/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if the `getpgrp' function requires zero arguments. */ #define GETPGRP_VOID 1 /* Define to 1 if you have the `dlclose' function. */ #define HAVE_DLCLOSE 1 /* Define to 1 if you have the `dlerror' function. */ #define HAVE_DLERROR 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the `dlopen' function. */ #define HAVE_DLOPEN 1 /* Define to 1 if you have the `dlsym' function. */ #define HAVE_DLSYM 1 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef HAVE_DOPRNT */ /* C compilers can extern program symbols */ #define HAVE_EXTERN_SYMS 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `getrlimit' function. */ #define HAVE_GETRLIMIT 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `hstrerror' function. */ #define HAVE_HSTRERROR 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `dl' library (-ldl). */ #define HAVE_LIBDL 1 /* Define to 1 if you have the `m' library (-lm). */ #define HAVE_LIBM 1 /* Define to 1 if you have the `nsl' library (-lnsl). */ /* #undef HAVE_LIBNSL */ /* support fancy command line editing */ #define HAVE_LIBREADLINE 1 /* Define to 1 if you have the `resolv' library (-lresolv). */ /* #undef HAVE_LIBRESOLV */ /* Define to 1 if you have the `socket' library (-lsocket). */ /* #undef HAVE_LIBSOCKET */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `putenv' function. */ #define HAVE_PUTENV 1 /* Has rl_catch_signals */ #define HAVE_RL_CATCH_SIGNALS 1 /* Has rl_cleanup_after_signal */ #define HAVE_RL_CLEANUP_AFTER_SIGNAL 1 /* Has rl_reset_after_signal */ #define HAVE_RL_RESET_AFTER_SIGNAL 1 /* Define to 1 if you have the `select' function. */ #define HAVE_SELECT 1 /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 /* Define to 1 if you have the `setrlimit' function. */ #define HAVE_SETRLIMIT 1 /* Define to 1 if you have the `sigaction' function. */ #define HAVE_SIGACTION 1 /* Define to 1 if you have the `sigignore' function. */ #define HAVE_SIGIGNORE 1 /* Define to 1 if you have the `sigrelse' function. */ #define HAVE_SIGRELSE 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STROPTS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_RESOURCE_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Has uint64_t datatype */ #define HAVE_UINT64_T 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the `unsetenv' function. */ #define HAVE_UNSETENV 1 /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Name of package */ #define PACKAGE "nickle" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "http://nickle.org" /* Define to the full name of this package. */ #define PACKAGE_NAME "nickle" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "nickle 2.81" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "nickle" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "2.81" /* The size of `unsigned int', as computed by sizeof. */ /* #undef SIZEOF_UNSIGNED_INT */ /* The size of `unsigned long', as computed by sizeof. */ /* #undef SIZEOF_UNSIGNED_LONG */ /* The size of `unsigned long long', as computed by sizeof. */ /* #undef SIZEOF_UNSIGNED_LONG_LONG */ /* The size of `unsigned short', as computed by sizeof. */ /* #undef SIZEOF_UNSIGNED_SHORT */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "2.81" /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #define YYTEXT_POINTER 1 nickle_2.81.orig/file.5c0000664000175000000620000000354510770315534014264 0ustar keithpstaff/* $Header$*/ /* * Copyright © 2003 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ extend namespace File { public file stdnull () { static bool set = false; static file f; if (!set) f = open("/dev/null", "r+"); return f; } public typedef union { file input; file output; file error; } childfd; public int mkchild(string path, string[*] argv, childfd fds ...) /* * Call filter transforming 'fds' into an array of three files. * This is what happens when you fork() */ { file[3] filter_fds = { stdnull(), ... }; for (int i = 0; i < dim(fds); i++) { union switch(fds[i]) { case input f: filter_fds[0] = f; break; case output f: filter_fds[1] = f; break; case error f: filter_fds[2] = f; break; } } return filter(path, argv, filter_fds); } public namespace FileGlobals { public int getchar () /* return getc (stdin); */ { return getc (stdin); } public void ungetchar (int ch) /* ungetc (ch, stdin); */ { ungetc (ch, stdin); } public void putchar (int c) /* putc (c, stdout) */ { putc (c, stdout); } public int getbyte () /* return getb (stdin) */ { return getb (stdin); } public void putbyte (int b) /* putb (b, stdout) */ { putb (b, stdout); } public string fgets (file f) /* * Return a line from 'f' as a string. * The trailing newline will be stripped off. */ { string s; int c; s = ""; while (!end(f)) { c = getc (f); switch (c) { case '\n': return s; default: s = s + String::new (c); } } return s; } public string gets () /* return fgets (stdin); */ { return fgets (stdin); } } public import FileGlobals; } public import File::FileGlobals; nickle_2.81.orig/aclocal.m40000664000175000000620000012655713202542702014755 0ustar keithpstaff# generated automatically by aclocal 1.15.1 -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Copyright (C) 1998-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_LEX # ----------- # Autoconf leaves LEX=: if lex or flex can't be found. Change that to a # "missing" invocation, for better error output. AC_DEFUN([AM_PROG_LEX], [AC_PREREQ([2.50])dnl AC_REQUIRE([AM_MISSING_HAS_RUN])dnl AC_REQUIRE([AC_PROG_LEX])dnl if test "$LEX" = :; then LEX=${am_missing_run}flex fi]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) nickle_2.81.orig/builtin-pid.c0000664000175000000620000001151211663766031015475 0ustar keithpstaff/* * Copyright © 1988-2008 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * builtin-process.c * * provide builtin functions for the PID namespace */ #include #include #include #include #include "builtin.h" NamespacePtr PIDNamespace; static Value do_PID_getuid (void) { ENTER (); RETURN (NewInt (getuid())); } static Value do_PID_geteuid (void) { ENTER (); RETURN (NewInt (geteuid())); } static Value do_PID_getgid (void) { ENTER (); RETURN (NewInt (getgid())); } static Value do_PID_getegid (void) { ENTER (); RETURN (NewInt (getegid())); } static Value error (Value value) { int err = errno; RaiseStandardException (exception_system_error, 3, FileGetErrorMessage (err), NewInt (err), value); return Void; } static Value do_PID_getgroups (void) { ENTER (); int n; gid_t *list; Value ret; int i; n = getgroups (0, NULL); list = AllocateTemp (n * sizeof (gid_t)); if (getgroups (n, list) < 0) RETURN(error(NewInt(n))); ret = NewArray (False, False, typePrim[rep_integer], 1, &n); for (i = 0; i < n; i++) ArrayValueSet(&ret->array, i, NewInt (list[i])); RETURN (ret); } static Value do_PID_getpid (void) { ENTER (); RETURN (NewInt (getpid())); } static Value do_PID_setuid (Value uid) { ENTER (); int u = IntPart (uid, "Invalid uid"); if (aborting) RETURN(Void); if (setuid (u) < 0) RETURN (error (uid)); RETURN (Void); } static Value do_PID_seteuid (Value euid) { ENTER (); int u = IntPart (euid, "Invalid euid"); if (aborting) RETURN(Void); if (seteuid (u) < 0) RETURN (error (euid)); RETURN (Void); } static Value do_PID_setgid (Value gid) { ENTER (); int u = IntPart (gid, "Invalid gid"); if (aborting) RETURN(Void); if (setgid (u) < 0) RETURN (error (gid)); RETURN (Void); } static Value do_PID_setegid (Value egid) { ENTER (); int u = IntPart (egid, "Invalid egid"); if (aborting) RETURN(Void); if (setegid (u) < 0) RETURN (error (egid)); RETURN (Void); } static Value do_PID_setgroups (Value groups) { ENTER (); int n; int i; gid_t *g; n = ArrayLimits (&groups->array)[0]; g = AllocateTemp (n * sizeof (gid_t)); for (i = 0; i < n; i++) { g[i] = IntPart (ArrayValueGet (&groups->array, i), "Invalid gid"); if (aborting) RETURN(Void); } if (setgroups (n, g) < 0) RETURN (error (groups)); RETURN (Void); } void import_PID_namespace (void) { ENTER (); static const struct fbuiltin_0 funcs_0[] = { { do_PID_getuid, "getuid", "i", "", "\n" " int getuid ()\n" "\n" " Return the current uid\n" }, { do_PID_geteuid, "geteuid", "i", "", "\n" " int geteuid ()\n" "\n" " Return the current effective uid\n" }, { do_PID_getgid, "getgid", "i", "", "\n" " int getgid ()\n" "\n" " Return the current gid\n" }, { do_PID_getegid, "getegid", "i", "", "\n" " int getegid ()\n" "\n" " Return the current effective gid\n" }, { do_PID_getgroups, "getgroups", "Ai", "", "\n" " int[*] getgroups ()\n" "\n" " Return the list of additional groups\n" }, { do_PID_getpid, "getpid", "i", "", "\n" " int getpid ()\n" "\n" " Return the current process id." }, { 0 } }; static const struct fbuiltin_1 funcs_1[] = { { do_PID_setuid, "setuid", "v", "i", "\n" " void setuid (int uid)\n" "\n" " Set the current uid." }, { do_PID_seteuid, "seteuid", "v", "i", "\n" " void seteuid (int euid)\n" "\n" " Set the current euid." }, { do_PID_setgid, "setgid", "v", "i", "\n" " void setgid (int gid)\n" "\n" " Set the current gid." }, { do_PID_setegid, "setegid", "v", "i", "\n" " void setegid (int egid)\n" "\n" " Set the current egid." }, { do_PID_setgroups, "setgroups", "v", "Ai", "\n" " void setgroups (int[*] groups)\n" "\n" " Set the list of additional groups." }, { 0 } }; static const struct ebuiltin excepts[] = { {"system_error", exception_system_error, "sEp", "\n" " system_error (string message, error_type error, poly value)\n" "\n" " Raised when a system function fails.\n" " 'message' is a printable error string.\n" " 'error' is a symbolic error code.\n" " 'value' is the value which failed.\n" }, { 0, 0 }, }; const struct ebuiltin *e; PIDNamespace = BuiltinNamespace (/*parent*/ 0, "PID")->namespace.namespace; for (e = excepts; e->name; e++) BuiltinAddException (&PIDNamespace, e->exception, e->name, e->args, e->doc); BuiltinFuncs0 (&PIDNamespace, funcs_0); BuiltinFuncs1 (&PIDNamespace, funcs_1); EXIT (); } nickle_2.81.orig/refer.c0000664000175000000620000000130410414112462014340 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include "mem.h" #include "ref.h" typedef struct _reference { DataType *data; void **object; } Reference; static void ReferenceMark (void *object) { ReferencePtr reference = object; MemReference (*reference->object); } static DataType referenceType = { ReferenceMark, 0, "referenceType" }; ReferencePtr NewReference (void **object) { ReferencePtr reference; reference = MemAllocate (&referenceType, sizeof (Reference)); reference->object = object; return reference; } nickle_2.81.orig/builtin-namespaces.h0000664000175000000620000000161613202404074017034 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ extern void import_Toplevel_namespace(void); extern void import_Debug_namespace(void); extern void import_File_namespace(void); extern void import_History_namespace(void); extern void import_Math_namespace(void); #ifdef BSD_RANDOM extern void import_BSDRandom_namespace(void); #endif extern void import_Semaphore_namespace(void); extern void import_String_namespace(void); extern void import_Thread_namespace(void); extern void import_Command_namespace(void); #ifdef GCD_DEBUG extern void import_Gcd_namespace(void); #endif extern void import_Environ_namespace(void); extern void import_Socket_namespace(void); extern void import_Foreign_namespace(void); extern void import_PID_namespace(void); extern void import_Date_namespace(void); nickle_2.81.orig/compile0000755000175000000620000001624513064665460014476 0ustar keithpstaff#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: nickle_2.81.orig/profile.c0000664000175000000620000000512411663765134014722 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include #include #define TICK_MS 10 volatile static unsigned long currentTick; volatile Bool signalProfile; static unsigned long previousTick; Bool profiling; static void sigprofile (int sig) { resetSignal (SIGVTALRM, sigprofile); currentTick += TICK_MS; SetSignalProfile (); } void ProfileInterrupt (Value thread) { unsigned long now; unsigned long ticks; InstPtr pc; ExprPtr stat; FramePtr frame; now = currentTick; ticks = now - previousTick; previousTick = now; if (!thread) return; pc = thread->thread.continuation.pc; if (pc) { ObjPtr obj = thread->thread.continuation.obj; stat = ObjStatement (obj, pc); if (stat) { stat->base.ticks += ticks; stat->base.line = -stat->base.line - 1; } obj->ticks += ticks; obj->error += 100; } for (frame = thread->thread.continuation.frame; frame; frame = frame->previous) { ObjPtr obj = frame->saveObj; stat = ObjStatement (obj, frame->savePc); if (stat && stat->base.line >= 0) { stat->base.sub_ticks += ticks; stat->base.line = -stat->base.line - 1; } if (obj->error < 100) { obj->sub_ticks += ticks; obj->error += 100; } } for (frame = thread->thread.continuation.frame; frame; frame = frame->previous) { ObjPtr obj = frame->saveObj; stat = ObjStatement (obj, frame->savePc); if (stat) stat->base.line = -stat->base.line + 1; if (obj->error >= 100) obj->error -= 100; } pc = thread->thread.continuation.pc; if (pc) { ObjPtr obj = thread->thread.continuation.obj; stat = ObjStatement (obj, pc); if (stat) stat->base.line = -stat->base.line + 1; if (obj->error >= 100) obj->error -= 100; } } Value do_profile (Value on) { struct itimerval v; Bool previous = profiling; if (True (on)) { previousTick = currentTick; catchSignal (SIGVTALRM, sigprofile); v.it_interval.tv_sec = 0; v.it_interval.tv_usec = TICK_MS * 1000; v.it_value = v.it_interval; setitimer (ITIMER_VIRTUAL, &v, 0); profiling = True; } else { v.it_interval.tv_sec = 0; v.it_interval.tv_usec = 0; v.it_value = v.it_interval; setitimer (ITIMER_VIRTUAL, &v, 0); profiling = False; /* * expr nodes clear their accumulated time * on GC when profiling is false */ MemCollect (); } return previous ? TrueVal : FalseVal; } nickle_2.81.orig/factorial.5c0000664000175000000620000000431111414530466015300 0ustar keithpstaff/* * Copyright © 2010 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ extend namespace Math { /* * PrimeSwing factorial algorithm by Peter Luschny * * Translated from the Java version as found here: * * http://www.luschny.de/math/factorial/FastFactorialFunctions.htm * * That code was released under the MIT license using this reference: * * http://www.opensource.org/licenses/mit-license.php * * This code is functionally equivalent, although is not a direct copy */ public int factorial(int n) /* * Return the factorial of 'n' */ { /* For small values, just do it the naïve way */ if (n < 20) { int r = 1; while (n > 0) { r *= n; n--; } return r; } int plen = 2 * floor(sqrt(n) + n / (log2(n) - 1)); int[plen] prime_list; int[] primes = PrimeSieve::primes(n); static int[] smallOddSwing = { 1, 1, 1, 3, 3, 15, 5, 35, 35, 315, 63, 693, 231, 3003, 429, 6435, 6435, 109395, 12155, 230945, 46189, 969969, 88179, 2028117, 676039, 16900975, 1300075, 35102025, 5014575, 145422675, 9694845, 300540195, 300540195 }; /* Compute the swing factorial of 'n' */ int swing(int n) { if (n < dim(smallOddSwing)) return smallOddSwing[n]; int sqrt_n = floor(sqrt(n)); PrimeSieve::range_t r1 = PrimeSieve::primes_range(&primes, 3, sqrt_n); PrimeSieve::range_t r2 = PrimeSieve::primes_range(&primes, sqrt_n + 1, n // 3); int count = 0; for (int i_p = r1.start; i_p < r1.end; i_p++) { int prime = primes[i_p]; int q = n, p = 1; while ((q //= prime) > 0) if ((q & 1) == 1) p *= prime; if (p > 1) prime_list[count++] = p; } for (int i_p = r2.start; i_p < r2.end; i_p++) { int prime = primes[i_p]; if (((n // prime) & 1) == 1) prime_list[count++] = prime; } int prod = PrimeSieve::primorial(&primes, n // 2 + 1, n); for (int i = 0; i < count; i++) prod *= prime_list[i]; return prod; } /* Final factorial computation */ int recursive_factorial(int n) { if (n < 2) return 1; return recursive_factorial(n>>1) ** 2 * swing(n); } return recursive_factorial(n) << (n - popcount(n)); } } nickle_2.81.orig/builtin-command.c0000664000175000000620000001436110770377745016354 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * command.c * * provide builtin functions for the Command namespace */ #include #include #include #include "builtin.h" NamespacePtr CommandNamespace; void import_Command_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { { do_Command_delete, "delete", "b", "s", "\n" " bool delete(string command)\n" "\n" " Remove 'command' from the set of valid commands\n" }, { do_Command_edit, "edit", "v", "A*s", "\n" " void edit(string[*] function)\n" "\n" " Invoke $EDITOR on 'function', parse the file when done\n" }, { do_Command_display, "display", "v", "p", "\n" " void display (poly value)\n" "\n" " Built-in display primitive for read/eval/print loop" }, { do_Command_valid_name, "valid_name", "b", "A*s", "\n" " bool valid_name (string[*] name)\n" "\n" " Check for a symbol table entry\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_Command_new, "new", "v", "sp", "\n" " void new (string name, poly f)\n" "\n" " Create a new command which calls 'f'.\n" " 'f' will be invoked with an array of values\n" }, { do_Command_new_names, "new_names", "v", "sp", "\n" " void new_names (string name, poly f)\n" "\n" " Create a new command which calls 'f' with literal arguments.\n" " 'f' will be invoked with an array of strings\n" }, { 0 } }; static const struct fbuiltin_4 funcs_4[] = { { do_Command_lex_input, "lex_input", "b", "fsbb", "\n" " bool lex_input (file f, string name, bool after, bool interactive)" "\n" " Add 'f' to the list of files to be read by the lexer.\n" " 'name' will be used when reporting parse errors.\n" " If 'after', the specified file will be read when all other\n" " input sources are exhausted.\n" " If 'interactive', the lexer will display prompts as if\n" " input was coming from a terminal.\n" }, { 0 } }; static const struct fbuiltin_v funcs_v[] = { { do_Command_undefine, "undefine", "v", ".A*s", "\n" " void undefine (string[*] ... name)\n" "\n" " removes 'name' from its namespace\n" }, { do_Command_pretty_print, "pretty_print", "v", "f.A*s", "\n" " void pretty_print (file f, string[*] ... name)\n" "\n" " Prints the variable and value in a format capable of\n" " reproducing the value if fed back to the parser\n" }, { 0 } }; CommandNamespace = BuiltinNamespace (/*parent*/ 0, "Command")->namespace.namespace; BuiltinFuncs1 (&CommandNamespace, funcs_1); BuiltinFuncs2 (&CommandNamespace, funcs_2); BuiltinFuncs4 (&CommandNamespace, funcs_4); BuiltinFuncsV (&CommandNamespace, funcs_v); EXIT (); } static char * command_name (Value name) { char *cmd_base = StrzPart (name, "argument must be valid name"); char *cmd = cmd_base; int c; if (!cmd_base) return 0; while ((c = *cmd++)) { if (isupper (c) || islower (c)) continue; if (cmd != cmd_base + 1) { if (isdigit ((int)c) || c == '_') continue; } RaiseStandardException (exception_invalid_argument, 3, NewStrString ("argument must be valid name"), NewInt (0), name); return 0; } return cmd_base; } static Value do_Command_new_common (Value name, Value func, Bool names) { ENTER(); char *cmd = command_name (name); if (!cmd) RETURN (Void); if (!ValueIsFunc(func)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("argument must be func"), NewInt (1), func); RETURN (Void); } CurrentCommands = NewCommand (CurrentCommands, AtomId (cmd), func, names); RETURN (Void); } Value do_Command_new (Value name, Value func) { return do_Command_new_common (name, func, False); } Value do_Command_new_names (Value name, Value func) { return do_Command_new_common (name, func, True); } Value do_Command_delete (Value name) { ENTER(); Atom id; char *cmd = command_name (name); if (!cmd) RETURN (Void); id = AtomId (cmd); if (!CommandFind (CurrentCommands, id)) RETURN (FalseVal); CurrentCommands = CommandRemove (CurrentCommands, id); RETURN (TrueVal); } Value do_Command_pretty_print (int argc, Value *args) { ENTER(); Value f; Value names; NamespacePtr namespace; SymbolPtr symbol; Publish publish; int i; f = args[0]; if (argc == 1) { PrettyPrint (f, publish_public, 0); RETURN (Void); } for (i = 1; i < argc; i++) { names = args[i]; if (NamespaceLocate (names, &namespace, &symbol, &publish, False)) PrettyPrint (f, publish, symbol); else RaiseStandardException (exception_invalid_argument, 3, NewStrString ("name not found"), NewInt (i), names); } RETURN (Void); } Value do_Command_undefine (int argc, Value *args) { ENTER (); NamespacePtr namespace; SymbolPtr symbol; Publish publish; int i; for (i = 0; i < argc; i++) if (NamespaceLocate (args[i], &namespace, &symbol, &publish, True)) NamespaceRemoveName (namespace, symbol->symbol.name); RETURN (Void); } Value do_Command_valid_name (Value names) { ENTER (); NamespacePtr namespace; SymbolPtr symbol; Publish publish; Value ret; if (NamespaceLocate (names, &namespace, &symbol, &publish, False)) ret = TrueVal; else ret = FalseVal; RETURN (ret); } Value do_Command_edit (Value names) { ENTER(); NamespacePtr namespace; SymbolPtr symbol; Publish publish; if (NamespaceLocate (names, &namespace, &symbol, &publish, True)) EditFunction (symbol, publish); RETURN (Void); } Value do_Command_display (Value v) { ENTER (); FilePrintf (FileStdout, "%v\n", v); RETURN (Void); } Value do_Command_lex_input (Value file, Value name, Value after, Value interactive) { ENTER (); NewLexInput (file, AtomId (StringChars (&name->string)), after == TrueVal, interactive == TrueVal); RETURN (TrueVal); } nickle_2.81.orig/builtin-date.c0000664000175000000620000001242313202542656015634 0ustar keithpstaff/* * Copyright © 2017 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * date.c * * provide builtin functions for the Date namespace */ #include #include #include #include "builtin.h" NamespacePtr DateNamespace; static Type *typeDate; #define DATE_I 0 #define DATE_S "00" static Value int_value(int s) { return Reduce(NewSignedDigitInteger((signed_digit) s)); } static int value_int(Value s, Atom member, char *error, int def) { Value ref = StructMemRef(s, AtomId(member)); Value mem; if (ref == 0) return def; mem = RefValueGet(ref); if (mem == 0) return def; return IntPart(mem, error); } static int value_bool(Value s, Atom member, char *error, int def) { Value ref = StructMemRef(s, AtomId(member)); Value mem; if (ref == 0) return def; mem = RefValueGet(ref); if (mem == 0) return def; return BoolPart(mem, error); } static Value to_date(struct tm *tm) { Value ret; BoxPtr box; ret = NewStruct(TypeCanon(typeDate)->structs.structs, False); box = ret->structs.values; BoxValueSet (box, 0, int_value(tm->tm_sec)); BoxValueSet (box, 1, int_value(tm->tm_min)); BoxValueSet (box, 2, int_value(tm->tm_hour)); BoxValueSet (box, 3, int_value(tm->tm_mday)); BoxValueSet (box, 4, int_value(tm->tm_mon + 1)); BoxValueSet (box, 5, int_value(tm->tm_year + 1900)); BoxValueSet (box, 6, int_value(tm->tm_wday)); BoxValueSet (box, 7, int_value(tm->tm_yday)); BoxValueSet (box, 8, tm->tm_isdst ? TrueVal : FalseVal); BoxValueSet (box, 9, NewStrString(tm->tm_zone)); return ret; } static void from_date(Value date, struct tm *tm) { tm->tm_sec = value_int(date, "sec", "invalid sec", 0); tm->tm_min = value_int(date, "min", "invalid min", 0); tm->tm_hour = value_int(date, "hour", "invalid hour", 0); tm->tm_mday = value_int(date, "mday", "invalid mday", 1); tm->tm_mon = value_int(date, "mon", "invalid mon", 1) - 1; tm->tm_year = value_int(date, "year", "invalid year", 1970) - 1900; tm->tm_wday = value_int(date, "wday", "invalid wday", 0); tm->tm_yday = value_int(date, "yday", "invalid yday", 0); tm->tm_isdst = value_bool(date, "isdst", "invalid isdst", 0); tm->tm_zone = NULL; } static Value do_Date_gmtime(Value v) { ENTER(); time_t seconds = SignedDigitPart(v, "Illegal time"); struct tm result; if (aborting) RETURN(Void); gmtime_r(&seconds, &result); RETURN(to_date(&result)); } static Value do_Date_localtime(Value v) { ENTER(); time_t seconds = SignedDigitPart(v, "Illegal time"); struct tm result; if (aborting) RETURN(Void); localtime_r(&seconds, &result); RETURN(to_date(&result)); } static Value do_Date_timegm(Value v) { ENTER(); struct tm tm; time_t seconds; from_date(v, &tm); seconds = timegm(&tm); RETURN(Reduce(NewSignedDigitInteger((signed_digit) seconds))); } static Value do_Date_timelocal(Value v) { ENTER(); struct tm tm; time_t seconds; from_date(v, &tm); seconds = timelocal(&tm); RETURN(Reduce(NewSignedDigitInteger((signed_digit) seconds))); } static Type * make_typedef (char *name_str, Namespace *namespace, Publish publish, int usertype_id, Symbol **sret, Type *type) { ENTER (); Atom name = AtomId (name_str); Symbol *sym = NewSymbolType (name, type); Type *typed = NewTypeName (NewExprAtom (name, 0, False), sym); NamespaceAddName (namespace, sym, publish); BuiltinSetUserdefType (typed, usertype_id); MemAddRoot (typed); if (sret) *sret = sym; RETURN (typed); } void import_Date_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { { do_Date_gmtime, "gmtime", DATE_S, "i", "\n" " date_t gmtime (int time)\n" "\n" " Convert 'time' into a date_t structure using UTC.\n" }, { do_Date_localtime, "localtime", DATE_S, "i", "\n" " date_t localtime (int time)\n" "\n" " Convert 'time' into a date_t structure using the local timezone.\n" }, { do_Date_timegm, "timegm", "i", DATE_S, "\n" " int timegm (date_t date)\n" "\n" " Convert 'date' into seconds using UTC.\n" }, { do_Date_timelocal, "timelocal", "i", DATE_S, "\n" " int timelocal (date_t date)\n" "\n" " Convert 'date' into seconds using the local timezone.\n" }, { do_Date_timelocal, "mktime", "i", DATE_S, "\n" " int mktime (date_t date)\n" "\n" " Convert 'date' into seconds using the local timezone.\n" }, { 0 } }; DateNamespace = BuiltinNamespace (/*parent*/ 0, "Date")->namespace.namespace; typeDate = make_typedef("date_t", DateNamespace, publish_public, DATE_I, NULL, BuildStructType (10, typePrim[rep_integer], "sec", typePrim[rep_integer], "min", typePrim[rep_integer], "hour", typePrim[rep_integer], "mday", typePrim[rep_integer], "mon", typePrim[rep_integer], "year", typePrim[rep_integer], "wday", typePrim[rep_integer], "yday", typePrim[rep_bool], "isdst", typePrim[rep_string], "zone")); BuiltinFuncs1 (&DateNamespace, funcs_1); EXIT (); } nickle_2.81.orig/prime_sieve.5c0000664000175000000620000000465111414535476015660 0ustar keithpstaff/* * Copyright © 2010 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ public namespace PrimeSieve { int num_to_pos(int n) = (n - 3) // 2; int pos_to_num(int p) = (p * 2) + 3; /* Generate a list of primes from a boolean array of composite * test results */ int[] sieve_to_array(&bool[] composite, int n_prime) { int[n_prime] primes; int p = 0; for (int i = 0; i < dim(composite); i++) if (!composite[i]) primes[p++] = pos_to_num(i); return primes; } /* Use the sieve of Eratosthenes to compute the set of * primes <= max */ public int[] primes (int max) { int n = num_to_pos(max) + 1; bool[n] composite = { false ... }; int n_prime = 0; for (int p = 0; p < n; p++) { if (!composite[p]) { int prime = pos_to_num(p); int step = prime; int init = p + prime; for (int v = init; v < n; v += step) composite[v] = true; n_prime++; } } return sieve_to_array(&composite, n_prime); } public typedef struct { int start, end; } range_t; /* Binary search in a list of numbers for the value <= 'v' */ public int primes_search(&int[] primes, int v) { int min = 0, max = dim(primes); while (min < max) { int mid = (max + min) >> 1; int p = primes[mid]; if (p == v) return mid; if (p > v) max = mid; else { if (min == mid) return mid; min = mid; } } return min; } /* Return the indices within a list of primes such that * primes[start] <= min && max < primes[end] */ public range_t primes_range(&int[] primes, int min, int max) { int start = primes_search(&primes, min); if (primes[start] < min) start++; int end = primes_search(&primes, max) + 1; return (range_t) { start = start, end = end }; } /* * Multiply all primes between min and max within the * supplied list. */ public int primorial(&int[] primes, int min, int max) { range_t r = primes_range(&primes, min, max); int v = 1; for (int i = r.start; i < r.end; i++) v *= primes[i]; return v; } } nickle_2.81.orig/builtin-foreign.c0000664000175000000620000000336510770315535016356 0ustar keithpstaff/* $Header$ */ /* * Copyright © 2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include #include #include #include "builtin.h" NamespacePtr ForeignNamespace; #if HAVE_EXTERN_SYMS #if HAVE_DLFCN_H && HAVE_DLOPEN && HAVE_DLSYM #define HAVE_FOREIGN_LOAD 1 #include static Value do_Foreign_load (Value av) { ENTER (); char *name = StrzPart (av, "invalid foreign module name"); void *lib; Value (*init) (void); Value ret = False; if (!name) RETURN (Void); lib = dlopen (name, RTLD_NOW); if (!lib) { char *err = 0; int e = errno; #if HAVE_DLERROR err = dlerror (); #endif if (!err) err = "cannot open"; RaiseStandardException (exception_open_error, 3, NewStrString (err), NewInt(e), av); RETURN (Void); } init = (Value (*) (void)) dlsym (lib, "nickle_init"); if (!init) { char *err = 0; #if HAVE_DLERROR err = dlerror (); #endif if (!err) err = "missing nickle_init"; RaiseStandardException (exception_open_error, 3, NewStrString (err), NewInt (0), av); #if HAVE_DLCLOSE dlclose (lib); #endif RETURN (Void); } ret = (*init) (); RETURN (ret); } #endif #endif void import_Foreign_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { #if HAVE_EXTERN_SYMS && HAVE_FOREIGN_LOAD { do_Foreign_load, "load", "b", "s", "\n" " bool load (string name)\n" "\n" " Load a foreign library into nickle\n" }, #endif { 0 } }; ForeignNamespace = BuiltinNamespace (/*parent*/ 0, "Foreign")->namespace.namespace; BuiltinFuncs1 (&ForeignNamespace, funcs_1); EXIT (); } nickle_2.81.orig/box.c0000664000175000000620000000734313062260671014046 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static void BoxMark (void *object) { BoxPtr box = object; Value *elements; int i; elements = BoxElements(box); if (box->replace) MemReference (box->u.replace); else if (box->homogeneous) MemReference (box->u.type); else MemReference (box->u.types); for (i = 0; i < box->nvalues; i++) MemReference (elements[i]); } DataType BoxType = { BoxMark, 0, "BoxType" }; BoxPtr NewBox (Bool constant, Bool array, int nvalues, TypePtr type) { ENTER (); BoxPtr box; int i; box = ALLOCATE (&BoxType, sizeof (Box) + nvalues * sizeof (Value)); box->constant = constant; box->homogeneous = True; box->replace = False; box->nvalues = nvalues; box->u.type = type; for (i = 0; i < nvalues; i++) BoxValueSet(box, i, 0); RETURN (box); } BoxPtr NewTypedBox (Bool array, BoxTypesPtr bt) { ENTER (); BoxPtr box; int i; box = ALLOCATE (&BoxType, sizeof (Box) + bt->count * sizeof (Value)); box->constant = False; box->homogeneous = False; box->replace = False; box->nvalues = bt->count; box->u.types = bt; for (i = 0; i < bt->count; i++) BoxValueSet (box, i, 0); RETURN (box); } static void MarkBoxReplace (void *object) { BoxReplacePtr replace = object; MemReference (replace->new); } DataType BoxReplaceType = { MarkBoxReplace, 0, "BoxReplaceType" }; void BoxSetReplace (BoxPtr old, BoxPtr new, int oldstride, int newstride) { ENTER (); BoxReplacePtr r = ALLOCATE (&BoxReplaceType, sizeof (BoxReplace)); r->new = new; r->oldstride = oldstride; r->newstride = newstride; old->replace = True; old->u.replace = r; EXIT (); } BoxPtr BoxRewrite (BoxPtr box, int *ep) { int e = *ep; while (box->replace) { BoxReplacePtr r = box->u.replace; int chunk, off; chunk = e / r->oldstride; off = e % r->oldstride; e = chunk * r->newstride + off; box = r->new; } /* * XXX oops. References to previously available storage * should do something sensible instead of cratering. * The desired semantic is for them to persist, pointing * to whatever storage was there before the underlying object * was resized. But, that's "hard". This check will * at least prevent a seg fault. */ if (e >= box->nvalues) { RaiseStandardException (exception_invalid_array_bounds, 2, Void, NewInt (e)); e = 0; box = NewBox (True, False, 1, typePrim[rep_void]); BoxValueSet (box, 0, 0); } *ep = e; return box; } static void MarkBoxTypes (void *object) { BoxTypesPtr bt = object; int i; for (i = 0; i < bt->count; i++) MemReference (BoxTypesValue(bt,i)); } DataType BoxTypesType = { MarkBoxTypes, 0, "BoxTypesType" }; #define BT_INCR 4 BoxTypesPtr NewBoxTypes (int size) { ENTER (); BoxTypesPtr bt; bt = ALLOCATE (&BoxTypesType, sizeof (BoxTypes) + size * sizeof (Type *)); bt->size = size; bt->count = 0; RETURN (bt); } int AddBoxType (BoxTypesPtr *btp, Type *t) { ENTER (); BoxTypesPtr bt, new; int count, size; int position; bt = *btp; if (!bt) { count = 0; size = 0; } else { count = bt->count; size = bt->size; } if (count == size) { size = size + BT_INCR; new = NewBoxTypes (size); if (count) { memcpy (BoxTypesElements (new), BoxTypesElements (bt), count * sizeof (Type *)); } new->size = size; new->count = count; *btp = new; bt = new; } position = bt->count++; BoxTypesValueSet(bt,position,t); EXIT (); return position; } nickle_2.81.orig/nickle.spec.in0000664000175000000620000000264412046261235015635 0ustar keithpstaffSummary: Desk calculator language, similar to C. Name: nickle Version: @VERSION@ Release: 1 Group: Development/Languages License: MIT URL: http://nickle.org Source: http://nickle.org/release/nickle-%{version}.tar.gz Buildroot: %{_tmppath}/%{name}-%{version}-root %description Nickle is a desk calculator language with powerful programming and scripting capabilities. Nickle supports a variety of datatypes, especially arbitrary precision integers, rationals, and imprecise reals. The input language vaguely resembles C. Some things in C which do not translate easily are different, some design choices have been made differently, and a very few features are simply missing. %prep %setup -q %build export CFLAGS="$RPM_OPT_FLAGS" %configure make %install [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT #mkdir -p $RPM_BUILD_ROOT%{prefix} %makeinstall #make prefix=$RPM_BUILD_ROOT%{prefix} install cp -R examples $RPM_BUILD_ROOT%{_datadir}/nickle/ %files %defattr(-,root,root) %doc README README.name COPYING AUTHORS INSTALL NEWS TODO doc/tutorial/nickle-tutorial.pdf %attr(755,root,root) %{_bindir}/nickle %dir %{_datadir}/nickle %{_mandir}/man1/nickle.1* %{_datadir}/nickle/* %dir %{_includedir}/nickle %{_includedir}/nickle/* %exclude %{_datadir}/doc/nickle/* %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT %changelog * Thu Mar 1 2004 Mike A. Harris 2.29-2 - Initial rpm spec file nickle_2.81.orig/missing0000755000175000000620000001533013064666316014512 0ustar keithpstaff#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: nickle_2.81.orig/gram.h0000664000175000000620000000664413064744544014224 0ustar keithpstaff#define VAR 257 #define EXPR 258 #define ARRAY 259 #define STRUCT 260 #define UNION 261 #define ENUM 262 #define COMP 263 #define HASH 264 #define SEMI 265 #define MOD 266 #define OC 267 #define CC 268 #define DOLLAR 269 #define DOTDOTDOT 270 #define ENDFILE 271 #define GLOBAL 272 #define AUTO 273 #define STATIC 274 #define CONST 275 #define POLY 276 #define INTEGER 277 #define NATURAL 278 #define RATIONAL 279 #define REAL 280 #define STRING 281 #define FOREIGN 282 #define FILET 283 #define MUTEX 284 #define SEMAPHORE 285 #define CONTINUATION 286 #define THREAD 287 #define VOID 288 #define BOOL 289 #define FUNCTION 290 #define FUNC 291 #define EXCEPTION 292 #define RAISE 293 #define TYPEDEF 294 #define IMPORT 295 #define NEW 296 #define ANONINIT 297 #define NAMESPACE 298 #define PUBLIC 299 #define PROTECTED 300 #define EXTEND 301 #define WHILE 302 #define DO 303 #define FOR 304 #define SWITCH 305 #define BREAK 306 #define CONTINUE 307 #define RETURNTOK 308 #define FORK 309 #define CASE 310 #define DEFAULT 311 #define TWIXT 312 #define NAME 313 #define TYPENAME 314 #define NAMESPACENAME 315 #define COMMAND 316 #define NAMECOMMAND 317 #define TEN_NUM 318 #define OCTAL0_NUM 319 #define OCTAL_NUM 320 #define BINARY_NUM 321 #define HEX_NUM 322 #define TEN_FLOAT 323 #define OCTAL0_FLOAT 324 #define OCTAL_FLOAT 325 #define BINARY_FLOAT 326 #define HEX_FLOAT 327 #define CHAR_CONST 328 #define STRING_CONST 329 #define POLY_CONST 330 #define THREAD_CONST 331 #define COMMENT_CONST 332 #define VOIDVAL 333 #define BOOLVAL 334 #define DARROW 335 #define ISTYPE 336 #define HASMEMBER 337 #define POUND 338 #define COMMA 339 #define ASSIGN 340 #define ASSIGNPLUS 341 #define ASSIGNMINUS 342 #define ASSIGNTIMES 343 #define ASSIGNDIVIDE 344 #define ASSIGNDIV 345 #define ASSIGNMOD 346 #define ASSIGNPOW 347 #define ASSIGNSHIFTL 348 #define ASSIGNSHIFTR 349 #define ASSIGNLXOR 350 #define ASSIGNLAND 351 #define ASSIGNLOR 352 #define ASSIGNOR 353 #define ASSIGNAND 354 #define QUEST 355 #define COLON 356 #define OR 357 #define AND 358 #define LOR 359 #define LXOR 360 #define LAND 361 #define EQ 362 #define NE 363 #define LT 364 #define GT 365 #define LE 366 #define GE 367 #define SHIFTL 368 #define SHIFTR 369 #define PLUS 370 #define MINUS 371 #define TIMES 372 #define DIVIDE 373 #define DIV 374 #define POW 375 #define STARSTAR 376 #define POW2 377 #define POW3 378 #define UNIONCAST 379 #define UMINUS 380 #define BANG 381 #define FACT 382 #define LNOT 383 #define INC 384 #define DEC 385 #define STAR 386 #define AMPER 387 #define THREADID 388 #define OS 389 #define CS 390 #define DOT 391 #define ARROW 392 #define STAROS 393 #define CALL 394 #define OP 395 #define CP 396 #define POINTER 397 #define COLONCOLON 398 #define IF 399 #define TRY 400 #define NONL 401 #define ELSE 402 #define CATCH 403 #define NL 404 #ifdef YYSTYPE #undef YYSTYPE_IS_DECLARED #define YYSTYPE_IS_DECLARED 1 #endif #ifndef YYSTYPE_IS_DECLARED #define YYSTYPE_IS_DECLARED 1 typedef union { int ints; Value value; Class class; ArgType *argType; Type *type; Publish publish; ExprPtr expr; Atom atom; DeclListPtr declList; MemListPtr memList; Fulltype fulltype; ArgDecl argDecl; SymbolPtr symbol; NamespacePtr namespace; CodePtr code; Bool bool; AtomListPtr atomList; FuncDecl funcDecl; } YYSTYPE; #endif /* !YYSTYPE_IS_DECLARED */ extern YYSTYPE yylval; nickle_2.81.orig/configure0000775000175000000620000061550413202542702015017 0ustar keithpstaff#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for nickle 2.81. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and http://nickle.org $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do $0: have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='nickle' PACKAGE_TARNAME='nickle' PACKAGE_VERSION='2.81' PACKAGE_STRING='nickle 2.81' PACKAGE_BUGREPORT='http://nickle.org' PACKAGE_URL='' ac_unique_file="nickle.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS nicklelibdir HASDOCBOOK_FALSE HASDOCBOOK_TRUE DOCBOOK2PDF EGREP GREP CPP NICKLE_LDFLAGS YACC LEXLIB LEX_OUTPUT_ROOT LEX LN_S am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC RELEASE_DATE MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking with_readline ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures nickle 2.81 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/nickle] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of nickle 2.81:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-readline=DIR GNU readline library in DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF nickle configure 2.81 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------- ## ## Report this to http://nickle.org ## ## -------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by nickle $as_me 2.81, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu RELEASE_DATE="2017-11-14" ac_config_headers="$ac_config_headers config.h" ac_aux_dir= for ac_dir in . "$srcdir"/.; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='nickle' VERSION='2.81' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi for ac_prog in byacc yacc bison do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" case "$YACC" in *bison) YACC="$YACC -y" ;; esac ac_fn_c_check_func "$LINENO" "log" "ac_cv_func_log" if test "x$ac_cv_func_log" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log in -lm" >&5 $as_echo_n "checking for log in -lm... " >&6; } if ${ac_cv_lib_m_log+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char log (); int main () { return log (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_log=yes else ac_cv_lib_m_log=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_log" >&5 $as_echo "$ac_cv_lib_m_log" >&6; } if test "x$ac_cv_lib_m_log" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi fi ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi fi ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if ${ac_cv_lib_socket_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_socket=yes else ac_cv_lib_socket_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hstrerror in -lresolv" >&5 $as_echo_n "checking for hstrerror in -lresolv... " >&6; } if ${ac_cv_lib_resolv_hstrerror+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char hstrerror (); int main () { return hstrerror (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_hstrerror=yes else ac_cv_lib_resolv_hstrerror=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_hstrerror" >&5 $as_echo "$ac_cv_lib_resolv_hstrerror" >&6; } if test "x$ac_cv_lib_resolv_hstrerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRESOLV 1 _ACEOF LIBS="-lresolv $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Wl,-E" >&5 $as_echo_n "checking to see if compiler understands -Wl,-E... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wl,-E" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0 ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes; then GCC_EXTERN="yes" true else GCC_EXTERN="no" true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } if test $GCC_EXTERN = yes; then NICKLE_LDFLAGS="-Wl,-E" $as_echo "#define HAVE_EXTERN_SYMS 1" >>confdefs.h else NICKLE_LDFLAGS="" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in fcntl.h strings.h time.h sys/time.h unistd.h sys/resource.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stropts.h do : ac_fn_c_check_header_mongrel "$LINENO" "stropts.h" "ac_cv_header_stropts_h" "$ac_includes_default" if test "x$ac_cv_header_stropts_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STROPTS_H 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done for ac_header in stdint.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" if test "x$ac_cv_header_stdint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H 1 _ACEOF fi done case "$ac_cv_header_stdint_h" in no) # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5 $as_echo_n "checking size of unsigned long long... " >&6; } if ${ac_cv_sizeof_unsigned_long_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5 $as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 $as_echo_n "checking size of unsigned long... " >&6; } if ${ac_cv_sizeof_unsigned_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 $as_echo "$ac_cv_sizeof_unsigned_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 $as_echo_n "checking size of unsigned int... " >&6; } if ${ac_cv_sizeof_unsigned_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 $as_echo "$ac_cv_sizeof_unsigned_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5 $as_echo_n "checking size of unsigned short... " >&6; } if ${ac_cv_sizeof_unsigned_short+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_short=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5 $as_echo "$ac_cv_sizeof_unsigned_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short _ACEOF ;; yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint64_t" >&5 $as_echo_n "checking for uint64_t... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uint64_t" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_UINT64_T 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f conftest* ;; esac for ac_func in vprintf do : ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" if test "x$ac_cv_func_vprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VPRINTF 1 _ACEOF ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes; then : $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h fi fi done for ac_func in unsetenv setenv putenv gettimeofday hstrerror select do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in sigaction sigrelse sigignore setrlimit getrlimit do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in dlopen dlsym dlerror dlclose do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_prog in docbook2pdf do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOCBOOK2PDF+:} false; then : $as_echo_n "(cached) " >&6 else case $DOCBOOK2PDF in [\\/]* | ?:[\\/]*) ac_cv_path_DOCBOOK2PDF="$DOCBOOK2PDF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DOCBOOK2PDF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DOCBOOK2PDF=$ac_cv_path_DOCBOOK2PDF if test -n "$DOCBOOK2PDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOCBOOK2PDF" >&5 $as_echo "$DOCBOOK2PDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DOCBOOK2PDF" && break done if test -n "$DOCBOOK2PDF"; then HASDOCBOOK_TRUE= HASDOCBOOK_FALSE='#' else HASDOCBOOK_TRUE='#' HASDOCBOOK_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getpgrp requires zero arguments" >&5 $as_echo_n "checking whether getpgrp requires zero arguments... " >&6; } if ${ac_cv_func_getpgrp_void+:} false; then : $as_echo_n "(cached) " >&6 else # Use it with a single arg. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { getpgrp (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_func_getpgrp_void=no else ac_cv_func_getpgrp_void=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpgrp_void" >&5 $as_echo "$ac_cv_func_getpgrp_void" >&6; } if test $ac_cv_func_getpgrp_void = yes; then $as_echo "#define GETPGRP_VOID 1" >>confdefs.h fi doit=yes # Check whether --with-readline was given. if test "${with_readline+set}" = set; then : withval=$with_readline; doit=$with_readline fi case $doit in no) ;; *) readline_header="readline" readline_libdir="" case $doit in yes) ;; *) readline_libdir="-L$doit/lib -R$doit/lib" readline_incdir="-I$doit/include" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tparm in -lncurses" >&5 $as_echo_n "checking for tparm in -lncurses... " >&6; } if ${ac_cv_lib_ncurses_tparm+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lncurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tparm (); int main () { return tparm (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ncurses_tparm=yes else ac_cv_lib_ncurses_tparm=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tparm" >&5 $as_echo "$ac_cv_lib_ncurses_tparm" >&6; } if test "x$ac_cv_lib_ncurses_tparm" = xyes; then : TERMLIB=-lncurses else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 $as_echo_n "checking for tgetent in -ltermcap... " >&6; } if ${ac_cv_lib_termcap_tgetent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltermcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_termcap_tgetent=yes else ac_cv_lib_termcap_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 $as_echo "$ac_cv_lib_termcap_tgetent" >&6; } if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : TERMLIB=-ltermcap fi fi saved_LIBS="$LIBS" LIBS="$LIBS $TERMLIB" saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $readline_libdir" saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $readline_incdir" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_readline_readline=yes else ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } if test "x$ac_cv_lib_readline_readline" = xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" if test "x$ac_cv_header_readline_readline_h" = xyes; then : LIBS="$saved_LIBS -lreadline $TERMLIB" $as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cannot find readline. Build with --without-readline or set the readline path appropriately." >&5 $as_echo "Cannot find readline. Build with --without-readline or set the readline path appropriately." >&6; } exit 1 fi ;; esac if test "x$ac_cv_header_readline_readline_h" = xyes; then ac_fn_c_check_decl "$LINENO" "rl_catch_signals" "ac_cv_have_decl_rl_catch_signals" "#include " if test "x$ac_cv_have_decl_rl_catch_signals" = xyes; then : $as_echo "#define HAVE_RL_CATCH_SIGNALS 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "rl_reset_after_signal" "ac_cv_have_decl_rl_reset_after_signal" "#include " if test "x$ac_cv_have_decl_rl_reset_after_signal" = xyes; then : $as_echo "#define HAVE_RL_RESET_AFTER_SIGNAL 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "rl_cleanup_after_signal" "ac_cv_have_decl_rl_cleanup_after_signal" "#include " if test "x$ac_cv_have_decl_rl_cleanup_after_signal" = xyes; then : $as_echo "#define HAVE_RL_CLEANUP_AFTER_SIGNAL 1" >>confdefs.h fi fi if test "x$prefix" = xNONE; then prefix="$ac_default_prefix" fi nicklelibdir=`eval echo ${datadir}`/nickle ac_config_files="$ac_config_files Makefile test/Makefile bench/Makefile examples/Makefile examples/smlng/Makefile examples/turtle/Makefile doc/Makefile doc/tutorial/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HASDOCBOOK_TRUE}" && test -z "${HASDOCBOOK_FALSE}"; then as_fn_error $? "conditional \"HASDOCBOOK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by nickle $as_me 2.81, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ nickle config.status 2.81 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; "bench/Makefile") CONFIG_FILES="$CONFIG_FILES bench/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "examples/smlng/Makefile") CONFIG_FILES="$CONFIG_FILES examples/smlng/Makefile" ;; "examples/turtle/Makefile") CONFIG_FILES="$CONFIG_FILES examples/turtle/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/tutorial/Makefile") CONFIG_FILES="$CONFIG_FILES doc/tutorial/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi nickle_2.81.orig/doc/0002775000175000000620000000000013202543025013643 5ustar keithpstaffnickle_2.81.orig/doc/Makefile.am0000664000175000000620000000002012045633647015703 0ustar keithpstaffSUBDIRS=tutorialnickle_2.81.orig/doc/Makefile.in0000664000175000000620000004245613202542702015722 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = tutorial all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/doc/tutorial/0002775000175000000620000000000013202543025015506 5ustar keithpstaffnickle_2.81.orig/doc/tutorial/Makefile.am0000664000175000000620000000211513066263270017550 0ustar keithpstaff SGMLFILES=nickle-tutorial.sgml PDFFILES=$(SGMLFILES:.sgml=.pdf) PDF_DATE=$(shell date -ud '$(RELEASE_DATE)') .sgml.pdf: docbook2tex $< && \ pdfjadetex '\pdfinfo{/CreationDate($(PDF_DATE))/ModDate($(PDF_DATE))}\input{$*.tex}' >/dev/null && \ pdfjadetex '\pdfinfo{/CreationDate($(PDF_DATE))/ModDate($(PDF_DATE))}\input{$*.tex}' >/dev/null && \ pdfjadetex '\pdfinfo{/CreationDate($(PDF_DATE))/ModDate($(PDF_DATE))}\input{$*.tex}' >/dev/null && \ sed -i '/^\/ID \[<[0-9A-F][0-9A-F]*> <[0-9A-F][0-9A-F]*>\]/d' $@ && \ rm $*.aux $*.log *$.out *$.tex SGMLINC= \ tour/tour.sgml \ basics/invoke.sgml \ basics/command.sgml \ intro/variables.sgml \ intro/expressions.sgml \ intro/statements.sgml \ intro/functions.sgml \ builtins/io.sgml \ builtins/math.sgml \ builtins/strings.sgml \ advanced/copying.sgml \ advanced/namespaces.sgml \ advanced/exceptions.sgml \ advanced/concurrency.sgml \ advanced/continuations.sgml EXTRA_DIST=$(SGMLFILES) $(SGMLINC) if HASDOCBOOK all-local: $(PDFFILES) clean-local: $(RM) -f $(PDFFILES) $(PDFFILES): $(SGMLINC) doc_DATA = $(PDFFILES) endif nickle_2.81.orig/doc/tutorial/tour/0002775000175000000620000000000013202543025016477 5ustar keithpstaffnickle_2.81.orig/doc/tutorial/tour/tour.sgml0000664000175000000620000000705112045650731020364 0ustar keithpstaff $ nickle Arithmetic works as expected, with a rich set of operators. > 1 + 1 2 > 2 ** (2 + 2) 16 > 5! 120 Rationals are represented exactly, but printed in decimal. Math is done with infinite precision. Notice that integer division (//) is different from rational division (/). Nickle provides some conveniences, such as . denoting the last value printed. > 1 / 3 0.{3} > . * 3 1 > 1 // 3 0 Variables can be declared implicitly at the top level, as well as explicitly with type. The results of statements are not printed; terminating an expression with a semicolon makes it a simple statement. C-like control structures may also be used at the top level; the + prompt indicates an incomplete line to be continued. x = . 0 > int y = x; > ++y; > for(int i = 0; i < 25; i++) + x += 0; > x 0 > for(int i = 1; i < 9; i += 2) + x += i; > x 16 ]]> When performing square roots, Nickle will stay exact when possible. If the result is irrational, however, it will be stored as an inexact real. Imprecision is contagious; if a rational operator combines an imprecise variable with a precise one, the result will be imprecise. > sqrt(x) 4 > sqrt(2) 1.414213562373095 > .**2 2 > sqrt(5) 2.236067977499789 > . ** 2 4.999999999999999 > . / 5 0.999999999999999 Functions can also be typed at the top level. Since functions, as most things, are first-class in Nickle, they may be declared and assigned as below. > real foo(real x, real y) { + return x * y; + } > foo(2, 3) 6 > foo(4, 2) 8 > real(real, real) bar = foo; > bar(4, 2) 8 > Nickle is guaranteed never to dump core; it has a simple yet powerful exception system it uses to handle all errors. An unhandled exception leads to the debugger, which uses a - prompt. The debugger can be used to trace the stack, move up and down on it, and check values of variables. > (-1) ** (1/2) Unhandled exception invalid_argument ("sqrt of negative number", 0, -1) /usr/share/nickle/math.5c:19: raise invalid_argument ("sqrt of negative number", 0, v); sqrt (-1) /usr/share/nickle/math.5c:895: result = sqrt (a); pow (-1, 0.5) <stdin>:1: -1 ** (1 / 2); - done > quit $ Large chunks of code can be placed in a separate text file and loaded when needed. The print command can be used to inspect variables, functions, namespaces, and other names. import brings the names in a namespace into scope. The :: operator can be used to view those names without importing them. (These can also be used with several namespaces built in to Nickle, such as Math and File.) $ nickle > load "cribbage.5c" > print Cribbage namespace Cribbage { public void handprint (int[*] hand); public int scorehand (int[*] hand); } > print Cribbage::handprint public void handprint (int[*] hand) { printf ("hand { "); for (int i = 0; i < dim (hand); ++i) switch (hand[i]) { case 1: printf ("A "); break; case 11: printf ("J "); break; case 12: printf ("Q "); break; case 13: printf ("K "); break; default: printf ("%d ", hand[i]); } printf ("} "); } > import Cribbage; > int[5] hand = { 7, 8, 12, 10, 5 }; > handprint(hand); printf(" has %d points.\n", scorehand(hand)); hand { 7 8 Q 10 5 } has 6 points. > quit $ nickle_2.81.orig/doc/tutorial/intro/0002775000175000000620000000000013202543025016641 5ustar keithpstaffnickle_2.81.orig/doc/tutorial/intro/variables.sgml0000664000175000000620000005230212047363266021512 0ustar keithpstaffNickle Datatypes Primitive datatypes Nickle has a large set of primitive datatypes. Instead of overloading existing datatypes to represent fundamentally distinct objects, Nickle provides additional primitive datatypes to allow for typechecking. For instance, instead of using small integers to identify file handles, Nickle provides a file datatype. Numeric datatypes Nickle has three numeric datatypes: int rational real Int and rational values are represented exactly to arbitrary precision so that computations need not be concerned about values out of range or a loss of precision during computation. For example, > 1/3 + 2/3 == 1 true > 1000! + 1 > 1000! true As rationals are a superset of the integers, rational values with denominator of 1 are represented as ints. The builtin is_int demonstrates this by recognizing such rationals as integers: > rational r = 1/3; > is_int(r) false > is_int(r*3) true Real values are either represented as a precise int or rational value or as an imprecise value using a floating point representation with arbitrary precision mantissa and exponent values. Imprecision is a contagious property; computation among precise and imprecise values yields an imprecise result. > real i=3/4, j=sqrt(2); > is_rational(i) true > is_rational(j) false > is_rational(i*j) false Upward type conversion is handled automatically; divide an int by and int and the result is rational. Downward conversion only occurs through builtin functions which convert rational or real values to integers. > int i=4, j=2; > is_rational(i/j) true String datatype A string holds a read-only null-terminated list of characters. Several builtin functions accept and return this datatype. Elements of a string are accessible as integers by using the array index operators. See the section on Strings. string foo = "hello"; string bar = "world"; string msg = foo + ", " + bar; printf("%s\n", msg); /* hello, world */ File datatype The file datatype provides access to the native file system. Several builtin functions accept and return this datatype. See the section on input and output. file f = open("file", "w"); File::fprintf(f, "hello, world!\n"); close(f); Concurrency and control flow datatypes Nickle has builtin support for threading, mutual exclusion, and continuations, along with the associated types: thread mutex semaphore continuation Threads are created with the fork expression, the result of which is a thread value. Mutexes and semaphores are synchronization datatypes. See the section on Concurrency and Continuations. thread t = fork 5!; # do stuf... printf("5! = %d\n", join(t)); /* 5! = 120 */ Continuations capture the dynamic state of execution in much the same way as a C jmp_buf except that the longjmp operation is not limited to being invoked from a nested function invocation. Rather, it can be invoked at any time causing execution to resume from the point of setjmp. See the section on Continuations. Poly datatype Non-polymorphic typechecking is occasionally insufficient to describe the semantics of an application. Nickle provides an 'escape hatch' through the poly datatype. Every value is compatible with poly; a variable with this type can be used in any circumstance. Nickle performs full run-time typechecking on poly datatypes to ensure that the program doesn't violate the type rules. poly i=3, s="hello\n"; > i+3 6 > s+3 /* can't add string and int */ Unhandled exception "invalid_binop_values" at :45 3 "hello\n" "invalid operands" > printf(i) /* printf expects a string */ Unhandled exception "invalid_argument" at :47 3 0 "Incompatible argument" > printf(s) hello > ]]> Void datatype To handle functions with no return value and other times when the value of an object isn't relevant, Nickle includes the void datatype. This is designed to operate in much the same way as the unit type does in ML. Void is a type that is compatible with only one value, '<>'. This value can be assigned and passed just like any other value, but it is not type compatible with any type other than void and poly. Composite datatypes Nickle allows the basic datatypes to be combined in several ways. struct union arrays pointers references functions Structs Structs work much like C structs; they composite several datatypes into an aggregate with names for each element of the structure. One unusual feature is that a struct value is compatible with a struct type if the struct value contains all of the entries in the type. For example: typedef struct { int i; real r; } i_and_r; typedef struct { int i; } just_i; i_and_r i_and_r_value = { i = 12, r = 37 }; just_i i_value; i_value = i_and_r_value; The assignment is legal because i_and_r contains all of the elements of just_i. i_value will end up with both i and r values. Unions Unions provide a way to hold several different datatypes in the same object. Unions are declared and used much like structs. When a union element is referenced, Nickle checks to make sure the referring element tag is the one currently stored in the union. This provides typechecking at runtime for this kind of polymorphism. Values can be converted to a union type by specifying a compatible union tag cast. A control structure union switch exists to split out the different tags and perform different functions based on the current tag: typedef union { int i; real r; } i_and_r_union; i_and_r_union u_value; u_value.i = 37; union switch (u_value) { case i: printf ("i value %d\n", u_value.i); break; case r: printf ("r value %d\n", u_value.r); break; } u_value = (i_and_r_union.r) 1.2; printf ("u_value %g\n", u_value); /* u_value r = 1.2 */ Arrays Array types in Nickle determine only the number of dimensions and not the size of each dimension. Therefore they can be declared in one of three ways: int[*] a; int[...] b; int[3] c; By these declarations, a, b and c are of the same type (one-dimensional array). The specification of the size of c actually has no effect on its declaration but rather on its initialization. See Initialization below. Declaring multidimensional arrays in Nickle is different than in C; C provides only arrays of arrays while Nickle allows either: int[3,3] array_2d = {}; int[3][3] array_of_arrays = { (int[3]) {} ... }; array_2d[0,0] = 7; array_of_arrays[0][0] = 7; array_of_arrays[1] = (int[2]) { 1, 2 }; These two types can be used in similar circumstances, but the first ensures that the resulting objects are rectangular while the second allows for each row of the array to have a different number of elements. The second also allows for each row to be manipulated separately. The final example shows an entire row being replaced with new contents. Array values created with '...' in place of the dimension information are resizable; requests to store beyond the bounds of such arrays will cause the array dimensions to be increased to include the specified location. Resizable arrays may also be passed to the setdim and setdims built-in functions. Hashes Hashes provide an associative mapping from arbitrary keys to values. Any type may be used as the key. This allows indexing by strings, and even composite values. They are called hashes instead of associative arrays to make the performance characteristics of the underlying implementation clear. Hashes are declared a bit like arrays, but instead of a value in the brackets, a type is placed: int[string] string_to_int = { "hello" => 2, => 0 }; float[float] float_to_float = { 2.5 => 27 }; string_to_int["bar"] = 17; string_to_int["foo"] += 12; float_to_float[pi] = pi/2; The initializer syntax uses the double-arrow => to separate key from value. Eliding the key specifies the "default" value -- used to instantiate newly created elements in the hash. Pointers Pointers hold a reference to a separate object; multiple pointers may point at the same object and changes to the referenced object are reflected both in the underlying object as well as in any other references to the same object. While pointers can be used to point at existing storage locations, anonymous locations can be created with the reference built-in function; this allows for the creation of pointers to existing values without requiring that the value be stored in a named object. References References, like pointers, refer to objects. They are unlike pointers, however; they are designed to provide for calls by reference in a completely by-value language. They may eventually replace pointers altogether. They are declared and assigned similarly, but not identically, to pointers: ref is declared as a reference to an integer, &int. An integer, i, is declared and given the value 3. Finally, the assignment carries some interesting semantics: the address of the reference is set to the address of i. References may also be assigned otherwise anonymous values with reference, e.g. References, unlike pointers, need not be dereferenced; they are used exactly as any other value. Changing either the value it refers to or the reference itself changes both. printf("%g\n", i); /* 3 */ printf("%g\n", ref); /* 3 */ ++ref; printf("%g\n", i); /* 4 */ printf("%g\n", ref); /* 4 */ Functions Nickle has first-class functions. These look a lot like function pointers in C, but important semantic differences separate the two. Of course, if you want a function pointer in Nickle, those are also available. Function types always have a return type and zero or more argument types. Functions may use the void return type. The final argument type may be followed by an elipsis (...), in which case the function can take any number of arguments at that point, each of the same type as the final argument type: int(int, int) a; void(int ...) b; a(1,2); b(1); b(1,2); b(1,"hello"); /* illegal, "hello" is not compatible with int */ See the section on Functions. Declarations A declaration in Nickle consists of four elements: publication, storage class, type, and name. Publication, class, and type are all optional but at least one must be present and they must be in that order. Publication is one of public or protected, which defines the name's visibility within its namespace. When publication is missing, Nickle uses private meaning that the name will not be visible outside of the current namespace. See the section on Namespaces. Class is one of global, static, or auto. When class is missing, Nickle uses auto for variables declared within a function and global for variables declared at the top level. See Storage classes below. Type is some type as described here, for instance When type is missing, Nickle uses poly, which allows the variable to hold data of any type. In any case, type is always checked at runtime. Initializers Initializers in Nickle are expressions evaluated when the storage for a variable comes into scope. To initialize array and structure types, expressions which evaluate to a struct or array object are used: int k = 12; int z = floor (pi * 27); int[3] a = (int[3]) { 1, 2, 3 }; typedef struct { int i; real r; } i_and_r; i_and_r s = (i_and_r) { i = 12, r = pi/2 }; As a special case, initializers for struct and array variables may elide the type leaving only the bracketed initializer: int[3] a = { 1, 2, 3 }; i_and_r s = { i = 12, r = pi/2 }; Instead of initializing structures by their position in the declared type, Nickle uses the structure tags. This avoids common mistakes when the structure type is redeclared. An arrays initializer followed by an elipsis (...) is replicated to fill the remainder of the elements in that dimension: int[4,4] a = { { 1, 2 ... }, { 3, 4 ... } ... }; This leaves a initialized to an array who's first row is { 1, 2, 2, 2 } and subsequent rows are { 3, 4, 4, 4 }. It is an error to use this elipsis notation when the associated type specification contains stars instead of expressions for the dimensions of the array. Variables need not be completely initialized; arrays can be partially filled and structures may have only a subset of their elements initialized. Using an uninitialized variable causes a run time exception to be raised. Identifier scope Identifiers are scoped lexically; any identifier in lexical scope can be used in any expression (with one exception described below). Each compound statement creates a new lexical scope. Function declarations and statement blocks also create new lexical scopes. This limits the scope of variables in situations like: if (int i = foo(x)) printf ("i in scope here %d\n", i); else printf ("i still in scope here %d\n", i); printf ("i not in scope here\n"); Identifiers are lexically scoped even when functions are nested: function foo (int x) { int y = 1; function bar (int z) { return z + y; } return bar (x); } Storage classes There are three storage classes in Nickle: auto static global The storage class of a variable defines the lifetime of the storage referenced by the variable. When the storage for a variable is allocated, any associated initializer expression is evaluated and the value assigned to the variable. Auto variables Auto variables have lifetime equal to the dynamic scope where they are defined. When a function is invoked, storage is allocated which the variables reference. Successive invocations allocate new storage. Storage captured and passed out of the function will remain accessible. a1 and a2 now refer to separately allocated storage. Static variables Static variables have lifetime equal to the scope in which the function they are declared in is evaluated. A function value includes both the executable code and the storage for any enclosed static variables, function values are created from function declarations. int() function incrementer () { return (func () { static int x = 0; return ++x; }); } int() a = incrementer(); int() b = incrementer(); a and b refer to functions with separate static state and so the values they return form independent sequences. Because static variables are initialized as the function is evaluated and not during function execution, any auto variables declared within the enclosing function are not accessible. This is the exception to the lexical scoping rules mentioned above. It is an error to reference auto variables in this context. Additionally, any auto variables declared within an initializer for a static variable exist in the frame for the static initializer, not for the function. The static initializer is an anonymous function sharing the same static scope as the function containing the static declarations, but having its own unique dynamic scope. Global variables Global variables have lifetime equal to the global scope. When declared at global scope, storage is allocated and the initializer executed as soon as the declaration is parsed. When declared within a function, storage is allocated when the function is parsed and the initializer is executed in the static initializer of the outermost enclosing function. function foo () { function bar () { global g = 1; static s = 1; g++; s++; return (int[2]) { g, s }; } return bar (); } Because g has global scope, only a single instance exists and so the returned values from foo increment each time foo is called. However, because s has static scope, it is reinitialized each time bar is reevaluated as the static initializer is invoked and returns the same value each time foo is called. nickle_2.81.orig/doc/tutorial/intro/functions.sgml0000664000175000000620000000360612045650731021547 0ustar keithpstaffNickle Functions An example function might be declared like this: First comes the return type of the function, then the function name, then the list of arguments (with types), and finally the statement list in curly braces. If any types are left off, Nickle assumes poly. In any case, all typechecking is done at runtime. A function can take any number of arguments. The final argument may be succeeded by an ellipses (...) to indicate an arbitrary, variable number of succeeding arguments, each of the type of the final argument; the last argument takes on a list value to store them. ... > print sum int sum (int a, int b ...) { for (int i = 0; i < dim (b); ++i) a += b[i]; return a; } > sum(1,2) 3 > sum(4) 4 > sum(1,2,4,6) 13 Functions are called as in C, with their names followed by argument values in parentheses: foo ( "hello", 7.2 ); Since they are first class, functions can be assigned: int(int,int) a = gcf; See the section on Copy semantics for details on what functions may be assigned to each other. Functions may also be declared and used anonymously: (int func ( int a, int b ) { return a + b; })(2,3); /* 5 */ Replacing the function name with the keyword func indicates its anonymity. nickle_2.81.orig/doc/tutorial/intro/statements.sgml0000664000175000000620000002311212045650731021720 0ustar keithpstaffControl Statements in Nickle Simple statements expr; ; /* null statement */ { statement ... } The simplest statement is merely an expression terminated by a semicolon; the expression is evaluated. A semicolon by itself is allowed but does nothing. One or more statements may be grouped inside curly braces to form one compound statement; each is executed in order. Any statements may compose the statement list, including control statements and other curly-bracketed lists. Conditionals if ( expr ) statement else statement if is used to execute a section of code only under some condition: If expr is true, statement is executed; otherwise control skips over it. For example: if ( x == 0 ) printf ( "x is zero.\n" ); In this case, the message will be printed only if x is zero. else allows for a choice if the condition fails. It executes its statement if the most recent if or twixt (see below) did not. For example, if ( x == 0 ) printf ( "x is zero.\n" ); else printf ( "x is not zero.\n" ); More than one option may be presented by nesting further 'if's in 'else' statements like this: if ( x == 0 ) printf ( "x is zero.\n" ); else if ( x < 0 ) printf ( "x is negative.\n" ); else printf ( "x is positive.\n" ); Twixt twixt ( expr; expr ) statement Ensures that the the first expr will always have been evaluated whenever control flow passes into any part of statement and ensures that the second expr will be evaluated anytime control flow passes out of statement. That order is gauranteed. If a long_jmp target is inside statement, the first expr will be executed before control passes to the target. If statement throws an exception or long_jmps out of the twixt, the second expr will be evaluated. Thus, twixt is useful in locked operations where the statement should only be executed under a lock and that lock must be released afterwards. twixt ( get_lock ( ); release_lock ( ) ) locked_operation ( ); Switch switch ( expr ) { case expr: statement-list ... default: statement-list } Control jumps to the first case whose expr evaluates to the same value as the expr at the top. Unlike in C, these values do not have to be integers, or even constant. The optional case default matches any value. If nothing is matched and there is no default, control skips the switch entirely. This example prints out a number to the screen, replacing it by a letter as though it were a poker card: switch ( x ) { case 1: printf ( "A\n" ); /* ace */ break; case 11: printf ( "J\n" ); /* jack */ break; case 12: printf ( "Q\n" ); /* queen */ break; case 13: printf ( "K\n" ); /* king */ break; default: printf ( "%d\n", x ); /* numeric */ break; } Notice the breaks in the example. Once control jumps to the matching case, it continues normally: Upon exhausting that statement-list, it does not jump out of the switch; it continues through the subsequent statement lists. Here is an example of this 'falling through': int x = 3; switch ( sign ( x ) ) { case -1: printf ( "x is negative.\n" ); case 1: printf ( "x is positive.\n" ); default: printf ( "x is zero.\n" ); } This prints: x is positive. x is zero. Falling through may be desirable if several cases are treated similarly; however, it should be used sparingly and probably commented so it is clear you are doing it on purpose. This is a difficult error to catch. Union switch union switch ( union ) { case name: statement-list ... default: statement-list } union switch is similar to switch. It matches its cases based on what name currently applies to the union's value. As always, default matches everything. The following example chooses the best way to print the union: union { int a; string b; } u; u.b = "hello"; union switch ( u ) { case a: printf ( "%d\n", u.a ); break; case b: printf ( "%s\n", u.b ); break; } In this case, it prints 'hello'. An additional name may follow that of a case; the union's value will be available inside the case by that name. The switch above could have been written: union switch ( u ) { case a num: printf ( "%d\n", num ); break; case b str: printf ( "%s\n", str ); break; } Loops while ( expr ) statement do statement while ( expr ) for ( expr; expr; expr ) statement while executes statement repeatedly as long as expr is true. Control continues outside the loop when expression becomes false. For example: int x = 0; while ( x < 10 ) { printf ( "%d\n", x ); ++x; } This prints the numbers from zero to nine. do-while is like while, but tests the condition after each iteration rather than before. Thus, it is garaunteed to execute at least once. It is often used in input while testing for end-of-file: file f = File::open ( "test", "r" ); do { printf ( "%s\n", File::fgets ( f ) ); } while ( ! end ( f ) ); close ( f ); for begins by evaluating the first expr, which often initializes a counter variable; since declarations are expressions in Nickle, they may be used here and the counter will be local to the loop. Then it executes statement as long as the second expr is true, like while. After each iteration, the third expr is evaluated, which usually increments or decrements the counter variable. The while example above can also be written as the following for loop: for ( int x = 0; x < 10; ++x ) printf ( "%d\n", x ); Flow control continue break return expr continue restarts the nearest surrounding do-while, while, or for loop by jumping directly to the conditional test. The iterative statement of a for loop will be evaluated first. break leaves the nearest surrounding do-while, while, for, or switch statement by jumping to its end. The iterative statement of a for loop will not be evaluated. return returns from the nearest surrounding function with value expr. nickle_2.81.orig/doc/tutorial/intro/expressions.sgml0000664000175000000620000002225012045650731022115 0ustar keithpstaffNickle Expressions Expression types are listed in order of increasing precedence. Variable declarations Variable declarations are expressions in Nickle; the value of a declaration is the value of the last variable with an initialization expression. For example, > int val; > val = (int i=2, j=3); > print val global int val = 3; If no initialization expressions are present, it is an error to use the value of the expression. val = (int i,j); Unhandled exception "uninitialized_value" at :73 "Uninitialized value" ]]> Because they are expressions, declarations can be used in contructs such as: for (int i = 0; i < 10; i++) { } Anonymous function declarations Functions may be declared anonymously and used immediately, e.g. > (int func ( int a, int b ) { return a + b; })(2,3) 5 Any context available to the function at definition time will be available whenever it is executed. See Storage classes in the section on Variables. Binary operators Addition a + b Subtraction a - b Multiplication a * b DivisionInteger division a / b a // b Remainder a % b Exponentiation a ** b Left shiftRight shift a << b a >> b Binary xorBinary andBinary or a ^ b a & b a | b Boolean andBoolean or a && b a || b EqualNot equal a == b a != b Less thanLess than or equal to a < b a <= b Greater thanGreater than or equal to a > b a >= b Assignment a = b Assignment with operator a += b a -= b a *= b a /= b a //= b a %= b a **= b a >>= b a <<= b a ^= b a &= b a |= b Unary operators Dereference: * a Reference: & a Negation: - a Bitwise inverse: ~ a Logical not: ! a Factorial: a ! Increment: ++ a a ++ Decrement: -- a a -- Constants Integer constants Integer constants with a leading zero are interpreted in octal, with a leading 0x in hex-decimal and with a leading 0b in binary. Here are some examples: 12 /* 12, decimal */ 014 /* 12, octal */ 0xc /* 12, hex */ 0b1100 /* 12, binary */ Rational constants Rational constants are the combination of an integer part, a mantissa with an initial and repeating part, and an exponent. All of these pieces are optional, but at least one of the parts (other than the exponent) must be present. If no fractional part is given, the resulting type of the value is int rather than rational. Some examples: > 12 12 > 12.5 12.5 > .34 0.34 > .{56} 0.{56} > .34e3 340 > .{56}e12 565656565656.{56} String constants String constants are surrounded in double quotes, e.g. "hello, world". Characters preceded by a backslash stand for themselves, including double-quote (\") and blackslash (\\). The following backslashed characters are special: \n is newline \r is carriage return \b is backspace \t is tab \f is formfeed Variables The name of a variable is replaced by the value of that variable in expressions. If the name is of a pointer, preceding it with the * dereference operator yields the value of its target. Struct and union references The construct struct.name yields the element name of the struct or union struct. To retrieve elements from a struct or union pointer, as in C, use struct->name Array references arr[expr] arr[expr,expr,...,expr] Elements of an array are indexed with square braces. Elements of multidimensional arrays have indices in each dimension as in the second form. Pointers to arrays can be indexed by placing the * dereference operator between the name of the array and the first square brace: arr*[expr] This is, however, deprecated in favor of using references to arrays, which have no such problems. The fork operator The fork operator evaluates its argument in a child thread. See the section on Concurrency. Comma operator expr, expr Evaluates each expression in turn, the resulting value is that of the right hand expression. For example, > 1+2, 5!, 3**4, 27/3 9 nickle_2.81.orig/doc/tutorial/advanced/0002775000175000000620000000000013202543025017253 5ustar keithpstaffnickle_2.81.orig/doc/tutorial/advanced/exceptions.sgml0000664000175000000620000001266612045650731022340 0ustar keithpstaffNickle Exceptions Nickle has first-class exceptions for error handling and quick escapes from recursive algorithms. A number of exceptions are builtin to Nickle that it throws for various errors, including: exception uninitialized_value(string msg) - Attempt to use an uninitialized value. exception invalid_argument(string msg,int arg,poly val) - The argth argument to a builtin function had invalid value val. exception readonly_box(string msg,poly val) - Attempt to change the value of a read-only quantity to val. exception invalid_array_bounds(string msg,poly a,poly i) - Attempt to access array a at index i is out of bounds. exception divide_by_zero(string msg,real num,real den) - Attempt to divide num by den when den is zero. exception invalid_struct_member(string msg,poly struct,string name) - Attempt to refer to member name of the object struct, which does not exist. exception invalid_binop_values(string msg,poly arg1,poly arg2) - Attempt to evaluate a binary operator with arguments arg1 and arg2, where at least one of these values is invalid. exception invalid_unop_values(string msg,poly arg) - Attempt to evaluate a unary operator with invalid argument arg. The following syntax may be used to declare a new exception: exception name ( type name, ... ) For example, exception my_exception ( string msg, int a, int b, int c ); Raise raise name ( value, ... ) Raises the named exception with the given arguments, e.g. raise my_exception ( "message", 0, 1, 2 ); Execution is broken and my_exception travels up the stack until it is caught by a try-catch block or it reaches the top level, where it prints an error message such as: Unhandled exception "my_exception" 3 2 1 "message" Try - catch try statement catch name ( type name, ... ) { statement-list } try executes statement; if it raises an exception whose name matches that of a succeeding catch block, the arguments are placed in the names specified and the associated statement-list is executed. Control continues after the catch without continuing up the stack; if further propagation is desired, statement-list should re-raise the exception. Any number of catch blocks may be associated with a try statement. For example: exception my_exception(string msg,int a,int b,int c); try raise my_exception("blah",1,2,3); catch my_exception(string msg,int a,int b,int c) { printf("%s: exception successfully caught (%d,%d,%d).\n",msg,a,b,c); } This example tries to execute a function that raises an exception; since that exception matches the catch block, "blah", 1, 2, and 3 (the arguments) are put into msg, a, b, and c and the statement list is executed, which in this case merely prints out the arguments received and continues: blah: exception successfully caught (1,2,3). Twixt Nickle does not provide a finally clause to a try-catch. In order to ensure the order of some expressions, it provides twixt (See the section on Statements). For example, exception my_exception(string msg, int a, int b, int c); void foo(string msg, int a, int b, int c) { twixt(printf("entering twixt..."); printf("leaving twixt.\n")) raise my_exception(msg, a, b, c); } try foo("blah", 1, 2, 3); catch my_exception(string msg,int a,int b,int c) { printf("%s: exception successfully caught (%d,%d,%d).\n",msg,a,b,c); } Will produce the output: entering twixt...leaving twixt. blah: exception successfully caught (1,2,3). Notice the order of the printed messages: twixt finished up before the exception was handled by the catch. This is an elegant way to accomplish something that should be done finally, in this case printing the message "leaving twixt" for demonstration. nickle_2.81.orig/doc/tutorial/advanced/namespaces.sgml0000664000175000000620000001076212045650731022271 0ustar keithpstaffNickle Namespaces Namespaces collect related variable and function names and allow control over visibility. A number of Nickle builtins are gathered into builtin namespaces that may be used. The following builtin namespaces have sections in this tutorial: Math - Useful mathematical functions. File - File input/output with the 'file' type. Thread - Concurrent processing. Semaphore and Mutex - Synchronization of threads. String - Useful functions for strings. An example namespace might be declared like this: namespace Example { int blah = 1; public int a = 0; int function bar(int a) { ... } protected int function foo(int a) { ... } } The keyword namespace is followed by the name of the namespace and a list of statements that declare names in the namespace. The publication of those declarations, e.g. public or protected defines how visible they will be outside the namespace. The namespace itself may be preceeded by publication information, but this has no bearing on the names within the namespace; it defines the visibility of the name of the namespace. If the example above had been declared protected namespace Example { ... } Then the names within Example would have the same visibility as always, but Example itself would be protected in whatever namespace it belongs to. In this case, it belongs to the top-level namespace, but namespaces can be nested within each other, which makes the visibility of their own names important. Extend extend namespace name { statement-list } Names may be added to a namespace after it is initially defined with the extend command. The namespace name is reopened and the new statement-list is added to the previous ones. For example, extend namespace Example { string[*] greeting = [2]{ "hello", "world" }; } Adds greeting to the names already defined in Example. Peering inside namespace::name import namespace The :: operator refers to a name, which is in namespace, analogously to a structure dereference. If name also refers to a namespace, its names too are visible this way. Either protected or public names are visible in this way. An import statement brings all the public names in namespace into scope, overshadowing conflicting names. Thereafter, those names may be used normally. A variable is declared with one of three visibilities that defines how it is visible outside its namespace: "public" may be seen outside with :: or imported "protected" may be seen outside with :: but not imported if neither is specified, it may not be seen outside at all Thus, in our example namespace Example: blah, bar, and greeting have no visibility specified and may only be used inside Example. both a (which is public) and foo (which is protected) may be seen with ::. an import will only bring a into scope, as it is the only name that is public. nickle_2.81.orig/doc/tutorial/advanced/continuations.sgml0000664000175000000620000000647412045650731023054 0ustar keithpstaffNickle Continuations Arbitrary flow control is accomplished in Nickle with first-class continuations and the functions setjmp and longjmp. These are similar to those in C, but without restrictions on the target. poly setjmp ( continuation *c, poly retval ) void lomgjmp ( continuation c, poly retval ) Setjmp saves the state of the program, including program counter and names in scope, in c and returns retval. Longjmp returns retval from the setjmp that set c. There can be two distinctions from this jump and the initial call to setjmp: the return value may differ, and variables that have changed retain their new values. Continuations are often used to implement control structures that do not exist in the language, interpreters, and escaping from recursive algorithms. For example, the following is a simple binary tree search that uses continuations to jump directly to the top instead of returning up each branch once the result is found. t.key && ! is_void ( t.right ) ) search ( t.right, i, &c ); else if ( i == t.key ) longjmp ( c, t.data ); } tree t = { key = 2, data = "blah", left = reference ( <> ), right = reference ( <> ) }; continuation c; int i = 0; { poly p = setjmp ( &c, <> ); ++i; printf ( "I have been here %d times.\n", i ); if ( is_void ( p ) ) search ( t, 2, &c ); else printf ( "value = %g\n", p ); } ]]> This is a pretty normal binary tree search, but notice how it is run: a continuation is set; if setjmp returns <> (which it will the first time), a value is searched for (this is a pretty degenerate example with only one node). If an actual value is returned, it must be from the longjmp in search, and the value is printed; a message is printed to emphasize that setjmp returns twice. This optimizes the return from what can be a very deeply nested search. Notice that the last part of the code is inside curly braces. This is legal, of course, but ordinarily not very useful. It is used in this case to get around a slight flaw in Nickle: currently, each top-level command is executed in its own thread. Thus when longjmp tries to return from the setjmp, that thread has already finished and the program exits. By placing those statements in curly braces, they will all be executed in the same thread and setjmp will still exist for longjmp to find. This sort of escape from a nested search is also commonly done with exceptions, raising one when the value is found and catching it at the top, passing the value as an argument to the exception. Actually, that method is more common because of its simplicity, but this example was done using continuations to demonstrate them. nickle_2.81.orig/doc/tutorial/advanced/concurrency.sgml0000664000175000000620000002064012047363532022502 0ustar keithpstaffThreads and Mutual Exclusion in Nickle Basic threading Threads provide concurrent processing of calculations. They are created with the fork operator, which spawns a child thread to evaluate its argument and returns it as a variable of the first-class type thread: fork expr The thread it returns is typically stored like this: thread t = fork x!; In the above example, fork immediately returns a thread, which is stored in t. That thread will calculate the factorial of x in the background while the program continues; when the calculation is finished it will block and wait for the parent thread (the one that forked it) to kill, join, or otherwise recognize it. Threads share names; if a thread changes the value of a variable, that change will occur in the other threads as well. See Mutual exclusion below. Thread functions The builtin namespace Thread has functions for manipulating threads once they have been forked. Kill int kill ( thread t, ... ) Kills the threads it takes as arguments, regardless of whether or not they are finished, and returns the number of threads successfully killed. Join poly join ( thread t ) Waits for thread t to finish and returns the value of its expression. This is how to get the value back out of a thread. Once joined, the thread will dissappear. For example, thread t = fork 1000!; # something else... printf("1000! = %d\n",Thread::join(t)); will execute 'something else' while t runs, then wait for it to complete and print out its value. Current thread current ( ) Returns the currently running thread. Note that things such as kill(current()) and join(current()) are allowed, although the former merely exits and the latter hangs forever; watch out for these errors. Priorities int set_priority ( thread t, int i ) int get_priority ( thread t ) Priorities determine how runtime is divided among threads; a thread with higher priority will always run before one with a lower priority. set_priority sets the priority of t to i and returns the new priority. get_priority returns the priority of thread t. Mutual exclusion Consider the following situation: import Thread; void function para() { printf("My next statement will be false.\n"); } void function dox() { printf("My previous statement was true.\n"); } thread t = fork para(); thread s = fork dox(); join(t); join(s); When run, this prints out the less than clear message MMyy nperxetv isotuast esmteantte mweinltl wbaes ftarlusee.. Why? Because the two threads are running simultaneously and take turns printing out their messages; the result is that they are interleaved unreadably. The solution is in the builtin namespace Mutex. A mutex is a first-class object which threads can use to coordinate conflicting sections of code. Mutex defines the following functions: New mutex new ( ) Creates a new mutex and returns it. Acquire bool acquire ( mutex m ) acquire blocks until m is free, then locks it and returns true. At the top of the conflicting code, each thread should acquire the mutex; since only one at a time can have it, they will take turns executing. There is also a try_acquire that returns false immediately rather than blocking if m is in use, but it is deprecated. Release void release ( mutex m ) When the thread which owns a mutex leaves the conflicting section of code, it should call release to free it for the next thread to acquire it. Owner mutex_owner owner ( mutex m ) Returns the owner of m: either the thread which currently owns it or null if it is free. An example This is how the example above might work with mutual exclusion: import Mutex; import Thread; mutex m = new(); void function para() { acquire(m); printf("My next statement will be false.\n"); release(m); } void function dox() { acquire(m); printf("My previous statement was true.\n"); release(m); } thread t = fork para(); thread s = fork dox(); join(t); join(s); This prints out, as expected, My next statement will be false. My previous statement was true. Semaphores Nickle also has counting semaphores, implemented in the Semaphore namespace. Semaphores are similar to mutexes, but have some number of threads that may run that isn't necessarily one, as it is with mutexes. A semaphore with a count of one behaves just like a mutex. New Semaphores are created with new, which is unlike Mutex::new in that it takes an argument: the number of threads it will run simultaneously. semaphore new ( int c ) Wait and Signal Just as Mutexes are acquired and released, threads wait on semaphores and signal them when finished. void wait ( semaphore s ) void signal ( semaphore s ) wait merely decrements the count of s, which starts with the initial value specified by new. If the count, after the decrement, is positive, the thread continues to run; if it is negative, it blocks until the count becomes positive again. This will occur when one of the running threads calls signal, which increments the count of s and wakes up another thread if any are waiting. Negative initial counts If new is called with a negative initial count, much of the meaning of the semaphore is inverted. The count now refers to the number of threads that must wait until one can execute; that is, the first c threads will block, and the c+1th will execute. Why semaphores? Semaphores are useful in situations where several threads can run simultaneously, but not more than a certain number. They would be great, for instance, to work in a licensing system, where each thread needs some command, but only a certain number may run at a given time. Be careful Semaphores, unlike mutexes, are very error-prone. They are not owned, in the sense that mutexes are, and therefore do not check what threads are signalling or waiting on them. Thus, situations like this are possible: > import Semaphore; > semaphore s = new(3); > s semaphore 1 (3); > wait(s); > s semaphore 1 (2); > wait(s); > s semaphore 1 (1); > s semaphore 1 (1) > for(int i=0; i < 100; ++i) + signal(s); > s semaphore 1 (101) > wait(s) > s semaphore 1 (100) > Therefore, code must be written carefully so that threads do not signal the semaphore more than once, and only once they have waited on it. nickle_2.81.orig/doc/tutorial/advanced/copying.sgml0000664000175000000620000001267412045650731021626 0ustar keithpstaffCopy Semantics and Garbage Collection Copy by value In Nickle, assignment, argument passing, and definitions--in short everything involving the values of variables--are all by-value. Nickle avoids the weird C-isms, like being by-value except for arrays and strings. Everything is copied. Consider the following example: > int[*] foo = { 1, 2, 3 }; > int[*] bar = foo; > foo[2] = 4; > foo [3] {1, 2, 4} What will bar[2] be? > bar [3] {1, 2, 3} Since assignment is by-value, bar has its own values--it is unchanged. Also consider function arguments: > string s = "hello, world"; > (void func(string s) { s = "foobar"; printf("%s\n",s); })(s); foobar Does s still have its original value, or "foobar"? Since the function was modifying a copy--which was passed by-value--s will be unchanged. > s "hello, world" What if you want to pass something by reference? Nickle has a reference type to accomplish just that. (You could also use pointers, but references are The Right Way. Anyway, pointers may eventually be removed from the language in preference to references.) For example, to reimplement the example above using references: string s = "hello, world"; > (void func(&string s) { s = "foobar"; printf("%s\n",s); })(&s); foobar > s "foobar" ]]> Notice that s was changed; it was passed as a reference (&string). See the section on Variables for a discussion of references. Garbage collection But if all those strings and arrays are copied entirely every time a function is called or an assignment made, won't there be a lot of unused, unreferenceable memory lying around? No. Nickle is fully garbage-collected; when a value no longer has any names, it is freed. This is invisible to the user/programmer, who need not worry about allocation, deallocation, or any other aspects of their assignments and argument passing. In short, everything is by-value, and Nickle takes care of allocation and deallocation. Type checking and subtyping Type checking in Nickle is a combination of compile-time and runtime checking. At compile-time, Nickle will ensure that all assignments, argument passing, and other copying situations are sane, for instance that no strings are being assigned to integers. It will let some errors through if it cannot be sure they are errors. For instance, variables of type 'poly' can hold any type; at compile-time, nothing is ruled out, but this does not mean you can't break typing at run-time. At runtime, Nickle makes sure all assignments are actually valid. It does so by determining if one type is a subtype of the other, i.e. if the set of all values that can fit in it also fit into the other. As a concrete example: int i = 1; > rational r = i; > i = r/3; Unhandled exception "invalid_argument" at :8 (1/3) 0 "Incompatible types in assignment" ]]> The int can hold the integer value 1 without difficulty, because they are the same type. The rational can accept the same value because integers are a subset of rationals. However, attempting to assign a rational (1/3) to the integer raises an exception. This demonstrates that int is a subtype of rational; conversely, rational is the supertype of int. A variable can take on a value from any of its subtypes, but not from its supertypes--and if the two values do not share a sub/supertype relationship, they will not get pass the compile-time checker. A similar check occurs with structs. If one struct's elements are a subset of another's, it may take that value. For example, typedef struct { int i; string s; } i_and_s; > typedef struct { int i; } just_i; > i_and_s is = { i=2, s="hello" }; > just_i i = is; > just_i ji = { i=2 }; > is = ji; Unhandled exception "invalid_argument" at :17 {i = 2} 0 "Incompatible types in assignment" ]]> Since just_i is a subtype of i_and_s (it has i but not s), the assignment to i from is worked. However, attempting to assign to is from a just_i failed, because it did not have an s to copy over. Finally, in assignments of one function to another, the following must be the case: The arguments of the right-side function must be able to be assigned to those of the left-side function. In other words, that on the left must accept a subset of the arguments of that on the right. The return type of the left-side function must be able to be assigned to that of the right-side function. In other words, its value should be usable anywhere that of the one on the right could be used. nickle_2.81.orig/doc/tutorial/Makefile.in0000664000175000000620000003471513202542702017564 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = doc/tutorial ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(docdir)" DATA = $(doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SGMLFILES = nickle-tutorial.sgml PDFFILES = $(SGMLFILES:.sgml=.pdf) PDF_DATE = $(shell date -ud '$(RELEASE_DATE)') SGMLINC = \ tour/tour.sgml \ basics/invoke.sgml \ basics/command.sgml \ intro/variables.sgml \ intro/expressions.sgml \ intro/statements.sgml \ intro/functions.sgml \ builtins/io.sgml \ builtins/math.sgml \ builtins/strings.sgml \ advanced/copying.sgml \ advanced/namespaces.sgml \ advanced/exceptions.sgml \ advanced/concurrency.sgml \ advanced/continuations.sgml EXTRA_DIST = $(SGMLFILES) $(SGMLINC) @HASDOCBOOK_TRUE@doc_DATA = $(PDFFILES) all: all-am .SUFFIXES: .SUFFIXES: .pdf .sgml $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/tutorial/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/tutorial/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am @HASDOCBOOK_FALSE@all-local: all-am: Makefile $(DATA) all-local installdirs: for dir in "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @HASDOCBOOK_FALSE@clean-local: clean: clean-am clean-am: clean-generic clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-docDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-docDATA .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-docDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ uninstall uninstall-am uninstall-docDATA .PRECIOUS: Makefile .sgml.pdf: docbook2tex $< && \ pdfjadetex '\pdfinfo{/CreationDate($(PDF_DATE))/ModDate($(PDF_DATE))}\input{$*.tex}' >/dev/null && \ pdfjadetex '\pdfinfo{/CreationDate($(PDF_DATE))/ModDate($(PDF_DATE))}\input{$*.tex}' >/dev/null && \ pdfjadetex '\pdfinfo{/CreationDate($(PDF_DATE))/ModDate($(PDF_DATE))}\input{$*.tex}' >/dev/null && \ sed -i '/^\/ID \[<[0-9A-F][0-9A-F]*> <[0-9A-F][0-9A-F]*>\]/d' $@ && \ rm $*.aux $*.log *$.out *$.tex @HASDOCBOOK_TRUE@all-local: $(PDFFILES) @HASDOCBOOK_TRUE@clean-local: @HASDOCBOOK_TRUE@ $(RM) -f $(PDFFILES) @HASDOCBOOK_TRUE@$(PDFFILES): $(SGMLINC) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/doc/tutorial/nickle-tutorial.sgml0000664000175000000620000000623213064744415021515 0ustar keithpstaff ]> Nickle Tutorial Robert Burgess Keith Packard This is a user tutorial for Nickle, a powerful desktop calculator language. Nickle supports many features of advanced languages, as well as arbitrary precision numbers. This tutorial is intended to teach Nickle to someone who is already fairly familiar with programming, using descriptions with examples. Topics are covered progressively, beginning with invocation and commands, moving on to learning the language, and finally to more advanced topics. Nickle Tour The following is an example Nickle session, interspersed with comments. &tour; Nickle Basics Nickle is a powerful desktop calculator language with many features of advanced languages and support for arbitrary precision numbers. It can run interactively to fulfill its role as a calculator, evaluate single expressions, and execute Nickle scripts. It also has an array of useful top-level commands for interacting with the interpreter. &invoke; &command; Language introduction In this chapter, the features of Nickle such as datatypes, expressions, control statements, and functions will be discussed. By the end, most of the basic language features will have been covered. &variables; &expressions; &statements; &functions; Builtins This chapter will explain various important builtin functions of Nickle, such as those for input and output and math. It will also discuss the various operators and builtin functions that manipulate strings. &io; &math; &strings; Advanced topics This chapter will discuss more advanced topics; these features make Nickle as powerful as it is. The semantics of copying and garbage collection, namespaces, exceptions, threading and mutual exclusion, and continuations will all be covered. ©ing; &namespaces; &exceptions; &concurrency; &continuations; nickle_2.81.orig/doc/tutorial/basics/0002775000175000000620000000000013202543025016752 5ustar keithpstaffnickle_2.81.orig/doc/tutorial/basics/invoke.sgml0000664000175000000620000000273512045650731021145 0ustar keithpstaffInvocation nickle -f file -l file -e expr script -- arg ... -f Evaluate file. -l Evaluate file like -f, but expect it to be in $NICKLEPATH. -e Evaluate a Nickle expression, e.g. $ nickle -e 3**4 81 $ script If Nickle encounters an unflagged argument, it assumes it to be the name of a script, which it runs. If a .nicklerc file is available, it will be evaluated first. No more arguments are processed; the rest of the line is given to the script as its arguments. Without -e or a script as an argument, Nickle runs interactively, accepting standard input and writing to standard output. nickle_2.81.orig/doc/tutorial/basics/command.sgml0000664000175000000620000000746612045650731021276 0ustar keithpstaffCommands The following are commands that the Nickle interpreter understands, not actual language constructs. They may be issued only at the top level. Expressions If an expression is issued at the top level, such as 3**4 or 100!,, its value is printed to standard output. If the expression ends with a # sign and another expression, its value is printed in whatever base the second expression evaluates to. $ nickle > 10! 3628800 > 3**4 81 > 3**4 # 3 10000 > Statements, from expressions terminated by semicolons to complicated control structures, are executed but have no value to print. Statements are not commands but actual syntax, so they may be used in scripts. If a line is ended before it can be sensible as an expression or statement, Nickle will continue until it is a statement, e.g. $ nickle > int x + = 0 + ; > Quit The quit command exits Nickle. An optional argument specifies the return value. $ nickle > quit $ Print The print command provides information such as visibility, type, and value, about a name. It need not be the name of a variable; functions, namespaces, etc. may also be printed. int x = 2; > print x global int x = 2; > print String public namespace String { public int length (string) public string new (poly) public int index (string, string) public string substr (string, int, int) public int rindex (string target, string pattern); public string dirname (string name); } > void function hello() { printf("hello, world\n"); } > print hello void hello () { printf ("hello, world\n"); } > ]]> Undefine A defined name can be undefined, e.g. $ nickle > print x No symbol "x" in namespace > int x = 0; > print x global int x = 0; > undefine x > print x No symbol "x" in namespace > Loading files The load and library commands evaluate a file at runtime like the -f and -l flags, respectively. Edit The edit command invokes $EDITOR on the name given as an argument. This is particularly useful to change a function while in interactive mode. $ nickle > void function hello() { printf("hello, world\n"); } > edit hello 49 3 printf ("hello, world\n"); c printf ("goodbye, cruel world\n"); wq 53 > print hello void hello () { printf ("goodbye, cruel world\n"); } > History The history command retrieves the values of the last ten expressions. With an argument, it instead retrieves the values of that many preceeding values. With two arguments, it retrieves the specified range in history. $ nickle ... > history $176 20 $177 5 $178 0 $179 12 $180 12 $181 -2 $182 2 $183 2 $184 0 $185 10 $186 32 > history 3 $184 0 $185 10 $186 32 > history 180,185 $180 12 $181 -2 $182 2 $183 2 $184 0 $185 10 These history items may be named and used directly: > $180 ** 2 144 > nickle_2.81.orig/doc/tutorial/builtins/0002775000175000000620000000000013202543025017337 5ustar keithpstaffnickle_2.81.orig/doc/tutorial/builtins/math.sgml0000664000175000000620000000652112045650731021165 0ustar keithpstaffMath Numbers The three numeric types in Nickle--int, rational, and real--have a hierarchical relationship. Specifically, int is a subset of rational, which is a subset of real. Ints and rationals are stored internally in infinite precision, and printed as precisely as possible (rationals with repeating portions are represented with curly braces to allow more precision in printing; see the section on Expressions for a discussion of rational constants). Reals are stored in finite, floating-point representations. The mantissa defaults to 256 bits long, but this number can be changed. Whenever performing calculations, Nickle will keep numbers in their most specific format. For example, the result of '4/2' is an int, because although the result (2) is a rational, it is also an int, and int is more specific. Similarly, reals are not always in imprecise floating representation; if they are known exactly, they will be represented as rationals or ints. Nickle will only produce imprecise reals when it has to, as in square roots and logarithms. Operators In order to do the Right Thing for a desk calculator, Nickle provides several operators that are not present in C; these are extremely useful. To force division to produce an integer, even if the result would be a rational, use the '//' integer divide operator, which always rounds its results to ints. Nickle also has an exponentiation operator '**', which behaves correctly for all exponents, including negative and fractional. Therefore, sqrt(x) is the same as x**.5, and 1/x is the same as x**-1. Finally, it provides a factorial operator '!'. The Math namespace Nickle provides the builtin namespace Math for useful functions such as trigonometric functions, logarithms, as well as useful constants such as pi and e. Logarithms real log ( real a ) real log10 ( real a ) real log2 ( real a ) The logarithm of a in base e, ten, and two, respectively. $ nickle > log ( Math::e ) 1.000000000000000 > log10 ( 16 ) / log10 ( 4 ) /* change of base formula, log_4 16 */ 1.999999999999999 > log2 ( 16 ) 3.999999999999999 > Trigonometric functions real sin ( real a ) real cos ( real a ) real tan ( real a ) real asin ( real a ) real acos ( real a ) real atan ( real a ) The sine, cosine, and tangent of a, and the inverse functions. $ nickle > sin ( pi ) ** 2 + cos ( pi ) **2 1 > atan ( 1 ) * 4 3.141592653589793 > Constants protected real e real pi pi and e define the usual constants (3.14..., 2.72...). e is protected and must be called Math::e to allow ordinary use of the name e. nickle_2.81.orig/doc/tutorial/builtins/io.sgml0000664000175000000620000002030312045650731020635 0ustar keithpstaffInput and Output Input and output in Nickle are mostly accomplished through the File builtin namespace; some top-level builtins refer to those functions. Nickle's input and output are modeled, as much of the language is, on C, but many changes have been made. Opening and closing files The functions in the File namespace use the file primitive type to describe filehandles. Three are predefined, with their usual meanings: stdin, stdout, and stderr. For many functions in File, there is a top-level builtin which assumes one of these standard streams. Other files may be read and written by opening them: file open(string path, string mode) The first string gives the path to the file to be opened; the second is one of: "r" to open read-only, starting at the beginning of the file. "r+" to open read-write, starting at the beginning of the file. "w" to create or truncate the file and open write-only. "w+" to create or truncate the file and open read-write. "a" to open write-only, appending to the end of the file. "a+" to open read-write, appending to the end of the file. If successful, a filehandle will be returned that can then be used. Nickle can also open pipes to other programs, reading or writing to their stdouts or stdins; these are also treated as files, and the difference is transparent to the functions that manipulate them. Pipes are opened with pipe rather than open; otherwise they are treated identically to flat files. file pipe(string path, string[*] argv, string mode) The first string refers to the program to be run; argv is an array of the arguments to pass to it. By convention, argv[0] should be the name of the program. Finally, mode is one of those for open; reading from the pipe reads from the program's stdout, and writing to the pipe writes to the program's stdin. For example, $ nickle > string[*] args = {"-a"}; > file ls = File::pipe ( "ls", args, "r" ); > do printf ( "%s\n", File::fgets ( ls ) ); + while ( ! File::end ( ls ) ); bin man nickle share When a file is no longer needed, it should be closed. void close(file f) > File::close ( ls ); Flush Output written to a file is not immediately written, but buffered until an appropriate time. Ordinarily, this is not noticed; if, however, it is important to know that all buffers have been written to a file, they can be flushed: void flush (file f) End Returns true if the file is at end-of-file, otherwise returns false. bool end (file f) Characters and strings Individual characters can be read and written using getc, getchar, putc, and putchar. int getc(file f) int getchar() int putc(int c,file f) void putchar(int c) A character can be pushed back onto the stream with ungetc or ungetchar. int ungetc(int c, file f) int ungetchar(int c) Strings can be read, a line at a time, using fgets and gets. string fgets(file f) string gets() All of these are like their C counterparts, with the exception noted in the following section. Unicode and characters vs. bytes Unicode is a standard for representing characters, like ASCII. However, Unicode is designed to be able to support a much larger range of characters; in fact, every character in every alphabet worldwide. It is optimized so standard ASCII characters retain their ASCII codes, and characters are not larger than they have to be. Because of its advantages, and the possibility that it may become more standard than ASCII, and because there is no reason not to, Nickle reads and writes Unicode. This is entirely transparent to the user/programmer. However, there is one situation in which the programmer will notice (disregarding the case where the programmer finds himself typing on a Sanskrit keyboard): extended characters that do not stand for themselves the same in ASCII and Unicode are not one byte long; they can be as many as four for the really obscure characters. Therefore, unlike in C, characters cannot be counted on to be the same as bytes. For this reason, Nickle provides the following functions: int putb(int c,file f) int getb(file f) int ungetb(file f) These operate the same as putc, getc, and ungetc, but will always read or write one byte at a time, regardless of character representation. Formatted I/O Nickle provides functions such as printf, sprintf, and scanf to perform formatted input and output. These functions perform like their C counterparts, with the following exceptions: The precision of a field in the format string may be specified to be '-', which means infinite precision. The %g format specifier requires a number, and prints it in the best way possible. For example: > printf("%g %g %g\n", 1, 1/3, sqrt(2)); 1 0.{3} 1.414213562373095 The %v format specifier will attempt to find the best way to print whatever value it is given. This is a great way to print polys whose types will not be known ahead of time. > printf("%v %v %v\n", 1/3, "hello", fork 4!); (1/3) "hello" %38 Notice that it can even figure out difficult things like the thread returned by 'fork'. At the top level Many functions in the File namespace have counterparts builtin at the top level; these do not need to be imported from File because they are automatically present. int printf(string fmt, poly args...) is the same as File::printf. string printf(string fmt, poly args...) is the same as File::sprintf. void putchar(int c) is the same as File::putchar. File also contains a namespace called FileGlobals, which is automatically imported. It contains the following definitions: public int scanf (string format, *poly args...) { return File::vfscanf (stdin, format, args); } public int vscanf (string format, (*poly)[*] args) { return File::vfscanf (stdin, format, args); } public string gets () { return File::fgets (stdin); } public int getchar () { return File::getc (stdin); } public void ungetchar (int ch) { File::ungetc (ch, stdin); } Thus, scanf, vscanf, gets, getchar, and ungetchar call the appropriate functions in File and return their results. The other functions in File must be imported as normal. nickle_2.81.orig/doc/tutorial/builtins/strings.sgml0000664000175000000620000000711612045650731021726 0ustar keithpstaffStrings Unlike in C, strings in Nickle are not arrays of or pointers to individual characters. Consistent with its pattern of providing primitive datatypes for types for things that make sense (e.g. file instead of integer file handles), Nickle provides the string type. This has several interesting differences from C-style strings: In Nickle, strings are immutable--individual characters may not be changed. Strings are, as with everything else, assigned and passed by-value. See the section on Copy semantics for details. Operators Two useful operators have been overloaded to allow sane manipulation of strings: '+' and array subscript ('[]'). Subscripting Although they are not arrays of characters, it is often useful to access a string a character at a time; the array subscript operator has been overloaded to allow this. For example: > string s = "hello, world"; > s[0] 104 > s[1] 101 > s[2] 108 > s[3] 108 > s[4] 111 > Those are the integer representations of each character; they are most likely in ASCII, but not necessarily--see the section on Unicode in the I/O section. The String namespace provides new to recreate a string from these integer character representations, regardless of ASCII or Unicode: string new(int c) string new(int[*] cv) For instance, > String::new(s[0]) "h" Concatenation On strings, '+' is the concatenation operator. For example, > string s = "hello", t = "world"; > s = s + ", "; > t += "!"; > s+t "hello, world!" String namespace In addition, the String namespace provides several useful functions that facilitate using strings, including the following. Length int length ( string s ) Returns the number of characters in s. For example, $ nickle > String::length ( "hello, world" ) 12 > Index int index ( string t, string p ) int rindex ( string t, string p ) Returns the index of the first occurence of the substring p in t, or -1 if p is not in t; rindex returns the last occurance instead. For example, $ nickle > String::index ( "hello, world", "or" ) 8 > String::index ( "hello, world", "goodbye" ) -1 > String::rindex ( "hello, world", "o" ) 8 Substr string substr ( string s, int i, int l ) Returns the substring of s which begins at index i and is l characters long. If l is negative, returns the substring of that length which preceeds i instead. For example, $ nickle > String::substr ( "hello, world", 8, 2 ) "or" > String::substr ( "hello, world", 8, -4 ) "o, w" > nickle_2.81.orig/NEWS0000664000175000000620000000002510414112462013567 0ustar keithpstaffNo news is good news nickle_2.81.orig/compile.c0000664000175000000620000035222611766016400014707 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "gram.h" #undef DEBUG SymbolPtr CompileNamespace (ExprPtr); static void ObjMark (void *object) { ObjPtr obj = object; InstPtr inst; int i; MemReference (obj->nonLocal); inst = ObjCode (obj, 0); for (i = 0; i < obj->used; i++, inst++) { switch (inst->base.opCode) { case OpGlobal: case OpGlobalRef: case OpGlobalRefStore: case OpTagGlobal: MemReference (inst->box.box); break; case OpBuildStruct: MemReference (inst->structs.structs); break; case OpBuildArrayInd: case OpBuildArray: MemReference (inst->array.type); break; case OpBuildHash: MemReference (inst->hash.type); break; case OpConst: MemReference (inst->constant.constant); break; case OpObj: MemReference (inst->code.code); break; case OpFork: MemReference (inst->obj.obj); break; case OpCatch: MemReference (inst->catch.exception); break; case OpRaise: MemReference (inst->raise.exception); break; case OpFarJump: MemReference (inst->farJump.farJump); break; default: break; } } if (!profiling) obj->ticks = obj->sub_ticks = 0; for (i = 0; i < obj->used_stat; i++) MemReference (ObjStat (obj, i)->stat); } DataType ObjType = { ObjMark, 0, "ObjType" }; static ObjPtr NewObj (int size, int size_stat) { ENTER (); ObjPtr obj; obj = ALLOCATE (&ObjType, sizeof (Obj) + size * sizeof (Inst) + size_stat * sizeof (Stat)); obj->size = size; obj->used = 0; obj->size_stat = size_stat; obj->used_stat = 0; obj->error = False; obj->nonLocal = 0; obj->ticks = 0; obj->sub_ticks = 0; RETURN (obj); } #define OBJ_INCR 32 #define OBJ_STAT_INCR 16 static ObjPtr AddInst (ObjPtr obj, ExprPtr stat) { ENTER (); ObjPtr nobj; int need_stat = 1; if (obj->used_stat && ObjStat(obj, obj->used_stat - 1)->stat == stat) need_stat = 0; if (obj->used == obj->size || obj->used_stat + need_stat > obj->size_stat) { int nsize = obj->size, nsize_stat = obj->size_stat; if (obj->used == obj->size) nsize = obj->size + OBJ_INCR; if (obj->used_stat + need_stat > obj->size_stat) nsize_stat = obj->size_stat + OBJ_STAT_INCR; nobj = NewObj (nsize, nsize_stat); memcpy (ObjCode (nobj, 0), ObjCode (obj, 0), obj->used * sizeof (Inst)); memcpy (ObjStat (nobj, 0), ObjStat (obj, 0), obj->used_stat * sizeof (Stat)); nobj->used = obj->used; nobj->used_stat = obj->used_stat; nobj->error = obj->error; nobj->nonLocal = obj->nonLocal; obj = nobj; } if (need_stat) { StatPtr s = ObjStat (obj, obj->used_stat); s->inst = obj->used; s->stat = stat; obj->used_stat++; } obj->used++; RETURN (obj); } static ObjPtr AppendObj (ObjPtr first, ObjPtr last) { int i; InstPtr firsti, lasti; for (i = 0; i < last->used; i++) { lasti = ObjCode (last, i); first = AddInst (first, ObjStatement (last, lasti)); firsti = ObjCode (first, ObjLast (first)); *firsti = *lasti; } if (last->error) first->error = True; return first; } ExprPtr ObjStatement (ObjPtr obj, InstPtr inst) { int i = inst - ObjCode(obj, 0); int low = 0, high = obj->used_stat - 1; while (low < high - 1) { int mid = (low + high) >> 1; if (ObjStat(obj,mid)->inst <= i) low = mid; else high = mid - 1; } while (low <= high) { StatPtr s = ObjStat(obj, high); if (s->inst <= i) return s->stat; high--; } return 0; } static void ResetInst (ObjPtr obj, int i) { obj->used = i; while (obj->used_stat && ObjStat(obj, obj->used_stat - 1)->inst > i) obj->used_stat--; } /* * Set branch offsets to zero so that CompileIsReachable can * use them before the real values get filled in. This is correct * because the reachability targets are always in nested blocks which * can never be the target for this instruction */ #define NewInst(_o,_op,_i,_stat) \ {\ InstPtr __inst__; \ (_o) = AddInst(_o, _stat); \ (_i) = ObjLast(_o); \ __inst__ = ObjCode (_o, _i); \ __inst__->base.opCode = (_op); \ __inst__->base.flags = 0; \ __inst__->branch.offset = 0; \ } #define BuildInst(_o,_op,_inst,_stat) \ {\ (_o) = AddInst (_o, _stat); \ (_inst) = ObjCode(_o, ObjLast(_o)); \ (_inst)->base.opCode = (_op); \ (_inst)->base.flags = 0; \ (_inst)->branch.offset = 0; \ } #define SetFlag(_o,_f) ((_o)->used ? (ObjCode((_o), \ ObjLast(_o))->base.flags |= (_f)) \ : 0) #define SetPush(_o) SetFlag(_o,InstPush) #define SetAInit(_o) SetFlag(_o,InstAInit) /* * Select the correct code body depending on whether * we're compiling a static initializer */ #define CodeBody(c) ((c)->func.inStaticInit ? &(c)->func.staticInit : &(c)->func.body) typedef enum _tail { TailNever, TailVoid, TailAlways } Tail; ObjPtr CompileLvalue (ObjPtr obj, ExprPtr expr, ExprPtr stat, CodePtr code, Bool createIfNecessary, Bool assign, Bool initialize, Bool amper, Bool auto_reference); ObjPtr CompileBinOp (ObjPtr obj, ExprPtr expr, BinaryOp op, ExprPtr stat, CodePtr code); ObjPtr CompileBinFunc (ObjPtr obj, ExprPtr expr, BinaryFunc func, ExprPtr stat, CodePtr code, char *name); ObjPtr CompileUnOp (ObjPtr obj, ExprPtr expr, UnaryOp op, ExprPtr stat, CodePtr code); ObjPtr CompileUnFunc (ObjPtr obj, ExprPtr expr, UnaryFunc func, ExprPtr stat, CodePtr code, char *name); ObjPtr CompileAssign (ObjPtr obj, ExprPtr expr, Bool initialize, ExprPtr stat, CodePtr code); ObjPtr CompileAssignOp (ObjPtr obj, ExprPtr expr, BinaryOp op, ExprPtr stat, CodePtr code); ObjPtr CompileAssignFunc (ObjPtr obj, ExprPtr expr, BinaryFunc func, ExprPtr stat, CodePtr code, char *name); ObjPtr CompileArrayIndex (ObjPtr obj, ExprPtr expr, TypePtr indexType, ExprPtr stat, CodePtr code, int *ndimp); ObjPtr CompileCall (ObjPtr obj, ExprPtr expr, Tail tail, ExprPtr stat, CodePtr code, Bool auto_reference); ObjPtr _CompileExpr (ObjPtr obj, ExprPtr expr, Bool evaluate, ExprPtr stat, CodePtr code); ObjPtr _CompileBoolExpr (ObjPtr obj, ExprPtr expr, Bool evaluate, ExprPtr stat, CodePtr code); void CompilePatchLoop (ObjPtr obj, int start, int continue_offset, int break_offset, int catch_offset); ObjPtr _CompileStat (ObjPtr obj, ExprPtr expr, Bool last, CodePtr code); ObjPtr CompileFunc (ObjPtr obj, CodePtr code, ExprPtr stat, CodePtr previous, NonLocalPtr nonLocal); ObjPtr CompileDecl (ObjPtr obj, ExprPtr decls, Bool evaluate, ExprPtr stat, CodePtr code); ObjPtr CompileFuncCode (CodePtr code, ExprPtr stat, CodePtr previous, NonLocalPtr nonLocal); void CompileError (ObjPtr obj, ExprPtr stat, char *s, ...); static Bool CompileIsReachable (ObjPtr obj, int i, int frame); static ObjPtr CompileArrayDimValue (ObjPtr obj, TypePtr type, Bool lvalue, ExprPtr stat, CodePtr code); static ObjPtr CompileType (ObjPtr obj, ExprPtr decls, TypePtr type, ExprPtr stat, CodePtr code); /* * Set storage information for new symbols */ static void CompileStorage (ObjPtr obj, ExprPtr stat, SymbolPtr symbol, CodePtr code) { ENTER (); if (!symbol) obj->error = True; /* * For symbols hanging from a frame (statics, locals and args), * locate the frame and set their element value */ else if (ClassFrame(symbol->symbol.class)) { switch (symbol->symbol.class) { case class_static: symbol->local.element = AddBoxType (&code->func.statics, symbol->symbol.type); symbol->local.staticScope = True; symbol->local.code = code; break; case class_arg: case class_auto: symbol->local.element = AddBoxType (&CodeBody (code)->dynamics, symbol->symbol.type); symbol->local.staticScope = code->func.inStaticInit; symbol->local.code = code; break; default: break; } } EXIT (); } /* * Set storage information for array dimensions */ static void CompileDimensionStorage (ObjPtr obj, Class class, TypePtr type, CodePtr code) { ENTER (); if (class == class_typedef) class = code ? class_auto : class_global; switch (class) { case class_global: case class_const: type->array.storage = DimStorageGlobal; type->array.u.global = NewBox (True, False, 1, typeArrayInt); break; case class_static: type->array.storage = DimStorageStatic; type->array.u.frame.element = AddBoxType (&code->func.statics, typeArrayInt); type->array.u.frame.staticScope = True; type->array.u.frame.code = code; break; case class_arg: case class_auto: type->array.storage = DimStorageAuto; type->array.u.frame.element = AddBoxType (&CodeBody (code)->dynamics, typeArrayInt); type->array.u.frame.staticScope = code->func.inStaticInit; type->array.u.frame.code = code; break; default: break; } EXIT (); } /* * Make sure a symbol is valid */ static SymbolPtr CompileCheckSymbol (ObjPtr obj, ExprPtr stat, ExprPtr name, CodePtr code, int *depth, Bool createIfNecessary) { ENTER (); SymbolPtr s; int d; CodePtr c; s = name->atom.symbol; if (!s) { if (name->atom.atom == AtomId ("[]")) CompileError (obj, stat, "Using [] outside of comprehension scope"); else CompileError (obj, stat, "No visible symbol \"%A\" in scope%s", name->atom.atom, name->atom.privateFound ? " (found non-public symbol)" : ""); RETURN (0); } /* * For args and autos, make sure we're not compiling a static * initializer, in that case, the locals will not be in dynamic * namespace */ d = 0; switch (s->symbol.class) { case class_static: case class_arg: case class_auto: /* * See if the name is above a global init scope */ for (c = code; c; c = c->base.previous) if (c->func.inGlobalInit) break; for (; c; c = c->base.previous) if (c == s->local.code) break; if (c) { CompileError (obj, stat, "\"%A\" not in global initializer scope", name->atom.atom); break; } c = s->local.code; if (!c) { CompileError (obj, stat, "Class %C invalid at global scope", s->symbol.class); break; } /* * Ensure the dynamic scope will exist */ if (c->func.inStaticInit && !s->local.staticScope) { CompileError (obj, stat, "\"%A\" not in static initializer scope", name->atom.atom); break; } /* * Compute the static link offset */ d = 0; for (c = code; c && c != s->local.code; c = c->base.previous) d++; break; default: break; } *depth = d; RETURN (s); } void CompileError (ObjPtr obj, ExprPtr stat, char *s, ...) { va_list args; FilePrintf (FileStderr, "-> "); PrettyStat (FileStderr, stat, False); if (stat->base.file) FilePrintf (FileStderr, "%A:%d: ", stat->base.file, stat->base.line); va_start (args, s); FileVPrintf (FileStderr, s, args); va_end (args); FilePrintf (FileStderr, "\n"); obj->error = True; } static TypePtr CompileRefType (ObjPtr obj, ExprPtr expr, TypePtr t) { t = TypeCanon (t); if (!t) { CompileError(obj, expr, "reference to incomplete type"); return 0; } if (t->base.tag == type_ref && !t->ref.pointer) return t->ref.ref; return 0; } static TypePtr CompileIndexType (ExprPtr expr) { TypePtr type = expr->base.type, indexType = typePoly; if (type) { switch (type->base.tag) { case type_array: indexType = typePrim[rep_integer]; break; case type_hash: indexType = type->hash.keyType; break; default: break; } } return indexType; } /* * Compile the left side of an assignment statement. * The result is a 'ref' left in the value register * The type is the type of the refered value, not a reference * to that type. */ ObjPtr CompileLvalue (ObjPtr obj, ExprPtr expr, ExprPtr stat, CodePtr code, Bool createIfNecessary, Bool assign, Bool initialize, Bool amper, Bool auto_reference) { ENTER (); InstPtr inst = 0; SymbolPtr s; int depth; int ndim; TypePtr t; Bool flipTypes = False; switch (expr->base.tag) { case VAR: obj = CompileDecl (obj, expr, False, stat, code); { DeclListPtr decl; s = 0; for (decl = expr->decl.decl; decl; decl = decl->next) s = decl->symbol; } /* the symbol was compiled in this frame */ depth = 0; goto isName; case NAME: s = CompileCheckSymbol (obj, stat, expr, code, &depth, createIfNecessary); isName: if (!s) { expr->base.type = typePoly; break; } inst = 0; switch (s->symbol.class) { case class_const: if (!initialize) { CompileError (obj, stat, "Attempt to assign to static variable \"%A\"", expr->atom.atom); expr->base.type = typePoly; break; } /* fall through ... */ case class_global: BuildInst (obj, OpGlobalRef, inst, stat); inst->box.box = s->global.value; break; case class_static: BuildInst (obj, OpStaticRef, inst, stat); inst->frame.staticLink = depth; inst->frame.element = s->local.element; break; case class_arg: case class_auto: BuildInst (obj, OpLocalRef, inst, stat); inst->frame.staticLink = depth; inst->frame.element = s->local.element; break; default: CompileError (obj, stat, "Invalid use of %C \"%A\"", s->symbol.class, expr->atom.atom); expr->base.type = typePoly; break; } if (!inst) break; expr->base.type = s->symbol.type; flipTypes = True; break; case AMPER: obj = CompileLvalue (obj, expr->tree.left, stat, code, createIfNecessary, assign, initialize, True, auto_reference); expr->base.type = expr->tree.left->base.type; break; case COLONCOLON: obj = CompileLvalue (obj, expr->tree.right, stat, code, False, assign, initialize, amper, auto_reference); expr->base.type = expr->tree.right->base.type; amper = False; /* has been dealt with in nested call */ break; case DOT: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); expr->base.type = TypeCombineStruct (expr->tree.left->base.type, expr->base.tag, expr->tree.right->atom.atom); if (!expr->base.type) { CompileError (obj, stat, "Object left of '.' is not a struct or union containing \"%A\"", expr->tree.right->atom.atom); expr->base.type = typePoly; break; } BuildInst (obj, OpDotRef, inst, stat); inst->atom.atom = expr->tree.right->atom.atom; flipTypes = True; break; case ARROW: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); expr->base.type = TypeCombineStruct (expr->tree.left->base.type, expr->base.tag, expr->tree.right->atom.atom); if (!expr->base.type) { CompileError (obj, stat, "Object left of '->' is not a struct or union containing \"%A\"", expr->tree.right->atom.atom); expr->base.type = typePoly; break; } BuildInst (obj, OpArrowRef, inst, stat); inst->atom.atom = expr->tree.right->atom.atom; flipTypes = True; break; case OS: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); obj = CompileArrayIndex (obj, expr->tree.right, CompileIndexType (expr->tree.left), stat, code, &ndim); if (!ndim) { expr->base.type = typePoly; break; } expr->base.type = TypeCombineArray (expr->tree.left->base.type, ndim, True); if (!expr->base.type) { CompileError (obj, stat, "Incompatible type '%T', for %d dimension operation", expr->tree.left->base.type, ndim); expr->base.type = typePoly; break; } BuildInst (obj, OpArrayRef, inst, stat); inst->ints.value = ndim; flipTypes = True; break; case STAR: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); expr->base.type = TypeCombineUnary (expr->tree.left->base.type, expr->base.tag); if (!expr->base.type) { CompileError (obj, stat, "Incompatible type, value '%T', for * operation", expr->tree.left->base.type); expr->base.type = typePoly; break; } break; case OP: if (auto_reference) { obj = CompileCall (obj, expr, TailNever, stat, code, True); break; } default: if (auto_reference) { obj = _CompileExpr (obj, expr, True, stat, code); BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = do_reference; } else { CompileError (obj, stat, "Invalid lvalue"); expr->base.type = typePoly; } break; } if (flipTypes) { t = CompileRefType (obj, expr, expr->base.type); if (amper) { if (t) { /* * reference to a reference type; that * means just reference the variable itself, but * switch the expression type to '*foo' instead of * '&foo' */ expr->base.type = NewTypeRef (t, True); if (assign) inst->base.opCode++; amper = False; } } else { if (t) { /* * access to a reference type; that means * fetch the value of the reference */ inst->base.opCode--; expr->base.type = t; } else { /* * access to a non-reference type; that * means just reference the variable itself and * leave the type alone */ if (assign) inst->base.opCode++; } } } /* * Handle any remaining & from above */ if (amper) { if (auto_reference) { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = do_reference; expr->base.type = NewTypeRef (expr->base.type, True); } else { /* * reference to a non-reference type. Error */ CompileError (obj, stat, "Object right of '&' is not of ref type"); expr->base.type = typePoly; } } assert (expr->base.type); RETURN (obj); } static void _CompileCheckException (ObjPtr obj, ExprPtr stat) { SymbolPtr except = CheckStandardException (); if (except) CompileError (obj, stat, "Exception \"%A\" raised during compilation", except->symbol.name); } /* * Compile a binary operator -- * compile the left side, push, compile the right and then * add the operator */ ObjPtr CompileBinOp (ObjPtr obj, ExprPtr expr, BinaryOp op, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst; int left, right; left = obj->used; obj = _CompileExpr (obj, expr->tree.left, True, stat, code); SetPush (obj); right = obj->used; obj = _CompileExpr (obj, expr->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, expr->base.tag, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for %O operation", expr->tree.left->base.type, expr->tree.right->base.type, op); expr->base.type = typePoly; } else if (obj->used == left + 2 && ObjCode (obj, left)->base.opCode == OpConst && ObjCode (obj, right)->base.opCode == OpConst && !signalException) { inst = ObjCode (obj, left); inst->constant.constant = BinaryOperate (ObjCode(obj, left)->constant.constant, ObjCode(obj, right)->constant.constant, op); _CompileCheckException (obj, stat); inst->base.flags &= ~InstPush; obj->used = left + 1; } else { BuildInst (obj, OpBinOp, inst, stat); inst->binop.op = op; } RETURN (obj); } ObjPtr CompileBinFunc (ObjPtr obj, ExprPtr expr, BinaryFunc func, ExprPtr stat, CodePtr code, char *name) { ENTER (); InstPtr inst; int left, right; left = obj->used; obj = _CompileExpr (obj, expr->tree.left, True, stat, code); SetPush (obj); right = obj->used; obj = _CompileExpr (obj, expr->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, expr->base.tag, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for %s operation", expr->tree.left->base.type, expr->tree.right->base.type, name); expr->base.type = typePoly; } else if (obj->used == left + 2 && ObjCode (obj, left)->base.opCode == OpConst && ObjCode (obj, right)->base.opCode == OpConst && !signalException) { inst = ObjCode (obj, left); inst->constant.constant = (*func) (ObjCode(obj, left)->constant.constant, ObjCode(obj, right)->constant.constant); _CompileCheckException (obj, stat); inst->base.flags &= ~InstPush; obj->used = left + 1; } else { BuildInst (obj, OpBinFunc, inst, stat); inst->binfunc.func = func; } RETURN (obj); } /* * Unaries are easy -- * compile the operand and add the operator */ ObjPtr CompileUnOp (ObjPtr obj, ExprPtr expr, UnaryOp op, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst; ExprPtr down; int d; if (expr->tree.right) down = expr->tree.right; else down = expr->tree.left; d = obj->used; obj = _CompileExpr (obj, down, True, stat, code); expr->base.type = TypeCombineUnary (down->base.type, expr->base.tag); if (!expr->base.type) { CompileError (obj, stat, "Incompatible type, value '%T', for %U operation", down->base.type, op); expr->base.type = typePoly; } else if (obj->used == d + 1 && ObjCode (obj, d)->base.opCode == OpConst && !signalException) { inst = ObjCode (obj, d); inst->constant.constant = UnaryOperate (ObjCode(obj, d)->constant.constant, op); _CompileCheckException (obj, stat); inst->base.flags &= ~InstPush; obj->used = d + 1; } else { BuildInst (obj, OpUnOp, inst, stat); inst->unop.op = op; } RETURN (obj); } ObjPtr CompileUnFunc (ObjPtr obj, ExprPtr expr, UnaryFunc func, ExprPtr stat, CodePtr code, char *name) { ENTER (); InstPtr inst; ExprPtr down; int d; if (expr->tree.right) down = expr->tree.right; else down = expr->tree.left; d = obj->used; obj = _CompileExpr (obj, down, True, stat, code); expr->base.type = TypeCombineUnary (down->base.type, expr->base.tag); if (!expr->base.type) { CompileError (obj, stat, "Incompatible type, value '%T', for %s operation", down->base.type, name); expr->base.type = typePoly; } else if (obj->used == d + 1 && ObjCode (obj, d)->base.opCode == OpConst && !signalException) { inst = ObjCode (obj, d); inst->constant.constant = (*func) (ObjCode(obj, d)->constant.constant); _CompileCheckException (obj, stat); inst->base.flags &= ~InstPush; obj->used = d + 1; } else { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = func; } RETURN (obj); } /* * Assignement -- * compile the value, build a ref for the LHS and add the operator */ ObjPtr CompileAssign (ObjPtr obj, ExprPtr expr, Bool initialize, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst; obj = CompileLvalue (obj, expr->tree.left, stat, code, True, True, initialize, False, False); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, expr->base.tag, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for = operation", expr->tree.left->base.type, expr->tree.right->base.type); expr->base.type = typePoly; } BuildInst (obj, OpAssign, inst, stat); inst->assign.initialize = initialize; RETURN (obj); } ObjPtr CompileAssignOp (ObjPtr obj, ExprPtr expr, BinaryOp op, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst; obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, False); SetPush (obj); BuildInst (obj, OpFetch, inst, stat); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, expr->base.tag, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for %O= operation", expr->tree.left->base.type, expr->tree.right->base.type, op); expr->base.type = typePoly; } BuildInst (obj, OpAssignOp, inst, stat); inst->binop.op = op; RETURN (obj); } ObjPtr CompileAssignFunc (ObjPtr obj, ExprPtr expr, BinaryFunc func, ExprPtr stat, CodePtr code, char *name) { ENTER (); InstPtr inst; obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, False); SetPush (obj); BuildInst (obj, OpFetch, inst, stat); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, expr->base.tag, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for %s= operation", expr->tree.left->base.type, expr->tree.right->base.type, name); expr->base.type = typePoly; } BuildInst (obj, OpAssignFunc, inst, stat); inst->binfunc.func = func; RETURN (obj); } static ObjPtr CompileArgs (ObjPtr obj, int *argcp, Bool *varactualp, ExprPtr arg, Bool pushValue, ExprPtr stat, CodePtr code) { ENTER (); int argc; argc = 0; *varactualp = False; while (arg) { if (pushValue) SetPush (obj); if (arg->tree.left->base.tag == DOTDOTDOT) { InstPtr inst; obj = _CompileExpr (obj, arg->tree.left->tree.left, True, stat, code); BuildInst (obj, OpVarActual, inst, stat); *varactualp = True; } else { obj = _CompileExpr (obj, arg->tree.left, True, stat, code); } arg = arg->tree.right; pushValue = True; argc++; } *argcp = argc; RETURN(obj); } /* * Typecheck function object and arguments */ static Bool CompileTypecheckArgs (ObjPtr obj, Type *type, ExprPtr args, int argc, ExprPtr stat) { ENTER (); Bool ret = True; ArgType *argt; ExprPtr arg; Type *func_type; Type *actual_type; int i; Bool varactual; func_type = TypeCombineFunction (type); if (!func_type) { CompileError (obj, stat, "Incompatible type, value '%T', for call", type); EXIT (); return False; } if (func_type->base.tag == type_func) { argt = func_type->func.args; arg = args; i = 0; varactual = False; while ((arg && !varactual) || (argt && !argt->varargs)) { if (!argt) { CompileError (obj, stat, "Too many parameters for function type '%T'", func_type); ret = False; break; } if (!arg) { CompileError (obj, stat, "Too few parameters for function type '%T'", func_type); ret = False; break; } varactual = arg->tree.left->base.tag == DOTDOTDOT; if (varactual) actual_type = TypeCombineArray (arg->tree.left->tree.left->base.type, 1, False); else actual_type = arg->tree.left->base.type; if (!TypeIsOrdered (argt->type, actual_type)) { CompileError (obj, stat, "Incompatible types, formal '%T', actual '%T', for argument %d", argt->type, arg->tree.left->base.type, i); ret = False; } i++; if (!argt->varargs) argt = argt->next; if (arg && (!varactual || !argt)) arg = arg->tree.right; } } EXIT (); return ret; } static void MarkNonLocal (void *object) { NonLocal *nl = object; MemReference (nl->prev); } DataType NonLocalType = { MarkNonLocal, 0, "NonLocalType" }; static NonLocal * NewNonLocal (NonLocal *prev, NonLocalKind kind, int target) { ENTER(); NonLocal *nl; nl = ALLOCATE (&NonLocalType, sizeof (NonLocal)); nl->prev = prev; nl->kind = kind; nl->target = target; RETURN (nl); } /* * Compile a function call -- * * + compile the code that generates a function object * + compile the args, pushing value on the stack * + Typecheck the arguments. Must be done here so that * the type of the function is available * + Add the OpCall * + Add an OpNoop in case the result must be pushed; otherwise there's * no place to hang a push bit */ ObjPtr CompileCall (ObjPtr obj, ExprPtr expr, Tail tail, ExprPtr stat, CodePtr code, Bool auto_reference) { ENTER (); InstPtr inst; int argc; Bool varactual; TypePtr t; obj = _CompileExpr (obj, expr->tree.left, True, stat, code); obj = CompileArgs (obj, &argc, &varactual, expr->tree.right, True, stat, code); if (!CompileTypecheckArgs (obj, expr->tree.left->base.type, expr->tree.right, argc, stat)) { expr->base.type = typePoly; RETURN (obj); } expr->base.type = TypeCombineReturn (expr->tree.left->base.type); t = CompileRefType (obj, expr, expr->base.type); if ((t && !auto_reference) || (!t && auto_reference)) tail = TailNever; if (!code) tail = TailNever; if ((tail == TailAlways && !TypePoly (expr->base.type) && TypeIsSupertype (code->base.type, expr->base.type)) || (tail == TailVoid && TypeCanon (expr->base.type) == typePrim[rep_void])) { BuildInst (obj, OpTailCall, inst, stat); inst->ints.value = varactual ? -argc : argc; } else { BuildInst (obj, OpCall, inst, stat); inst->ints.value = varactual ? -argc : argc; if (t && !auto_reference) { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = Dereference; expr->base.type = t; } else if (!t && auto_reference) { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = do_reference; /* * this is called from CompileLvalue which * must return a value of the type pointed to, not the * type of the object itself, so don't create a pointer * type here. Someday we'll figure all of this out... */ /* expr->base.type = NewTypeRef (expr->base.type, True); */ } else BuildInst (obj, OpNoop, inst, stat); } RETURN (obj); } /* * Compile an exception -- * * + lookup the name * + compile the args, pushing * + typecheck the args * + Add the OpRaise */ static ObjPtr CompileRaise (ObjPtr obj, ExprPtr expr, ExprPtr stat, CodePtr code) { ENTER(); int argc; ExprPtr name; SymbolPtr sym; InstPtr inst; Bool varactual; if (expr->tree.left->base.tag == COLONCOLON) name = expr->tree.left->tree.right; else name = expr->tree.left; sym = name->atom.symbol; if (!sym) { CompileError (obj, stat, "No exception '%A' in scope", name->atom.atom); RETURN (obj); } if (sym->symbol.class != class_exception) { CompileError (obj, stat, "'%A' is not an exception", name->atom.atom); RETURN (obj); } obj = CompileArgs (obj, &argc, &varactual, expr->tree.right, False, stat, code); if (!CompileTypecheckArgs (obj, sym->symbol.type, expr->tree.right, argc, stat)) RETURN(obj); expr->base.type = typePoly; BuildInst (obj, OpRaise, inst, stat); inst->raise.argc = varactual ? -argc : argc; inst->raise.exception = sym; RETURN (obj); } /* * Compile a twixt -- * * twixt (enter; leave) body * * enter: * enter * OpEnterDone * OpTwixt enter: leave: * body * OpTwixtDone * leave: * leave * OpLeaveDone * */ static ObjPtr CompileTwixt (ObjPtr obj, ExprPtr expr, ExprPtr stat, CodePtr code) { ENTER (); int enter_inst, twixt_inst; InstPtr inst; enter_inst = obj->used; /* Compile enter expression */ if (expr->tree.left->tree.left) obj = _CompileExpr (obj, expr->tree.left->tree.left, True, stat, code); BuildInst (obj, OpEnterDone, inst, stat); /* here's where the twixt instruction goes */ NewInst (obj, OpTwixt, twixt_inst, stat); obj->nonLocal = NewNonLocal (obj->nonLocal, NonLocalTwixt, 0); /* Compile the body */ obj = _CompileStat (obj, expr->tree.right->tree.left, False, code); obj->nonLocal = obj->nonLocal->prev; BuildInst (obj, OpTwixtDone, inst, stat); /* finish the twixt instruction */ inst = ObjCode (obj, twixt_inst); inst->twixt.enter = enter_inst - twixt_inst; inst->twixt.leave = obj->used - twixt_inst; /* Compile leave expression */ if (expr->tree.left->tree.right) obj = _CompileExpr (obj, expr->tree.left->tree.right, False, stat, code); BuildInst (obj, OpLeaveDone, inst, stat); RETURN (obj); } /* * Compile an array index expression tree */ ObjPtr CompileArrayIndex (ObjPtr obj, ExprPtr expr, TypePtr indexType, ExprPtr stat, CodePtr code, int *ndimp) { ENTER (); int ndim; ndim = 0; while (expr) { SetPush (obj); obj = _CompileExpr (obj, expr->tree.left, True, stat, code); if (!TypeIsOrdered (indexType, expr->tree.left->base.type)) { CompileError (obj, stat, "Incompatible expression type '%T', for index %d type '%T'", expr->tree.left->base.type, ndim, indexType); break; } expr = expr->tree.right; ndim++; } *ndimp = ndim; RETURN (obj); } /* * Return an expression that will build an * initializer for a fully specified composite * type */ /* * Calculate the number of dimensions in an array by looking at * the initializers */ static int CompileCountInitDimensions (TypePtr type, ExprPtr expr) { int ndimMax, ndimSub, ndim; switch (expr->base.tag) { case ANONINIT: type = TypeCanon (type); if (type->base.tag == type_struct) ndim = 0; else ndim = 1; break; case ARRAY: expr = expr->tree.left; ndimMax = 0; while (expr) { if (expr->tree.left && expr->tree.left->base.tag != DOTDOTDOT) { ndimSub = CompileCountInitDimensions (type, expr->tree.left); if (ndimSub < 0) return ndimSub; if (ndimMax && ndimSub != ndimMax) return -1; ndimMax = ndimSub; } expr = expr->tree.right; } ndim = ndimMax + 1; break; default: ndim = 0; break; } return ndim; } static int CompileCountDeclDimensions (ExprPtr expr) { int ndim; ndim = 0; while (expr) { expr = expr->tree.right; ndim++; } return ndim; } static int CompileCountImplicitDimensions (ExprPtr expr) { switch (expr->base.tag) { case ARRAY: return 1 + CompileCountImplicitDimensions (expr->tree.left); case ANONINIT: return 0; case COMMA: return CompileCountImplicitDimensions (expr->tree.left); default: return 0; } } static ObjPtr CompileBuildArray (ObjPtr obj, ExprPtr expr, TypePtr type, ExprPtr dim, int ndim, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst; if (dim) { while (dim) { obj = _CompileExpr (obj, dim->tree.left, True, stat, code); SetPush (obj); dim = dim->tree.right; } BuildInst (obj, OpBuildArray, inst, stat); } else { obj = CompileArrayDimValue (obj, type, False, stat, code); BuildInst (obj, OpBuildArrayInd, inst, stat); } inst->array.ndim = ndim; inst->array.type = type->array.type; inst->array.resizable = type->array.resizable; RETURN (obj); } static Bool CompileSizeDimensions (ExprPtr expr, int *dims, int ndims) { int dim; if (!expr) dim = 0; else switch (expr->base.tag) { case ARRAY: dim = 0; expr = expr->tree.left; while (expr) { if (expr->tree.left->base.tag == DOTDOTDOT) return False; if (ndims != 1) { CompileSizeDimensions (expr->tree.left, dims + 1, ndims - 1); if (dims[1]) dim++; } else dim++; expr = expr->tree.right; } break; case COMP: return False; case ANONINIT: dim = 0; break; default: dim = 1; if (expr->tree.left->base.tag == DOTDOTDOT) return False; if (ndims != 1) CompileSizeDimensions (expr, dims + 1, ndims - 1); break; } if (dim > *dims) *dims = dim; return True; } static ExprPtr CompileImplicitArray (ObjPtr obj, ExprPtr stat, ExprPtr inits, int ndim) { ENTER (); ExprPtr sub; int *dims; int n; dims = AllocateTemp (ndim * sizeof (int)); memset (dims, '\0', ndim * sizeof (int)); if (!CompileSizeDimensions (inits, dims, ndim)) { CompileError (obj, stat, "Implicit dimensioned array with variable initializers"); RETURN (0); } sub = 0; for (n = ndim - 1; n >= 0; n--) { sub = NewExprTree (COMMA, NewExprConst (TEN_NUM, NewInt (dims[n])), sub); } RETURN(sub); } static ObjPtr CompileArrayInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code); static ObjPtr CompileHashInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code); static ObjPtr CompileStructUnionInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code); static ExprPtr CompileImplicitInit (Type *type); static ObjPtr CompileInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code) { ENTER (); Type *canon_type; canon_type = TypeCanon (type); if (!canon_type) { CompileError(obj, stat, "Initializer with undefined type '%T'", type); RETURN(obj); } type = canon_type; if (!expr || expr->base.tag == ANONINIT) { switch (type->base.tag) { case type_array: obj = CompileArrayInit (obj, 0, type, stat, code); break; case type_hash: obj = CompileHashInit (obj, 0, type, stat, code); break; case type_struct: obj = CompileStructUnionInit (obj, 0, type, stat, code); break; case type_union: default: CompileError (obj, stat, "Invalid empty initializer , type '%T'", type); break; } } else switch (expr->base.tag) { case ARRAY: case COMP: if (type->base.tag != type_array) CompileError (obj, stat, "Array initializer type mismatch, type '%T'", type); else obj = CompileArrayInit (obj, expr, type, stat, code); break; case HASH: if (type->base.tag != type_hash) CompileError (obj, stat, "Hash initializer type mismatch, type '%T'", type); else obj = CompileHashInit (obj, expr, type, stat, code); break; case STRUCT: if (type->base.tag != type_struct && type->base.tag != type_union) CompileError (obj, stat, "Struct/union initializer type mismatch, type '%T'", type); else obj = CompileStructUnionInit (obj, expr, type, stat, code); break; default: obj = _CompileExpr (obj, expr, True, stat, code); if (!TypeCombineBinary (type, ASSIGN, expr->base.type)) CompileError (obj, stat, "Incompatible types, storage '%T', value '%T', for initializer", type, expr->base.type); } RETURN (obj); } static ObjPtr CompileArrayInits (ObjPtr obj, ExprPtr expr, TypePtr type, int ndim, ExprPtr stat, CodePtr code, AInitMode mode) { ENTER (); InstPtr inst; ExprPtr e; if (ndim == 0) { obj = CompileInit (obj, expr, type, stat, code); } else { ExprPtr next; switch (expr->base.tag) { case ARRAY: for (e = expr->tree.left; e; e = next) { AInitMode subMode = AInitModeElement; next = e->tree.right; if (next && next->tree.left->base.tag == DOTDOTDOT) { subMode = AInitModeRepeat; next = next->tree.right; } obj = CompileArrayInits (obj, e->tree.left, type, ndim-1, stat, code, subMode); } break; case ANONINIT: break; default: CompileError (obj, stat, "Not enough initializer dimensions"); break; } } BuildInst (obj, OpInitArray, inst, stat); inst->ainit.dim = ndim; inst->ainit.mode = mode; RETURN (obj); } static ExprPtr CompileArrayInitArgs (int ndim) { ExprPtr a = NewExprConst (TEN_NUM, One); a->base.type = typePrim[rep_integer]; if (!ndim) return 0; return NewExprTree (COMMA, a, CompileArrayInitArgs (ndim - 1)); } static ArgType * CompileComprehensionArgs (ExprPtr e) { ArgType *down = 0; if (e->base.tag == COMMA) { down = CompileComprehensionArgs (e->tree.right); e = e->tree.left; } down = NewArgType (typePrim[rep_integer], False, e->atom.atom, e->atom.symbol, down); return down; } static ObjPtr CompileComprehension (ObjPtr obj, TypePtr type, ExprPtr expr, ExprPtr stat, CodePtr code) { ENTER (); ExprPtr body = expr->tree.right; ExprPtr lambda; ArgType *args; /* * Convert a single expression into a block containing a * return statement */ switch (body->base.tag) { case STRUCT: case COMP: case ARRAY: case ANONINIT: body = NewExprTree (NEW, body, 0); body->base.type = type; } if (body->base.tag != OC) body = NewExprTree (OC, NewExprTree (RETURNTOK, 0, body), NewExprTree (OC, 0, 0)); /* * Convert the args */ args = CompileComprehensionArgs (expr->tree.left->tree.left); /* * Compile [] symbol */ CompileStorage (obj, stat, expr->tree.left->tree.right->atom.symbol, code); /* * Build a func expression */ lambda = NewExprCode (NewFuncCode (type, args, body, Void), 0); obj = _CompileExpr (obj, lambda, True, stat, code); expr->tree.left->base.type = lambda->base.type; RETURN(obj); } /* * typedef struct { int x; } foo; * typedef struct { foo[2,2] q; } bar; * bar y = { q = { { { x = 1 } ... } ... } }; * * * ARRAY * / \ * COMMA 0 * / \ * ARRAY COMMA * / \ | \ * COMMA 0 DOTDOTDOT 0 * / \ * STRUCT COMMA * / \ | \ * COMMA 0 DOTDOTDOT 0 * / \ * ASSIGN 0 * | \ * NAME TEN_NUM * "x" 1 */ static ObjPtr CompileArrayInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code) { ENTER (); int ndim; Type *sub = type->array.type; Expr *dimensions; ndim = CompileCountDeclDimensions (type->array.dimensions); if (!ndim) { if (expr) ndim = CompileCountImplicitDimensions (expr); if (!ndim) { CompileError (obj, stat, "Cannot compute number of array dimensions"); RETURN (obj); } } if (type->array.dimensions && type->array.dimensions->tree.left) dimensions = 0; else { dimensions = CompileImplicitArray (obj, stat, expr, ndim); if (!dimensions) RETURN (obj); } if (expr && expr->base.tag == COMP) { ExprPtr args = CompileArrayInitArgs (ndim); Type *retType; obj = CompileComprehension (obj, sub, expr, stat, code); if (!CompileTypecheckArgs (obj, expr->tree.left->base.type, args, ndim, stat)) { RETURN(obj); } retType = TypeCombineReturn (expr->tree.left->base.type); if (!TypeCombineBinary (sub, ASSIGN, retType)) { CompileError (obj, stat, "Incompatible types, array '%T', return '%T', for initializer", sub, expr->base.type); RETURN(obj); } SetPush (obj); obj = CompileLvalue (obj, expr->tree.left->tree.right, stat, code, False, True, True, False, False); SetPush (obj); } obj = CompileBuildArray (obj, expr, type, dimensions, ndim, stat, code); if (expr) { InstPtr inst; if (expr->base.tag == COMP) { int start_inst; int top_inst; /* * Comprehension: * * Obj ^ (obj) * InitArray ndim (Start) * Branch L1 * L2: InitArray ndim (Func) * Call * InitArray 0 (Element) * L1: InitArray n (Test) * BranchFalse L2 * InitArray n (Element) */ BuildInst (obj, OpAssign, inst, stat); inst->assign.initialize = True; BuildInst (obj, OpInitArray, inst, stat); inst->ainit.mode = AInitModeStart; inst->ainit.dim = ndim; /* Branch L1 */ NewInst (obj, OpBranch, start_inst, stat); top_inst = obj->used; BuildInst (obj, OpInitArray, inst, stat); inst->ainit.dim = ndim; inst->ainit.mode = AInitModeFunc; BuildInst (obj, OpCall, inst, stat); inst->ints.value = ndim; BuildInst (obj, OpInitArray, inst, stat); inst->ainit.dim = 0; inst->ainit.mode = AInitModeElement; /* Patch Branch L1 */ inst = ObjCode (obj, start_inst); inst->branch.offset = obj->used - start_inst; inst->branch.mod = BranchModNone; BuildInst (obj, OpInitArray, inst, stat); inst->ainit.dim = 0; inst->ainit.mode = AInitModeTest; /* Branch L2 */ BuildInst (obj, OpBranchFalse, inst, stat); inst->branch.offset = top_inst - ObjLast(obj); inst->branch.mod = BranchModNone; /* Finish up */ BuildInst (obj, OpInitArray, inst, stat); inst->ainit.dim = ndim; inst->ainit.mode = AInitModeFuncDone; } else { int ninitdim; if (expr->base.tag != ARRAY && expr->base.tag != ANONINIT) { CompileError (obj, stat, "Non array initializer"); RETURN (obj); } ninitdim = CompileCountInitDimensions (sub, expr); if (ninitdim < 0) { CompileError (obj, stat, "Inconsistent array initializer dimensionality"); RETURN (obj); } if (ndim > ninitdim || (ndim < ninitdim && TypeCanon(sub)->base.tag != type_array)) { CompileError (obj, stat, "Array dimension mismatch %d != %d\n", ndim, ninitdim); RETURN (obj); } BuildInst (obj, OpInitArray, inst, stat); inst->ainit.mode = AInitModeStart; inst->ainit.dim = ndim; obj = CompileArrayInits (obj, expr, sub, ndim, stat, code, AInitModeElement); } } RETURN (obj); } static ObjPtr CompileHashInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst; ExprPtr inits = expr ? expr->tree.left : 0; ExprPtr init; if (type->base.tag == type_hash) { BuildInst (obj, OpBuildHash, inst, stat); inst->hash.type = type; if (expr) expr->base.type = type; /* * Initialize any elements given values */ for (init = inits; init; init = init->tree.right) { ExprPtr key = init->tree.left->tree.left; ExprPtr value = init->tree.left->tree.right; SetPush (obj); /* push the hash */ if (key) { /* * Compute the key */ obj = CompileInit (obj, key, type->hash.keyType, stat, code); if (!TypeIsOrdered (type->hash.keyType, key->base.type)) { CompileError (obj, stat, "Incompatible expression type '%T', for hash index type '%T'", key->base.type, type->hash.keyType); RETURN (obj); } SetPush (obj); /* push the key */ } /* * Compute the value */ obj = CompileInit (obj, value, type->hash.type, stat, code); /* * Store the pair */ BuildInst (obj, key ? OpInitHash : OpInitHashDef, inst, stat); } } RETURN (obj); } /* * Construct an implicit initializer expression for the specified type */ static ExprPtr CompileImplicitInit (Type *type) { ENTER (); ExprPtr init = 0; Type *sub; int dim; StructTypePtr structs; TypePtr *types; Atom *atoms; int i; type = TypeCanon (type); switch (type->base.tag) { case type_array: if (type->array.dimensions) { if (type->array.resizable) { init = NewExprTree (ANONINIT, 0, 0); } else if (type->array.dimensions->tree.left) { sub = type->array.type; init = CompileImplicitInit (sub); if (init) { dim = CompileCountDeclDimensions (type->array.dimensions); while (--dim >= 0) { init = NewExprTree (ARRAY, NewExprTree (COMMA, init, NewExprTree (COMMA, NewExprTree (DOTDOTDOT, 0, 0), 0)), 0); } } else init = NewExprTree (ANONINIT, 0, 0); } } break; case type_hash: init = NewExprTree (HASH, 0, 0); break; case type_struct: structs = type->structs.structs; types = BoxTypesElements (structs->types); atoms = StructTypeAtoms (structs); init = 0; for (i = 0; i < structs->nelements; i++) { ExprPtr member; sub = types[i]; member = CompileImplicitInit (sub); if (member) { init = NewExprTree (COMMA, NewExprTree (ASSIGN, NewExprAtom (atoms[i], 0, False), member), init); } } if (init) init = NewExprTree (STRUCT, init, 0); else init = NewExprTree (ANONINIT, 0, 0); break; default: break; } RETURN (init); } static Bool CompileStructInitElementIncluded (ExprPtr expr, Atom atom) { while (expr) { if (atom == expr->tree.left->tree.left->atom.atom) return True; expr = expr->tree.right; } return False; } static ObjPtr CompileStructUnionInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr code) { ENTER (); StructType *structs = type->structs.structs; InstPtr inst; ExprPtr inits = expr ? expr->tree.left : 0; ExprPtr init; Type *mem_type; int i; TypePtr *types = BoxTypesElements (structs->types); Atom *atoms = StructTypeAtoms (structs); if (type->base.tag == type_struct) { BuildInst (obj, OpBuildStruct, inst, stat); inst->structs.structs = structs; /* * Initialize any elements which were given explicit values */ for (init = inits; init; init = init->tree.right) { mem_type = StructMemType (structs, init->tree.left->tree.left->atom.atom); if (!mem_type) { CompileError (obj, stat, "Type '%T' is not a struct or union containing \"%A\"", type, init->tree.left->tree.left->atom.atom); continue; } SetPush (obj); /* push the struct */ /* * Compute the initializer value */ obj = CompileInit (obj, init->tree.left->tree.right, mem_type, stat, code); /* * Assign to the member */ BuildInst (obj, OpInitStruct, inst, stat); inst->atom.atom = init->tree.left->tree.left->atom.atom; } /* * Implicitly initialize any remaining elements */ for (i = 0; i < structs->nelements; i++) { TypePtr type = TypeCanon (types[i]); if (!inits || !CompileStructInitElementIncluded (inits, atoms[i])) { ExprPtr init = CompileImplicitInit (type); if (init) { SetPush (obj); obj = CompileInit (obj, init, type, stat, code); BuildInst (obj, OpInitStruct, inst, stat); inst->atom.atom = atoms[i]; } } } } else { init = inits; if (!init) { CompileError (obj, stat, "Empty initializer for union '%T'", type); RETURN (obj); } if (init->tree.right) { CompileError (obj, stat, "Multiple initializers for union '%T'", type); RETURN (obj); } mem_type = StructMemType (structs, init->tree.left->tree.left->atom.atom); if (!mem_type) { CompileError (obj, stat, "Type '%T' is not a struct or union containing \"%A\"", type, init->tree.left->tree.left->atom.atom); RETURN (obj); } /* * Compute the initializer value */ obj = CompileInit (obj, init->tree.left->tree.right, mem_type, stat, code); SetPush (obj); /* push the initializer value */ BuildInst (obj, OpBuildUnion, inst, stat); inst->structs.structs = structs; BuildInst (obj, OpInitUnion, inst, stat); inst->atom.atom = init->tree.left->tree.left->atom.atom; } RETURN (obj); } static int CompileCountCatches (ExprPtr catches) { int c = 0; while (catches) { c++; catches = catches->tree.left; } return c; } static ObjPtr CompileCatch (ObjPtr obj, ExprPtr catches, ExprPtr body, ExprPtr stat, CodePtr code, int nest) { ENTER (); int catch_inst, exception_inst; InstPtr inst; ExprPtr catch; ExprPtr name; SymbolPtr exception; Type *catch_type; NonLocal *nonLocal; int nest_tmp; if (catches) { catch = catches->tree.right; /* * try a catch b * * CATCH b OpCall EXCEPTION a ENDCATCH * +----------------------+ * +-----------------+ */ if (catch->code.code->base.name->base.tag == COLONCOLON) name = catch->code.code->base.name->tree.right; else name = catch->code.code->base.name; exception = name->atom.symbol; if (!exception) { CompileError (obj, stat, "No exception '%A' in scope", name->atom.atom); RETURN(obj); } if (exception->symbol.class != class_exception) { CompileError (obj, stat, "Invalid use of %C \"%A\" as exception", exception->symbol.class, catch->code.code->base.name->atom); RETURN (obj); } catch_type = NewTypeFunc (typePoly, catch->code.code->base.args); if (!TypeIsOrdered (exception->symbol.type, catch_type)) { CompileError (obj, stat, "Incompatible types, formal '%T', actual '%T', for catch", exception->symbol.type, catch_type); RETURN (obj); } NewInst (obj, OpCatch, catch_inst, stat); /* * Pop peer catch blocks from non local list while * compiling exception handler */ nonLocal = obj->nonLocal; if (nest) { REFERENCE (nonLocal); nest_tmp = nest; while (nest_tmp-- > 0) obj->nonLocal = obj->nonLocal->prev; } /* * Exception arguments are sitting in value, push * them on the stack */ BuildInst (obj, OpNoop, inst, stat); SetPush (obj); /* * Compile the exception handler and the * call to get to it. */ catch->code.code->base.func = code ? code->base.func : 0; obj = CompileFunc (obj, catch->code.code, stat, code, NewNonLocal (obj->nonLocal, NonLocalCatch, NON_LOCAL_RETURN)); /* * Patch non local returns inside */ CompilePatchLoop (obj, catch_inst, -1, -1, -1); /* * Unwind any peer catch blocks while executing catch */ if (nest) { BuildInst (obj, OpUnwind, inst, stat); inst->unwind.twixt = 0; inst->unwind.catch = nest; /* replace peer catch blocks */ obj->nonLocal = nonLocal; } BuildInst (obj, OpExceptionCall, inst, stat); exception_inst = obj->used; BuildInst (obj, OpBranch, inst, stat); inst->branch.offset = 0; inst->branch.mod = BranchModCatch; inst = ObjCode (obj, catch_inst); inst->catch.offset = obj->used - catch_inst; inst->catch.exception = exception; obj->nonLocal = NewNonLocal (obj->nonLocal, NonLocalTry, 0); obj = CompileCatch (obj, catches->tree.left, body, stat, code, nest+1); obj->nonLocal = obj->nonLocal->prev; if (!nest) { BuildInst (obj, OpEndCatch, inst, stat); inst->ints.value = CompileCountCatches (catches); /* * Patch Catch branches inside */ CompilePatchLoop (obj, exception_inst, -1, -1, obj->used); } } else obj = _CompileStat (obj, body, False, code); RETURN (obj); } ObjPtr _CompileExpr (ObjPtr obj, ExprPtr expr, Bool evaluate, ExprPtr stat, CodePtr code) { ENTER (); int ndim; int top_inst, test_inst, middle_inst; InstPtr inst; SymbolPtr s; Type *t; int staticLink; Bool bool_const; switch (expr->base.tag) { case NAME: s = CompileCheckSymbol (obj, stat, expr, code, &staticLink, False); if (!s) { expr->base.type = typePoly; break; } switch (s->symbol.class) { case class_const: case class_global: BuildInst (obj, OpGlobal, inst, stat); inst->box.box = s->global.value; assert (s->global.value); #if 0 inst->var.name = s; inst->var.staticLink = 0; #endif break; case class_static: BuildInst (obj, OpStatic, inst, stat); inst->frame.staticLink = staticLink; inst->frame.element = s->local.element; break; case class_arg: case class_auto: BuildInst (obj, OpLocal, inst, stat); inst->frame.staticLink = staticLink; inst->frame.element = s->local.element; break; default: CompileError (obj, stat, "Invalid use of %C \"%A\"", s->symbol.class, expr->atom.atom); expr->base.type = typePoly; inst = 0; break; } if (!inst) break; expr->base.type = s->symbol.type; t = CompileRefType (obj, expr, expr->base.type); if (t) { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = Dereference; expr->base.type = t; } break; case VAR: obj = CompileDecl (obj, expr, evaluate, stat, code); break; case NEW: if (expr->base.type) obj = CompileType (obj, 0, expr->base.type, stat, code); obj = CompileInit (obj, expr->tree.left, expr->base.type, stat, code); break; case UNION: if (expr->tree.right) obj = _CompileExpr (obj, expr->tree.right, True, stat, code); else { BuildInst (obj, OpConst, inst, stat); inst->constant.constant = Void; } SetPush (obj); t = TypeCanon (expr->base.type); if (t && t->base.tag == type_union) { StructType *st = t->structs.structs; Type *mt; expr->tree.left->base.type = StructMemType (st, expr->tree.left->atom.atom); if (!expr->tree.left->base.type) { CompileError (obj, stat, "Union type '%T' has no member \"%A\"", expr->base.type, expr->tree.left->atom.atom); break; } mt = TypeCanon (expr->tree.left->base.type); BuildInst (obj, OpBuildUnion, inst, stat); inst->structs.structs = st; if (expr->tree.right) { if (mt == typePrim[rep_void]) { CompileError (obj, stat, "Union type '%T', member '%A' requires no constructor value", expr->base.type, expr->tree.left->atom.atom); break; } if (!TypeCombineBinary (expr->tree.left->base.type, ASSIGN, expr->tree.right->base.type)) { CompileError (obj, stat, "Incompatible types, member '%T', value '%T', for union constructor", expr->tree.left->base.type, expr->tree.right->base.type); break; } } else { if (mt != typePrim[rep_void]) { CompileError (obj, stat, "Union member '%A' requires constructor value", expr->tree.left->atom.atom); break; } } BuildInst (obj, OpInitUnion, inst, stat); inst->atom.atom = expr->tree.left->atom.atom; } else { CompileError (obj, stat, "Incompatible type, type '%T', for union constructor", expr->base.type); expr->base.type = typePoly; break; } break; case TEN_NUM: case OCTAL0_NUM: case OCTAL_NUM: case BINARY_NUM: case HEX_NUM: case CHAR_CONST: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; expr->base.type = typePrim[rep_integer]; break; case TEN_FLOAT: case OCTAL_FLOAT: case BINARY_FLOAT: case HEX_FLOAT: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; if (ValueRep(expr->constant.constant) == &IntRep) expr->base.type = typePrim[rep_integer]; else expr->base.type = typePrim[ValueTag(expr->constant.constant)]; break; case STRING_CONST: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; expr->base.type = typePrim[rep_string]; break; case THREAD_CONST: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; expr->base.type = typePrim[rep_thread]; break; case VOIDVAL: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; expr->base.type = typePrim[rep_void]; break; case BOOLVAL: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; expr->base.type = typePrim[rep_bool]; break; case POLY_CONST: BuildInst (obj, OpConst, inst, stat); inst->constant.constant = expr->constant.constant; expr->base.type = typePoly; /* FIXME composite const type */ break; case OS: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); obj = CompileArrayIndex (obj, expr->tree.right, CompileIndexType (expr->tree.left), stat, code, &ndim); if (!ndim) { expr->base.type = typePoly; break; } expr->base.type = TypeCombineArray (expr->tree.left->base.type, ndim, False); if (!expr->base.type) { CompileError (obj, stat, "Incompatible type '%T', for %d dimension operation", expr->tree.left->base.type, ndim); expr->base.type = typePoly; break; } BuildInst (obj, OpArray, inst, stat); inst->ints.value = ndim; break; case OP: /* function call */ obj = CompileCall (obj, expr, TailNever, stat, code, False); break; case COLONCOLON: obj = _CompileExpr (obj, expr->tree.right, evaluate, stat, code); expr->base.type = expr->tree.right->base.type; break; case DOT: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); expr->base.type = TypeCombineStruct (expr->tree.left->base.type, expr->base.tag, expr->tree.right->atom.atom); if (!expr->base.type) { CompileError (obj, stat, "Type '%T' is not a struct or union containing \"%A\"", expr->tree.left->base.type, expr->tree.right->atom.atom); expr->base.type = typePoly; break; } BuildInst (obj, OpDot, inst, stat); inst->atom.atom = expr->tree.right->atom.atom; t = CompileRefType (obj, expr, expr->base.type); if (t) { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = Dereference; expr->base.type = t; } break; case ARROW: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); expr->base.type = TypeCombineStruct (expr->tree.left->base.type, expr->base.tag, expr->tree.right->atom.atom); if (!expr->base.type) { CompileError (obj, stat, "Type '%T' is not a struct or union ref containing \"%A\"", expr->tree.left->base.type, expr->tree.right->atom.atom); expr->base.type = typePoly; break; } BuildInst (obj, OpArrow, inst, stat); inst->atom.atom = expr->tree.right->atom.atom; t = CompileRefType (obj, expr, expr->base.type); if (t) { BuildInst (obj, OpUnFunc, inst, stat); inst->unfunc.func = Dereference; expr->base.type = t; } break; case FUNC: obj = CompileFunc (obj, expr->code.code, stat, code, 0); expr->base.type = NewTypeFunc (expr->code.code->base.type, expr->code.code->base.args); break; case STAR: obj = CompileUnFunc (obj, expr, Dereference, stat, code,"*"); break; case AMPER: obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, True); t = CompileRefType (obj, expr->tree.left, expr->tree.left->base.type); if (!t) t = expr->tree.left->base.type; expr->base.type = NewTypeRef (t, True); if (!expr->base.type) { CompileError (obj, stat, "Type '%T' cannot be an l-value", expr->tree.left->base.type); expr->base.type = typePoly; break; } break; case UMINUS: obj = CompileUnOp (obj, expr, NegateOp, stat, code); break; case LNOT: obj = CompileUnFunc (obj, expr, Lnot, stat, code,"~"); break; case BANG: obj = CompileUnFunc (obj, expr, Not, stat, code,"!"); break; case FACT: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right, True, stat, code); expr->base.type = TypeCombineUnary (expr->tree.right->base.type, expr->base.tag); if (!expr->base.type) { CompileError (obj, stat, "Incompatible type, value '%T', for ! operation", expr->tree.right->base.type); expr->base.type = typePoly; break; } BuildInst (obj, OpCall, inst, stat); inst->ints.value = 1; BuildInst (obj, OpNoop, inst, stat); break; case INC: if (expr->tree.left) { obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, False); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, ASSIGNPLUS, typePrim[rep_int]); BuildInst (obj, OpPreOp, inst, stat); } else { obj = CompileLvalue (obj, expr->tree.right, stat, code, False, False, False, False, False); expr->base.type = TypeCombineBinary (expr->tree.right->base.type, ASSIGNPLUS, typePrim[rep_int]); BuildInst (obj, OpPostOp, inst, stat); } inst->binop.op = PlusOp; if (!expr->base.type) { CompileError (obj, stat, "Incompatible type, value '%T', for ++ operation ", expr->tree.left ? expr->tree.left->base.type : expr->tree.right->base.type); expr->base.type = typePoly; break; } break; case DEC: if (expr->tree.left) { obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, False); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, ASSIGNMINUS, typePrim[rep_int]); BuildInst (obj, OpPreOp, inst, stat); } else { obj = CompileLvalue (obj, expr->tree.right, stat, code, False, False, False, False, False); expr->base.type = TypeCombineBinary (expr->tree.right->base.type, ASSIGNMINUS, typePrim[rep_int]); BuildInst (obj, OpPostOp, inst, stat); } inst->binop.op = MinusOp; if (!expr->base.type) { CompileError (obj, stat, "Incompatible type, value '%T', for -- operation", expr->tree.left ? expr->tree.left->base.type : expr->tree.right->base.type); expr->base.type = typePoly; break; } break; case PLUS: obj = CompileBinOp (obj, expr, PlusOp, stat, code); break; case MINUS: obj = CompileBinOp (obj, expr, MinusOp, stat, code); break; case TIMES: obj = CompileBinOp (obj, expr, TimesOp, stat, code); break; case DIVIDE: obj = CompileBinOp (obj, expr, DivideOp, stat, code); break; case DIV: obj = CompileBinOp (obj, expr, DivOp, stat, code); break; case MOD: obj = CompileBinOp (obj, expr, ModOp, stat, code); break; case POW: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right->tree.left, True, stat, code); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.right->tree.left->base.type, expr->base.tag, expr->tree.right->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for ** operation", expr->tree.right->tree.left->base.type, expr->tree.right->tree.right->base.type); expr->base.type = typePoly; break; } BuildInst (obj, OpCall, inst, stat); inst->ints.value = 2; BuildInst (obj, OpNoop, inst, stat); break; case SHIFTL: obj = CompileBinFunc (obj, expr, ShiftL, stat, code, "<<"); break; case SHIFTR: obj = CompileBinFunc (obj, expr, ShiftR, stat, code, ">>"); break; case QUEST: /* * a ? b : c * * a QUEST b COLON c * +-------------+ * +-------+ */ top_inst = obj->used; obj = _CompileBoolExpr (obj, expr->tree.left, True, stat, code); if (obj->used == top_inst + 1 && (inst = ObjCode (obj, top_inst))->base.opCode == OpConst) { test_inst = -1; bool_const = True (inst->constant.constant); obj->used = top_inst; } else { NewInst (obj, OpBranchFalse, test_inst, stat); bool_const = False; } top_inst = obj->used; obj = _CompileExpr (obj, expr->tree.right->tree.left, evaluate, stat, code); if (test_inst == -1) { middle_inst = -1; if (!bool_const) obj->used = top_inst; } else { NewInst (obj, OpBranch, middle_inst, stat); inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; } top_inst = obj->used; obj = _CompileExpr (obj, expr->tree.right->tree.right, evaluate, stat, code); if (middle_inst == -1) { if (bool_const) obj->used = top_inst; } else { inst = ObjCode (obj, middle_inst); inst->branch.offset = obj->used - middle_inst; inst->branch.mod = BranchModNone; BuildInst (obj, OpNoop, inst, stat); } expr->base.type = TypeCombineBinary (expr->tree.right->tree.left->base.type, COLON, expr->tree.right->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, true '%T', false '%T', for ?: operation", expr->tree.right->tree.left->base.type, expr->tree.right->tree.right->base.type); expr->base.type = typePoly; break; } break; case LXOR: obj = CompileBinFunc (obj, expr, Lxor, stat, code, "^"); break; case LAND: obj = CompileBinOp (obj, expr, LandOp, stat, code); break; case LOR: obj = CompileBinOp (obj, expr, LorOp, stat, code); break; case AND: /* * a && b * * a ANDAND b * +--------+ */ top_inst = obj->used; obj = _CompileBoolExpr (obj, expr->tree.left, True, stat, code); if (obj->used == top_inst + 1 && (inst = ObjCode (obj, top_inst))->base.opCode == OpConst) { test_inst = -1; bool_const = True (inst->constant.constant); if (bool_const) obj->used = top_inst; } else { NewInst (obj, OpBranchFalse, test_inst, stat); bool_const = True; } middle_inst = obj->used; /* * Always compile the RHS to check for errors */ obj = _CompileBoolExpr (obj, expr->tree.right, evaluate, stat, code); /* * Smash any instructions if they'll be skipped */ if (!bool_const) obj->used = middle_inst; if (test_inst >= 0) { inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; BuildInst (obj, OpNoop, inst, stat); } expr->base.type = TypeCombineBinary (expr->tree.left->base.type, AND, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for && operation", expr->tree.left->base.type, expr->tree.right->base.type); expr->base.type = typePoly; break; } break; case OR: /* * a || b * * a OROR b * +--------+ */ top_inst = obj->used; obj = _CompileExpr (obj, expr->tree.left, True, stat, code); if (obj->used == top_inst + 1 && (inst = ObjCode (obj, top_inst))->base.opCode == OpConst) { test_inst = -1; bool_const = True (inst->constant.constant); if (!bool_const) obj->used = top_inst; } else { NewInst (obj, OpBranchTrue, test_inst, stat); bool_const = False; } middle_inst = obj->used; /* * Always compile the RHS to check for errors */ obj = _CompileExpr (obj, expr->tree.right, evaluate, stat, code); /* * Smash any instructions if they'll be skipped */ if (bool_const) obj->used = middle_inst; if (test_inst >= 0) { inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; BuildInst (obj, OpNoop, inst, stat); } expr->base.type = TypeCombineBinary (expr->tree.left->base.type, OR, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right, '%T', for || operation", expr->tree.left->base.type, expr->tree.right->base.type); expr->base.type = typePoly; break; } break; case ASSIGN: obj = CompileAssign (obj, expr, False, stat, code); break; case ASSIGNPLUS: obj = CompileAssignOp (obj, expr, PlusOp, stat, code); break; case ASSIGNMINUS: obj = CompileAssignOp (obj, expr, MinusOp, stat, code); break; case ASSIGNTIMES: obj = CompileAssignOp (obj, expr, TimesOp, stat, code); break; case ASSIGNDIVIDE: obj = CompileAssignOp (obj, expr, DivideOp, stat, code); break; case ASSIGNDIV: obj = CompileAssignOp (obj, expr, DivOp, stat, code); break; case ASSIGNMOD: obj = CompileAssignOp (obj, expr, ModOp, stat, code); break; case ASSIGNPOW: obj = _CompileExpr (obj, expr->tree.left, True, stat, code); SetPush (obj); obj = CompileLvalue (obj, expr->tree.right->tree.left, stat, code, False, False, False, False, False); SetPush (obj); obj = _CompileExpr (obj, expr->tree.right->tree.right, True, stat, code); expr->base.type = TypeCombineBinary (expr->tree.right->tree.left->base.type, expr->base.tag, expr->tree.right->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for **= operation", expr->tree.right->tree.left->base.type, expr->tree.right->tree.right->base.type); expr->base.type = typePoly; break; } BuildInst (obj, OpCall, inst, stat); inst->ints.value = 2; BuildInst (obj, OpNoop, inst, stat); break; case ASSIGNSHIFTL: obj = CompileAssignFunc (obj, expr, ShiftL, stat, code, "<<"); break; case ASSIGNSHIFTR: obj = CompileAssignFunc (obj, expr, ShiftR, stat, code, ">>"); break; case ASSIGNLXOR: obj = CompileAssignFunc (obj, expr, Lxor, stat, code, "^"); break; case ASSIGNLAND: obj = CompileAssignOp (obj, expr, LandOp, stat, code); break; case ASSIGNLOR: obj = CompileAssignOp (obj, expr, LorOp, stat, code); break; case ASSIGNAND: /* * a &&= b * * a ASSIGNAND b * +--------+ */ top_inst = obj->used; obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, False); SetPush (obj); NewInst (obj, OpFetch, middle_inst, stat); NewInst (obj, OpBranchFalse, test_inst, stat); /* no short circuit */ obj = _CompileBoolExpr (obj, expr->tree.right, True, stat, code); if (test_inst >= 0) { inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; BuildInst (obj, OpAssign, inst, stat); NewInst(obj, OpBranch, test_inst, stat); } else { NewInst (obj, OpAssign, middle_inst, stat); NewInst(obj, OpBranch, test_inst, stat); } /* short circuit */ NewInst(obj, OpDrop, middle_inst, stat); inst = ObjCode(obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; /* exit: is this Noop necessary? */ BuildInst (obj, OpNoop, inst, stat); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, AND, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for &&= operation", expr->tree.left->base.type, expr->tree.right->base.type); expr->base.type = typePoly; break; } break; case ASSIGNOR: /* * a ||= b * * a ASSIGNOR b * +--------+ */ top_inst = obj->used; obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False, False); SetPush (obj); NewInst (obj, OpFetch, middle_inst, stat); NewInst (obj, OpBranchTrue, test_inst, stat); /* no short circuit */ obj = _CompileBoolExpr (obj, expr->tree.right, True, stat, code); if (test_inst >= 0) { inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; BuildInst (obj, OpAssign, inst, stat); NewInst(obj, OpBranch, test_inst, stat); } else { NewInst (obj, OpAssign, middle_inst, stat); NewInst(obj, OpBranch, test_inst, stat); } /* short circuit */ NewInst(obj, OpDrop, middle_inst, stat); inst = ObjCode(obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; /* exit: is this Noop necessary? */ BuildInst (obj, OpNoop, inst, stat); expr->base.type = TypeCombineBinary (expr->tree.left->base.type, OR, expr->tree.right->base.type); if (!expr->base.type) { CompileError (obj, stat, "Incompatible types, left '%T', right '%T', for ||= operation", expr->tree.left->base.type, expr->tree.right->base.type); expr->base.type = typePoly; break; } break; case EQ: obj = CompileBinOp (obj, expr, EqualOp, stat, code); break; case NE: obj = CompileBinFunc (obj, expr, NotEqual, stat, code,"!="); break; case LT: obj = CompileBinOp (obj, expr, LessOp, stat, code); break; case GT: obj = CompileBinFunc (obj, expr, Greater, stat, code,">"); break; case LE: obj = CompileBinFunc (obj, expr, LessEqual, stat, code,"<="); break; case GE: obj = CompileBinFunc (obj, expr, GreaterEqual, stat, code,">="); break; case COMMA: top_inst = obj->used; obj = _CompileExpr (obj, expr->tree.left, False, stat, code); if (obj->used == top_inst + 1 && (inst = ObjCode (obj, top_inst))->base.opCode == OpConst) { obj->used = top_inst; } expr->base.type = expr->tree.left->base.type; if (expr->tree.right) { obj = _CompileExpr (obj, expr->tree.right, evaluate, stat, code); expr->base.type = expr->tree.right->base.type; } break; case FORK: BuildInst (obj, OpFork, inst, stat); inst->obj.obj = CompileExpr (expr->tree.right, code); expr->base.type = typePrim[rep_thread]; break; case THREAD: obj = CompileCall (obj, NewExprTree (OP, expr->tree.right, NewExprTree (COMMA, expr->tree.left, (Expr *) 0)), TailNever, stat, code, False); expr->base.type = typePrim[rep_thread]; break; case DOLLAR: { ExprPtr value, new; if (expr->tree.left) value = expr->tree.left; else value = NewExprConst (TEN_NUM, Zero); new = BuildCall ("History", "fetch", 1, value); obj = _CompileExpr (obj, new, True, stat, code); } expr->base.type = typePoly; break; case ISTYPE: obj = _CompileExpr (obj, expr->type.left, evaluate, stat, code); BuildInst (obj, OpIsType, inst, stat); inst->isType.type = expr->type.type; expr->base.type = typePrim[rep_bool]; break; case HASMEMBER: obj = _CompileExpr (obj, expr->tree.left, evaluate, stat, code); BuildInst (obj, OpHasMember, inst, stat); inst->atom.atom = expr->tree.right->atom.atom; expr->base.type = typePrim[rep_bool]; break; case EXPR: /* reposition statement reference so top-level errors are nicer*/ obj = _CompileExpr (obj, expr->tree.left, evaluate, expr, code); expr->base.type = expr->tree.left->base.type; break; case OC: /* statement block embedded in an expression */ obj = _CompileStat (obj, expr, True, code); BuildInst (obj, OpConst, inst, stat); inst->constant.constant = Void; expr->base.type = typePrim[rep_void]; break; default: assert(0); } assert (!evaluate || expr->base.type); RETURN (obj); } void CompilePatchLoop (ObjPtr obj, int start, int continue_offset, int break_offset, int catch_offset) { InstPtr inst; while (start < obj->used) { inst = ObjCode (obj, start); switch (inst->base.opCode) { case OpBranch: if (inst->branch.offset == 0) { switch (inst->branch.mod) { case BranchModBreak: inst->branch.offset = break_offset - start; break; case BranchModContinue: if (continue_offset >= 0) inst->branch.offset = continue_offset - start; break; case BranchModCatch: if (catch_offset >= 0) inst->branch.offset = catch_offset - start; break; default: break; } } break; case OpFarJump: if (inst->farJump.farJump->inst == -1) { switch (inst->farJump.mod) { case BranchModBreak: inst->farJump.farJump->inst = break_offset; break; case BranchModContinue: inst->farJump.farJump->inst = continue_offset; break; case BranchModReturn: case BranchModReturnVoid: inst->farJump.farJump->inst = -2; break; case BranchModNone: case BranchModCatch: break; } } break; case OpObj: if (!inst->code.code->base.builtin && inst->code.code->func.body.obj->nonLocal) { if (inst->code.code->func.body.obj) CompilePatchLoop (inst->code.code->func.body.obj, 0, continue_offset, break_offset, -1); if (inst->code.code->func.staticInit.obj) CompilePatchLoop (inst->code.code->func.staticInit.obj, 0, continue_offset, break_offset, -1); } break; default: break; } ++start; } } static void CompileMoveObj (ObjPtr obj, int start, int depth, int amount) { InstPtr inst; while (start < obj->used) { inst = ObjCode (obj, start); switch (inst->base.opCode) { case OpFarJump: if (inst->farJump.farJump->frame == depth && inst->farJump.farJump->inst >= 0) { inst->farJump.farJump->inst += amount; } break; case OpObj: if (!inst->code.code->base.builtin && inst->code.code->func.body.obj->nonLocal) { if (inst->code.code->func.body.obj) CompileMoveObj (inst->code.code->func.body.obj, 0, depth + 1, amount); if (inst->code.code->func.staticInit.obj) CompileMoveObj (inst->code.code->func.staticInit.obj, 0, depth + 1, amount); } break; default: break; } ++start; } } static ObjPtr _CompileNonLocal (ObjPtr obj, BranchMod mod, ExprPtr expr, CodePtr code) { ENTER (); int twixt = 0, catch = 0, frame = 0; NonLocal *nl; InstPtr inst; int target; switch (mod) { case BranchModBreak: target = NON_LOCAL_BREAK; break; case BranchModContinue: target = NON_LOCAL_CONTINUE; break; case BranchModReturn: case BranchModReturnVoid: target = NON_LOCAL_RETURN; break; case BranchModNone: default: RETURN(obj); } for (nl = obj->nonLocal; nl; nl = nl->prev) { if (nl->target & target) break; switch (nl->kind) { case NonLocalTwixt: twixt++; break; case NonLocalTry: catch++; break; case NonLocalCatch: frame++; break; case NonLocalControl: break; } } if (!nl) { switch (target) { case NON_LOCAL_BREAK: CompileError (obj, expr, "break not in loop/switch/twixt"); break; case NON_LOCAL_CONTINUE: CompileError (obj, expr, "continue not in loop"); break; case NON_LOCAL_RETURN: break; } } if (twixt || catch || frame) { BuildInst (obj, OpFarJump, inst, expr); inst->farJump.farJump = 0; inst->farJump.farJump = NewFarJump (-1, twixt, catch, frame); inst->farJump.mod = mod; } else { switch (mod) { case BranchModReturn: BuildInst (obj, OpReturn, inst, expr); break; case BranchModReturnVoid: BuildInst (obj, OpReturnVoid, inst, expr); break; case BranchModBreak: case BranchModContinue: BuildInst (obj, OpBranch, inst, expr); inst->branch.offset = 0; /* filled in by PatchLoop */ inst->branch.mod = mod; case BranchModNone: case BranchModCatch: break; } } RETURN (obj); } /* * Check if a return foo () can be turned into a tail call. */ static Bool _CompileCanTailCall (ObjPtr obj, CodePtr code) { /* not in a function ("can't" happen) */ if (!code) return False; /* if profiling, disable tail calls to avoid losing information */ if (profiling) return False; /* Check for enclosing non-local branch targets */ if (obj->nonLocal != 0) return False; /* Check for compiling in a nested exception handler */ if (code->base.func != code) return False; return True; } ObjPtr _CompileBoolExpr (ObjPtr obj, ExprPtr expr, Bool evaluate, ExprPtr stat, CodePtr code) { obj = _CompileExpr (obj, expr, evaluate, stat, code); if (!TypePoly (expr->base.type) && !TypeBool (expr->base.type)) { CompileError (obj, expr, "Incompatible type, value '%T', for boolean", expr->base.type); } return obj; } ObjPtr _CompileStat (ObjPtr obj, ExprPtr expr, Bool last, CodePtr code) { ENTER (); int start_inst, top_inst, continue_inst, test_inst, middle_inst; ExprPtr c; int ncase, *case_inst, icase; Bool has_default; InstPtr inst; StructType *st; ObjPtr cobj, bobj; switch (expr->base.tag) { case IF: /* * if (a) b * * a BRANCHFALSE b * +-------------+ */ top_inst = obj->used; obj = _CompileBoolExpr (obj, expr->tree.left, True, expr, code); if (obj->used == top_inst + 1 && (inst = ObjCode (obj, top_inst))->base.opCode == OpConst) { Bool t = True (inst->constant.constant); obj->used = top_inst; if (t) obj = _CompileStat (obj, expr->tree.right, last, code); } else { NewInst (obj, OpBranchFalse, test_inst, expr); obj = _CompileStat (obj, expr->tree.right, last, code); inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; } break; case ELSE: /* * if (a) b else c * * a BRANCHFALSE b BRANCH c * +--------------------+ * +--------+ */ top_inst = obj->used; obj = _CompileBoolExpr (obj, expr->tree.left, True, expr, code); if (obj->used == top_inst + 1 && (inst = ObjCode (obj, top_inst))->base.opCode == OpConst) { Bool t = True (inst->constant.constant); obj->used = top_inst; /* * Check which side wins */ if (t) obj = _CompileStat (obj, expr->tree.right->tree.left, last, code); else obj = _CompileStat (obj, expr->tree.right->tree.right, last, code); } else { NewInst (obj, OpBranchFalse, test_inst, expr); /* * Compile b */ obj = _CompileStat (obj, expr->tree.right->tree.left, last, code); /* * Branch around else if reachable */ if (CompileIsReachable (obj, obj->used, 0)) { NewInst (obj, OpBranch, middle_inst, expr); } else middle_inst = -1; /* * Fix up branch on a */ inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; /* * Compile c */ obj = _CompileStat (obj, expr->tree.right->tree.right, last, code); /* * Fix up branch around else if necessary */ if (middle_inst != -1) { inst = ObjCode (obj, middle_inst); inst->branch.offset = obj->used - middle_inst; inst->branch.mod = BranchModNone; } } break; case WHILE: /* * while (a) b * * a BRANCHFALSE b BRANCH * +--------------------+ * +---------------+ */ cobj = NewObj (OBJ_INCR, OBJ_STAT_INCR); cobj = _CompileBoolExpr (cobj, expr->tree.left, True, expr, code); if (cobj->used == 1 && (inst = ObjCode (cobj, 0))->base.opCode == OpConst) { Bool t = True (inst->constant.constant); if (!t) { /* strip out the whole while loop */ break; } start_inst = -1; } else { NewInst (obj, OpBranch, start_inst, expr); } top_inst = obj->used; obj->nonLocal = NewNonLocal (obj->nonLocal, NonLocalControl, NON_LOCAL_BREAK|NON_LOCAL_CONTINUE); obj = _CompileStat (obj, expr->tree.right, False, code); obj->nonLocal = obj->nonLocal->prev; continue_inst = obj->used; if (start_inst != -1) { inst = ObjCode (obj, start_inst); inst->branch.offset = obj->used - start_inst; inst->branch.mod = BranchModNone; middle_inst = obj->used; obj = AppendObj (obj, cobj); CompileMoveObj (obj, middle_inst, 0, middle_inst); BuildInst (obj, OpBranchTrue, inst, expr); inst->branch.offset = top_inst - ObjLast(obj); inst->branch.mod = BranchModNone; } else { BuildInst (obj, OpBranch, inst, expr); inst->branch.offset = top_inst - ObjLast(obj); inst->branch.mod = BranchModNone; } CompilePatchLoop (obj, top_inst, continue_inst, obj->used, -1); break; case DO: /* * do a while (b); * * a b DO * +---+ */ top_inst = obj->used; obj->nonLocal = NewNonLocal (obj->nonLocal, NonLocalControl, NON_LOCAL_BREAK|NON_LOCAL_CONTINUE); obj = _CompileStat (obj, expr->tree.left, False, code); obj->nonLocal = obj->nonLocal->prev; continue_inst = obj->used; obj = _CompileBoolExpr (obj, expr->tree.right, True, expr, code); if (obj->used == continue_inst + 1 && (inst = ObjCode (obj, continue_inst))->base.opCode == OpConst) { Bool t = True (inst->constant.constant); obj->used = continue_inst; if (t) { BuildInst (obj, OpBranch, inst, expr); inst->branch.offset = top_inst - ObjLast(obj); inst->branch.mod = BranchModNone; } } else { BuildInst (obj, OpBranchTrue, inst, expr); inst->branch.offset = top_inst - ObjLast(obj); inst->branch.mod = BranchModNone; } CompilePatchLoop (obj, top_inst, continue_inst, obj->used, -1); break; case FOR: /* * for (a; b; c) d * * a BRANCH d c b BRANCHTRUE * +----------+ * +-----+ */ /* a */ if (expr->tree.left->tree.left) obj = _CompileExpr (obj, expr->tree.left->tree.left, False, expr, code); test_inst = -1; start_inst = -1; /* check for b */ bobj = 0; if (expr->tree.left->tree.right->tree.left) { bobj = NewObj (OBJ_INCR, OBJ_STAT_INCR); bobj = _CompileBoolExpr (bobj, expr->tree.left->tree.right->tree.left, True, expr, code); NewInst (obj, OpBranch, start_inst, expr); } /* check for c */ cobj = 0; if (expr->tree.left->tree.right->tree.right->tree.left) { cobj = NewObj (OBJ_INCR, OBJ_STAT_INCR); cobj = _CompileExpr (cobj, expr->tree.left->tree.right->tree.right->tree.left, False, expr, code); } top_inst = obj->used; /* d */ obj->nonLocal = NewNonLocal (obj->nonLocal, NonLocalControl, NON_LOCAL_BREAK|NON_LOCAL_CONTINUE); obj = _CompileStat (obj, expr->tree.right, False, code); obj->nonLocal = obj->nonLocal->prev; /* glue c into place */ continue_inst = obj->used; if (cobj) { middle_inst = obj->used; obj = AppendObj (obj, cobj); CompileMoveObj (obj, middle_inst, 0, middle_inst); } /* glue b into place */ if (bobj) { int middle_inst = obj->used; obj = AppendObj (obj, bobj); CompileMoveObj (obj, middle_inst, 0, middle_inst); if (obj->used == middle_inst + 1 && (inst = ObjCode (obj, middle_inst))->base.opCode == OpConst) { Bool t = True(inst->constant.constant); obj->used = middle_inst; if (t) { BuildInst (obj, OpBranch, inst, expr); inst->branch.offset = top_inst - ObjLast (obj); inst->branch.mod = BranchModNone; } else { /* delete whole for body */ ResetInst (obj, start_inst); continue_inst = top_inst = start_inst; } } else { BuildInst (obj, OpBranchTrue, inst, expr); inst->branch.offset = top_inst - ObjLast(obj); inst->branch.mod = BranchModNone; } /* patch start branch */ inst = ObjCode (obj, start_inst); inst->branch.offset = middle_inst - start_inst; inst->branch.mod = BranchModNone; } else { BuildInst (obj, OpBranch, inst, expr); inst->branch.offset = top_inst - ObjLast (obj); inst->branch.mod = BranchModNone; } CompilePatchLoop (obj, top_inst, continue_inst, obj->used, -1); break; case SWITCH: case UNION: /* * switch (a) { case b: c; case d: e; } * * a b CASE d CASE DEFAULT c e * +------------------+ * +-------------+ * +--------+ */ obj = _CompileExpr (obj, expr->tree.left, True, expr, code); st = 0; if (expr->base.tag == SWITCH) SetPush (obj); else { if (expr->tree.left->base.type) { Type *t; t = TypeCanon (expr->tree.left->base.type); if (t->base.tag == type_union) st = t->structs.structs; else if (!TypePoly (t)) { CompileError (obj, expr, "Union switch type '%T' not union", expr->tree.left->base.type); } } } c = expr->tree.right; has_default = False; ncase = 0; while (c) { if (!c->tree.left->tree.left) has_default = True; else ncase++; c = c->tree.right; } /* * Check to see if the union switch covers * all possible values */ test_inst = 0; if (expr->base.tag == UNION && st) { Bool missing = False; int i; Atom *atoms = StructTypeAtoms(st); /* * See if every member of the union has a case */ for (i = 0; i < st->nelements; i++) { c = expr->tree.right; while (c) { ExprPtr pair = c->tree.left->tree.left; if (pair) { Atom tag = pair->tree.left->atom.atom; if (tag == atoms[i]) break; } c = c->tree.right; } if (!c) { missing = True; break; } } if (!missing) { test_inst = -1; if (has_default) CompileError (obj, expr, "Union switch has unreachable default"); } if (missing && !has_default) CompileError (obj, expr, "Union switch missing elements with no default"); } case_inst = AllocateTemp (ncase * sizeof (int)); /* * Compile the comparisons */ c = expr->tree.right; icase = 0; while (c) { if (c->tree.left->tree.left) { if (expr->base.tag == SWITCH) { obj = _CompileExpr (obj, c->tree.left->tree.left, True, c, code); if (!TypeCombineBinary(expr->tree.left->base.type, EQ, c->tree.left->tree.left->base.type)) { CompileError (obj, expr, "Incompatible types, left '%T', right '%T', for case comparison", expr->tree.left->base.type, c->tree.left->tree.left->base.type, EQ); expr->base.type = typePoly; } } NewInst (obj, expr->base.tag == SWITCH ? OpCase : OpTagCase, case_inst[icase], expr); icase++; } c = c->tree.right; } /* add default case at the bottom */ if (test_inst == 0) { /* don't know what the opcode is yet */ NewInst (obj, expr->base.tag == SWITCH ? OpDefault : OpBranch, test_inst, expr); } top_inst = obj->used; obj->nonLocal = NewNonLocal (obj->nonLocal, NonLocalControl, NON_LOCAL_BREAK); /* * Compile the statements */ c = expr->tree.right; icase = 0; while (c) { ExprPtr s = c->tree.left->tree.right; /* * Patch the branch */ if (c->tree.left->tree.left) { inst = ObjCode (obj, case_inst[icase]); if (expr->base.tag == SWITCH) { inst->branch.offset = obj->used - case_inst[icase]; inst->branch.mod = BranchModNone; } else { ExprPtr pair = c->tree.left->tree.left; Atom tag = pair->tree.left->atom.atom; Type *mt = typePoly; /* * Find the member type */ if (st) { mt = StructMemType (st, tag); if (!mt) { mt = typePoly; CompileError (obj, expr, "Union case tag '%A' not in type '%T'", tag, expr->tree.left->base.type); } } /* * Make sure there's no fall-through */ if (icase > 0 && pair->tree.right && CompileIsReachable (obj, obj->used, 0)) { CompileError (obj, expr, "Fall-through case with variant value"); } inst->tagcase.offset = obj->used - case_inst[icase]; inst->tagcase.tag = tag; /* * this side holds the name to assign the * switch value to. Set it's type and * build the assignment */ if (pair->tree.right) { SymbolPtr name = pair->tree.right->atom.symbol; InstPtr assign; name->symbol.type = mt; CompileStorage (obj, expr, name, code); if (ClassFrame (name->symbol.class)) { BuildInst (obj, OpTagLocal, assign, expr); assign->frame.staticLink = 0; assign->frame.element = name->local.element; } else { BuildInst (obj, OpTagGlobal, assign, expr); assign->box.box = name->global.value; } } } icase++; } else if (test_inst >= 0) { inst = ObjCode (obj, test_inst); if (expr->base.tag == SWITCH) inst->base.opCode = OpDefault; else inst->base.opCode = OpBranch; inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; test_inst = -1; } while (s->tree.left) { obj = _CompileStat (obj, s->tree.left, False, code); s = s->tree.right; } c = c->tree.right; } obj->nonLocal = obj->nonLocal->prev; /* * Add a default branch if necessary */ if (test_inst >= 0) { inst = ObjCode (obj, test_inst); inst->branch.offset = obj->used - test_inst; inst->branch.mod = BranchModNone; } CompilePatchLoop (obj, top_inst, -1, obj->used, -1); break; case FUNC: obj = CompileDecl (obj, expr, False, expr, code); break; case TYPEDEF: if (expr->tree.left->decl.type) obj = CompileType (obj, expr->tree.left, expr->tree.left->decl.type, expr, code); break; case OC: while (expr->tree.left) { obj = _CompileStat (obj, expr->tree.left, last && !expr->tree.right->tree.left, code); expr = expr->tree.right; } break; case BREAK: obj = _CompileNonLocal (obj, BranchModBreak, expr, code); break; case CONTINUE: obj = _CompileNonLocal (obj, BranchModContinue, expr, code); break; case RETURNTOK: if (!code || !code->base.func) { CompileError (obj, expr, "return not in function"); break; } if (expr->tree.right) { if (expr->tree.right->base.tag == OP && _CompileCanTailCall (obj, code)) { obj = CompileCall (obj, expr->tree.right, TailAlways, expr, code, False); } else { obj = _CompileExpr (obj, expr->tree.right, True, expr, code); } if (ObjCode (obj, ObjLast (obj))->base.opCode != OpTailCall) obj = _CompileNonLocal (obj, BranchModReturn, expr, code); expr->base.type = expr->tree.right->base.type; } else { obj = _CompileNonLocal (obj, BranchModReturnVoid, expr, code); expr->base.type = typePrim[rep_void]; } if (!TypeCombineBinary (code->base.func->base.type, ASSIGN, expr->base.type)) { CompileError (obj, expr, "Incompatible types, formal '%T', actual '%T', for return", code->base.type, expr->base.type); break; } break; case EXPR: if (last && expr->tree.left->base.tag == OP && !profiling) obj = CompileCall (obj, expr->tree.left, TailVoid, expr, code, False); else obj = _CompileExpr (obj, expr->tree.left, False, expr, code); break; case SEMI: break; case NAMESPACE: obj = _CompileStat (obj, expr->tree.right, last, code); break; case IMPORT: break; case CATCH: obj = CompileCatch (obj, expr->tree.left, expr->tree.right, expr, code, 0); break; case RAISE: obj = CompileRaise (obj, expr, expr, code); break; case TWIXT: obj = CompileTwixt (obj, expr, expr, code); break; } RETURN (obj); } static Bool CompileIsUnconditional (InstPtr inst) { switch (inst->base.opCode) { case OpBranch: case OpFarJump: case OpDefault: case OpReturn: case OpReturnVoid: case OpTailCall: case OpCatch: case OpRaise: return True; default: return False; } } static Bool CompileIsBranch (InstPtr inst) { switch (inst->base.opCode) { case OpBranch: case OpBranchFalse: case OpBranchTrue: case OpCase: case OpTagCase: case OpDefault: case OpCatch: return True; default: return False; } } static Bool CompileIsReachable (ObjPtr obj, int target, int frame) { InstPtr inst; int i; for (i = 0; i < obj->used; i++) { inst = ObjCode (obj, i); if (frame == 0 && CompileIsBranch (inst) && i + inst->branch.offset == target) return True; if (inst->base.opCode == OpObj && !inst->code.code->base.builtin && inst->code.code->func.body.obj->nonLocal) { if (CompileIsReachable(inst->code.code->func.body.obj, target, frame + 1)) return True; } if (inst->base.opCode == OpFarJump && inst->farJump.farJump->frame == frame && inst->farJump.farJump->inst == target) return True; if (frame == 0 && i == target - 1 && !CompileIsUnconditional (inst)) return True; } return False; } ObjPtr CompileFuncCode (CodePtr code, ExprPtr stat, CodePtr previous, NonLocalPtr nonLocal) { ENTER (); ObjPtr obj; InstPtr inst; Bool needReturn; code->base.previous = previous; obj = NewObj (OBJ_INCR, OBJ_STAT_INCR); obj->nonLocal = nonLocal; obj = _CompileStat (obj, code->func.code, True, code); needReturn = False; if (!obj->used || CompileIsReachable (obj, obj->used, 0)) needReturn = True; if (needReturn) { /* * If control reaches the end of the function, * flag an error for non-void functions, * don't complain about void functions or catch blocks */ if (!nonLocal && !TypeCombineBinary (code->base.func->base.type, ASSIGN, typePrim[rep_void])) { CompileError (obj, stat, "Control reaches end of function with type '%T'", code->base.func->base.type); } BuildInst (obj, OpReturnVoid, inst, stat); } #ifdef DEBUG ObjDump (obj, 0); FileFlush (FileStdout, True); #endif RETURN (obj); } ObjPtr CompileFunc (ObjPtr obj, CodePtr code, ExprPtr stat, CodePtr previous, NonLocalPtr nonLocal) { ENTER (); InstPtr inst; ArgType *args; ObjPtr staticInit; for (args = code->base.args; args; args = args->next) { CompileStorage (obj, stat, args->symbol, code); if (!args->varargs) code->base.argc++; } code->func.body.obj = CompileFuncCode (code, stat, previous, nonLocal); obj->error |= code->func.body.obj->error; BuildInst (obj, OpObj, inst, stat); inst->code.code = code; if ((staticInit = code->func.staticInit.obj)) { SetPush (obj); BuildInst (staticInit, OpStaticDone, inst, stat); /* BuildInst (staticInit, OpEnd, inst, stat); */ #ifdef DEBUG ObjDump (staticInit, 1); FileFlush (FileStdout, True); #endif code->func.staticInit.obj = staticInit; BuildInst (obj, OpStaticInit, inst, stat); BuildInst (obj, OpNoop, inst, stat); obj->error |= staticInit->error; } RETURN (obj); } /* * Get the class, defaulting as appropriate */ static Class CompileDeclClass (ExprPtr decls, CodePtr code) { Class class; class = decls ? decls->decl.class : class_undef; if (class == class_undef) class = code ? class_auto : class_global; return class; } /* * Find the code object to compile the declaration in */ static CodePtr CompileDeclCodeCompile (Class class, CodePtr code) { CodePtr code_compile = 0; switch (class) { case class_global: case class_const: /* * Globals are compiled in the static initializer for * the outermost enclosing function. */ code_compile = code; while (code_compile && code_compile->base.previous) code_compile = code_compile->base.previous; break; case class_static: /* * Statics are compiled in the static initializer for * the nearest enclosing function */ code_compile = code; break; case class_auto: case class_arg: /* * Autos are compiled where they lie; just make sure a function * exists somewhere to hang them from */ break; default: break; } return code_compile; } static ObjPtr * CompileDeclInitObjStart (ObjPtr *obj, CodePtr code, CodePtr code_compile) { ObjPtr *initObj = obj; if (code_compile) { if (!code_compile->func.staticInit.obj) code_compile->func.staticInit.obj = NewObj (OBJ_INCR, OBJ_STAT_INCR); initObj = &code_compile->func.staticInit.obj; code_compile->func.inStaticInit = True; if (code != code_compile) code->func.inGlobalInit = True; } return initObj; } static void CompileDeclInitObjFinish (ObjPtr *obj, ObjPtr *initObj, CodePtr code, CodePtr code_compile) { if (code_compile) { code_compile->func.inStaticInit = False; code->func.inGlobalInit = False; } } /* * Compile a type. This consists only of compiling array dimension expressions * so those values can be used later */ static ObjPtr CompileArrayDimValue (ObjPtr obj, TypePtr type, Bool lvalue, ExprPtr stat, CodePtr code) { ENTER (); InstPtr inst = 0; int d; CodePtr c; switch (type->array.storage) { case DimStorageNone: assert (0); break; case DimStorageGlobal: BuildInst (obj, OpGlobal, inst, stat); inst->box.box = type->array.u.global; break; case DimStorageStatic: case DimStorageAuto: d = 0; for (c = code; c && c != type->array.u.frame.code; c = c->base.previous) d++; if (type->array.storage == DimStorageStatic) { BuildInst (obj, OpStatic, inst, stat); } else { BuildInst (obj, OpLocal, inst, stat); } inst->frame.staticLink = d; inst->frame.element = type->array.u.frame.element; break; } if (lvalue) inst->base.opCode += 2; RETURN (obj); } static ObjPtr CompileArrayDims (ObjPtr obj, ExprPtr dim, ExprPtr stat, CodePtr code) { ENTER (); if (dim) { InstPtr inst; obj = CompileArrayDims (obj, dim->tree.right, stat, code); obj = _CompileExpr (obj, dim->tree.left, True, stat, code); BuildInst (obj, OpInitArray, inst, stat); inst->ainit.dim = 0; inst->ainit.mode = AInitModeElement; } RETURN (obj); } static ObjPtr CompileArrayType (ObjPtr obj, ExprPtr decls, TypePtr type, ExprPtr stat, CodePtr code) { ENTER (); type->array.dims = CompileCountDeclDimensions (type->array.dimensions); if (type->array.dims && type->array.dimensions->tree.left) { Class class = CompileDeclClass (decls, code); CodePtr code_compile = CompileDeclCodeCompile (class, code); ExprPtr dim = type->array.dimensions; InstPtr inst; ObjPtr *initObj; CompileDimensionStorage (obj, class, type, code); initObj = CompileDeclInitObjStart (&obj, code, code_compile); /* * Prepare the lvalue for assignment */ *initObj = CompileArrayDimValue (*initObj, type, True, stat, code); /* * Allocate an array for the dimension information */ SetPush (*initObj); BuildInst (*initObj, OpConst, inst, stat); inst->constant.constant = NewInt (type->array.dims); SetPush (*initObj); BuildInst (*initObj, OpBuildArray, inst, stat); inst->array.ndim = 1; inst->array.resizable = False; inst->array.type = typePrim[rep_integer]; /* * Initialize the dimension array */ BuildInst (*initObj, OpInitArray, inst, stat); inst->ainit.mode = AInitModeStart; inst->ainit.dim = 1; *initObj = CompileArrayDims (*initObj, dim, stat, code); BuildInst (*initObj, OpInitArray, inst, stat); inst->ainit.dim = 1; inst->ainit.mode = AInitModeElement; /* * Assign it */ BuildInst (*initObj, OpAssign, inst, stat); inst->assign.initialize = True; } RETURN (obj); } static ObjPtr CompileType (ObjPtr obj, ExprPtr decls, TypePtr type, ExprPtr stat, CodePtr code) { ENTER(); ArgType *at, *aat; StructType *st; TypeElt *et; int i, j; switch (type->base.tag) { case type_prim: break; case type_name: break; case type_ref: obj = CompileType (obj, decls, type->ref.ref, stat, code); break; case type_func: obj = CompileType (obj, decls, type->func.ret, stat, code); for (at = type->func.args; at; at = at->next) { if (at->name) for (aat = at->next; aat; aat = aat->next) if (aat->name == at->name) CompileError (obj, stat, "Duplicate function parameter '%A'", at->name); obj = CompileType (obj, decls, at->type, stat, code); } break; case type_array: obj = CompileArrayType (obj, decls, type, stat, code); obj = CompileType (obj, decls, type->array.type, stat, code); break; case type_hash: obj = CompileType (obj, decls, type->hash.type, stat, code); obj = CompileType (obj, decls, type->hash.keyType, stat, code); break; case type_struct: case type_union: st = type->structs.structs; for (i = 0; i < st->nelements; i++) { for (j = 0; j < i; j++) if (StructTypeAtoms(st)[j] == StructTypeAtoms(st)[i]) CompileError (obj, stat, "Duplicate structure member %A", StructTypeAtoms(st)[i]); obj = CompileType (obj, decls, BoxTypesElements(st->types)[i], stat, code); } break; case type_types: for (et = type->types.elt; et; et = et->next) obj = CompileType (obj, decls, et->type, stat, code); break; } RETURN (obj); } /* * Compile a declaration expression. Allocate storage for the symbol, * Typecheck and compile initializers, make sure a needed value * is left in the accumulator */ ObjPtr CompileDecl (ObjPtr obj, ExprPtr decls, Bool evaluate, ExprPtr stat, CodePtr code) { ENTER (); SymbolPtr s = 0; DeclListPtr decl; TypePtr type = decls->decl.type; Class class = CompileDeclClass (decls, code); CodePtr code_compile = CompileDeclCodeCompile (class, code); ObjPtr *initObj; if (ClassFrame (class) && !code) { CompileError (obj, decls, "Invalid storage class %C", class); decls->base.type = typePoly; RETURN (obj); } if (type) obj = CompileType (obj, decls, type, stat, code); for (decl = decls->decl.decl; decl; decl = decl->next) { ExprPtr init; s = decl->symbol; CompileStorage (obj, decls, s, code); /* * Automatically build initializers for composite types * which fully specify the storage */ init = decl->init; if (!init && s) init = CompileImplicitInit (s->symbol.type); if (init) { InstPtr inst; ExprPtr lvalue; /* * Compile the initializer value */ initObj = CompileDeclInitObjStart (&obj, code, code_compile); /* * Assign it */ lvalue = NewExprAtom (decl->name, decl->symbol, False); *initObj = CompileLvalue (*initObj, lvalue, decls, code, False, True, True, CompileRefType (obj, lvalue, s->symbol.type) != 0, False); SetPush (*initObj); *initObj = CompileInit (*initObj, init, s->symbol.type, stat, code); CompileDeclInitObjFinish (&obj, initObj, code, code_compile); BuildInst (*initObj, OpAssign, inst, stat); inst->assign.initialize = True; } } if (evaluate) { if (s) { InstPtr inst; switch (class) { case class_global: case class_const: BuildInst (obj, OpGlobal, inst, stat); inst->box.box = s->global.value; break; case class_static: BuildInst (obj, OpStatic, inst, stat); inst->frame.staticLink = 0; inst->frame.element = s->local.element; break; case class_auto: case class_arg: BuildInst (obj, OpLocal, inst, stat); inst->frame.staticLink = 0; inst->frame.element = s->local.element; break; default: break; } decls->base.type = s->symbol.type; } else decls->base.type = typePoly; } RETURN (obj); } ObjPtr CompileStat (ExprPtr expr, CodePtr code) { ENTER (); ObjPtr obj; InstPtr inst; obj = NewObj (OBJ_INCR, OBJ_STAT_INCR); obj = _CompileStat (obj, expr, False, code); BuildInst (obj, OpEnd, inst, expr); #ifdef DEBUG ObjDump (obj, 0); FileFlush (FileStdout, True); #endif RETURN (obj); } ObjPtr CompileExpr (ExprPtr expr, CodePtr code) { ENTER (); ObjPtr obj; InstPtr inst; ExprPtr stat; stat = NewExprTree (EXPR, expr, 0); obj = NewObj (OBJ_INCR, OBJ_STAT_INCR); obj = _CompileExpr (obj, expr, True, stat, code); BuildInst (obj, OpEnd, inst, stat); #ifdef DEBUG ObjDump (obj, 0); FileFlush (FileStdout, True); #endif RETURN (obj); } const char *const OpNames[] = { "Noop", /* * Statement op codes */ "Branch", "BranchFalse", "BranchTrue", "Case", "TagCase", "TagGlobal", "TagLocal", "Default", "Return", "ReturnVoid", "Fork", "Catch", "EndCatch", "Raise", "OpTwixt", "OpTwixtDone", "OpEnterDone", "OpLeaveDone", "OpFarJump", "OpUnwind", /* * Expr op codes */ "Global", "GlobalRef", "GlobalRefStore", "Static", "StaticRef", "StaticRefStore", "Local", "LocalRef", "LocalRefStore", "Fetch", "Const", "BuildArray", "BuildArrayInd", "InitArray", "BuildHash", "InitHash", "InitHashDef", "BuildStruct", "InitStruct", "BuildUnion", "InitUnion", "Array", "ArrayRef", "ArrayRefStore", "VarActual", "Call", "TailCall", "ExceptionCall", "Dot", "DotRef", "DotRefStore", "Arrow", "ArrowRef", "ArrowRefStore", "Obj", "StaticInit", "StaticDone", "BinOp", "BinFunc", "UnOp", "UnFunc", "PreOp", "PostOp", "Assign", "AssignOp", "AssignFunc", "IsType", "HasMember", "End", "Drop", }; static char * ObjBinFuncName (BinaryFunc func) { static const struct { BinaryFunc func; char *name; } funcs[] = { { ShiftL, "ShiftL" }, { ShiftR, "ShiftR" }, { Lxor, "Lxor" }, { NotEqual, "NotEqual" }, { Greater, "Greater" }, { LessEqual, "LessEqual" }, { GreaterEqual, "GreaterEqual" }, { 0, 0 } }; int i; for (i = 0; funcs[i].func; i++) if (funcs[i].func == func) return funcs[i].name; return ""; } static char * ObjUnFuncName (UnaryFunc func) { static const struct { UnaryFunc func; char *name; } funcs[] = { { Dereference, "Dereference" }, { Lnot, "Lnot" }, { Not, "Not" }, { Factorial, "Factorial" }, { do_reference, "do_reference" }, { 0, 0 } }; int i; for (i = 0; funcs[i].func; i++) if (funcs[i].func == func) return funcs[i].name; return ""; } static void ObjIndent (int indent) { int j; for (j = 0; j < indent; j++) FilePrintf (FileStdout, " "); } static char * BranchModName (BranchMod mod) { switch (mod) { case BranchModNone: return "BranchModNone"; case BranchModBreak: return "BranchModBreak"; case BranchModContinue: return "BranchModContinue"; case BranchModReturn: return "BranchModReturn"; case BranchModReturnVoid: return "BranchModReturnVoid"; case BranchModCatch: return "BranchModCatch"; } return "?"; } void InstDump (InstPtr inst, int indent, int i, int *branch, int maxbranch) { int j; Bool realBranch = False; #ifdef DEBUG FilePrintf (FileStdout, "%x: ", (int) inst); #endif ObjIndent (indent); FilePrintf (FileStdout, "%s%s %c ", OpNames[inst->base.opCode], " " + strlen(OpNames[inst->base.opCode]), inst->base.flags & InstPush ? '^' : ' '); switch (inst->base.opCode) { case OpTagCase: FilePrintf (FileStdout, "(%A) ", inst->tagcase.tag); goto branch; case OpCatch: FilePrintf (FileStdout, "\"%A\" ", inst->catch.exception->symbol.name); goto branch; case OpBranch: case OpBranchFalse: case OpBranchTrue: case OpCase: case OpDefault: realBranch = True; branch: if (branch) { j = i + inst->branch.offset; if (0 <= j && j < maxbranch) FilePrintf (FileStdout, "branch L%d", branch[j]); else FilePrintf (FileStdout, "Broken branch %d", inst->branch.offset); } else FilePrintf (FileStdout, "branch %d", inst->branch.offset); if (realBranch) FilePrintf (FileStdout, " %s", BranchModName (inst->branch.mod)); break; case OpReturn: case OpReturnVoid: break; case OpFork: FilePrintf (FileStdout, "\n"); ObjDump (inst->obj.obj, indent+1); break; case OpEndCatch: FilePrintf (FileStdout, " %d catches", inst->ints.value); break; case OpRaise: FilePrintf (FileStdout, "%A", inst->raise.exception->symbol.name); FilePrintf (FileStdout, " argc %d", inst->raise.argc); break; case OpTwixt: if (branch) { j = i + inst->twixt.enter; if (0 <= j && j < maxbranch) FilePrintf (FileStdout, "enter L%d", branch[j]); else FilePrintf (FileStdout, "Broken enter %d", inst->branch.offset); j = i + inst->twixt.leave; if (0 <= j && j < maxbranch) FilePrintf (FileStdout, " leave L%d", branch[j]); else FilePrintf (FileStdout, " Broken leave %d", inst->branch.offset); } else { FilePrintf (FileStdout, "enter %d leave %d", inst->twixt.enter, inst->twixt.leave); } break; case OpFarJump: FilePrintf (FileStdout, "twixt %d catch %d frame %d inst %d mod %s", inst->farJump.farJump->twixt, inst->farJump.farJump->catch, inst->farJump.farJump->frame, inst->farJump.farJump->inst, BranchModName (inst->farJump.mod)); break; case OpUnwind: FilePrintf (FileStdout, "twixt %d catch %d", inst->unwind.twixt, inst->unwind.catch); break; case OpStatic: case OpStaticRef: case OpStaticRefStore: case OpLocal: case OpLocalRef: case OpLocalRefStore: case OpTagLocal: FilePrintf (FileStdout, " (link %d elt %d)", inst->frame.staticLink, inst->frame.element); break; case OpConst: FilePrintf (FileStdout, "%v", inst->constant.constant); break; case OpCall: case OpTailCall: FilePrintf (FileStdout, "%d args", inst->ints.value); break; case OpBuildArray: FilePrintf (FileStdout, "%d dims %sresizable", inst->array.ndim, inst->array.resizable ? "" : "un"); break; case OpInitArray: FilePrintf (FileStdout, "%d %s", inst->ainit.dim, inst->ainit.mode == AInitModeStart ? "start": inst->ainit.mode == AInitModeElement ? "element": inst->ainit.mode == AInitModeRepeat ? "repeat": inst->ainit.mode == AInitModeFunc ? "func": inst->ainit.mode == AInitModeTest ? "test": "?"); break; case OpDot: case OpDotRef: case OpDotRefStore: case OpArrow: case OpArrowRef: case OpArrowRefStore: case OpInitStruct: case OpInitUnion: FilePrintf (FileStdout, "%s", AtomName (inst->atom.atom)); break; case OpObj: FilePrintf (FileStdout, "\n"); if (inst->code.code->func.staticInit.obj) { ObjIndent (indent); FilePrintf (FileStdout, "Static initializer:\n"); ObjDump (inst->code.code->func.staticInit.obj, indent+1); ObjIndent (indent); FilePrintf (FileStdout, "Function body:\n"); } ObjDump (inst->code.code->func.body.obj, indent+1); break; case OpBinOp: case OpPreOp: case OpPostOp: case OpAssignOp: FilePrintf (FileStdout, "%O", inst->binop.op); break; case OpBinFunc: case OpAssignFunc: FilePrintf (FileStdout, "%s", ObjBinFuncName (inst->binfunc.func)); break; case OpUnOp: FilePrintf (FileStdout, "%U", inst->unop.op); break; case OpUnFunc: FilePrintf (FileStdout, "%s", ObjUnFuncName (inst->unfunc.func)); break; case OpIsType: FilePrintf (FileStdout, "%T", inst->isType.type); break; case OpHasMember: FilePrintf (FileStdout, "%A", inst->atom.atom); break; default: break; } FilePrintf (FileStdout, "\n"); } void ObjDump (ObjPtr obj, int indent) { int i, j; InstPtr inst; ExprPtr stat; int *branch; int b; branch = AllocateTemp (obj->used * sizeof (int)); memset (branch, '\0', obj->used * sizeof (int)); ObjIndent (indent); FilePrintf (FileStdout, "%d instructions %d statements (0x%x)\n", obj->used, obj->used_stat, ObjCode(obj,0)); b = 0; for (i = 0; i < obj->used; i++) { inst = ObjCode(obj, i); if (CompileIsBranch (inst)) { j = i + inst->branch.offset; if (0 <= j && j < obj->used) if (!branch[j]) branch[j] = ++b; } if (inst->base.opCode == OpFarJump) { j = inst->farJump.farJump->inst; if (0 <= j && j < obj->used) if (!branch[j]) branch[j] = ++b; } if (inst->base.opCode == OpTwixt) { j = i + inst->twixt.enter; if (0 <= j && j < obj->used) if (!branch[j]) branch[j] = ++b; j = i + inst->twixt.leave; if (0 <= j && j < obj->used) if (!branch[j]) branch[j] = ++b; } } b = 0; stat = 0; for (i = 0; i < obj->used; i++) { ExprPtr nextStat = ObjStatement (obj, inst = ObjCode (obj, i)); if (nextStat && nextStat != stat) { stat = nextStat; FilePrintf (FileStdout, " "); PrettyStat (FileStdout, stat, False); } if (branch[i]) FilePrintf (FileStdout, "L%d:\n", branch[i]); InstDump (inst, indent, i, branch, obj->used); } } nickle_2.81.orig/README0000664000175000000620000000077210414112462013761 0ustar keithpstaff$Header$ This contains the sources for 'nickle', a desk calculator language with powerful programming and scripting capabilities. This program has been tested on Solaris and Linux. It uses only Posix-style system call interfaces, and should easily port to most any reasonable platform. Have fun! Keith Packard keithp@ncd.com Bart Massey bart@cs.pdx.edu --- Copyright © 1988-2004 Keith Packard and Bart Massey. All Rights Reserved. See the file COPYING in this directory for licensing information. nickle_2.81.orig/ChangeLog0000664000175000000620000066037013202543025014662 0ustar keithpstaffcommit bbdfc46d5f640db769ade04a3b94b9306f7ab472 Author: Keith Packard Date: Tue Nov 14 02:31:00 2017 -0800 Update to version 2.81 Signed-off-by: Keith Packard commit c97d95c71805bd1b0e9b21228f7786cef51def25 Author: Keith Packard Date: Tue Nov 14 02:26:04 2017 -0800 test: Can't test for Y2038 fix because 32 bit machines glibc on all 32-bit machines fails the Y2038 test. Change that to use the maximum possible 32-bit value instead (sigh) Signed-off-by: Keith Packard commit 49591a84a6bb23ff64a49578cf7ce0ff7a6715e3 Author: Keith Packard Date: Tue Nov 14 02:25:42 2017 -0800 Remove unused variable in builtin-date.c Signed-off-by: Keith Packard commit b331afa2478638c06664612ff6620ba100e6635e Author: Keith Packard Date: Tue Nov 14 02:00:54 2017 -0800 Version 2.80-2 Debian packaging fixes. Signed-off-by: Keith Packard commit e6549ca1f74a90ef9d9b464b3eddd41214671773 Author: Keith Packard Date: Tue Nov 14 02:00:09 2017 -0800 debian: Clean up lintian warnings * Update standards version to 4.1.1 * Remove use of autotools-dev Signed-off-by: Keith Packard commit f8edfe3e497f84290f1a59a0b95ca62ac9d2f80e Author: Keith Packard Date: Tue Nov 14 00:25:16 2017 -0800 Update to version 2.80 Signed-off-by: Keith Packard commit 4945fbf7a6852245094e4425c1f416fa08ac9c6d Author: Keith Packard Date: Mon Nov 13 15:49:38 2017 -0800 Add date conversion functions localtime, gmtime, timelocal, timegm These just wrap the C versions, except they report actual years, rather than years since 1900 and January is month 1, not 0. Signed-off-by: Keith Packard commit 0880d7445ba518ef17a8fb3febc4489734995418 Author: Keith Packard Date: Fri Mar 24 09:45:49 2017 +0100 Add JSON tests Signed-off-by: Keith Packard commit 0240e97419536a7a5474afae077b42fd49725100 Author: Keith Packard Date: Fri Mar 24 09:45:12 2017 +0100 Add floats to JSON module. Support floating point values in JSON input and output. Signed-off-by: Keith Packard commit 8064554410bc05798fe7a8cafa80da0fdec16b87 Author: Keith Packard Date: Thu Mar 23 14:38:10 2017 +0100 Make nickle-tutorial.pdf build reproducibly Set TeX dates to RELEASE_DATE. Remove PDF /ID entry. Signed-off-by: Keith Packard commit b03fa4fcfe5e8bca6552c8be83eb5c67180b7f8a Author: Keith Packard Date: Thu Mar 23 07:49:45 2017 +0100 Fix a pile of lintian warnings Update to standard 3.9.8 and dh 10. COPYING files from exmaples shouldn't be installed. Use 3.0 (quilt) format so we can have a packaging revision with dh 10. Get the tutorial installed correctly. Mark the sudoku example script executable. Signed-off-by: Keith Packard commit 62538ae681138311fdb0d60419049dee291e4b4e Author: Keith Packard Date: Thu Mar 23 06:45:53 2017 +0100 Update to version 2.79 Signed-off-by: Keith Packard commit fb25c7d70763848f4bbb110c747ece6a0a667c29 Author: Keith Packard Date: Thu Mar 16 10:51:13 2017 -0700 Ensure data cache value array is aligned adequately Data caches are used to store pointers and other potentially long values. Make sure that the position of the values portion of the cache is aligned to a suitable address. Fixes a bus error on sparc64 machines. Signed-off-by: Keith Packard commit f2037097c19ca6a7a9f4fad92448fe57dae34a48 Author: Keith Packard Date: Wed Mar 15 22:06:33 2017 -0700 Building nickle on arm64 now, change package names built .deb and .rpm files are now amd64 instead of i386 Signed-off-by: Keith Packard commit 229a665691f244427e33793129eb76f3607790f9 Author: Keith Packard Date: Wed Mar 15 09:40:34 2017 -0700 Update to version 2.78 Signed-off-by: Keith Packard commit 9dcb5baf7d263317f4fd4c8cd6a9695c2f3824b1 Author: Keith Packard Date: Wed Mar 15 21:54:05 2017 -0700 Also depend on bison and flex commit b568f99722b760810f209cdab5b5a29460c5d650 Author: Keith Packard Date: Wed Mar 15 21:51:54 2017 -0700 newer version of flex doesn't have yyunput This line was just removing a warning about yyunput unused; newer versions of flex don't even have that symbol anymore. Better to have a warning than fail to compile. Signed-off-by: Keith Packard commit c100536369045242614f71a44e09c2c3df5359ab Author: Keith Packard Date: Wed Mar 15 09:25:17 2017 -0700 Adapt tests to new automake requirements Automake now has a separate variable for the program to run the test scripts with, and breaks if you try to embed that in the TESTS_ENVIRONMENT variable, which used to be how this was done. Signed-off-by: Keith Packard commit 334780afcc76da6e158aeefb5e7f3df533e5aaf2 Author: Keith Packard Date: Wed Mar 15 09:24:20 2017 -0700 Use 'G' format for elements when printing arrays in 'g' format This restricts array printing to just recurse one level. Signed-off-by: Keith Packard commit a251ccf47ef335f293d3e53dd8fd9f03c9901bc0 Author: Keith Packard Date: Wed Mar 15 08:52:48 2017 -0700 When using pointer as hash, first cast to intptr_t This avoids a compiler warning when pointers are not the same size as HashValues. Signed-off-by: Keith Packard commit 3337ca1580d84430246ed8693a200031474f60e9 Author: Keith Packard Date: Wed Mar 15 08:42:41 2017 -0700 Initialize 'replace' in NewTypedBox When left uninitialized, undefined results will occur. This caused a test failure on MIPS when being built with PIE support. Debian bug 857840. Reported-by: James Cowgill Signed-off-by: Keith Packard commit c4f176d76f88a2046619fce0af7f7cc8cef7c1de Author: Keith Packard Date: Wed Mar 15 08:39:16 2017 -0700 Open quote character is a single char, not a string When checking to see if a string needs to be dequoted, check the first character of the string against the quote character, rather than checking the whole string. Probably using strings for the quote markers wasn't the best API choice as this would have been caught by typechecking had the quote characters been an int instead. Signed-off-by: Keith Packard commit 74e92c3ff8b3b8478d44ee5e9b1f0fc75283fd88 Author: Keith Packard Date: Fri Jul 8 16:32:55 2016 +0200 Define release date in configure.ac and use that instead of build date This avoids encoding the current date into the resulting output so that it can be reproduced. Signed-off-by: Keith Packard commit 0da19be66deb245f83e17c6f2a998a7c7702835f Author: Keith Packard Date: Thu Jul 7 17:57:40 2016 +0200 Add JSON input/output code Signed-off-by: Keith Packard commit a6a9375b89b3281b6ed670619e6d317a1d8af7e8 Author: Keith Packard Date: Thu Jul 7 17:54:56 2016 +0200 Reverse data written in linked FileChains FileChains are linked in newest-in order, so they need to be written last-first. Signed-off-by: Keith Packard commit 18aa99c09b5be9561be9f908ed5a5aaee55e04e3 Author: Keith Packard Date: Thu Jul 7 17:54:11 2016 +0200 Add is_hash primitive Checks whether a value is a hash Signed-off-by: Keith Packard commit 7fd6e3c6727983c10098d92a469dd802c3196142 Author: Keith Packard Date: Sat Jun 21 21:24:02 2014 -0700 Abort karatsuba multiply in more places commit b766c8f934e4a0dadbed59233158251ea06a7a73 Author: Bart Massey Date: Sat Aug 23 09:38:26 2014 -0700 removed gratuitous -O2 from Makefile.am to let CFLAGS handle it commit 8de064cd50660797959b7988ce15b5e2a51ae946 Author: Bart Massey Date: Wed Jul 10 15:11:08 2013 -0700 Added a lightly-optimized choose(n, k) function to math.5c. The lack of a choose operator has continually bugged me; I've constantly rewritten it "the bad way". This is a lightly optimized version of that function that seems to handle most edge cases reasonably. It has only been tested a little bit. commit e309b5a8d9df4f8ec2027cf09d4070997a0d2a47 Author: Bart Massey Date: Sat Nov 10 00:40:50 2012 -0800 added check mode to sudoku solver commit 061cb1ec69aabe674a343f5612e49dd7c7779fc1 Author: Bart Massey Date: Sat Nov 10 00:03:50 2012 -0800 cleaned up a bunch of sudoku solver stuff commit 929e8ec4598d46a4f4bb040148d9f818a6d2fd2a Author: Bart Massey Date: Fri Nov 9 22:48:54 2012 -0800 added edge cache to sudoku example commit 1e29f3df828ec68ca7b4556e9b1bb830c8afbb4b Author: Keith Packard Date: Fri Nov 9 21:35:40 2012 -0800 tutorial: Close a couple of SGML tags nsgmls found a couple of unclosed tags which may make some versions of docbook tools unhappy. Signed-off-by: Keith Packard commit b3e13a3f246956ade058332c6a1f02ea73d0b986 Author: Keith Packard Date: Fri Nov 9 21:35:12 2012 -0800 Fix release docs to use git log instead of git-log git-log disappeared a long time ago Signed-off-by: Keith Packard commit 3bb1adaa4f0cbf99343f41c7a326b36554590c07 Author: Bart Massey Date: Tue Nov 6 14:36:20 2012 -0800 actually added Sudoku example commit eda745fc866fb7d0b44f254c1f18c8a481c5c9dd Merge: 73d8de9 610cfee Author: Bart Massey Date: Tue Nov 6 14:32:28 2012 -0800 added Sudoku generator example commit 610cfee23a6d94007a79ffe7b14604ca7b5a58f7 Author: Bart Massey Date: Tue Nov 6 14:31:12 2012 -0800 added sudoku example commit 73d8de9c965de8329ee50391665d5cc359049273 Author: Keith Packard Date: Tue Nov 6 11:23:42 2012 -0800 Update to version 2.77 Signed-off-by: Keith Packard commit 9be5752d7c3af90aa006be7aa050e881916b3239 Author: Keith Packard Date: Tue Nov 6 11:20:04 2012 -0800 Fix RPM spec file to not install tutorial twice By default, the tutorial gets stuck in /usr/share/doc/nickle, while rpm wants it in /usr/shar/doc/nickle-. Ignore the one in /usr/share/doc/nickle. Signed-off-by: Keith Packard commit b3e0c5b3893b8c67e4d8e42a013e1f16bae774c8 Author: Keith Packard Date: Sun Nov 4 21:48:57 2012 -0800 doc: Expand tabs to spaces in .sgml files Makes code examples readable. Signed-off-by: Keith Packard commit 48ab6b7bc8eccb9a0c79ae1a044e99381cd01111 Author: Keith Packard Date: Sun Nov 4 21:27:30 2012 -0800 Build tutorial when docbook2pdf is available And build it on debian Signed-off-by: Keith Packard commit 85e960e9091c34820ec08f68336a0614dffda634 Author: Keith Packard Date: Sun Nov 4 21:26:40 2012 -0800 tutorial: Use sgml entities instead of < and > Signed-off-by: Keith Packard commit 8267429a2cc9f4a4f33a788dff6bca2ba7d38f1e Author: Keith Packard Date: Sun Nov 4 21:25:54 2012 -0800 Tutorial: twixt doesn't have an optional 'else' block This was a proposed feature that was removed Signed-off-by: Keith Packard commit 3a96936bea9ac3376f33d07628231c1ff176ab26 Author: Keith Packard Date: Sun Nov 4 21:24:45 2012 -0800 Rename nickle tutorial to nickle-tutorial Makes any built files include 'nickle' by default Signed-off-by: Keith Packard commit ad5cf39a2ce4730cba665d862635506da99a5167 Author: Bart Massey Date: Sun Nov 4 13:37:06 2012 -0800 corrected some Nickle Tour nits commit 7654ceb8b892ce483b8480755485888ef2402420 Author: Keith Packard Date: Tue Jun 12 21:55:04 2012 -0700 Handle OpFarJump in CompileReachable A FarJump within a catch block references instructions one or more frames outside of the instruction context. When checking for reachable code, look down inside the catch blocks to see if any of the FarJumps within them touch the target instruction. Fixes this example: void foo() { for (;;) try { } catch uninitialized_value(string x) { break; } } Without this fix, the 'break' will not get noticed and no ReturnVoid will be appended to the object code for 'foo', leaving the break dangling in space. Signed-off-by: Keith Packard commit 86456a8a2a7ae92da7c082a93d4ccf40c740f879 Author: Keith Packard Date: Tue Jun 12 21:54:31 2012 -0700 New instructions IsType and HasMember need entries in OpNames Otherwise, the array no longer matches the enum Signed-off-by: Keith Packard commit 9364ad117ab8cb6828fc308e99fd854a6029e277 Author: Keith Packard Date: Tue Jun 12 21:53:46 2012 -0700 Fix VALIDATE_EXECUTION test code Needed ObjType defined. Signed-off-by: Keith Packard commit c749d6a74d74aff873b93c6cf0883f4863b6d257 Author: Keith Packard Date: Mon Jun 11 13:29:55 2012 -0700 Update to 2.76 Signed-off-by: Keith Packard commit 131599bc78bd0e3d7ff94535238c3df78092f19d Author: Keith Packard Date: Mon Jun 11 13:22:15 2012 -0700 Don't erase twixt pointer during JumpContinue until after stack copy Otherwise, if MemCollect occurs during the stack copy, the twixt's stack copy can get collected. Signed-off-by: Keith Packard commit 0ced7273d96c6d86c1cf7676efb4321e610f9633 Author: Keith Packard Date: Mon Jun 11 13:18:03 2012 -0700 Check for lost stack chunks If a stack chunk gets collected, the 'type' field will get cleared. Check to see if this has happened and abort. Signed-off-by: Keith Packard commit e7352c5728c4773c54988308c9b54780e957d003 Author: Keith Packard Date: Mon Jun 11 13:15:51 2012 -0700 Add debug code to check thread validity during execution If something gets corrupted, it's useful to have this code to help track it down. Signed-off-by: Keith Packard commit e421d2775c25d717a72d29ac30bf67571655cbe8 Author: Keith Packard Date: Mon Jun 11 13:13:20 2012 -0700 Handle initializers with undefined types. Emit an error instead of crashing. Signed-off-by: Keith Packard commit 5b00e11e61e5c659c7ad49fec7d7a4a1ab53d686 Author: Keith Packard Date: Thu May 10 10:22:55 2012 -0700 Handle systems which don't define PATH_MAX (Hurd) This is a hack; a correct fix would involve actually allocating the correct length object. Signed-off-by: Keith Packard commit 77553983f0edd58201675da8cc020993513703bd Author: Keith Packard Date: Fri Mar 30 08:42:16 2012 -0700 Version 2.75 Signed-off-by: Keith Packard commit 364505a116c631a0dd4f4d8a01a0f9b65ddf78c4 Author: Keith Packard Date: Fri Mar 30 08:56:09 2012 -0700 Delete ancient .cvsignore files Not exactly useful anymore Signed-off-by: Keith Packard commit 1a499d9f0fe3f9203edd1286369c85939ce97f55 Author: Keith Packard Date: Fri Mar 30 08:55:54 2012 -0700 Examples shouldn't be executable Signed-off-by: Keith Packard commit d1876db5e305ad157a9fbbe7c75fed0b8d4f342a Author: Keith Packard Date: Fri Mar 30 08:37:43 2012 -0700 Fix Source URL in nickle.spec file Point at nickle.org, as appropriate. Signed-off-by: Keith Packard commit fd7488e29c9c5dd6705368baf28dff248419d5c6 Author: Keith Packard Date: Fri Mar 30 08:36:42 2012 -0700 Make 'G' format limit array and struct recursion This makes stack traces tractable. Signed-off-by: Keith Packard commit beab4e662ab095e914f9ad2ab3d1834633219145 Author: Keith Packard Date: Fri Mar 30 08:35:16 2012 -0700 Switch to dh for debian builds Vastly simplifies debian/rules... Signed-off-by: Keith Packard commit 197cb418aa20436d35124cb56dfff48d51cffedb Author: Keith Packard Date: Tue Mar 13 23:16:34 2012 -0700 Stop printing recursive structs with 'g' format. This gets annoying really quickly, so just terminate the recursive struct printing right away. Signed-off-by: Keith Packard commit 4bb7b4720f0c5a15e4b26bd70c9d01040f0612c1 Author: Keith Packard Date: Thu Mar 8 11:16:57 2012 -0800 Handle ref types in &foo->bar operations For some reason, this case was left out of the usual ref type hacks Signed-off-by: Keith Packard commit a236e4a7e349b220760aefb58e6b4e62e3fea156 Author: Keith Packard Date: Sat Mar 3 17:17:12 2012 -0800 Version 2.74 Signed-off-by: Keith Packard commit 97205c5a67f602af41a83032368ef5e65a7d50e2 Author: Keith Packard Date: Sat Mar 3 17:14:13 2012 -0800 Switch from debuild to pdebuild Catch more package building problems by using pbuilder. Signed-off-by: Keith Packard commit a572170045122e4f0942a250c12bfe4b0f422319 Author: Keith Packard Date: Fri Mar 2 11:09:51 2012 -0800 Fix Semaphore::wait logic (again) - partial means we've woken up The only way to run do_Semaphore::wait with 'partial' set to true is if the thread is waking up; in this case, the semaphore count may well be negative if other threads are also waiting. Ignore the count in this case and just complete the operation. Signed-off-by: Keith Packard commit e24a73f89019a22a2ced7c5fd0dc4681ff4de5c6 Author: Keith Packard Date: Wed Feb 29 22:05:59 2012 +1300 Add explicit debian source format 3.0 (native) Keep lintian happy Signed-off-by: Keith Packard commit 9c31311a34a7f6f6751a23eaf439ee1ef40890a9 Author: Keith Packard Date: Wed Feb 29 21:48:16 2012 +1300 Clean up some debian lintian warnings Signed-off-by: Keith Packard commit 8c1b5242e3605cf356c8c1643a415bc0f585c7d3 Author: Keith Packard Date: Wed Feb 29 21:47:16 2012 +1300 Fix new FileVPrintf 'G' format comparison Was comparing the pointer to the representation enum. oops. Signed-off-by: Keith Packard commit 48c4dda9a1e56388173385caaa13ebfb04674d81 Author: Keith Packard Date: Wed Feb 29 17:00:42 2012 +1300 Update debian/changelog for eventual 2.73 release Signed-off-by: Keith Packard commit f19cc51156c96689ac0207d3c30ed549c24afd6b Author: Keith Packard Date: Wed Feb 29 16:54:16 2012 +1300 git-log has become git log Needed to build ChangeLog Signed-off-by: Keith Packard commit b7c533e875dfe15ac46de4ecfee6586c8e759d18 Author: Keith Packard Date: Wed Feb 29 16:49:39 2012 +1300 Back autoconf requirement to 2.64 so debian stable can run it Signed-off-by: Keith Packard commit 22f9d58233450a4e6ff67abbaf8e4008e4f3998d Author: Keith Packard Date: Mon Feb 27 15:06:05 2012 +1300 Shorten backtrace display Don't display composite values in backtraces so that the backtrace doesn't get flooded with giant values. Signed-off-by: Keith Packard commit b1f691286f2aae54839a3b4e969d318e646c70c8 Author: Keith Packard Date: Mon Feb 27 13:28:08 2012 +1300 Typecheck switch expressions Make sure switch expression and case expresssions are all type compatible. Signed-off-by: Keith Packard commit d70e73e96b53142e4273565e63e10ebd2fa8d1d5 Author: Keith Packard Date: Mon Feb 27 12:32:52 2012 +1300 Add is_type and has_member built-ins These provide the ability to do run-time type comparisons without needing full introspection in the language. Signed-off-by: Keith Packard commit 42aeaa3494c68fee1b1559dde8d99ee52677b361 Author: Keith Packard Date: Thu Feb 23 00:56:41 2012 +1300 Add list.5c A useful data type Signed-off-by: Keith Packard commit ab2ed22e6ff90868fbbebaba1e1851f131044555 Author: Keith Packard Date: Thu Feb 23 00:15:02 2012 +1300 add 'millis' function to return a clock in milliseconds. Useful when doing things with sleep Signed-off-by: Keith Packard commit 67801c2111e9f35afcd1667fb59a72efcfdb5df8 Author: Keith Packard Date: Tue Feb 21 23:50:18 2012 +1300 Add Semaphore::count Useful for checking current semaphore value without modifying it. Signed-off-by: Keith Packard commit 0d6d153498b51bf02286eff06d327ab42914361e Author: Keith Packard Date: Tue Feb 21 23:49:37 2012 +1300 Clean up do_Semaphore_wait Make it clear that the semaphore count gets bumped down the first time into this function. Signed-off-by: Keith Packard commit 6fd77649e822e026000ea5c857d2c30af8874030 Author: Keith Packard Date: Tue Feb 21 23:47:30 2012 +1300 Check for thread switch even if current thread is last Threads can switch due to semaphores or other signals; that can leave the current thread last in the run queue. Check for any case where running changes instead of only when the current thread isn't last. Signed-off-by: Keith Packard commit 61bd1359a1bc3766833071d04610176a5dfe6b6a Author: Keith Packard Date: Tue Feb 21 17:42:29 2012 +1300 Make scanf not report valid conversion on blank input. scanf was incorrectly accepting " " as a valid number, returning a conversion of 0. Fix this by checking for empty strings in any numeric conversion. Signed-off-by: Keith Packard commit e6abc97a91f08a6ca6d06da5f88b627cf6b16a35 Author: Keith Packard Date: Tue Feb 21 17:41:13 2012 +1300 Add tests for scanf function Scanf incorrectly accepts blank strings for numbers; here's a pile of tests to validate various numeric input. Signed-off-by: Keith Packard commit 2d3f8dc35a068bac522115d6dfc6f573922040c5 Author: Keith Packard Date: Tue Feb 21 14:32:11 2012 +1300 Add sort and skiplist to standard nickle library These are too useful to just be examples Signed-off-by: Keith Packard commit d9d1cb686aac1709c55884f3c621185cfc94ecaf Author: Keith Packard Date: Mon Jan 30 19:32:27 2012 -0800 Add gamma function Signed-off-by: Keith Packard commit 8a2d817b59aa16b0e15309d4372b69e4453cbc40 Author: Keith Packard Date: Mon Jan 30 12:10:56 2012 -0800 Printing rational 0 in 'e' format doesn't need an exponent Computing a negative exponent requires a non-zero value, so just skip that if the value is zero Signed-off-by: Keith Packard commit 9bdf4cd13fa6e473f23ffa171566ffc296074194 Author: Keith Packard Date: Mon Jan 30 10:02:16 2012 -0800 NaturalGcd must return a Natural* when aborting It was returning One (an Integer) instead of one_natural; Signed-off-by: Keith Packard commit 478825cfa4a72b7f0de80d8b4e07df1ae2e77c9f Author: Keith Packard Date: Sun Jan 29 23:26:02 2012 -0800 floor() and ceil() should work on imprecise floats They should return an approximate integer value instead of raising an exception. Signed-off-by: Keith Packard commit 01b07df6e8929e2ef605327c3403271670eeccf1 Author: Keith Packard Date: Sun Jan 29 22:53:07 2012 -0800 Set version to 2.73 in prepartion for eventually release Signed-off-by: Keith Packard commit faab094af3dcf9a062ba9b6ec1b6b74ab8291c50 Author: Keith Packard Date: Sun Jan 29 22:50:46 2012 -0800 Only call readline tty cleanup on signal readline is active If readline isn't active, the cleanup functions tend to make a mess of the tty state, so don't call them. This really only matters when handling SIGTSTP. Signed-off-by: Keith Packard commit 9e373c7f302b194b33fc83c10b66d7d367a821d8 Author: Keith Packard Date: Sun Jan 29 22:05:21 2012 -0800 Update to version 2.72 commit d5a82d02ea1ae6d02a4c14898d9737d03ddb9cc7 Author: Keith Packard Date: Sun Jan 29 21:48:07 2012 -0800 Keep readline from catching signals This stops readline from catching signals, letting nickle handle them all by itself. Signed-off-by: Keith Packard commit 8b7aef95d231edf71b5388702b16b706e3425000 Author: Keith Packard Date: Sun Jan 29 20:19:09 2012 -0800 Block in select instead of sigsuspend when waiting for I/O The kernel doesn't appear to reliably deliver SIGIO while the application is blocked, so sit in select instead of sigsuspend to make sure we hear about pending I/O. Signed-off-by: Keith Packard commit 6719d500e3bcc2a3428680a7b4176b7660ecbe1b Author: Keith Packard Date: Mon Nov 28 22:29:53 2011 -0800 rename configure.in to configure.ac commit 8515fa7a571f4e7bf0e66e09b1b73e747fa597c6 Author: Keith Packard Date: Mon Nov 28 22:27:33 2011 -0800 Switch version to 2.72 in preparation for an eventual release Signed-off-by: Keith Packard commit 395b70966490f406c7b40a41d18c8f7b93c057a8 Author: Keith Packard Date: Fri Nov 25 12:11:07 2011 -0800 wait3 returns 0 when there's nothing left to do Don't keep looping when wait3 is done Signed-off-by: Keith Packard commit 416a3cff1f7f1a125326aa70eedeaf3a9170e14e Author: Keith Packard Date: Fri Nov 25 11:46:47 2011 -0800 Update to version 2.71 commit a60ad0adac6a338839e4e6194838f5918dfa0953 Author: Keith Packard Date: Fri Nov 25 11:33:52 2011 -0800 Clean up a pile of build warnings Signal return types, unused return values and stepping off the end of the typePrim array (the value of which was unused anyways). Signed-off-by: Keith Packard commit c4b149a4cca5a5c011d74502374a15900c5adfaf Author: Keith Packard Date: Mon Oct 31 10:20:35 2011 -0700 Catch attempts to use uninitialized pointer contents Dereferencing a pointer to uninitialized storage is an error, instead of passing this value along to callers, catch it immediately and raise an exception. Check for this case in the ++ and -- operators to generate a better error message (otherwise, we'll pass Void along and generate an error much later). Signed-off-by: Keith Packard commit 7a7a8a063796ab581af5179ce211f4cd5b602879 Author: Keith Packard Date: Thu Sep 29 01:49:42 2011 -0700 Exit after two consecutive interrupts If the first interrupt isn't received by the nickle code, when the second one comes in, just exit Signed-off-by: Keith Packard commit cc6c2f55d76e2d1a07ded25bf09e313d5e6de255 Author: Keith Packard Date: Thu Sep 29 01:15:39 2011 -0700 Cleanup struct type changes commit 0a8a685e99043f5e983d7b46a0db155e91cc2af4 Author: Keith Packard Date: Thu Sep 29 00:43:08 2011 -0700 Replace most parameterized macros with static inline functions Typechecking, decent compiler warnings and smaller code. Signed-off-by: Keith Packard commit 0640100035a54205ab8b7117aa82291de19a03e7 Author: Keith Packard Date: Wed Sep 28 23:40:12 2011 -0700 Replace macros with static inline functions in value.h Actual type checking, and smaller compiler output to boot. Signed-off-by: Keith Packard commit ee70963b79933423751ae8602882891bbefbb6bc Author: Keith Packard Date: Wed Sep 28 23:32:17 2011 -0700 Get rid of old-school variable length struct allocations This confuses the new _FORTIFY_SOURCE bits in GCC, so use the 'sanctioned' form of placing a zero-length array at the end of the struct. Signed-off-by: Keith Packard commit 1491af33c3bca94c6bb604b483a5eabcf038eef1 Author: Keith Packard Date: Wed Jul 7 15:12:21 2010 -0400 Bump to version 2.70 Signed-off-by: Keith Packard commit 7334afef7a4235447e11a948a9d57c354dafac67 Author: Keith Packard Date: Tue Jul 6 11:02:33 2010 -0400 Test factorial function by comparing with Stirling approximation This checks larger factorial values for gross errors. Signed-off-by: Keith Packard commit 40bde0fbd244462a282f922483ef5aa4994d590b Author: Keith Packard Date: Tue Jul 6 01:29:07 2010 -0400 Update debian bits to standards-version 3.8.4 Signed-off-by: Keith Packard commit 601affcbaf587816a6be4b6815efd2cc99cff66e Author: Keith Packard Date: Tue Jul 6 01:20:50 2010 -0400 Fix prime sieve function to include 'max' when 'max' is prime The sieve code would drop the max value from the returned list when it was prime. Signed-off-by: Keith Packard commit d341e0220d181db50f7a6647433053293b3f45ec Author: Keith Packard Date: Tue Jul 6 01:20:11 2010 -0400 Fix factorial pretty-printing The expr tree built for factorial is different now, so the pretty print code needs to adapt. Signed-off-by: Keith Packard commit 6d4a60c69eac89ff72004a00a8e9a70876db2325 Author: Keith Packard Date: Tue Jul 6 01:19:15 2010 -0400 Add factorial test This tests factorial accuracy up to 1000, which should catch most errors Signed-off-by: Keith Packard commit 75187037e714eaadc671daba19a934608fd1069b Author: Keith Packard Date: Tue Jul 6 01:18:08 2010 -0400 Remove accidentally included cos debug printf This was accidentally added in the previous patch Signed-off-by: Keith Packard commit b249d719eeb86e8834ccfa2c91c4ead07d497e09 Author: Keith Packard Date: Tue Jul 6 00:28:41 2010 -0400 Replace naïve factorial algorithm with prime sieve from Peter Luschny commit 3111c1bbe21202ca13b0c3bba39ce61b87197269 Author: Bart Massey Date: Thu Nov 19 11:29:36 2009 -0800 changd csv parser to throw a bad_csv_parse exception on unclosed quotes commit ba82f22cf8eafa406618a93ec26bfc08e069627e Author: Bart Massey Date: Thu Nov 19 10:28:17 2009 -0800 Included a definition of SUN_LEN for systems that don't have it. This fix responded to a bug report from Claude Marinier that Nickle networking wouldn't build on Solaris. commit 168c8e3f857956401306d90f7bd3d3c8d17ad493 Author: Bart Massey Date: Thu Nov 19 10:22:31 2009 -0800 made parse_csv_t public commit 4c6a840a3f2596bf6565f1b9906b2500852b66c6 Author: Keith Packard Date: Thu Sep 17 15:03:12 2009 -0700 Update to version 2.69 commit eaf3950ad5308e33a5dbfd8b1c921ae2603fd5c5 Author: Keith Packard Date: Thu Sep 17 14:59:31 2009 -0700 Update to standards 3.8.3 and debhelper 7 commit b9bae75689465f0572deed07d0514f546648d32a Author: Keith Packard Date: Thu Sep 17 14:58:49 2009 -0700 Remove debian dir from debian orig.tar.gz file commit bb5e73b56f322a04d914f48856d72c4d00626214 Author: Keith Packard Date: Thu Sep 17 14:39:48 2009 -0700 Ignore more files commit a85c4aba193b67294c8bafeec24ce7c2b32ea75c Author: Keith Packard Date: Thu Sep 17 14:28:30 2009 -0700 Byacc now makes tables const by default. Remove Makefile.am hacks. The Makefile.am hacks served to turn the parser tables into constant data to save a bit of memory. That's no longer necessary now that byacc does this automatically. Signed-off-by: Keith Packard commit fb02b3053b9615b6872352fa0581ee68d047b625 Author: Keith Packard Date: Thu Sep 17 11:56:09 2009 -0700 Make debian build epend on libreadline-dev not libreadline5-dev. This ensures that we'll pick up any new readline versions as released. Signed-off-by: Keith Packard commit ac6bdfab92361bc999323e1f4bb1fa022527fd16 Author: Keith Packard Date: Thu Sep 17 10:20:11 2009 -0700 Get math-tables.5c built before tests are run This file is used by math.5c and is built by running the math-tables program; adding a dependency from math.5c appears to make sure it is built at the right time. Signed-off-by: Keith Packard commit 0a80c1f7816a19970a0751af5baaaf0643f68bdd Author: Keith Packard Date: Thu Sep 17 10:00:11 2009 -0700 Fix trig boundary conditions. limit angles to -Ï€ - Ï€, make sincos generate correct signs, make atan2(0,0) return 0. commit 8aa40d0d867bcfe8b917c49b7d36138c835130c2 Author: Keith Packard Date: Thu Sep 17 09:58:56 2009 -0700 Add tests for math functions. These compare the results of nickle with the C library math functions to provide a rough check of correctness as well as checking various boundary conditions for the functions. Signed-off-by: Keith Packard commit cab93dd5f5a04ce53bf826d9a0e5e8063bd293a6 Author: Keith Packard Date: Sun Jun 14 17:27:16 2009 -0700 math.5c: fix quadrant errors in atan/asin/acos All of these had various quadrant related errors. Signed-off-by: Keith Packard commit 84f404bfbd19c460c559717f8d9f4f20ed92a3dc Merge: 992ed90 0eb4259 Author: Bart Massey Date: Thu Feb 19 13:21:04 2009 -0800 Merge branch 'master' of ssh://keithp.com/git/nickle commit 992ed90e64cbe1cc9cc703dbcfaa64bc5ab6fe6e Author: Bart Massey Date: Thu Feb 19 13:20:09 2009 -0800 Removed redundant gram.y in YACCCOMPILE This was preventing current autotools from compiling the grammar with byacc. commit 0eb425902db7e6291afb881086aef5a4a4e5019f Author: Bart Massey Date: Mon Sep 8 00:37:58 2008 -0700 added variable to control default floating point precision commit d24ae2f1bd182bd07eea8ef6918c3798c7d98393 Author: Bart Massey Date: Sat Sep 6 22:45:33 2008 -0700 replaced the copyright symbol in value.h, which had somehow become mangled commit c5dfef94042eedfd69d8bc110c7e2000f348efb1 Author: Bart Massey Date: Sat Sep 6 22:44:17 2008 -0700 reverted inadvertent change to DEFAULT_FLOAT_PREC commit 9a1ad39e7b3207925a807c27401450bd47d555d0 Author: Bart Massey Date: Fri Sep 5 22:18:08 2008 -0700 added string reverse() commit 815ea2aadc2644a426b87f8c4e41d58a01d50de0 Author: Keith Packard Date: Sat Jun 21 02:31:29 2008 -0700 Bump to version 2.68 commit e278cfc926e5cd2ee51c9e45a642b2803d93cceb Author: Keith Packard Date: Sat Jun 21 02:28:53 2008 -0700 Bump debian standards to 3.8.0 commit d69f9ba5dbf231bf2c8ecd5ab55e550d11f5ebae Author: Keith Packard Date: Sat Jun 21 02:28:34 2008 -0700 Add README.release commit 74d032db530e2441f47b68549d18a70956ddf601 Author: Keith Packard Date: Mon May 19 13:22:11 2008 -0700 Non-interactive stdin is always available for reading. Failing to set the 'stdinOwned' flag meant that you could never read from stdin which wasn't a terminal. Oops. commit d0604e797cf194eb025a1784766ebea8cf38ec87 Author: Keith Packard Date: Wed Mar 26 23:21:41 2008 -0700 Allow background nickle to not poll on tty ownership When stdin is connected to a terminal but nickle is not the foreground process on that terminal, the io code would poll to wait for ownership to flip back to nickle so that reads could be performed without generating a signal. Now, nickle waits until someone actually tries to read from the terminal before starting to poll. This means that simple background processing nickle programs will not poll every 100ms. commit fd8d02af5bf2884858108421fec40b8c7ca9863b Author: Keith Packard Date: Wed Mar 26 16:22:44 2008 -0700 Remove support for non-SIGIO pipes Older version of the kernel (before 2001) failed to generate SIGIO on pipes, so nickle had code to poll instead. I think we can safely remove that code now. commit 5106300e425315c5f753dd4e1bf2c1ff6d19db64 Author: Keith Packard Date: Fri Mar 21 12:31:00 2008 -0700 Fix floating point printing to correctly round output commit e7f78ce3e66259f0a08c0099de4b89ad739c03c8 Author: Keith Packard Date: Thu Mar 20 10:56:38 2008 -0700 Fix divide_by_zero exception type in fourfours.5c example commit e00e48546d26c6e0c22c70cb7eb14e81c897c61e Author: Keith Packard Date: Thu Mar 20 10:20:52 2008 -0700 Make SRPM + RPM build work by serializing dependencies. $(SRPM) $(RPM): ... build fails as it does 'build' twice. commit 48e852689a43de236f93aa13172d31c8eb536fc1 Author: Keith Packard Date: Wed Mar 19 23:24:45 2008 -0700 Makefile fixes: make main.o depend on Makefile, ensure debuild actually does commit 27ace3a23d90e8e5fe16b943743a8d9144cca7e6 Author: Keith Packard Date: Wed Mar 19 23:12:13 2008 -0700 Avoid having the 'pretty_print' builtin show two error messages. NamespaceLocate takes a 'complain' boolean that will print out an error message, but the pretty_print command also raises an exception when it fails to find the name. Two errors is at least one too many here. commit 31e633b55cece8a6e46d763b2e51c974b450a12f Author: Keith Packard Date: Wed Mar 19 22:38:18 2008 -0700 Rename the builtin Process namespace to PID to not conflict with the Process library commit ffc553a721015347939cc07da4a81577d86093d0 Author: Keith Packard Date: Wed Mar 19 22:37:49 2008 -0700 FileGetErrorMessage returns a Value, not a char * commit 3382f746e5423aa6bdd18349e6b47a8a6a5b5259 Author: Keith Packard Date: Wed Mar 19 16:09:24 2008 -0700 bump to 2.67 commit 88f787164419f814d149e39eec89b94790b164e3 Author: Keith Packard Date: Wed Mar 19 17:19:26 2008 -0700 Fix a few broken calls to RaiseStandardException. RaiseStandardException was changed to remove the need to pass a string argument first, but a few calls were not converted, and C varargs cannot catch these errors. I checked all calls and they appear OK now. commit 085584b85f75c5ea25a95be949d2286e7974df2d Author: Keith Packard Date: Wed Mar 19 16:00:09 2008 -0700 Divide by zero declaration is (real, real), not (string, real, real) The type declaration for the divide_by_zero exception was wrong. commit b3023c298db4e22eb86fd809ef76d7776d7e68df Author: Keith Packard Date: Mon Feb 25 10:07:14 2008 -0800 Change yacc invocation to make yacc tables const. byacc (and bison) leave the yacc tables in writable pages; this change edits the C output code to move them to read-only pages. commit fec8c2e743f1b2ab194652b5074f99a9e373cc22 Author: Keith Packard Date: Mon Feb 25 10:00:51 2008 -0800 Track profile ticks per function in addition to per statement. Recursive functions make gathering useful profile data harder. This avoids some recursion mis-counting by separately tracking function and statement lifetimes. commit eefcdbb5330160a0197e425b45f174f34b1b5db7 Author: Keith Packard Date: Mon Feb 25 08:40:42 2008 -0800 Remove old "function" keyword from examples commit 3e6fed4d93df52b6593af4b93d320a7bac683c51 Author: Keith Packard Date: Mon Feb 11 08:29:26 2008 -0800 Raise io_eof exception when reading past EOF. Instead of returning -1, raise an exception so that applications don't end up spinning at EOF. Applications should check for File::end before reading or catch the exception. commit 2d56ac7537216e699a24fa7127e6c3fa18e80ea7 Author: Keith Packard Date: Mon Feb 11 08:28:13 2008 -0800 Remove first string arg from RaiseStandardException. Every standard exception was required to have a string for the first argument, which isn't always desired. Eliminating this forced first argument allows each exception to have the desired arguments. commit 9cd6fc05beac5155f9039781d79c11a112fea731 Author: Keith Packard Date: Thu Feb 7 17:52:05 2008 -0800 Avoid using getc at EOF commit 14bd65ea0fb8d23bbf553340cde57a270e2201cd Author: Bart Massey Date: Wed Feb 6 11:14:29 2008 -0800 changed print command to print all public on no argument, fail if argument is bogus commit 2b5a2b9f8fed04cd08a175e3916a089d54f89d21 Merge: 453e6d8 d285315 Author: Bart Massey Date: Wed Feb 6 10:39:33 2008 -0800 Merge branch 'master' of git+ssh://keithp.com/git/nickle commit 453e6d8e416686b1cac547c4c31c9ccbbdb9c17c Author: Bart Massey Date: Wed Feb 6 10:38:58 2008 -0800 added reimport command commit 6e99ad8d6210075f758c7311d9d628c09dad64da Author: Bart Massey Date: Wed Feb 6 10:21:38 2008 -0800 fixed ordering bug when autoloading / autoimporting multiple namespaces in a single commad commit 209997e5b9cf2e51b74816189615ebd64c187a15 Author: Bart Massey Date: Wed Feb 6 10:20:01 2008 -0800 cleaned up command.5c a bit before changes commit d28531507f1064d5eea4b21988817ead2012fe7a Author: Carl Worth Date: Sat Feb 2 23:36:50 2008 +1100 Socket: Provide varargs versions of bind and connect With this change, the hostname is now not-required, (and even not allowed), for an AF_UNIX socket. Also, for an AF_INET socket the port can now be an integer as well as a string service or port. commit d710bcf28a3d6bbaea6ace8870f2c503f3576796 Author: Carl Worth Date: Sat Feb 2 21:31:26 2008 +1100 Socket: Store address family in file structure This is more straightforward than using getsockname to read the address family back out from the kernel. commit 7c97c425b259d9c710bfe81aa226e6fa3acb0909 Author: Carl Worth Date: Sat Feb 2 17:19:15 2008 +1100 Socket::create: Make the family argument optional commit 50f17cd7b03b984643f9e2fc1472160f939a3a08 Author: Carl Worth Date: Fri Feb 1 09:25:19 2008 +1100 Socket::create: Add support for Unix domain sockets commit 116b96de8e915d8fd8c48d6bbc2334e4641c5e7f Author: Keith Packard Date: Sun Feb 3 15:31:45 2008 -0800 Add pid/gid/uid functions in Process namespace commit 2ee7d1bc95bb2bbbbc5792ed11618a229133eb22 Author: Keith Packard Date: Sun Feb 3 14:36:06 2008 -0800 Signal exception arguments were not getting forwarded. Exception arguments must land in thread value register so that they can be passed to the exception handler (if any). Also, add a test for signaling. commit 6adae78f5e70be0031718e0e7ebeff81996951e3 Author: Keith Packard Date: Sun Feb 3 07:22:28 2008 -0800 Add signal exceptions, treat SIGINT as raise signal(2) SIGINT used to interrupt the current thread and enter the debugger with the thread 'interrupted'; in this state, the thread could be continued. However, this means that threads cannot catch SIGINT and cleanup at process exit. This commit changes all this around so that SIGINT simply raises a signal exception in all threads. This patch also keeps the interpreter running until all threads have exited. commit 689ea14db8ca29f3338a03e71be5865089972488 Author: Keith Packard Date: Sat Feb 2 22:07:54 2008 +1100 Add 'signal' exception and 'send_signal' function. The 'send_signal' function raises a 'signal' exception in another thread, causing it to abort processing immediately. commit 20a5db3ef34d47fdff2dd98052b577db80f76ffc Author: Keith Packard Date: Sat Feb 2 12:32:45 2008 +1100 Add unlink, rename, mkdir, rmdir builtins. commit b5830866a10e7eed272c52e7aafc17d3593c2dac Author: Keith Packard Date: Sat Feb 2 12:29:52 2008 +1100 Twixt mark function shouldn't reference leave instruction. Instructions cannot be referenced directly, only the object block containing them. The twixt continuation already has a reference to the object, so the extra MemReference on the leave instruction is spurious (and causes crashing). commit b739d5a6f5816100b56b5278f4a99ab4ee937222 Author: Keith Packard Date: Tue Jan 29 17:08:53 2008 +1100 Silent underflow on conversion to machine double commit 9f26613cfa6ce6dd58edf671390d3379fbaf1a34 Author: Keith Packard Date: Fri Jan 25 19:44:19 2008 -0800 Fix autoimport for nested namespaces commit d9959cfa510ebc56ed6d66cd529c85529b780886 Author: Keith Packard Date: Sun Jan 13 17:34:02 2008 -0800 Notice that some TODO items were done a long time ago commit a8439dbfd270b47bc62b0e6d9a8bf37471ba470d Author: Keith Packard Date: Tue Jan 8 23:27:53 2008 -0800 Support autoload/autoimport of nested namespaces. While nested namespaces could be loaded, the filenames would reference only the last element making it hard to actually use them. This change glues the namespace elements together with '-' when building filenames. commit e324f392b2bf13f99a2e39dfde7b7f4913be7dfb Author: Keith Packard Date: Tue Jan 8 13:14:16 2008 -0800 Search for unpublished names with NamespaceLocate commit 4a8813f98e03663108757ade2da6d6f372598060 Author: Keith Packard Date: Sun Jan 6 16:41:03 2008 -0800 Bump version to 2.65 commit 8e8c6197f0b7448fd27fa1bae5daf2bb839ce1df Author: Keith Packard Date: Sun Jan 6 16:26:07 2008 -0800 Exit with status 1 if last action was parse failure. Nickle normally exits with the status of the last thread; if the last action of the user was a parse failure (causing no thread to execute), exit with failure (status 1). commit edc47ba279d74bbc18de3531dd8aabdbbdd60f70 Author: Keith Packard Date: Sun Jan 6 16:18:49 2008 -0800 Function declarations would segfault the pretty printer. void g () { void f (int i); } print g would segfault as 'f' was a function declaration without a code body. Fixed by adding pretty printing code to handle this case. commit 691a76447cea42cb3c5bdc3ccb1aae228081fe3b Author: Keith Packard Date: Sun Jan 6 15:51:07 2008 -0800 Check for duplicate function param and struct/union members While duplicate function parameters and struct/union members may have well defined semantics, they're a bad idea, so we make them an error. commit cf60fcd340021ed1e29fdc208fe4634924c124e1 Author: Keith Packard Date: Sun Jan 6 15:50:39 2008 -0800 Reduce warnings when compiling flex output commit 4ae8bb3a888432b3101e16fbbd63e04c9229fb9b Author: Keith Packard Date: Sun Jan 6 15:20:10 2008 -0800 Add new '+' type operator; creates subtypes for struct/union types. Merges two struct, union or enum types together to form a unified type containing each of the elements of the two original structures. commit 7761936b1b7318d29d4cc948308f9742f5c3f433 Author: Keith Packard Date: Fri Jan 4 00:41:57 2008 -0800 Bump to version 2.64 commit 0dde80f6dfed86346709a603499da6cbb2230e91 Author: Keith Packard Date: Fri Jan 4 00:38:41 2008 -0800 Floating floor and ceil functions broken for values with no integer part. The ceiling of any positive fraction < 1 is 1, the floor of any negative fraction > -1 is -1. These cases were missing from the existing functions. commit b4a4b66be2ce66de162818cd94ae17d840b00c05 Author: Keith Packard Date: Fri Jan 4 00:36:58 2008 -0800 Add test case for floor and ceil functions. Floating point floor and ceiling functions are broken, this demonstrates the bug. commit 0d645e8090c135b451949a844fdd53f8ebfc1575 Author: Keith Packard Date: Mon Dec 31 14:23:56 2007 -0800 Copy hash keys on insertion. Mutable hash keys must be copied when placed into the table as any changes to the original key value must not change the hash mapping. commit 2727d3ade55570c172a6fd6d22a92287503c917a Author: Keith Packard Date: Mon Dec 31 14:23:01 2007 -0800 Add tests for hash tables, including mutable key copying. Test hash tables. Has test that checks correct behaviour with mutable keys where the key is copied when placed into the table. commit cafadd2f2655b30fcc86df0b76492ac5afbf4152 Author: Keith Packard Date: Sat Dec 29 16:08:07 2007 -0800 Update to version 2.63 commit b0638d82ad3ad22e6de8c0c371bf76330db489d3 Author: Keith Packard Date: Sat Dec 29 15:56:28 2007 -0800 Make foreign objects equal when they point at the same data. commit 974283319c7ef54fa301df9b5eda26d3195e49e4 Author: Bart Massey Date: Sat Dec 29 00:59:41 2007 -0800 added newlines where missing in calls to panic() commit de73950c6dbad62d022378cf5e9e62b635458326 Author: Keith Packard Date: Sun Dec 9 22:26:21 2007 -0800 Use AC_LINK_IFELSE instead of AC_COMPILE_IFELSE to test linker flags. The -Wl,-E option is for the linker, so testing the compiler support isn't sufficient. commit 0d16382a67a39d928150b1970cf5295633ba2a50 Author: Keith Packard Date: Sun Dec 9 22:09:30 2007 -0800 Avoid using extra libraries unless necessary commit 16240c3265bd1991e6317901460a504499a12ac6 Author: Keith Packard Date: Sun Dec 9 21:20:44 2007 -0800 Update debian changelog to reflect doc change commit 44c2aa8ee30ea972eb852dec9d73075a569b273d Author: Keith Packard Date: Sun Dec 9 21:20:03 2007 -0800 Update documentation to reflect corrected // and % semantics commit eb5604f803cf5d442f389d1cad60301095266596 Author: Keith Packard Date: Sun Dec 9 21:15:04 2007 -0800 Bump debian changelog to 2.62 commit 4d90bffd79c2db94b377973321f552b4ee97e65f Author: Keith Packard Date: Sun Dec 9 21:10:38 2007 -0800 Bump version to 2.62 commit f78bf021e6bff9f422188f068a7a1b4aaa28d57f Author: Keith Packard Date: Sun Dec 9 21:08:47 2007 -0800 Make // and % operators modulus division operators. Herry S Warren Jr. defines three kinds of division -- truncating, floor and modulus. For all three kinds he requires a simple invarient: dividend = quotient * divisor + remainder Modulus division additionaly requires 0 <= remainder < abs (divisor) Floor division sets: quotient = floor (dividend / divisor) remainder = dividend - quotient * divisor Truncating division has quotient = round_towards_zero (dividend / divisor) remainder = dividend - quotient * divisor We select modulus division as it makes the most sense when you treat the values as a ring centered at zero. commit 3c1973bbb19744d3a870ed5a17a14bf04ad34e75 Author: Bart Massey Date: Sun Dec 9 21:01:00 2007 -0800 fixed modtest to check denominator properly commit d4dd7d847b17f7143a3d99bd0c23fc02c2b087de Author: Bart Massey Date: Sun Dec 9 20:59:17 2007 -0800 actually added modtest.5c commit 777fcaaefee0b25b09b62ed3bcf7a6d25a16b922 Author: Bart Massey Date: Sun Dec 9 20:58:02 2007 -0800 added test for modulus, because it was broken commit f697f8a66f4e4a408a076a6f7ea9daf5256a71c5 Author: Keith Packard Date: Sun Nov 25 22:00:19 2007 -0800 Bump to version 2.61 commit 94a41e46b6381304a5b1c67675afd9c5f3f8574c Author: Keith Packard Date: Sun Nov 25 21:51:23 2007 -0800 Examples - use '.' in struct initializers. Add '.' before struct tag in initializers now that it is permitted. commit 3cf7567bbfa16e93c32a5a2477b28e2a91b37ae1 Author: Keith Packard Date: Sun Nov 25 21:50:59 2007 -0800 Skiplist test code had a typo. "hi" is not a legal initializer for an integer variable. commit 9be14d5dcb8e55d22066845a0278a0c22374b0c9 Author: Keith Packard Date: Sun Nov 25 21:49:41 2007 -0800 'randtest' example used now-missing 'vprintf' function. vprintf was replaced by the general '...' mechanism for passing an array as a list of arguments. Somehow, this example was never updated. commit f8f1d223a46cffff9fcc89fa7524fdf57cbacf7c Author: Keith Packard Date: Sun Nov 25 21:48:22 2007 -0800 Tests - use '.' in struct initializers. Add '.' before struct tag in initializers now that it is permitted. commit 81beb0e9394e715e7354cebeb58c261a2e9b2019 Author: Keith Packard Date: Sun Nov 25 21:47:11 2007 -0800 Builtins -- add newly permitted '.' before tag in struct initializers. Now that struct initializers permit '.', use them for the builtin nickle code. commit 96c5c70c8226c3f60419fa2eee981d259efb07f2 Author: Keith Packard Date: Sun Nov 25 21:13:25 2007 -0800 Allow . in struct initializers. C places a '.' before the structure member name in initializers, which would eliminate a shift/reduce conflict in the grammar. Nickle has not allowed the dot in the past, so instead of requiring it, we'll just make it optional, which doesn't eliminate the conflict, but at least works. commit 102f74a6622b85aae100477bd861b1cec005cbe3 Author: Bart Massey Date: Wed Oct 17 15:28:00 2007 -0700 added comment about semaphores vs mutexes here commit f8a0f102072afdd4cb234a28b8a91c99ffa3c0c6 Author: Bart Massey Date: Wed Oct 17 15:23:16 2007 -0700 replaced queue with mbox commit 7110e52cdf3562adfd93073731b756f1fb26a96a Author: Bart Massey Date: Wed Oct 17 15:07:13 2007 -0700 added multiplexor output delay commit 22b106b4792531898d57ecd9ea32ed11cc8a5d34 Author: Bart Massey Date: Wed Oct 17 14:40:56 2007 -0700 added threaded multiplexor example commit b1735afed1a772ca6aee87f0ba349c43e8ab2c3e Author: Keith Packard Date: Tue Oct 2 01:57:55 2007 -0700 Bump to version 2.60 commit 2278b93b7e760f1153847a0b3c36d07684f72e0c Author: Keith Packard Date: Tue Oct 2 01:53:02 2007 -0700 Manage file buffer chains with explicit malloc/free. Buffer chains must have life equal to the file they belong to; an unreferenced file may still have buffered data, so the buffers cannot be reclaimed. The nickle GC does not have a separate pass that checks to see which objects can be freed, rather it assumes that such objects are self-contained. Hence, anything hanging off of an object which can refuse to be reclaimed must not have been allocated from the nickle GC system. Yes, this is a significant limitation to this allocator. Someday I'll figure out a good general fix for this problem, right now we'll stop segfaults when applications drop file references without closing them. commit 8e3690cea5da54d83e6fd6d26c073c1c4d8ae403 Author: Keith Packard Date: Tue Oct 2 01:16:05 2007 -0700 Extend Ctype namespace to latin-1. This should be extended to all of unicode, but that's a huge amount of data. commit 52c9ae4e5c476f6b202b49de3840c7ffdd0e02d8 Author: Keith Packard Date: Tue Oct 2 01:15:16 2007 -0700 Flush file output on exit call. Use of the built-in exit function should flush all file I/O, just as if the program terminated by returning to the top level at EOF. commit 68dfd4a10fc2c88b7618505b3c54e11ee4def1ee Author: Keith Packard Date: Sun Sep 23 21:18:31 2007 -0700 Update debian bits to 2.59 commit fca9c9e60a67f9b4cb3bbf2d5305f9a95da6d1f5 Author: Keith Packard Date: Sun Sep 23 21:12:01 2007 -0700 Bump to version 2.59 commit fb835ca271df82ce282360a45937e4d4b2f8436f Author: Keith Packard Date: Sun Sep 23 21:10:30 2007 -0700 Have git ignore nickle binary commit 27873b849950eace51db8b02491f06cc0f0ec43c Author: Keith Packard Date: Sun Sep 23 21:07:48 2007 -0700 Clean up some autotools warnings commit 02f2eb1115ba8b7541e8448959b0357be4c89905 Author: Keith Packard Date: Sun Sep 23 20:58:09 2007 -0700 Make default rational display not include braces commit 2bccdfcbbc85a86e544af1dd4f4e7756bd1f953a Author: Keith Packard Date: Sun Sep 23 20:46:52 2007 -0700 Clean up some lintian warnings commit 8b2a4a6bcf0fa2bf0187560ce4805f7fcce8796f Author: Keith Packard Date: Sun Sep 23 20:34:58 2007 -0700 Construct ChangeLog from git history for distribution. Including a Changelog with the distributed code allows people not using the git version to see what has happened since the last release. commit 89d28f4f223f96f6029fa4d373c39c3ff1779c40 Author: Keith Packard Date: Thu Jul 19 00:12:49 2007 -0700 No tail calls without a parent frame commit d6e6609c4a5cd81742760a18d722ae2c8525b15a Author: Keith Packard Date: Thu Apr 26 08:07:55 2007 -0700 Update to version 2.58 commit 897e8d99971cb1aa77662351f79ba6bcbffefa1c Merge: 2016a94 44ec50f Author: Keith Packard Date: Thu Apr 26 07:50:03 2007 -0700 Merge branch 'origin' commit 2016a94eb42a4f078c55e1ae2c5e0f0ceac89df3 Author: Keith Packard Date: Fri Mar 23 23:02:21 2007 -0700 More ChangeLog removal from debian/rules and nickle.spec commit 981d3c9742311d171336e6e0c8f070fc78a3bbd0 Author: Keith Packard Date: Fri Mar 23 12:40:47 2007 -0700 Use foreign automake option. Native automake requires ChangeLog file. commit 7acdf0e3c6c2e56915f35f84ccc630e2ea38e3aa Author: Keith Packard Date: Fri Mar 23 12:21:56 2007 -0700 Remove ChangeLog and remaining references commit 667f493f249a0040cb095bb4f7232ca2494fd6d8 Author: Keith Packard Date: Fri Mar 23 12:04:53 2007 -0700 Move version number to configure.in script and out of ChangeLog. ChangeLog is no longer used, so move the package version number to configure.in commit 0342ea7ea71bef8646bc851f17785f0bef45cff8 Author: Keith Packard Date: Fri Mar 23 11:56:52 2007 -0700 Avoid broken GCC signed integer changes using -fwrapv. Some utter idiot changed the semantics of signed integers in GCC. I'm afraid I can't express the level of incredulity I experienced when I learned of this change. Signed integers? Changing semantics? Have they any idea of level of random bugs this will expose? commit f081b147735949d81d17060f766d4057bd385a58 Author: Keith Packard Date: Fri Mar 23 11:46:16 2007 -0700 PRNG is no longer loaded by default, tests need to load it. commit b1146617f88c26e78ab3e6ecb8d344cbea9630f0 Author: Keith Packard Date: Fri Mar 23 10:59:07 2007 -0700 Merge IntBinaryOperate into BinaryOperate. This giant inline function was used only once. commit 1739d9e887d3317a3cff95657419f29b98710b92 Author: Keith Packard Date: Fri Mar 23 10:57:54 2007 -0700 De-macroize allocator. Eliminate macros for main allocator functions; the function call overhead is not worth it. commit 44ec50f2d511b62de12043b44b1269832a41587e Author: Bart Massey Date: Sun Mar 18 01:50:15 2007 -0700 get rid of archaic "v" print and scan functions commit db125426b90b6bacece1a35dc852a084684446a5 Author: Matthias Drochner Date: Sat Feb 24 17:16:12 2007 -0800 fixed signededness bug in integer carry calculation commit cde771e23ecaf856c24e5f59a033fa604f17c896 Author: Bart Massey Date: Sat Feb 24 13:17:14 2007 -0800 changed import PRNG to autoimport commit b7a5a73aaa002d3ffee7452af8a2b55b519ad15f Author: Bart Massey Date: Wed Dec 20 23:16:05 2006 -0800 CCITT/ITU CRC-32 computation example commit 8a80fa756bd1f6465336cc2c77062790f4cdb4c7 Author: Keith Packard Date: Tue Dec 5 18:14:16 2006 -0800 example/fourfours was using xor instead of exponentiation commit bf09d097b233433bb2d5be46ba233749b3fa4340 Author: Keith Packard Date: Tue Dec 5 16:05:03 2006 -0800 Fix release building portions of Makefile commit b71a445cf9edabebf61f7ddeb0b66e6502ac238c Author: Keith Packard Date: Tue Dec 5 13:39:02 2006 -0800 Update for 2.56 release. Fix 'release' target in Makefile. commit 985ee1fc0374acca339eac36117888344d21933d Author: Keith Packard Date: Tue Dec 5 12:54:50 2006 -0800 Uninitialized value visible during MemCollect in Catch record. Newly allocated memory is uninitialized and may contain garbage. If the allocator may be called during initialization of the object, all object fields must be initialized to a valid value before any further allocation occurs. This wasn't happening in the Catch object as the exception member was left unitialized while the continuation member was allocated. commit 75a3ab50ceeb7314511448ae041134ed9106c564 Author: Keith Packard Date: Tue Dec 5 03:48:42 2006 -0800 Update debian files to 2.55 and new debian version commit e5ba92562f689715fb59f27d535845ff9511ed26 Author: Keith Packard Date: Tue Dec 5 03:48:15 2006 -0800 Add fourfours.5c to examples Makefile.am commit eae97db26e17447ac4cf1043453af11bd7c3dcab Author: Keith Packard Date: Tue Dec 5 03:39:04 2006 -0800 Add changelog for previous commit, update version to 2.55 commit c582e76ae1452cc5a2eb6dc18e6522f2876e3878 Author: Keith Packard Date: Tue Dec 5 03:34:03 2006 -0800 Add four fours example. Using four '4's, find equations using unary and binary operators which compute ever integer from 1 to 100. commit b20b748e4211c93bbc734fa41d20c5d0ae8ee4eb Author: Keith Packard Date: Tue Dec 5 03:33:16 2006 -0800 Correct catch nest level inside multi-peer try/catch blocks. When a try/catch block has multiple catch elements, each of the catch blocks is a 'peer' of the others, exceptions raised inside any of them will not be handled by the peer catch. To do this, the compiler generates unwind code to set the exception stack to the right position before jumping into the exception handler function. This means that while compiling the exception handler function, the catch stack must match that from before entering the top-most catch peer. This was done by not pushing non-local objects on the non local stack while recursing to the peer catch block. However, aside from the nested catch blocks, the nested statement *must* have the correct number of non-local goto blocks. Instead of attempting to work around a shortage of non-local goto blocks while compiling the statement inside the try/catch, the non-local stack is stripped of peer catch blocks while compiling the exception handler. commit 4525426c35809fa043e4f3c5e31b8eb54047d2d4 Author: Keith Packard Date: Tue Dec 5 03:27:27 2006 -0800 Fix memory debugging code (not built by default commit 1d6ce081ad1f2205027cb5180cb9052772fceeb5 Merge: 8584b37 135fb9f Author: Keith Packard Date: Tue Dec 5 01:22:54 2006 -0800 Merge branch 'origin' commit 135fb9f205c4664ec3d010e4d13013bf3a783a8f Author: Bart Massey Date: Sat Sep 23 20:40:18 2006 -0700 Use "score" instead of "pct" for local, since the quantity is a score and not a percentage. commit 14a340f73752e4c6ad7b09b8f84ef453b3a9ba8e Author: Bart Massey Date: Sat Sep 23 20:00:01 2006 -0700 Completely revamped for modern Nickle, to take care of the clamping that should be performed in the calculation, and to give some references and rationale for the wacky formula. commit 8584b377f56b7a44a9b56baeba5e07d45d6ede02 Author: Keith Packard Date: Tue Aug 29 22:27:43 2006 -0700 Doc string for File::print confused -1 (default) with -2 (sufficient). The documentation string for File::print stated that -1 used sufficient precision to represent the output exactly. This is wrong. -1 is an alias for the default precision (10). -2 is the value used to indicate sufficient precision should be used to represent the value exactly. commit 11f4741efb4a662a0af3a816468ef83d002f9a10 Author: Keith Packard Date: Sat May 20 11:07:54 2006 -0500 time() builtin needs to return all 32 bits commit 8bed6863b343acddad6fc8951ce3b83c44d4ec60 Author: Keith Packard Date: Sat May 20 10:47:21 2006 -0500 Version 2.54. Compute NICKLELIBDIR at build time. Update debian build to 3.7.2 commit dccfc2bab5ad042a366c92d0ebc6b295a912401f Author: Bart Massey Date: Thu Feb 16 06:06:12 2006 +0000 New example using continuations to implement channels and coroutines. commit aa9ca7e62e1f9fcdd5940a3f21bee2322137a4ee Author: Bart Massey Date: Thu Feb 16 05:46:09 2006 +0000 Updated ChangeLog :-) New example using continuations. commit da7006c1b4e6c8bc3fb0a5746dcc7a2502834ada Author: Bart Massey Date: Mon Feb 13 05:46:19 2006 +0000 New example using continuations. commit 952a0eeff9e9dacf6955fbafcb67274cb3c6df40 Author: Bart Massey Date: Sun Jan 29 01:22:59 2006 +0000 Update a bit to reflect current reality. commit 63c0e18598d20d9cb283d6a520d8ccaf654be493 Author: Bart Massey Date: Sat Jan 28 23:17:25 2006 +0000 Update for version 2.51-2.53 commit 6d17723725e976ef26596d062fc104766b56825c Author: Bart Massey Date: Sat Jan 28 20:05:26 2006 +0000 Necessary version bump, no other changes. commit c9593097382750f7216033df8372abc50537df40 Author: Keith Packard Date: Sat Dec 24 18:36:35 2005 +0000 Use rpmbuild instead of rpm to build rpms. Permit {} in numbers to allow exact rational input commit 15fb3a5cff191da30db8eecacc9ddd4be6ec81cf Author: Bart Massey Date: Sat Dec 24 07:53:39 2005 +0000 Make usage() function user-visible by exporting closure when parse_args() is called. commit 55be04624ec4f0deb6f53775a37d94b969da6357 Author: Bart Massey Date: Mon Dec 12 07:05:50 2005 +0000 Update for version 2.52 Since it's now autoimported, autoload ARC4 so that it will continue to work. Add needed autoloads/autoimports to make the examples work again. Not obvious that PRNG shouldn't continue to be loaded, and maybe even imported, although that would also force in ARC4 in the current implementation. commit ede92e16e7998658a3648ea8b39799cea389834a Author: Bart Massey Date: Sat Dec 10 22:11:45 2005 +0000 Update for version 2.51 Don't load every random library; make the user autoload or autoimport them if they want them instead. Replaced putc and getc in copy function. Added &&= and ||= operators. Added Drop opcode needed for short-circuit code for &&= and ||=. commit 3564c57b77f491a00c2443e60c747531b34c3433 Author: Keith Packard Date: Wed Dec 7 04:32:27 2005 +0000 Update for version 2.50 commit 85b9e50f7cdfbe365c1541d294302904fb08a9eb Author: Keith Packard Date: Thu Dec 1 16:15:31 2005 +0000 cbrt must use more intermediate precision to hit the specified error bound commit a96d474cf9445e0dd3a3e67c55e1f47054d0a14a Author: Bart Massey Date: Sun Nov 20 08:49:33 2005 +0000 New code to handle process creation provides system(), popen(), and run_process(). commit c283d668c690aae04267a99ae583db32a5ccbad5 Author: Bart Massey Date: Thu Oct 27 06:31:06 2005 +0000 Fixed to cope properly where args field of argd is uninit. Most common cause: no optional arguments. commit 6066cbd5eed1ec4d20efade71cb159d13ce0ae8c Author: Keith Packard Date: Thu Oct 20 18:24:22 2005 +0000 Permit any numeric type in this function, result type will always be integer. Let run-time system catch any representation problems. commit 4a64f9a79291099085622e146c00440c42c19a8b Author: Bart Massey Date: Wed Oct 5 06:17:07 2005 +0000 Fixes for various buglets including mis-parsing single-character options and using the wrong variable in an error message. Changed the semantics of argv. It is now dim 0 iff the program reads from standard input *and* was not passed arguments. commit e4c79eabe9936f298bccddcb6af161df2254811b Author: Bart Massey Date: Sun Oct 2 18:30:19 2005 +0000 Older versions of GNU Make (before 3.80, apparently) seem to require shell invocation macros to be defined with := Solaris yacc gives an error if a type is given to a non-terminal that does not actually appear in the grammar. Removed opttypename. commit 3db2ae4c0dc4d528d0d370f44c952fa091902873 Author: Keith Packard Date: Wed Aug 3 18:07:47 2005 +0000 Fix minor regression from argument parsing rewrite; library path was not augmented by script directory as it used to be. commit da66ef35cfb6843dc00628f98b75a1ab62b4ed28 Author: Keith Packard Date: Wed Aug 3 06:34:06 2005 +0000 Fix compiler warnings about signed/unsigned mismatches for StringNextChar (thanks GCC 4) Update for version 2.49 Use new readline (5), update policy to 3.6.2 commit a754a11f6a5820bc605e9a4b7b0fb853cca1e955 Author: Bart Massey Date: Wed Aug 3 04:42:53 2005 +0000 Fix documentation to reflect new argument parsing. commit bc845f39458598677fbfeeaa5fddb1a83d000800 Author: Bart Massey Date: Mon Aug 1 09:35:59 2005 +0000 Bumped the version to reflect the incompatible changes. commit 8a2a964aea5befac5eeb2556a1426b343f900df0 Author: Bart Massey Date: Mon Aug 1 09:20:30 2005 +0000 Big rewrite of parse-args code to work better and be more usable. Will now accomodate Nickle startup. Changes to use parse-args instead of ad hoc argument parsing at startup. Changed key conventions: -e now takes a single argument; -e, -f, and -l can be freely mixed; interactive mode can now have argv through "--"; others? Fixed trivial spelling error. commit 020c956026689f6270bff8556a4aafe91cb1f668 Author: Keith Packard Date: Sat Jul 9 05:46:54 2005 +0000 Set SO_BROADCAST just in case CompileCall with auto_reference == True must not return a pointer to the return type as this function is called from CompileLvalue which is defined to return the type of the underlying object, not a pointer to that type. The alternative is to return a reference type, and I'm fairly sure that's not right as & is supposed to return a pointer type, not a reference type, right? Make sure the nickle headers are installed Add a test for reference types which checks the above change commit b9adbd89e45a1dadfaa6cb5fe2e104fe977c09b5 Author: Keith Packard Date: Thu Jun 16 20:55:50 2005 +0000 Prepare for version 2.48 commit fd2698e8cfc650b7104eacb3ca9f8cd370a2986f Author: Keith Packard Date: Thu Jun 16 20:48:33 2005 +0000 &poly foo() { ... }; &poly x = &foo(); Compiler generated 'Dereference, do_reference' in this call which caused the object referenced by foo() to be copied. Notice case of call to reference value function followed by & operator and elide the Dereference/do_reference pair. commit 832e52f02686f1c084e31ce494be9f8aa2b30c7b Author: Keith Packard Date: Sun Jun 5 01:03:42 2005 +0000 Add Ï€ as an alias for pi Use signed_digit instead of long long commit 15c6509f7c1521604f56a4f0892c5515a5c8e292 Author: Keith Packard Date: Tue Mar 15 19:47:13 2005 +0000 Update for version 2.47 Builtin functions return pointers, not references as reference return values now auto-dereference commit 224acddfb0c71576481b185f81290cdb72fce259 Author: Keith Packard Date: Tue Mar 15 19:23:48 2005 +0000 Check for NULL hash value in a valid hash element. This occurs when a reference to a hash element is made and then not stored through. commit 746f7c0f8cd7bcf20f72cee0c3eceb2d5225c6a3 Author: Keith Packard Date: Fri Feb 25 03:23:06 2005 +0000 Initialize base.func pointer to NULL. reviewed by: Keith Packard commit 17722446533988a648193d1e5e7778f098c99c04 Author: Keith Packard Date: Fri Jan 14 16:58:53 2005 +0000 Functions returning reference type need auto-dereference on return value commit 5ef8945c0e50e59c74f34643675561f85431bc65 Author: Keith Packard Date: Fri Jan 14 05:51:23 2005 +0000 Bump to version 2.46 commit 2ae22162cf0868e7eb38ea0b5511cf6b39f3f44c Author: Keith Packard Date: Fri Jan 14 05:44:00 2005 +0000 Use error_type typedef instead of directly using the type. Use ArrayValue to catch uninitialized values Raise exception on non-float args Rearrange publish/class/type grammar elements to make them prettier Fix ignorenl decrementing to avoid going below zero on syntax error. commit cb48e493587e7ca1419ab22616a922f0081608f7 Author: Keith Packard Date: Fri Dec 24 09:20:48 2004 +0000 Update to version 2.45 commit 373ee99e719720a47366ef7af750ac1acea0c856 Author: Keith Packard Date: Thu Dec 23 22:07:16 2004 +0000 Change foreign API to include mark so that foreign objects can use nickle allocator if they like. Note this is an ABI incompatible change. EOF not handled correctly in '%s' scanf formats commit df0df945509a35253d9aaa50a97ea6450f4d0225 Author: Keith Packard Date: Sun Dec 19 03:01:01 2004 +0000 Look for -ldl, but don't depend on that, instead look for dlopen et al directly. Makes it build on FreeBSD commit 5efa521973ff1699f7dd28d7955026ee0ea6c9f5 Author: Keith Packard Date: Sat Dec 18 07:12:40 2004 +0000 Create and initialize dimension vector in BuildArrayType. commit 8744f0c1f376da6d18dac1663848a36ce2e3f39c Author: Keith Packard Date: Fri Dec 17 05:49:33 2004 +0000 Trim '0's from floating point when no precision is specified commit da4820268b9e3531b4e34c06c02ce39cbaae7b71 Author: Keith Packard Date: Fri Dec 17 02:05:20 2004 +0000 Add support for up to 100 user-defined types for builtin functions Fixed an execution ordering bug which should have caused an infinite loop in some weird file blocking cases. Don't print fractional part if it rounds to zero. Still need to trim trailing zeros from fractions. Best return 1 or the object will not actually be freed. Doc strings with multi-byte chars were broken. Add type construction helpers for foreign libraries commit c0400042d277b792b0c93924027e2229bc27ba52 Author: Keith Packard Date: Sat Dec 11 17:42:18 2004 +0000 Forgot to add actual foreign dataype and interface code. commit 2e8c0f8c168a0fa325b7ee8ca9d2068debec3795 Author: Keith Packard Date: Sat Dec 11 07:46:49 2004 +0000 Expose mechanism for using user-defined types in builtin functions commit a3342f528271ad71feebc29af58ebfec6fc3cead Author: Keith Packard Date: Sat Dec 11 06:02:23 2004 +0000 Add support for dlopen and Foreign datatypes Add block handlers. Change file block handling to use timers only on pipes, not on disk files or terminals. That makes for a lot fewer signals while idle at the prompt. commit a109655693f01e5ca7cf3913ca473c77fdc010fe Author: Keith Packard Date: Sat Dec 11 05:02:53 2004 +0000 ARC4 requires positive keys commit 3ad0eb80cb11269ee883b96cb1496daeb27e1f45 Author: Keith Packard Date: Sat Dec 11 04:53:43 2004 +0000 Round floats correctly for printing. Add double<->real conversion for (eventual) use in C code. commit e24450697185280c445eed3d5a16e18517259399 Author: Keith Packard Date: Thu Dec 9 23:27:13 2004 +0000 Add #include as required for Mac OS X. reviewed by: Martin Hoch commit 67e42ff16101341f3097b119172128feb887a899 Author: Keith Packard Date: Thu Dec 2 05:28:38 2004 +0000 Don't ship non-DFSG examples. Update to version 2.44 Fix debian bits to ignore extra (necessary) COPYING files Mark debian/copyright with all Copyright data commit 90b8c8d2c4bd6da65da2ebe844b9f3ce0c9979c5 Author: Keith Packard Date: Thu Dec 2 04:17:39 2004 +0000 Must reference new stack object before allocating chunks lest the collector run and eat our stack. Zero out previous pointer to make sure the stack is valid in case the collector is called. Declare panic when debugging stack problems. commit 3c256d0557beee4e365bf30a802f945434b12466 Author: Keith Packard Date: Tue Nov 30 19:51:16 2004 +0000 Provide hash function for float representation Implement general purpose crc32 function for hashing Use crc32 hash for naturals and strings Return Zero for representations without hash functions instead of uninit (oops). Initialize datacache to zero before adding as a root (just a cleanup) commit ec2b05cdf7ab5aa024c29de2174fd932a97b01d6 Author: Bart Massey Date: Tue Nov 30 18:34:41 2004 +0000 Made abort() available a bit earlier. commit f99d6443ff0d46482c7f6490c29e2e695fccee1e Author: Bart Massey Date: Tue Nov 30 18:28:21 2004 +0000 math.5c Added lsb() commit a4e8b0bbc63030b0350f102b5e323b3299560d61 Author: Keith Packard Date: Tue Nov 30 05:27:53 2004 +0000 Move AC_CONFIG_AUX_DIR above AM_INIT_AUTOMAKE as needed for new automake version commit 33fee3712fe99792265496b3d6f8349b043cb6b6 Author: Keith Packard Date: Tue Nov 30 05:16:08 2004 +0000 Call to panic had wrong arguments and caused a segfault. commit 6bff6e3cf421c92b40ba732c95a76d7889d73530 Author: Bart Massey Date: Tue Nov 23 05:02:07 2004 +0000 Change dims() to return dimensions in order consistent with array defns, setdims(), etc. Bug discovered by Jeremy Greenwald. commit a7aa5a61aa6ba5ec5f9b35299450f8b1b46ede23 Author: Keith Packard Date: Fri Nov 19 06:53:05 2004 +0000 Change copyright symbol encoding from Latin-1 to UTF-8 Catch negative array dimensions. Bug discovered by James LaMar commit 30ad9204bf1ca9ce94e49d1ca5a2e8f4687cc5c9 Author: Keith Packard Date: Mon Nov 15 20:16:38 2004 +0000 Add a bunch of copyright and license information commit 260c59910515526885a2866eb585c91559f9ec48 Author: Keith Packard Date: Mon Nov 15 19:58:39 2004 +0000 Lost **= somehow. commit fa88ecbb671c881efa9277a7265aa2443767852d Author: Keith Packard Date: Mon Nov 15 19:32:43 2004 +0000 Implicitly initialize resizable arrays to zero-length array. commit 14ceda097f2762d6cb71c463d2862f4ef2c06078 Author: Keith Packard Date: Mon Nov 15 19:31:41 2004 +0000 Add licensing information to some of the examples commit fc8931ed39d990a12f610f7a36d210f5dcd0f5c8 Author: Bart Massey Date: Mon Nov 8 08:53:24 2004 +0000 inchars() had the arguments to index() backward. commit ae524ce01f9724dc61e0b89c01f5ad2e65bac8ac Author: Bart Massey Date: Mon Nov 8 06:32:10 2004 +0000 Forgot "public" in previous checkin. commit e7faea2ec37ebe31bbb726b263f5a4bc2ad5e79e Author: Bart Massey Date: Mon Nov 8 06:28:38 2004 +0000 Add shiftn(), shift(), chump() functions. commit 7e5d477b1aa02824b9aa62f52d7c5faafa0daaf6 Author: Bart Massey Date: Mon Nov 8 06:06:44 2004 +0000 Add wordsplit() function. commit 7ab81bf7a4ed461875f5271e6156c4126887840d Author: Bart Massey Date: Mon Nov 8 06:01:51 2004 +0000 Failed to commit the ChangeLog long ago. Oops. commit 15732e5f578d9f91899406cc7eba4cd3b13d5bb1 Author: Keith Packard Date: Wed Oct 20 06:17:55 2004 +0000 Permit any non-ASCII character in an identifier. Better discrimination requires a better lexer generator as flex can't deal with UTF-8. commit 3d8ec7976f93b166ce1fc715678e0d9f7df1f01e Author: Keith Packard Date: Sun Oct 17 23:34:34 2004 +0000 Add POW2 and POW3 operators Add several non-ascii character equivalents. Make \r be white space (and ignored) Remove spurious semi-colon from ALLOCATE definition. commit 66664688212feb0cc4a0dc4f71555a63af9c5d45 Author: Keith Packard Date: Sat Oct 9 22:49:07 2004 +0000 Permit multiple namespaces in import statements commit 1209101c78a08c8d044729dce5575c6e1fc56f9a Author: Keith Packard Date: Sat Oct 9 22:38:28 2004 +0000 Optimize shifts of small ints by small ints commit ead913203756ec040f51289f9b2f69f95c10bd8b Author: Bart Massey Date: Fri Oct 1 19:58:54 2004 +0000 Compiler dumped core when trying to create a variable of incomplete structure type. commit 71ad1daab5b1aa1d5bb89eda8ab60520fbe98ed2 Author: Bart Massey Date: Wed Sep 22 16:51:31 2004 +0000 Made try blocks as well as try statements not create a new scope, for convenience in using try the way it is intended to be used. commit 03877252224598811fc695d41835e683ef0035ef Author: Bart Massey Date: Wed Sep 22 07:01:10 2004 +0000 Added operator precedences to resolve 3 of 4 shift/reduce conflicts in the grammar. Make sure builtin.o is always rebuilt, so that the "build" variable is kept up-to-date. commit a1cae8f4499722a9962b96c4013490163a7ed451 Author: Keith Packard Date: Sat Sep 18 05:04:17 2004 +0000 Resizing arrays to zero elements would cause segfault when adding to the array commit 38c1dc1af8ce6897483b3a96e0df603a2b1226f4 Author: Bart Massey Date: Fri Sep 17 08:05:16 2004 +0000 Fixed to include soln to second puzzle. Learned a lot about Nickle doing this! commit 497b4160563e820dd0799cf1fb9dcb69d06fc445 Author: Bart Massey Date: Fri Sep 17 06:57:24 2004 +0000 Fixed to return proper answer :-). Learned a lot about Nickle on this one :-) :-). commit 1323796bad6f424ab3a0e161ca559157c504365f Author: Keith Packard Date: Fri Sep 17 01:16:05 2004 +0000 Avoid having leading 0's convert in octal. Reformat to reasonable line lengths. Note that this still gets the wrong answer. commit e1585ca40e498eba3151d89feac68ee7726c25ea Author: Bart Massey Date: Thu Sep 16 17:53:48 2004 +0000 Added Google puzzle solution. Needs to be cleaned up after Nickle bugs are fixed. commit ee82a7b31b94ee2cb95fb1b9cda315d5eb69705c Author: Keith Packard Date: Mon Aug 23 00:42:06 2004 +0000 Base is allowed to be zero (in which case it uses 10). commit 0f1cb525cfa9d3aea1e89c41f906a3269cdb74a2 Author: Bart Massey Date: Sun Aug 22 23:45:32 2004 +0000 don't allow bases smaller than 2 in do_File_print(). Closes bug report by Clem Taylor . commit 2712256f8ce211137390e5aa26eebeb5147b46bf Author: Keith Packard Date: Fri Aug 13 04:40:18 2004 +0000 add clean-local to remove nickle.1 and nickle.spec Update to version 2.43 commit c91ab5248d3abca55d2da665e2eb0e78d6775a28 Author: Keith Packard Date: Tue Aug 10 17:45:40 2004 +0000 Clean up new allocator implementation. commit 92cb0a21ad5d1898668e2e23af807d8b0439fb74 Author: Keith Packard Date: Tue Aug 10 07:39:55 2004 +0000 Remove avl tree code Rewrite garbage collector to place reference bits right in each object by stealing the low bit of the type pointer. commit 9dcbb32471a64d9ac028838a7d580be84ffcd7d2 Author: Keith Packard Date: Wed Aug 4 18:38:53 2004 +0000 Update to 2.42, noting significant changes. commit a9ae70bd7116bc41a10b4cde746935f7ea92169a Author: Keith Packard Date: Wed Aug 4 18:19:28 2004 +0000 Bump version to 2.42 commit 3adb14d7b15577163b376546986596ab0a685b3e Author: Keith Packard Date: Thu Jul 29 00:23:33 2004 +0000 Unlimit stack so that GC can recurse forever Add skiplists Fix precedence of ** so that ++x**2 works Make sure hash element in table is valid before comparing Track newlines in files better. Add comments about x value for each test. commit 07b97b9bbabeb98422a1bf5b73475edf6a855504 Author: Bart Massey Date: Thu Jul 22 19:42:06 2004 +0000 Be able to mark a box uninit (for shift()) commit 1e0330c88654abb90d946abffe985e9025df7e4e Author: Keith Packard Date: Fri Jul 9 18:48:35 2004 +0000 Missed a few pointers in mark code A nasty one -- jumping into a continuation that is referenced from the thread object itself (catch) drops the reference to the continuation before finishing the jump. Combined with careful MemCollect timing, this can break the resulting thread state. Add assertions to make sure the stack pointer is in range Deal with non-blocking file descriptors commit 0afa63caad9da7200b8c837ee22d6112f1a1b899 Author: Keith Packard Date: Wed Jul 7 07:32:47 2004 +0000 Parallel catch blocks are peers, not nested. This affects how FarJump execution inside them happens; in particular, all of the peer catches are unwound before the handler is invoked so all jumps from inside use the same NonLocal data structure. Also added yet more debugging to continuation execution. Allow 'enum switch' commit e4d2f4ffaa0f18bab62f08598b96f14bc61758b9 Author: Bart Massey Date: Wed Jun 23 09:00:46 2004 +0000 Added rudimentary SVG output namespace. Added example: Floyd-Warshall all-pairs shortest-path algorithm. Added example: program illustrating both of above. commit 53b88095daec0da5ad7bdf4791c2b35f4721c5aa Author: Keith Packard Date: Sat Jun 19 19:56:45 2004 +0000 Tail call to lonjmp should not pop frame Make 'g' format print only the declaration, leaving 'v' printing the definition as well. Clean up continuation debug code to include call trace and adjust for changes since the last time it was used. commit 697b3f3d1abbf7c62c9cc6488a5c13aa7a3f17dd Author: Keith Packard Date: Fri Jun 18 00:30:33 2004 +0000 Add commands to upload release files to nickle.org Note changes since last debian package (2.38) commit 94e2b5090811d32a6f1776fb9711cd9836dc7cfc Author: Keith Packard Date: Thu Jun 17 23:53:41 2004 +0000 Generalize the previous fix to handle the remaining cases, including names. commit 6ec547f14ec5bca43bad8b1d19d59667a2ef64c2 Author: Keith Packard Date: Thu Jun 17 20:46:09 2004 +0000 Update conflict comment to note new reduce/reduce conflicts caused by accepting ** and && as unary operators commit f29f0e8ac135a917b908abf965c3888b8d5c7c1a Author: Keith Packard Date: Thu Jun 17 20:30:47 2004 +0000 Handle nested & in Lvalues with auto_reference so that &&7 works. Make ** and && work as unary operators. Get CodePtr out of CurrentFrame so that execution can refer to frame contents up the static link. commit 2ad5e719500d4bc1692a4e27db117eaeee2fc080 Author: Keith Packard Date: Mon Jun 14 06:58:32 2004 +0000 Don't open /dev/null until needed for mkchild commit 95f0b405f264ab5719e22c1ddcc2759b1233ef14 Author: Keith Packard Date: Mon Jun 14 06:43:33 2004 +0000 Add CVS Header and Copyright Clean up function doc comments Use 0.{3} for 1/3 Remove typeGroup/typeField Add (#if 0'd out) TypeIsCotype while we figure out how its supposed to work. commit 4d6ea5264c7da9f47edade95b1bebc1561f5cb8c Author: Keith Packard Date: Tue Jun 8 09:30:54 2004 +0000 Add doc strings to all functions and exceptions. commit a6efac7fc662cb1f49bbfb88a0007ef37e0b931f Author: Keith Packard Date: Thu Jun 3 07:46:23 2004 +0000 Fix fix for crash with empty array/hash initializers (really do need 'null' node in expr tree) commit 86269e10bb1eafc2e79e257cf1e90a579eff8e91 Author: Keith Packard Date: Thu Jun 3 07:29:17 2004 +0000 Fix crash with empty array/hash initializers commit db682242a9c10dce96d3f60b125ce2af3f4ebdde Author: Keith Packard Date: Thu Jun 3 06:55:24 2004 +0000 Eliminate 'primary' non-terminal. Add ENDFILE token to ensure files end at top level. Change NL handling to allow NL after simple declarations Allow 'func' values to not require SEMI termination commit 3c3c8ead1ef5417a91bffb1e4e7786767b25e237 Author: Keith Packard Date: Fri May 28 06:41:34 2004 +0000 Build nickle.1 and nickle.spec from Makefile where VERSION is set Update to version 2.38 commit b4da997fd2b43fbe2e380a5c8753c65850215ce5 Author: Keith Packard Date: Fri May 28 06:02:22 2004 +0000 Update for 2.37 commit 21ab8f0b13ef1fa5104810a723641b7d891432a1 Author: Keith Packard Date: Fri May 28 02:58:14 2004 +0000 Overflow detection from small integer add/subtract was broken. commit bbc98790df5ca0cffc02d2ff7dca6d24ed3686fe Author: Keith Packard Date: Fri May 28 01:26:38 2004 +0000 Ceiling, not Round for negative left operand in shift right commit fb29c84f5362ceca620bc3d8a961ed4bf4716af8 Author: Keith Packard Date: Fri May 28 00:36:41 2004 +0000 Update .cvsignore files commit 5980b01903b27e524dd8101d29d51bea3bf8287a Author: Keith Packard Date: Thu May 27 23:30:55 2004 +0000 Bogus effort to truncate compliment answers resulted in broken IntegerLand operation commit b6d2f0c23be55a5522c1d5a364fd8510af1676aa Author: Keith Packard Date: Wed May 26 08:59:23 2004 +0000 Distinguish between array types of static variables and initializers within static scope -- dimension storage is different. update to version 2.36 commit 84b452afa8411147e07993d2e6edb77091f3b36c Author: Keith Packard Date: Wed May 26 08:11:10 2004 +0000 Clean up examples to not try and run themselves as scripts commit 5e1a04a2538b970ea0f89c7d4a4b3d1d921bd111 Author: Keith Packard Date: Wed May 26 08:01:42 2004 +0000 Array dimension values are always local in static initializers Clean up examples so they all work again. Remove old files. add 'scanf' to top-level namespace commit 0860046f9754d93df03804adf883b63d0b39c04c Author: Keith Packard Date: Wed May 26 05:54:02 2004 +0000 Add version-sh.in commit 2f3f76ff4f7cbf95203200bd0844121ebe8cafdf Author: Keith Packard Date: Wed May 26 05:53:31 2004 +0000 Move version 2.35 mark in preparation for tag commit 8044204a5f7256a83cbb531ea1f96009ba340c36 Author: Keith Packard Date: Wed May 26 05:52:53 2004 +0000 Completely ignore VERSION support from configure and grub it out of the ChangeLog using $(shell) from the Makefile. commit 4eae4e6c1fe5ed1b40a48d12b275a9303365af45 Author: Keith Packard Date: Wed May 26 03:35:28 2004 +0000 Add comments for version 2.35 commit efe734b2f7e4a84694afd635158b288bb3188957 Author: Keith Packard Date: Wed May 26 03:13:06 2004 +0000 Allow &rvalue and have it automatically box the value. commit 58877a1554c06a939e8926e479e0912d254c72ad Author: Bart Massey Date: Sun May 23 06:01:51 2004 +0000 Make version.h from ChangeLog now. Will require ChangeLog version number maintenance, but hopefully will mean it gets bumped now. commit 0b9f90525fbf3363bc185a6adbdf2aad722c840a Author: Keith Packard Date: Fri May 21 06:10:34 2004 +0000 Ok, so the previous change was incomplete. Restructure CompileLvalue so that the processing of ampersands is unified. The unified rules were changed so that the value of a reference to a reference type is converted to a pointer instead of a reference. That seems confusing enough. Basically, it allows: &int r; *&int pr = & & r; commit 00836f1153e7612bdfe88dd124e653f16ce51a6c Author: Keith Packard Date: Fri May 21 05:21:13 2004 +0000 When compiling '&' expressions, if the operand is of ref type, the result type is the referenced type, not NULL. commit ebcff0ac30a9364f20ddf0833262f3b068263541 Author: Bart Massey Date: Thu May 20 09:51:55 2004 +0000 Bugged previous code. commit ce0dba4cf4aa8cda5573f069295063ec2b337508 Author: Bart Massey Date: Thu May 20 09:37:38 2004 +0000 Two-argument for() loop is legal now (no init expr). commit d09711c01d7e42e17a6e1e27d57d71cb921915e8 Author: Bart Massey Date: Tue May 18 06:26:03 2004 +0000 New argument parsing library. commit c1839e070adea859b62ea87892b19f612d86939a Author: Bart Massey Date: Thu May 13 22:17:20 2004 +0000 Rebuild dequote() and parse_csv() to handle quote contexts using generator functions. commit 9053f3605a5acbc5dea399cd84e12c461f3281a0 Author: Bart Massey Date: Thu May 13 21:16:52 2004 +0000 Rename is_defined() to is_uninit(). commit 04ecabb7cf3688d5cc04170748bef0de4a9bbf73 Author: Bart Massey Date: Thu May 13 08:21:44 2004 +0000 Added boolean is_defined(&poly) commit f70b1380317e3d5e427a1d0e02c57a08416b5ed3 Author: Keith Packard Date: Fri Apr 23 16:48:12 2004 +0000 Turn each test into an assertion which exits with an error on failure so that 'make check' validates the interpreter commit 63ad3b77deb1061de605eefe270df24e6b982df2 Author: Keith Packard Date: Mon Apr 19 03:13:39 2004 +0000 Label profile times in ms profile tracking code was quite busted, generating largely random numbers. commit 1ab2fb73bd8f6872b900454d254b06c37079b3c1 Author: Keith Packard Date: Fri Apr 16 21:41:52 2004 +0000 Change string representation to counted rather than null-terminated. Allow nulls in the middle of strings. Trap strings with nulls passed to the operating system. Raise exception when attempting to access the null which is stored off the end of the string. commit 15537e7d511f278af79b5cbd5de4dc7402fb00bc Author: Bart Massey Date: Fri Apr 16 18:19:08 2004 +0000 Last field wasn't being chomped and dequoted. commit e9f5e2c52b83e79145a009ba117c5853726b5aad Author: Bart Massey Date: Fri Apr 16 18:09:26 2004 +0000 Fixed unclosed string detection case in parse_csv. Fixed unclosed string detection in _dequote. Fixed function name in parse_csv exception msg. commit 4a0f0f4eeacc71c7ee080e8795990084b645a711 Author: Bart Massey Date: Fri Apr 16 09:34:30 2004 +0000 Allow a zero-length substr() at the end of the string. Clean up a bunch of substr() references. Remove accidental redundant code. commit c294b5f48f338f316cb1144a80a7c67a07a83140 Author: Bart Massey Date: Fri Apr 16 08:24:58 2004 +0000 Handle emitting backslash in quoted string properly. commit adcf8dcadce46d9dab98c6a402baaa5491c33d4c Author: Bart Massey Date: Fri Apr 16 07:46:02 2004 +0000 Added new string functions _dequote(), dequote(), inchars(), readcsv(), and associated machinery. String depends on Ctype now, so reordered. commit 96eae7a6a230527128675c9f78866f485af577b0 Author: Keith Packard Date: Fri Apr 16 06:06:01 2004 +0000 Fix warning about uninit 'good' commit c96735976f17d7860af404c43c8d7d4a9e3e846a Author: Keith Packard Date: Fri Apr 16 06:02:07 2004 +0000 Always regenerate configure in case version.m4 changes Update to autoconf 2.59 syntax Update to version 2.31 commit cb7dd3f2fd90351be179131a5e73dbaa1cb9839d Author: Keith Packard Date: Fri Apr 16 05:26:45 2004 +0000 Change resizable array representation to be a vector of single entry boxes. This allows clean semantics for array shrinking -- outranged elements still have storage, but are no longer accessible through the array, even if the array is subsequently enlarged. Change File::end semantic to actually peek at the file and check whether the next read would return EOF. This seems like the only useful semantic here. Was using ArrayDims instead of ArrayLimits white space change Must propogate error when appending objects together commit d3ff5a705869ba7f1d70a659ce2d38dbce5519d7 Author: Bart Massey Date: Fri Apr 16 03:37:12 2004 +0000 Allow identifiers to start with "_". commit ca9219b31470771f41b00ffc053e2664f04c0e73 Author: Bart Massey Date: Thu Apr 15 05:37:36 2004 +0000 Make hash table grow when full on get of default value. Clean boundary case in test in HashSet. Keithp really did this. reviewed by: Keith Packard commit c235715f7e31e62b8a9c449b2df8abc659607713 Author: Bart Massey Date: Sun Apr 11 09:33:25 2004 +0000 Added split() function commit 9264194e2386bfd56685ab68b8d2bed664177448 Author: Keith Packard Date: Sun Apr 11 07:02:12 2004 +0000 Add AM_MAINTAINER_MODE Update debian to 2.30 Update version to 2.30 commit 0306de21d12ab1289a58ec710f88e646df247f15 Author: Keith Packard Date: Sun Apr 11 06:43:19 2004 +0000 Primitive docs for resizable arrays and hashes. commit 051c59c3cdf9505fdf39e29ba6025a780c274690 Author: Keith Packard Date: Sun Apr 11 06:27:11 2004 +0000 setdims arguments need to be inverted to match array dimension order for ArrayResize. commit e608d3fb1a5d986f235aa1b26d35333d851142be Author: Keith Packard Date: Sun Apr 11 06:20:34 2004 +0000 Ugh. Array shrink causes problems with references to elements now outside the box boundaries. "real" fix is hard, so here's a kludge to keep the interpreter from crashing and (perhaps) prevent the error from propagating through the application. commit 916ecac2621ee3ecd34f873c58d9f4f26bc42c08 Author: Keith Packard Date: Sun Apr 11 06:06:52 2004 +0000 Make value distinction between resizable and unresizable arrays. Types now use '...' for resizable arrays and '*' for unresizable arrays of unspecified size. Also fixed a bug in the implicit array dimension computation for multi-dimensional arrays -- the dimensions were compiled in the reverse order. commit 22979ba5eec5cb6a3e9991e61a971ca794b774cd Author: Keith Packard Date: Sun Apr 11 02:30:22 2004 +0000 Add default hash table values, and initializes for same. Oops. Poly couldn't be a ref commit 4c0748024a659f99000b5c5a2039f7930f97355a Author: Keith Packard Date: Fri Apr 2 07:18:59 2004 +0000 Mark debian bug 241417 closed commit bf1726f44f951f9a26bf4e6d63ed4a569bf2e4c6 Author: Keith Packard Date: Fri Apr 2 07:06:17 2004 +0000 Update to 2.29-1 More pointer casting magic for gcc on ia64 commit 48514e9f806e60741ae00aa43f6cb66e2b06da7c Author: Keith Packard Date: Thu Apr 1 22:06:01 2004 +0000 Ouch. NaturalRslInplace was not checking argument for zero commit 5e38946735ffd2de0e788a19c0f16277837ab6eb Author: Keith Packard Date: Thu Apr 1 19:49:56 2004 +0000 Mike Harris provided a new .spec file. Move .spec file to .spec.in so that version can be set automatically. Add 'rpm' target in the Makefile Bump version (now 2.29) reviewed by: Mike Harris commit 54e83da04b60c93077271efc6582804d1cb01831 Author: Keith Packard Date: Thu Apr 1 19:47:39 2004 +0000 Add casts to avoid warnings where sizeof (int) != sizeof (void *) commit 5d2cf2dda0e03c263fb645b911bdb0a7cd2362a8 Author: Keith Packard Date: Thu Apr 1 15:48:23 2004 +0000 Debian bug 241417 Catch File::open_error when loading files and print reasonable message. exit(1) immediately if an file or library from the command line fails load. commit 0a4a65dce408176ae254845442e0dc867d069305 Author: Keith Packard Date: Wed Mar 3 03:09:54 2004 +0000 Separate build dependencies with commas commit c9115fb18d3c9dbf714c7018dd8065a928a819c2 Author: Keith Packard Date: Fri Feb 27 05:53:12 2004 +0000 Fix debuild stuff to always recreate tar files and share setup Update to 2.28 commit e99285011aaabba77432f812c6d2f248394ac2fd Author: Bart Massey Date: Fri Feb 27 05:13:46 2004 +0000 fixed buglet, remembered to bump version commit 3c2a2d1387d2da45a9864ef759a3983eecefb3a7 Author: Keith Packard Date: Fri Feb 27 05:12:24 2004 +0000 Oops, lost package signing commit a87b0ee45855189b13c8a8db16c58c28c965fee0 Author: Bart Massey Date: Fri Feb 27 05:05:18 2004 +0000 Added true integer logarithm commit 5c00e71fed2bf85de3aff7a671b5d241248a5d6c Author: Keith Packard Date: Fri Feb 27 04:49:07 2004 +0000 Add separate targets for signed/unsigned packages commit 95eae85ab4555a245da9704117a277ef821a45b8 Author: Keith Packard Date: Fri Feb 27 04:44:39 2004 +0000 Add DEBUILD_OPTS to pass options from make command line commit 50b2bca9c29c545cb253a6b1e208bbf4ef40e5b8 Author: Keith Packard Date: Fri Feb 27 04:13:55 2004 +0000 DIE DIE DIE commit 68c3cdcbf23f77d93c0410ed62396ae699cb347f Author: Keith Packard Date: Fri Feb 27 04:13:08 2004 +0000 Work harder at getting rid of builtin directory commit 6843340b341555e99b6eee66e4be5a4da0a02a9e Author: Keith Packard Date: Fri Feb 27 04:10:25 2004 +0000 Get rid of builtin directory contents commit 3b525bf3523fe4c1f660e7642fa28427ebeb31a6 Author: Keith Packard Date: Fri Feb 27 03:50:16 2004 +0000 version.h has moved Every file Change copyright to 2004 commit 84fe9b5d9174a06b84da968af159c19f919c3cb6 Author: Keith Packard Date: Fri Feb 27 03:19:59 2004 +0000 Clean up debian build instructions to make non-native package that conforms to policy. Change version.h build instructions commit 476b52500137d3b474d847d2ab02813417c57626 Author: Bart Massey Date: Fri Feb 27 01:40:58 2004 +0000 Fixed some initial build bugs with update-version usage. commit b41763ef9a39f5dc71a2d97c3d1512a69444461c Author: Keith Packard Date: Mon Feb 16 07:41:41 2004 +0000 Move builtin sources to top level directory so that make works right -- leaving them in the subdir meant that yacc/lex wouldn't get run at the right time. Use unsigned bitfields to make :1 values easier to read in gdb Prototype more functions Switch standards version to 3.5.10 to make lintian happy Don't install .cvsignore files in docs commit 13f5fc742e35ec27d826fa748f22ec6a20da2905 Author: Keith Packard Date: Mon Feb 16 00:15:05 2004 +0000 Fix EXTRA_DIST. Remove automatic version number updates. That should be done by CVS. Make separate build dir work. Take over debian package creation. Add 'D' format to print out 64-bit values (for tick counts) commit 3fdfbf7c9e930d5be186b990064d69d0636f6ae2 Author: Bart Massey Date: Sat Feb 7 00:46:58 2004 +0000 Made printf format strings of the form %0* work properly. commit 89d2791a9d04b8928522a30d194e76e052c8325f Author: Keith Packard Date: Sat Jan 17 15:32:15 2004 +0000 box->replace was uninitialized commit 1b0f8ea96d0a07b190ff13ee7834c14d5e7f31a8 Author: Keith Packard Date: Sat Jan 10 06:20:02 2004 +0000 Switch fds to nonblocking for connect/accept calls commit 6d62545e582343a4f5daa1ef5c3f6bd476aa272a Author: Keith Packard Date: Sun Dec 14 07:45:01 2003 +0000 Use canonical type to see if ANONINIT is an array. Don't need to call TypeCanon before recursive CompileImplicitInit call. commit 4ca53b50077ead73d48d535fe138e5561cf3ff2c Author: Bart Massey Date: Thu Dec 4 07:04:18 2003 +0000 Fixed weird missing semicolon. commit 69e510554cf1d6c6968c885a1635c637d39a0c65 Author: Keith Packard Date: Sat Oct 25 19:00:33 2003 +0000 Use automatic dependencies, fix up yacc stuff a bit. Replace autogen.sh with short version (this change was lost by a mistaken commit to the wrong repository...) Couple of valgrind problems: Initialize branch.offset field in all instructions so that CompileIsReachable can blindly fetch them before the real offset is set. Set the static link offset to zero for names contained in declarations; it was otherwise uninitialized. commit 4fdec2cf1458caebdd6d0ad21ea13f4b3209e7ad Author: Keith Packard Date: Sat Oct 25 18:37:08 2003 +0000 Eliminate bogus explicit dependencies from Makefile.am Eliminate need for gram.h in builtins Move #include version.h from builtin.h to builtin.c commit e6380e1595df113d4fe481ab08eff689110957eb Author: Keith Packard Date: Fri Oct 24 01:30:44 2003 +0000 Strings are separated by whitespace in scanf commit cce0c479595883cba762ed6c29c23513738e32fc Author: Bart Massey Date: Wed Oct 15 19:28:15 2003 +0000 Fixed missing dependency in auto-version stuff. commit d573c9234fdbf4ef46abadc44e2b2d11eccbf855 Author: Bart Massey Date: Wed Oct 15 09:16:23 2003 +0000 Installation instructions for novices. commit 49a79a1d9c3a0776588697b94f482ad5de37b3bb Author: Bart Massey Date: Tue Oct 14 01:43:55 2003 +0000 More fixes to make auto-version work. commit 4076cffdcddad30ce9749faed34b97952bafb2a2 Author: Bart Massey Date: Tue Oct 14 01:20:29 2003 +0000 Experimental changes to auto-increment the version number. I can't stand it any longer :-). commit 000b6e5f465fdbc893662b3e8bab0e3f77bc5bb2 Author: Keith Packard Date: Mon Oct 13 18:44:24 2003 +0000 close errpipe on fork failure in FileFilter commit 983a5752ecb0949aad6750f23044dd8b7d18229d Author: Keith Packard Date: Mon Oct 13 18:43:52 2003 +0000 Poll for read blocked (pipes busted on Linux) commit a7f2ef3b4512bca85d7bab45c528a76baebc93f4 Author: Keith Packard Date: Mon Oct 13 18:14:51 2003 +0000 Leave file descriptors blocking. Check with select before read/write. This allows nickle files to be shared with subprocesses cleanly. It does introduce a minor race if nickle and another application attempt to read at the same time, nickle may select and then try to read which may in fact block. It's a small window, so I'm not going to worry about it, the benefit of leaving fds blocking is too great. commit 09fc02f6c49e6eadc99529c4c115f7ae77086174 Author: Bart Massey Date: Mon Oct 13 06:15:24 2003 +0000 added mkchild() commit 3ad6981a518291cccc1f04bae30f4543dbbbe311 Author: Bart Massey Date: Mon Oct 13 05:48:57 2003 +0000 Cleaned up File namespace substantially. In particular, added file.5c to hold non printf/scanf File code. commit 06801de6f5d43ba4180568481cc861fdb5d5e2a0 Author: Keith Packard Date: Mon Oct 13 05:08:41 2003 +0000 Use SIGCHLD to trigger wait commit 7feef2e8b962ef19308247554e3f8ed29ffd47e3 Author: Bart Massey Date: Mon Oct 13 04:33:36 2003 +0000 Replace pipe() builtin with filter() and mkpipe(). Yes, the name mkpipe() is a poor choice, but didn't want existing apps to be confused about what happened. Will implement popen() atop these primitives eventually. commit e7dc87f792f447bb0b66e8831f6132c999fc7044 Author: Bart Massey Date: Sat Oct 11 09:50:05 2003 +0000 Use close-on-exec to make Popen fail in parent if exec fails in child (thanks Keith) commit 6b50480539b821d16345e865a3241a23ada21282 Author: Bart Massey Date: Fri Oct 10 05:00:49 2003 +0000 The temp value in the shuffler was int, but should have been poly. Oops. commit 0a0f475d0f80ae364fea4761ec57e89d20906aaa Author: Keith Packard Date: Tue Sep 16 01:18:30 2003 +0000 Speed up detection of large fractional part in rational printing. Speed up rational power by doing only a single GCD commit ee665eb83e1c46a533c7f8032d760a6f8af01fbc Author: Keith Packard Date: Fri Jul 25 23:47:54 2003 +0000 Hash tables map keys to storage. Compile array dims in the right order commit a1b1d9e8d6814793891fafe7d09846adb58b676a Author: Keith Packard Date: Thu Jul 24 18:10:19 2003 +0000 Array types include dimension expressions. These are now evaluated where the type is declared and stored in the appropriate context. OpGlobal/OpLocal/OpStatic now all changed to not point at the symbol table and instead point directly to storage. Should be faster, needed to reference array dimension storage created above. commit b2b348c113a7907bd260f554bf3ad2185d5b8e67 Author: Keith Packard Date: Tue Jul 22 04:32:36 2003 +0000 Eliminate bogus function layer in Hash API. Switch hash initializes from colon to double arrow (=>) Fix hash printing to produce re-parsable output Make HashHash compute reasonable hash values Add hash_key builtin commit 1a49831f089136c4fa29d717b96b064917ab7391 Author: Keith Packard Date: Mon Jul 21 22:22:11 2003 +0000 Add hashes, fix subscript type printing commit 6f6cc699a39b6fe61424bff2fb0641d7bd8f8b7e Author: Carl Worth Date: Fri Jul 11 16:27:34 2003 +0000 Replaced ad-hoc autoconf version check in autogen.sh with AC_PREREQ in configure.in commit bef226701845873735e906001e009deb35d42ec6 Author: Carl Worth Date: Thu Jul 10 17:43:53 2003 +0000 Updated .cvsignore commit 06a28ebe1ccbb3eff3f2df06a1554e32423f7859 Author: Erin Chapman Date: Mon Jul 7 16:12:48 2003 +0000 fixing an error in autogen.sh commit 864520a6b4b1106e5575aa221cb6135ab485bd44 Author: Erin Chapman Date: Mon Jul 7 16:03:33 2003 +0000 In autogen.sh, bart's test for the version of autoconf had a >= instead of a <=, so I changed it. commit dd69efb24ffcf1a4add6f0437f727e501d4e8c1e Author: Bart Massey Date: Mon Jul 7 02:36:24 2003 +0000 Make sure that stale autoconf doesn't confuse folks commit 7e0bf17b2b2a338b5de5dcb4b901ca43a48bba10 Author: Bart Massey Date: Mon Jul 7 02:24:47 2003 +0000 Make the debug trace depth user specifiable commit 158d8b40ef604c2f9e95a4dc59348014eecdf18b Author: Keith Packard Date: Mon Jun 30 04:53:43 2003 +0000 Tag arrays as resizable/fixed-size. Add setdims and setdim builtins commit e775c0d4e1955a3991542985b034290f66c1a1c4 Author: Keith Packard Date: Sun Jun 29 22:31:22 2003 +0000 Dim function returns logical rather than actual array sizes commit 6fede5c18bb73352074b9622c25327332ed804b8 Author: Keith Packard Date: Sun Jun 29 18:16:20 2003 +0000 Eliminate CDEBUGFLAGS as useless commit 7d0acd89486773bd0e182ef2be5f281c23ade48c Author: Keith Packard Date: Sun Jun 29 18:15:27 2003 +0000 Set data type after reference in allocate to avoid walking uninit structs commit 54ba2ee8cb67169a56bca0bf72e14a1b33785587 Author: Bart Massey Date: Fri Jun 27 08:18:29 2003 +0000 The claim that libtool 1.5 is necessary appears bogus for Nickle, and libtool 1.5 is not in Debian yet. commit 55a59017088ac5d8504e8a9b749216c5f3827a31 Author: Keith Packard Date: Thu Jun 26 11:18:22 2003 +0000 Make sure continuations are initialized in the right order to preserve invarients tested in ContinuationMark commit 8ce21c86f7136a937ac6337455eb1a96a5d8d759 Author: Keith Packard Date: Thu Jun 26 08:59:10 2003 +0000 Add File::reopen commit 2ca9220c73abb2bc89a33aa6702e7f0f7e353fa6 Author: Keith Packard Date: Wed Jun 25 19:52:50 2003 +0000 Switch to autogen.sh and force use of automake-1.7 et alia commit 0f3e8830651be5f0a7ec5ecef2d60b8636603720 Author: Keith Packard Date: Wed Jun 25 19:49:14 2003 +0000 Add stack trace to unhandled exception message, reformat message to reduce wasted space commit 6fc2bee66bf098cbfe7ff71249e206d8337f3098 Author: Bart Massey Date: Wed Jun 18 02:49:44 2003 +0000 Make the build environment compatible with reasonably modern autoconf, suppressing random warnings. commit 478bc51cf2da08ae01c41929e11691dcdfad84e9 Author: Keith Packard Date: Tue Jun 17 17:15:46 2003 +0000 Make array output match lexer format commit 346a170915c453c79dc25346bbf72f1b8488e260 Author: Keith Packard Date: Tue Jun 17 17:10:15 2003 +0000 Set type for anonymous poly arrays commit 287254158b2ea1c3f919303b54370e6c69dd4d58 Author: Keith Packard Date: Tue Jun 17 16:49:40 2003 +0000 implicit Debug::done on EOF commit 877d2dfe40289703fb1efeba98448e1c476a734b Author: Bart Massey Date: Tue Jun 17 03:53:14 2003 +0000 Added vprintf() commit 3aa139b60989b0994ab2a097943987951dfeb9a1 Author: Keith Packard Date: Wed Jun 11 05:02:42 2003 +0000 Add a couple of network address conversion utilities commit e66f685102b4d37788c5a124e71908d053fca565 Author: Keith Packard Date: Wed Jun 11 05:01:56 2003 +0000 Allow declarations to be lvalues. Typecheck printf arguments against format string. Do correct base conversions in scanf for b, o, x formats. Include only appropriate characters for each numeric scanf format. Rename Sockets namespace to Socket Add Socket::gethostname and Socket::getsockname. commit 382b9329d849c371f3ecbbb23828dc4f5c976aba Author: Keith Packard Date: Tue Jun 10 00:42:46 2003 +0000 Make nickle exit with error status when the last thread dies with an exception commit bb6e5e8a796f9578a543da22537887ac6f06e81c Author: Bart Massey Date: Mon Jun 9 20:49:09 2003 +0000 Refuse to quietly live without -lreadline during configuration. Clean up horrible acinclude.m4 formatting. Make autoconfigure.sh not tell you to type make if configure fails. commit 2c27f29a1b248bc02693fd1bef153f742da922d1 Author: Keith Packard Date: Sat Jun 7 18:21:19 2003 +0000 Fix up debian package build and make dist commit 1e39963352cb726a737c84d2eed45b9d46bfc0a9 Author: Bart Massey Date: Sat Jun 7 00:13:32 2003 +0000 Fixed introductory sentences. commit 971d8f520b2d968466d2dc04f3c18fd9e5ffdefd Author: Robert Burgess Date: Fri Jun 6 22:31:35 2003 +0000 Added comment by null statement in statements section. commit bb6f6df1a2e74e6e95efb0b22f9e2d9120faf635 Author: Robert Burgess Date: Fri Jun 6 22:26:24 2003 +0000 Changed lists to synopses. Tour subsection removed. Got repository up-to-date. commit be56219c1c3e3e50f214e478532ae5be32e6b226 Author: Keith Packard Date: Thu Jun 5 23:51:23 2003 +0000 Make multiple catch blocks in the same try statement handled at the same catch level instead of being nested commit 9ff8ad07085ed9a513c0ef8bd904f53bcb325868 Author: Keith Packard Date: Thu Jun 5 15:07:14 2003 +0000 Update comment about grammar conflicts commit e1aa699fd58505f52751173c52982969a553674f Author: Keith Packard Date: Thu Jun 5 15:03:34 2003 +0000 try { } catch a ... catch b was getting compiled backwards commit d261cb738064aa25c2984f15301638ad25b2d606 Author: Keith Packard Date: Tue Jun 3 06:03:57 2003 +0000 Eliminate remaining RaiseError calls. Make unhandled exceptions get a continuation to the crash through to the debugger with a magic stack push/pop commit c1417355cf1ba23bbac3ab2d2862730f389315cc Author: Bart Massey Date: Mon Jun 2 04:10:21 2003 +0000 Added shuffle(), and documented PRNG. commit f35bc5a050ac44863ee83fd44d42c84961e878ac Author: Bart Massey Date: Mon Jun 2 03:31:02 2003 +0000 added atoi() and atof() commit d1a0fb86d46886b270799813581ef3e579b95205 Author: Keith Packard Date: Fri May 30 06:18:51 2003 +0000 Make sure twixt exit blocks are run on unhandled exceptions commit 81cca1b76ea6f9754f53eeda0429486409a8ce4e Author: Keith Packard Date: Thu May 29 18:36:35 2003 +0000 Standard exception arguments were constructed backwards. Was attempting to use strerror; needed custom to handle EUTF8 commit e3ea6fae41150f7c2d8855e90372a963a7609f24 Author: Keith Packard Date: Thu May 29 16:37:59 2003 +0000 Missing NonLocal around twixt body commit 01d8fa2acf205c34b59f4a839d179f3ba0b3cd56 Author: Keith Packard Date: Thu May 29 07:47:33 2003 +0000 Detect read/write blocks on closed files commit a286218b26a439d10ef8886e49e94ac481deb624 Author: Keith Packard Date: Thu May 29 06:13:09 2003 +0000 Fix implicit multi-dimensional array initializers commit 61a7e93796035309825860a54ae4ae324665aa76 Author: Keith Packard Date: Wed May 28 23:12:11 2003 +0000 dont reload upper level libraries when loading lower level commit f979d1fe6574ee6a4f0fe85eaa72281170e95533 Author: Keith Packard Date: Wed May 28 22:12:41 2003 +0000 Make Sockets::accept work commit 219dd432dd556410a4f7e6e9a40d87c0da48185f Author: Keith Packard Date: Wed May 28 21:20:26 2003 +0000 allow undefined namespaces in NAMECOMMAND commit ea141d45ca44a05986c5403592d5b021a061527a Author: Keith Packard Date: Wed May 28 21:20:06 2003 +0000 Allow autoload foo::bar commit d8715138aae8cee6873360dd7814e82e7ac5b25e Author: Keith Packard Date: Wed May 28 19:10:09 2003 +0000 Dont try to check union case when types are broken commit 1509df1866dd56a53353f414458416c76a1d5d03 Author: Bart Massey Date: Fri May 23 23:49:00 2003 +0000 docbook version of Nickle tutorial commit 80116eacdb7ab053de587a41de785b638316386c Author: Bart Massey Date: Tue May 13 20:17:26 2003 +0000 Fixed up the Solaris build a bit. commit 115b7d417fa7555761e8028a6f1703c088d55f0b Author: Bart Massey Date: Tue May 13 18:18:05 2003 +0000 fixed stale address commit 6c71146f4ffcc62a138f05650ff24fde595b0887 Author: Keith Packard Date: Tue May 6 16:34:42 2003 +0000 Oops. Broke # "operator" commit 274ee1381ac530221ee06ed9e55c90ef10f976fb Author: Keith Packard Date: Fri May 2 00:23:38 2003 +0000 Replace TypeCompatible with TypeIsSupertype and TypeIsOrdered (which is a lame name, but is easy to understand at least) commit ce1af8b8135c4a9a3a464e213c59d4fc8d3404c2 Author: Keith Packard Date: Thu May 1 19:00:18 2003 +0000 Rewrite . and $n in the compiler not the grammar to make pretty printing look right commit cc4f5b2f1741a022d604ba3f1156ff086faad010 Author: Keith Packard Date: Wed Apr 23 03:11:28 2003 +0000 Delay exit until all buffered output is flushed commit f9bcdcd5184f44280a5723b3ebb5bca032422bc6 Author: Keith Packard Date: Tue Apr 22 23:25:38 2003 +0000 Delay freeing file until flushed. Flush files on collect. Collect on exit. Still to do -- delay exit until flushed commit ec4293ae29f2cf5a341a12f1eaba63cb36afed6c Author: Keith Packard Date: Sat Apr 12 00:04:10 2003 +0000 Raise reasonable exception on invalid UTF8 characters, use socketpair to support rw pipes. Update quicksort demo to use reference types commit 9b3cbb99cd58279b678603049872ce19dbec3c73 Author: Keith Packard Date: Fri Apr 11 23:49:38 2003 +0000 trim floats to available precision, catch exceptions commit 70d455f5fd7f648e23143b67b58c51d32166917c Author: Keith Packard Date: Fri Apr 11 23:48:55 2003 +0000 Dont accept non-positive precision commit fd9d70a465501cb5f6b17d36fdcc324ba2cf8f8b Author: Bart Massey Date: Fri Apr 11 20:58:57 2003 +0000 Added /dev/random code commit c534faedd6d054fa0458d12e3533b718a578de31 Author: Erin Chapman Date: Sat Mar 22 00:06:30 2003 +0000 Changed in debian/control Maintainer field to Erin Chapman from Bart Massey. commit 2ee70f038a873f7accfbd34008c2a5e9160f4367 Author: Keith Packard Date: Mon Mar 17 20:32:56 2003 +0000 Rewrite references to resized arrays commit 5df7cde9fab3df4abeda75aa2807513207e3d778 Author: Keith Packard Date: Mon Mar 17 05:51:33 2003 +0000 Add reference type modifier commit f89f72c7a8cce89c3c033ba4fcb2110d44487001 Author: Keith Packard Date: Sun Mar 16 22:49:26 2003 +0000 Growable arrays and hash function commit 7945f749e2a49dab0c6d6f21ea92f761780818db Author: Erin Chapman Date: Sat Mar 15 01:24:44 2003 +0000 Fixed a lot of little things so a debain package can be made. Also changes were made to pointer testing in orderofoptest.5c commit d21b127191ec05fff02b20e0501f7c0544438ba9 Author: Erin Chapman Date: Fri Feb 28 22:39:42 2003 +0000 Realized that the binary operators needed to be tested two ways, not just one, so I changed it so they are tested two ways. Trinary operators are tested 3 ways now too. commit 65b8108f846d33210f076478830ee8050819bc03 Author: Erin Chapman Date: Fri Feb 28 22:02:20 2003 +0000 Factorial order of operations test added. commit 217ec9ed1fb4f90956ddcdbcc803d285c17d8adb Author: Erin Chapman Date: Fri Feb 28 21:36:36 2003 +0000 The tests for order of operations with unary decrement and logical negation were added. The test no longer prints out true or false as the results; the results of the evaluation is returned instead to simplify things for the programmer when changes are made to the file. commit 57955978926296d8484300b1e60bcd3be5b86997 Author: Erin Chapman Date: Fri Feb 28 19:38:56 2003 +0000 Added orderofoptest.5c and optest.5c to the testing suite. commit 0c412993be38cfe7ed2a0edbb885ff49625d474c Author: Keith Packard Date: Tue Feb 18 04:25:53 2003 +0000 Lost THREAD_CONST case in compiler. do_Thread_id_to_thread returns Void on failure, not zero commit 128d77daa4c5f33adbab157298bcf65ca471b242 Author: Keith Packard Date: Mon Feb 10 19:50:11 2003 +0000 Move use of string.h to mem.h from refer.c commit dff04fa2052760262cdb367ef547ba1ae2b8a999 Author: Keith Packard Date: Mon Feb 10 19:44:49 2003 +0000 Clean up for building on Darwin commit cad2e7e33287e1133c7f71c9962d93022a248a4e Author: Keith Packard Date: Mon Feb 10 19:34:38 2003 +0000 Conditionalize all errno values commit 17265818bbca1f4f4876c113ecb305123a017225 Author: Keith Packard Date: Sat Feb 8 01:48:35 2003 +0000 Merge assignment back into simpleexpr, it adds a shift/reduce, but makes ? : work better commit b1f9e8aa9d8beaebc6c69884f099f600c0c5ec61 Author: Keith Packard Date: Fri Feb 7 21:00:33 2003 +0000 Special case pow for 1/2 and 1/3 commit c714004f05818990eef82ee2e21348d4d28c5492 Author: Keith Packard Date: Fri Feb 7 21:00:14 2003 +0000 Compiling **= operands in the wrong order commit e8f5895ea2f9f0ff19b29ea98da7479cea44eb49 Author: Keith Packard Date: Fri Feb 7 20:59:56 2003 +0000 Dereferencing null pointer commit dccad212a0833e9b816fc649341126953b861246 Author: Bart Massey Date: Sun Dec 29 11:42:00 2002 +0000 Screwed up the date format. This file should be built automagically from changelog.in to get the current version number info. That, in turn, should be automatically derived from a reasonable source management system such as BK. commit 45b93816b30843d2bac9e2f5152492e91618684a Author: Bart Massey Date: Sun Dec 29 11:32:19 2002 +0000 Get ready to build new debs... commit 32ff062dde0eb82fedd61d02ec42f9ae4526d350 Author: Bart Massey Date: Fri Dec 13 19:09:52 2002 +0000 Fixed bad bug in IntegerDiv sign handling commit f72cc5a9da38585d9d954589a28f982e4ca01d5f Author: Bart Massey Date: Wed Dec 11 21:43:59 2002 +0000 Fixed bad sign bug in integer division commit 632f60407fff8fccf9dd6478caf128f45d621a82 Author: Bart Massey Date: Tue Dec 10 00:34:25 2002 +0000 Minor formatting changes, for the webpage. Needs a total overhaul. commit a9dd1050e87071f0fd179173f73e4bd9099c5b77 Author: Bart Massey Date: Fri Dec 6 01:24:11 2002 +0000 Changed random default: cases that shouldn't happen to abort() commit 0a60d775f95dd727c8704d5dcc87e7528187d39c Author: Keith Packard Date: Fri Dec 6 01:10:53 2002 +0000 Rational subtraction was broken with two negative values commit b138afe07387836eb7584a47e1315942bde87e86 Author: Keith Packard Date: Thu Dec 5 17:40:41 2002 +0000 Unhandled exception message had actuals in wrong order commit a23e6f3beafe0d26918bab1fdf2cc253c2709b7a Author: Keith Packard Date: Thu Dec 5 16:10:13 2002 +0000 Fill in exception handler frame the right way around. No need to remove actuals from stack after jumping to an exception handler commit d53c31664e371c57eac28f184f2f023082d1903b Author: Bart Massey Date: Thu Dec 5 09:09:47 2002 +0000 Fixed dependencies to correctly reflect ../gram.h role so that parallel make would work out-of-box (gram.h gets built now). commit 1f98d63d302dc88aaeedda3baf77ab487853f0b6 Author: Bart Massey Date: Fri Nov 15 08:13:40 2002 +0000 Just a descriptive comment. commit d22466ff273ff071b5731df7c21b5e1dd8663332 Author: Keith Packard Date: Mon Nov 11 06:45:39 2002 +0000 Fix allocator to handle more than 2GB of address space on 32bit machines commit 944c54be46b2c07c18132a8b0b5f539d7ef87f32 Author: Keith Packard Date: Sat Nov 9 18:52:35 2002 +0000 Unify popcount implementation and make large numbers count faster commit 32b5e6f621f39a9e1265cd987d450658ab033578 Author: Keith Packard Date: Sat Nov 9 18:32:25 2002 +0000 replace natural with value in extended popcount computation commit ebc418e06e527b237d6f360316249eed31b86791 Author: Keith Packard Date: Sat Nov 9 18:30:47 2002 +0000 Permit e notation numbers to be ints commit 380a1d6988888851333e98af9230f45df1fe7f6b Author: Keith Packard Date: Sat Nov 9 07:38:25 2002 +0000 Oops. Stupid bug in NaturalLor commit 016e29b436bc61cf77eed79d6b4a61301e21b34e Author: Keith Packard Date: Sat Nov 9 07:26:28 2002 +0000 Dont complete Raise when exception unhandled commit 5b25f450438d84934b7b76d60776c36af62a8004 Author: Bart Massey Date: Sat Nov 9 06:23:39 2002 +0000 More functionality and the new debug function. commit 6dcc28f96c86321041cb4d317f1fadad71a1c539 Author: Keith Packard Date: Sat Nov 9 06:23:09 2002 +0000 NaturalLor was horribly broken -- walking off the end of the shorter number commit aad9f9020bef6836d19f8a96ea01d78fcc26ac53 Author: Bart Massey Date: Fri Nov 8 09:14:20 2002 +0000 Bump version number. commit 1603593684194b0fffb33c859cf4e0d604dfef0c Author: Keith Packard Date: Thu Nov 7 19:34:02 2002 +0000 Improve popcount performance a bit commit 99ba66ff14dd7828aec9a022814e0b5909abd142 Author: Bart Massey Date: Wed Nov 6 09:32:09 2002 +0000 Use real count_bits() algorithm. commit ce4fa38fb7e5ca372abf5d389337707ed2060d2d Author: Bart Massey Date: Wed Nov 6 09:09:07 2002 +0000 Added popcount() builtin. commit cd3fe4738e8637c792bbff28a7cc691791bb5e8e Author: Keith Packard Date: Tue Nov 5 18:34:58 2002 +0000 Always reference typedefs through the symbol commit 67dd48854e05ad952ef44d7a1b3de3f99a615b0b Author: Keith Packard Date: Tue Nov 5 16:59:33 2002 +0000 Permit {} syntax for union initialization commit c9c03c753f8489166e995cdfb05479eb001e8b6e Author: Keith Packard Date: Mon Nov 4 09:48:04 2002 +0000 Unbox ints. Untype boxes; use separate type vector or single type pointer. Eliminate duplicate data from arrays. Share boxtypes type with structs. Rearrange code to avoid thrashing on the reference stack commit bf47372bf26c5c715a4b686625f822600089a241 Author: Keith Packard Date: Sat Nov 2 21:34:50 2002 +0000 Move UTF8 I/O functions into C code to avoid duplication commit 423f32a7a20c381bc181ac7e83798c97437c7501 Author: Keith Packard Date: Fri Nov 1 20:47:51 2002 +0000 Hack up barts commandline parsing some more commit 7cbb5cdbf04c0342107d229514add5727a6d9df1 Author: Bart Massey Date: Fri Nov 1 19:51:22 2002 +0000 Renamed Nickle path variables once again. Got rid of the heinous substitution in builtin.5c.in, making sure that C code and Nickle code agree on NICKLELIBDIR/nickle_libdir. commit a7f9dc5d6b70fbd21a24e81692d92ab18fad1cbc Author: Bart Massey Date: Fri Nov 1 11:27:19 2002 +0000 Fix bug in previous, add error message for bad NICKLESTART commit 1a4f68b551fe94acf7e3794184233dad20915532 Author: Bart Massey Date: Fri Nov 1 10:58:05 2002 +0000 Cleaned up all of the path nightmares as best I could. Paths should work right now. Bumped the version number. commit 8b747db287f97587187233041b7cf0cb1cc2f77a Author: Keith Packard Date: Thu Oct 17 15:54:27 2002 +0000 Make more stuff const to reduce data size commit f4563f0b15e07fcba9eafde731090ef31e74acd8 Author: Keith Packard Date: Tue Oct 8 00:34:51 2002 +0000 Move command line parsing to builtin.5c. Fix implicit initialization of arrays of structures commit bf0b4b9bcbc1bb300ab90718332bb06a9fa13dec Author: Bart Massey Date: Tue Oct 8 00:07:46 2002 +0000 Forgot to make FileGlobals public in File: fixed commit a2c0fc61830f076e4524958c35a73c410ebed3d8 Author: Bart Massey Date: Fri Oct 4 20:24:51 2002 +0000 Added ungetchar(). Restructured to remove duplicate declarations. commit 84bb37b7d050faf9d8f23bd77e96c652bc06c223 Author: Bart Massey Date: Wed Oct 2 02:13:22 2002 +0000 Fixed no readline library case FileFlush() call commit 0c124a9e00b589038fcda5c621255176f1c257bd Author: Bart Massey Date: Tue Sep 24 18:45:29 2002 +0000 Add assert() to Abort commit 4f058d2179746c844004393e67dfb76f065091d7 Author: Keith Packard Date: Thu Sep 19 16:44:32 2002 +0000 Handle missing struct initializers commit bae419b357a9065fc8c498a81bb1f6b7041f1520 Author: Keith Packard Date: Thu Sep 19 16:41:08 2002 +0000 Handle invalid UTF8 sequences in lexer commit a4d9685dfef4d22e4fea5a727d810e1021c2173a Author: Bart Massey Date: Mon Sep 16 23:49:19 2002 +0000 Modernize this code a bit, and clean miller-rabin up a bit. commit ea689afa964a4e916513c276261ebc13c1ccd3b4 Author: Bart Massey Date: Mon Sep 16 07:03:15 2002 +0000 BUG: the invisible potential dangling else at the end of the startup was screwing the parser state (specifically, I observed this on a script where the first command was autoimport). Hacked for now. commit d04b3282c8bd90eb2c724ba91a831367dd938989 Author: Bart Massey Date: Mon Sep 16 06:55:08 2002 +0000 Forgot to add this: necessary for builtin.5c.in now. commit 6f62a43371acb2d65c932d140e5e580e17221929 Author: Bart Massey Date: Mon Sep 16 06:54:28 2002 +0000 Sieve of Eratosthenes in Nickle. Meant to add this long ago. commit 093ed10659863ed177143fb5c5e2e22f66251125 Author: Bart Massey Date: Mon Sep 16 06:52:59 2002 +0000 Sort out a whole bunch of issues around loading builtins, autoload and autoimport, library path, etc. Not right yet, but much better. commit e2eb904c4fb30cabc555731ca4b726e081a3bfad Author: Bart Massey Date: Mon Sep 16 05:03:02 2002 +0000 autoimport "fix" commit da7132bb28ad4c1591f28bef4eabf531d4fdaf44 Author: Bart Massey Date: Thu Sep 12 06:45:44 2002 +0000 Cleaned up and altered the behavior of require, creating instead autoload and autoimport. commit aea7f443c878d8903d0bc1f116cf35c96ac51c96 Author: Keith Packard Date: Wed Sep 11 17:03:43 2002 +0000 Add Command::valid_name builtin, fix require to use it commit b807c09d790c5bb5f8cef657bd3946f76a0728ee Author: Keith Packard Date: Wed Sep 11 16:15:02 2002 +0000 varactuals were horribly broken. Made pretty print accept a list of names. commit 1db79e467410ce18f6bd4de9e23c32b2afdec5a0 Author: Bart Massey Date: Wed Sep 11 09:01:30 2002 +0000 Added ctype.5c to builtin list. XXX not Unicode yet. Added "require" builtin for loading a namespace file by name. Fixed a bit of machinery to make it possible. commit e7969635f4ee679c651475358975e66a56b071a9 Author: Keith Packard Date: Tue Sep 10 06:25:15 2002 +0000 Label data types with name, add memory usage tracing with both total and current usage. Found a couple of misdeclared datatypes that were eating memory (Fpart, ValueCache and StructType) commit ab0ba2e4eb4f069ab492331edfa9859f9a13fa3d Author: Keith Packard Date: Sat Sep 7 00:05:19 2002 +0000 do loop was branching to the wrong place commit c930ff8cf198a33ca3723abb8207a385cfd03356 Author: Bart Massey Date: Sat Aug 31 01:31:39 2002 +0000 Reordered suffix type modifiers (array and function) to read left to right Repaired a bunch of array initializer bugs Cleaned up the grammar and commented the conflicts commit ee76002f6fa0a5a2924052ecc6b648ddb54bbde1 Author: Keith Packard Date: Fri Aug 30 07:14:35 2002 +0000 Permit nested comprehensions commit f31b2d712ed2e757c8b6d87eaebabcd6bf7d27fc Author: Keith Packard Date: Fri Aug 30 04:38:39 2002 +0000 Dropped object pointer during UNION cast expression commit 3cf67926cf80f1a53c2dabb58064a1945286babf Author: Keith Packard Date: Fri Aug 30 03:05:10 2002 +0000 Fencepost error in atov commit fe494a00f979fcc8d5189c8f19f78bc05b15676b Author: Keith Packard Date: Fri Aug 30 00:18:18 2002 +0000 Permit arrayinit for a comprehension commit 8644a3505263cd3f85eb3ad6c247eadad3416a1b Author: Keith Packard Date: Thu Aug 29 20:40:26 2002 +0000 Finally allow struct/array initializers to be arbitrarily nested commit 4273fa88395be726eac8fe49e6d2d53cca43afcd Author: Keith Packard Date: Thu Aug 29 03:12:26 2002 +0000 Allow leading whitespace in # comment lines, fix atov to allow non-hex digits for bases larger than 16 commit 8bb9b7cd6d1522f920922d3de4ade20dfccf23b7 Author: Bart Massey Date: Wed Aug 28 16:48:38 2002 +0000 It was way past time to bump the version number. Must remember to do better in the future. commit f011a2e8701673e56144543291e748287862345e Author: Bart Massey Date: Wed Aug 28 03:38:57 2002 +0000 Added lex and yacc dependencies. Shouldn't hurt; occasionally seems to help. commit 28f79894cb0e0392fa6594296ef286b848ad9e9d Author: Bart Massey Date: Wed Aug 28 03:36:57 2002 +0000 Changes to compile on Solaris (hasn't been tried in a while, so was busted). Pretty ugly, but best I could figure out how to do. Some autoconf/automake guru should look at this. commit b7fb9475c5655460bc1689ca1ab46ac1c0c7bdeb Author: Bart Massey Date: Mon Aug 19 01:02:55 2002 +0000 Added (integer-coefficient) polynomial operations, and a polytime primality test. commit 27adcf624ea70ba25ee8c1c28c4de1a69a68215d Author: Keith Packard Date: Fri Aug 16 15:43:02 2002 +0000 Allow ... to initialize zero elements of an array. Fix unary * error message commit 8dac2aafccc4479203d10cb2d49009aa056afe22 Author: Bart Massey Date: Fri Aug 16 05:58:23 2002 +0000 Added a help command to debug mode. commit 62a852a35aa42da5357e004b5f264f6a52e0a537 Author: Bart Massey Date: Fri Aug 16 04:43:02 2002 +0000 Fix max and min to take 1 or more args. commit 966986c8b564f826ff4f283e8fc28e22fe73f458 Author: Bart Massey Date: Fri Aug 16 04:38:09 2002 +0000 Added ctype package. Added max and min builtins to math. commit 258ae0e9bf87a9bbd580d9e8d1a9818f492dc854 Author: Keith Packard Date: Wed Aug 14 03:29:39 2002 +0000 Fix printing of zero element arrays. Fix zero element array initializers commit 610561c2f8780ec5d2ac206fca9f0d1c19cfdeab Author: Keith Packard Date: Sat Aug 10 08:49:48 2002 +0000 Ints were not getting tied down on return commit bf9cca8cfadf698f1b91ce5c9e0ab1b3c918a64e Author: Keith Packard Date: Sat Aug 10 07:59:03 2002 +0000 Fix atan2 for each quadrant commit c6682835d67e9f5206237d1455c4a4115f0c159e Author: Keith Packard Date: Sat Aug 10 04:05:19 2002 +0000 Clean up struct/array init parse tree generation commit 10d6d600f7d942837c06657ac62108e2504c76e7 Author: Keith Packard Date: Fri Aug 9 20:50:23 2002 +0000 Add [] name for array in comprehensions commit 53c9ec6736124f987867a352dad8b25ce2d93968 Author: Keith Packard Date: Fri Aug 9 17:25:45 2002 +0000 Add sort example code commit 6b9607c6497df7546a29735de48123554a0f7142 Author: Keith Packard Date: Fri Aug 9 06:39:32 2002 +0000 Catch AInitModeRepeat at end of dimension commit ee3c6e331f0aba3a91daf6fbcb351a1847a1694b Author: Keith Packard Date: Fri Aug 9 06:28:29 2002 +0000 Compile while and for in correct order, reordering object code. Change comprehension syntax commit 7ba2bc536211c8ae5c75ce7f366e928ffdf6befc Author: Keith Packard Date: Fri Aug 9 06:02:13 2002 +0000 Fix syntax in ARC4 to match limitations on array initializers commit 88290be659924279fa8c4405b872a6436b27da2b Author: Bart Massey Date: Thu Aug 8 05:45:48 2002 +0000 Fix compile error message argument passing commit 0b2f8c0610cdfc964d52652ae2b4c4deb8c05236 Author: Keith Packard Date: Thu Aug 8 05:43:47 2002 +0000 Handle EOF on string input files commit 709daf6dc9b2afea82eed505051a19eb493659ba Author: Bart Massey Date: Thu Aug 8 02:09:03 2002 +0000 Added sscanf. commit 0e329898beba6223ed19fe1b992923e2b9916ef5 Author: Carl Worth Date: Wed Aug 7 06:18:45 2002 +0000 iAdded .cvsignore file for autogenerated files. commit 7a4af7026b23d7a0b948a620cc7d8bba338f3ad4 Author: Carl Worth Date: Wed Aug 7 06:13:55 2002 +0000 Added .cvsignore files for generated files. commit 9d0d3b538145de9a3aac294f47576432b56e284f Author: Keith Packard Date: Sun Aug 4 20:09:18 2002 +0000 Evaluate function before args to keep L-to-R ordering, fix prime example commit fa03b1f876c3e1cd2ca083e6d9ae7d91031ce53a Author: Keith Packard Date: Sun Aug 4 17:36:55 2002 +0000 Regularize type errors, add comprehensions, clean up profiling commit 1b997ff18f2859a6f04f30e8ff539606ce0ce824 Author: Keith Packard Date: Fri Aug 2 06:56:04 2002 +0000 Forgot to reference object block in frames. Missed one case of profiling disabling TailCall. Eliminate self from sub profile values commit 0d9e6f56fecde241a2684b201e4fb2d12c6aa70a Author: Keith Packard Date: Fri Aug 2 06:07:12 2002 +0000 Make array expressions evaluate left-to-right. Redo array initializations to avoid exploding the stack. Move instruction stat references to separate list commit 36a785c56822e24e8966323aded20cd7c83e43e6 Author: Keith Packard Date: Tue Jul 30 02:47:58 2002 +0000 Eliminate compiler warning about uninit var (wasnt a bug) commit 853fdb0d01c6421c1f1281031f197f49e03c3695 Author: Keith Packard Date: Tue Jul 30 02:45:46 2002 +0000 Add variable actuals, remove else blocks from twixt, add ({ stmt ... }) syntax to expressions commit bca81fc65349f2320a3d217dfbac184ca9f6a1b9 Author: Keith Packard Date: Mon Jul 29 16:25:44 2002 +0000 Flipped boolean sense in do_profile commit eebde0b9eddda52e40afc813d99c675b8562c1ce Author: Keith Packard Date: Sat Jul 27 04:53:15 2002 +0000 Fix examples and tests to avoid null pointers and int tests commit fe87ee327b39db7f41907dafa8521fbb864f851b Author: Keith Packard Date: Sat Jul 27 04:52:43 2002 +0000 Raise reasonable exception on math domain errors commit 94e679b53df2845043ff06dffc11071035a68c0e Author: Keith Packard Date: Sat Jul 27 04:52:30 2002 +0000 Add constant folding commit a8c436c12db0f21fc6d7702daeddf46a7f542289 Author: Keith Packard Date: Sat Jul 27 02:16:20 2002 +0000 Poly narrowing was smashing things commit 249236517b11e4d014cce80807c33044e5c015ff Author: Keith Packard Date: Sat Jul 27 00:58:45 2002 +0000 Fix union case compiling code a bit commit e5ff3aeaaa1672ea9b1b2320c5e8ec4b6f8c7b79 Author: Keith Packard Date: Sat Jul 27 00:03:34 2002 +0000 Remove null pointers, add union switch case variables, switch to type lists for poly narrowing computations (eliminating anonymous unions), compute reachability for function return and union switch case variable scope, change syntax of union values, eliminate enum as union member type commit 888c7b80c21fa3b88839c18c260b09d5fc2eb50c Author: Keith Packard Date: Thu Jul 25 21:06:59 2002 +0000 getc wasnt using getb commit 96b4cc104163dde08a6e6dafeb47117aa0575329 Author: Keith Packard Date: Thu Jul 25 21:06:31 2002 +0000 Change internal terminolgy. Values have representations, expressions have types. Also clean up a few remaining bool issues in the examples commit 8d77cfb70e86ee0de223c12d01f559b66dc21b8e Author: Keith Packard Date: Thu Jul 25 18:15:48 2002 +0000 Change internal terminolgy. Values have representations, expressions have types. Also clean up a few remaining bool issues in the examples commit d4e5b9ca3949dc96e1ef778dbce28fc48bf0d6cd Author: Carl Worth Date: Thu Jul 25 17:29:27 2002 +0000 Fixed array declaration examples with incorrect syntax. commit 5f4b46a46db3e41332f1953d049f41976025c421 Author: Keith Packard Date: Thu Jul 25 05:12:12 2002 +0000 Check for recursive types commit 6e62c97bf7bd921d1a9110ad854c3614fe7675d9 Author: Keith Packard Date: Tue Jul 23 21:40:35 2002 +0000 Switch to UTF8 for characters, add bool type, fix evaluation order of assignment operators, fix default struct creation to check recursion commit 669a0b145306dada3176546ad3f3b10703c8049e Author: Keith Packard Date: Sun Jul 21 23:36:53 2002 +0000 Add support for binary/hex/octal float constants commit 766d524bf03338b7f585e69377bb2594a67fa777 Author: Keith Packard Date: Sat Jul 20 20:56:24 2002 +0000 Stack marking didnt handle GC while allocating stacks commit 70951f8db7303891f6948fc7b01324ed6734a119 Author: Keith Packard Date: Sat Jul 20 19:05:55 2002 +0000 A compiler warning and a broken semantic error check commit fb1055a3eaf663b188e2983c554e28b1f365756b Author: Keith Packard Date: Sat Jul 20 19:00:13 2002 +0000 Fix non-local branches from catch blocks commit 2a561b7a002ad19183fe41075bd204c6d006a7a1 Author: Keith Packard Date: Thu Jul 18 17:18:05 2002 +0000 Initialize frame before allocating dynamics, fix builtin exception argument order commit 464451f7ca5d8acc7f31721f313e64c916522de6 Author: Keith Packard Date: Wed Jul 17 13:44:01 2002 +0000 Create exceptions for file errors commit 29a5559f7c7985493611c5f1eee3d36943820511 Author: Keith Packard Date: Tue Jun 25 09:32:42 2002 +0000 Another uninitialized memory problem with -e arguments commit 431605ec289cd128aef7add228e6356efba14c98 Author: Keith Packard Date: Wed Jun 19 23:30:24 2002 +0000 Array creation left element uninitialized across allocation call commit 01a109d501e92276ca869891398ba94467c81d86 Author: Keith Packard Date: Wed Jun 5 08:06:15 2002 +0000 Fix profiling number printing to leave enough space for big numbers and not fail when numbers are too big commit 07f17a91a2cbc947077acefdde953685f840d89a Author: Keith Packard Date: Wed Jun 5 07:18:55 2002 +0000 Thread continuation wasnt getting frame value initialized on thread creation commit 549e1c6541a08b2bf1ac9529ae995b7e491c7b4b Author: Keith Packard Date: Wed Jun 5 07:01:45 2002 +0000 Missing type canonization for func return values. Missing bzero on implicit array initialization commit 36d9ef5445f9d47503fe3619ac543037ab0390e2 Author: Keith Packard Date: Tue Jun 4 03:36:49 2002 +0000 Flush IO in exit builtin commit b2debe4e0492e9b213697609dfe3824fd2a5f1c8 Author: Keith Packard Date: Tue Jun 4 03:32:50 2002 +0000 Scanf for strings was not checking for EOF commit 743ac1b2d5b7bc7926f3b5c5d97c3aed39b6e9f3 Author: Keith Packard Date: Thu May 23 07:45:32 2002 +0000 Fix socket code to block waiting threads commit c807b14f90152a9535efef3855816852c05e60a2 Author: Keith Packard Date: Thu May 23 07:07:37 2002 +0000 for(;;) was using BranchTrue (oops). Thread creation wasnt saving pointer to initial thread code object commit 687ae965a207179119263c64463b8453f93049f0 Author: Keith Packard Date: Thu May 23 06:42:54 2002 +0000 Get rid of lambdaexpr, folding lambdas into primary and accepting a reduce/reduce conflict. Reorder grammar to reduce the right way. Fix pretty printer to print lambdas commit baa817e4da331e16d4f8a5cf48c8b0aebe19aba9 Author: Keith Packard Date: Thu May 23 06:03:59 2002 +0000 Lost parens in exception and func definitions commit e812788298aba76c632878f0dabf04ee9965d0d9 Author: Keith Packard Date: Thu May 23 05:36:10 2002 +0000 Make "function" no longer necessary in function declarations, fix pretty printer to match commit 012385636ccb47e5c72405a6e9ae117c81a4f2ab Author: Keith Packard Date: Thu May 9 20:53:09 2002 +0000 broke a comment with a global replace commit c440c06bbc0322d38783073e3e6b4b82766532ba Author: Keith Packard Date: Thu May 9 20:48:37 2002 +0000 Replace Contexts with Continuations everywhere commit 461c3c50462fed692497de5fba22170b2d7d077c Author: Keith Packard Date: Thu May 9 19:39:53 2002 +0000 Create and use common continuation structure (Context) for thread, continuation and twixt commit ede48bd014e8d1668db3a32f7d6ff7187441bb9d Author: Keith Packard Date: Tue May 7 07:08:20 2002 +0000 Remove _Bool from value.h as that name is used in some environments already commit 874fe5dec173d3b0fac77bdb26e23c2308625f92 Author: Keith Packard Date: Tue May 7 06:15:54 2002 +0000 Performance tuning: + Remove memset from MemAllocate + Make lots of small functions inline + Reorder code generated for loops + Move ThreadStep inside ThreadsRun + Cache recent int/ref values + Change stacks to have one stackPointer Opcode reorganization: + Separate name/global/static opcodes + Combine binary/unary opcodes + Combine branch opcodes commit 65a9efa636a85bf35795c3ec3d462f2d8e88a7d7 Author: Keith Packard Date: Sun May 5 08:23:09 2002 +0000 Eliminate tag per value, fix few minor grammar syntax errors, tweek mem to eliminate sizeIndex array commit c646b736b09efc8bee16df2282680ba1a5a196d2 Author: Keith Packard Date: Sat May 4 18:27:36 2002 +0000 Add nested profiling, clean up profile printing, optimize a few hot spots commit a57c4c5127906119c2fd4ae2291bb0579c8bb2fe Author: Keith Packard Date: Wed May 1 23:59:55 2002 +0000 Close other end of pipe in child process commit 17a648aebe80c3688cddbaf3e0c817dd430e80d1 Author: Keith Packard Date: Fri Apr 12 20:46:53 2002 +0000 dims builtin created invalid array value commit 9c67ff5ce2ce22cc37e59379d3f6b11cbb7006a6 Author: Keith Packard Date: Fri Mar 22 07:30:30 2002 +0000 Remove unused history C code, fixed try pretty printing, fixed exception argument fetching commit b0a54da716232f7754d9602d2e3ff18e82f50d57 Author: Keith Packard Date: Thu Mar 21 06:50:52 2002 +0000 Add convenience command "char" that displays characters from integers commit e48d77ed3074f3c47cd02c07bfa630047f3ca65b Author: Keith Packard Date: Thu Mar 21 05:44:35 2002 +0000 Rewrite printf and history in nickle commit 4250703111b5a3073a7b700c065605a07b17ba70 Author: Keith Packard Date: Thu Jan 31 07:28:23 2002 +0000 With forward function declarations, the function type must pass from func_decl to the declaration directly instead of through the symbol commit 02fccc033aff45b7d973ed4f5296561ae6e0e8ac Author: Keith Packard Date: Thu Jan 31 07:08:17 2002 +0000 Clean up forward declarations to make sure types are contained and that the forward value is reset commit 2e22d78cffdc1d53f56671cc7e9267124e7c3b34 Author: Keith Packard Date: Thu Jan 31 07:00:27 2002 +0000 Permit forward declarations of functions, allow function arguments to have no name commit 0b1e603dde1b61d1c5f5547d5a9360cc2f70316c Author: Keith Packard Date: Thu Jan 31 05:10:02 2002 +0000 Dont force evaluation for unused expressions commit 4f2bac0fff637767b3426474839d0c54e9c26d57 Author: Keith Packard Date: Thu Jan 31 03:56:06 2002 +0000 Use formatted output for menace2.5c commit 63443330434b6bca1c4c9935ba21b0d5f8872203 Author: Keith Packard Date: Thu Jan 31 03:55:50 2002 +0000 Permit use of names within initializers for that name commit 6165555a8771e8c119797c10ac8d0bb07b0bfd33 Author: Keith Packard Date: Wed Jan 30 02:18:05 2002 +0000 Inhibit readline completion so that tab works normally commit de21539f01579d9db64b4482e6cf574570b4ee18 Author: Keith Packard Date: Wed Jan 30 01:15:21 2002 +0000 Avoid crashing when compiling a declaration using an undefined typedef commit 5ee87169df092cbb2de6394e7bbfe02d7ab95885 Author: Bart Massey Date: Wed Jan 2 04:48:06 2002 +0000 Expand missing symbol error message to indicate hidden private symbols commit 68d604594630a5f701b1f2a2883945e88dd841d3 Author: Bart Massey Date: Sat Nov 24 05:31:32 2001 +0000 Michie's MENACE TTT learning algorithm. commit c071af012751528c4ed21892a6f1299f0a519175 Author: Keith Packard Date: Fri Nov 16 20:01:25 2001 +0000 Non-ascii chars printed wrong in %v string format commit 2c132f582a55b013ad537f09870b8c4ba157ad2d Author: Keith Packard Date: Sat Oct 27 17:10:41 2001 +0000 Wrong archive file name commit f86533379fcbff1c06e8d0464c8ea1daaba991e8 Author: Keith Packard Date: Sat Oct 27 16:59:01 2001 +0000 Add AC_CONFIG_AUX_DIR to fix build issues on Mandrake commit f8cfc939193677b0b847de0baa947b781b6fb486 Author: Keith Packard Date: Sat Oct 27 16:56:33 2001 +0000 Modify build-rpm to work on more RPM systems commit 6d9880424af63727e6e2e5a57a75171d7d618044 Author: Bart Massey Date: Sat Oct 27 06:26:57 2001 +0000 Fixed RPM to be built using version information extracted (very crudely) from configure.in commit 03a627a43530d9978435319eb6366185a2952001 Author: Bart Massey Date: Sun Oct 21 08:28:03 2001 +0000 These should be provided by automake in current versions commit 60cdc6eb6330a50f93a02b6273819b319990d2aa Author: Bart Massey Date: Sun Oct 21 08:22:46 2001 +0000 More debian package changes. commit 364ad13698691c5231233162211978174adbc00e Author: Bart Massey Date: Sun Oct 21 08:21:50 2001 +0000 *** empty log message *** commit 96a7b694716db258b688f2e7c389828a4ba528cc Author: Bart Massey Date: Sun Oct 21 05:59:22 2001 +0000 Bump version to 2.00 before Debian package release commit 431ae5f2609a817886b7d418adbf0420e3c9d633 Author: Keith Packard Date: Fri Oct 5 07:56:41 2001 +0000 Clean up floating point formatting commit 85d0f057fdd8e0698354329d0760c1fd082e2f93 Author: Keith Packard Date: Fri Oct 5 07:14:44 2001 +0000 Clean up rational number formatting to respect width and precision arguments better commit c59249299b20d501057b8d6a8fede72649044aa1 Author: Keith Packard Date: Mon Aug 27 07:22:22 2001 +0000 Speed up rational decimal printing commit f6024295cd1d1c80d62298611cd935abd21d0c16 Author: Keith Packard Date: Tue Aug 14 08:34:14 2001 +0000 Add const storage class; easier than const data or general variables and more reasonable. Add 'enum's --actually union members with void type. Fixed array dimension order compilation Change mutex implementation to use new enum union members commit 34be8d42597b69c05e0f0a60d0f1842bf3cada15 Author: Bart Massey Date: Mon Aug 13 01:48:30 2001 +0000 Fix pretty printer to print void, fix voids to compare always equal commit 4399ecf1378f1da5373faf504ebaed77b2eedc25 Author: Bart Massey Date: Mon Aug 13 01:24:57 2001 +0000 Raising an exception checks for its existence and exceptionness now. commit bdf6c1726d29c0601e40d93618f312e42ed511b2 Author: Bart Massey Date: Sun Jul 29 02:59:52 2001 +0000 Need netinet/in.h on many architectures commit 0aeba128703abc651919d54d6bb6767b7113728a Author: Jamey Sharp Date: Sun Jul 29 00:19:13 2001 +0000 Added networking builtins for TCP and UDP. Fixed a minor build annoyance leftover from the builtin split. commit 112cff068382592cb3cdf3a04b28264e98b7b220 Author: Jamey Sharp Date: Fri Jul 27 08:36:31 2001 +0000 First shot at debianization. Not quite there yet. In particular you have to move the nickle directory to "nickle-(version)" before the packaging tools will know how to work with it. Also I haven't quite decided how to handle the ChangeLog and COPYING files; I want this to behave like a native Debian package, but that requires moving those files to debian/changelog and debian/copyright, respectively, and imposing a machine-readable format on the changelog. For now I hack around the copyright file and ignore the changelog. commit 7b1bdc9a5fc5d27a6d967f72c8c29485eec8ae89 Author: Keith Packard Date: Fri Jul 27 08:19:10 2001 +0000 Incorrect comparison for font selection commit cc531d0b2b7a836eb85159be576deb5fc62b2bec Author: Keith Packard Date: Fri Jul 27 08:01:59 2001 +0000 Add smlng generator commit 9281867552d15c9f0a0d6ee2c01488660bd2935a Author: Keith Packard Date: Fri Jul 27 07:55:45 2001 +0000 Require type compatibility in equality/inequality comparisons commit bc9b7f164dab67d40386aeabfa17dd52dfd22f3d Author: Carl Worth Date: Fri Jul 27 07:49:59 2001 +0000 Fixed precedence bug preventing EM tag from working commit cec7bbcb0354049647a53abccab088018adb5c7a Author: Carl Worth Date: Fri Jul 27 07:41:06 2001 +0000 Fixed some bugs in the parser commit 5e8559ef26d4a09bd17c2d4e24ddc46d989f8913 Author: Keith Packard Date: Fri Jul 27 07:28:54 2001 +0000 Fix context chaining after nickle reference was fixed commit d9f19b6ba136a4c422a371bd47fafdc25841b64e Author: Keith Packard Date: Fri Jul 27 07:27:31 2001 +0000 Make reference copy its argument commit 6a1f99ffa68ececfebe72b01c60139c0c9263b14 Author: Bart Massey Date: Fri Jul 27 07:10:58 2001 +0000 Got this committed :-(. commit 533da7243fe128bd87ed70803bfbddb6e55d5205 Author: Carl Worth Date: Fri Jul 27 06:44:12 2001 +0000 Initial commit of test.5c commit d04a2909c445b5a2f88c8191fac2d95c16362b64 Author: Carl Worth Date: Fri Jul 27 06:42:32 2001 +0000 Committed the parser, lots of bugs commit 7ac331d3f90c5c380adafae597e62cb69ff7bdae Author: Keith Packard Date: Fri Jul 27 06:09:27 2001 +0000 Print parameters in the right direction commit 7025648808776ab653881ef429131b419f630e6c Author: Bart Massey Date: Fri Jul 27 05:35:41 2001 +0000 Needs a new version number commit 65bae2486ba2b8cd3515c433920082f3b2fb6bbb Author: Keith Packard Date: Fri Jul 27 05:22:44 2001 +0000 Add build-rpm script commit 4c0e79b4128ab0d69c52d8649e44717e84a97408 Author: Keith Packard Date: Fri Jul 27 05:00:48 2001 +0000 Handle uninitialized undimensioned arrays commit 6b5be6642bab88e7b8a149693e6fd6d2ddda352b Author: Keith Packard Date: Fri Jul 27 04:40:22 2001 +0000 Cant assume initializer rvalues are const commit c5d36950171dace7be4438aacbfaefd7d300cdfb Author: Carl Worth Date: Fri Jul 27 01:04:51 2001 +0000 Initial add of state.5c commit 63934d96f723202a1188445d6051cc95f5d8e34a Author: Bart Massey Date: Fri Jul 27 01:04:32 2001 +0000 Cleaned up some bugs in Jamey's code and config. Bumped the version number. commit 6c0435000ef59c704b18af712d19c99ab20b279e Author: Carl Worth Date: Fri Jul 27 00:54:37 2001 +0000 Initial commit of Keith's sml parser commit 92d4ed52720c20303fe864c69fea628a664ca70c Author: Jamey Sharp Date: Thu Jul 26 05:49:56 2001 +0000 Split builtin.c into subdirectory "builtin" commit 1b061dc7416a4971b4bf680e4c70d841241d566a Author: Keith Packard Date: Tue Jul 3 04:08:31 2001 +0000 Fix aetov to use Negate, update config to use stdint.h commit d3097e9400d228316441a54a5bb02195ed9c4bd3 Author: Bart Massey Date: Mon Jul 2 18:30:41 2001 +0000 Make aetov() put the sign back at the end. commit 8ec6e7ca40a9f6e95fbbb0ebd216381b3a36390d Author: Keith Packard Date: Sat Jun 16 09:01:11 2001 +0000 Off by one errors in argument parsing commit 52c80698113c78b71d7febaabb72ed505a15267e Author: Keith Packard Date: Mon Jun 4 09:40:46 2001 +0000 Add profiling, evaluate arguments from left to right commit 679ae6c1ddea9790ba3bd5ad73b194513368adbc Author: Bart Massey Date: Mon Jun 4 06:58:52 2001 +0000 Added examples/turtle to distribution info in Makefile.am. Fixed typo/formatting in sched.c: now is . Added examples/restart.5c to repository (not yet in Makefile.am). commit 9e4474b841c1c8f86782cb93c84c9c55d5c1a3bc Author: Keith Packard Date: Wed May 30 19:36:10 2001 +0000 Speed up math functions using exponent values, fix compiler to emit correct error message on missing struct tag, fix compiler to set correct statement expr in declarations commit 057e297f2b8cb06173f22cda451eadb8bbcaeabb Author: Bart Massey Date: Tue May 29 02:56:32 2001 +0000 Added turtle graphics and snowflake demo. commit bf5a5da6df4b1a3412bfac1fc62d54fd466048a5 Author: Keith Packard Date: Mon May 28 23:59:44 2001 +0000 Fix sqrt initial estimate commit 068c6e3b074ab0ecb5679955079332704158ebe1 Author: Bart Massey Date: Sat May 19 16:25:05 2001 +0000 Changed decls around. commit 535480aff242e1592fd76d2050508e9bd8d9b1e1 Author: Keith Packard Date: Tue May 1 05:03:23 2001 +0000 Stop using sigrelse -- its not what we want commit 7e1e1fd0a7b6e37501a229ad7c33c777acbe0b8c Author: Bart Massey Date: Tue Apr 24 22:15:25 2001 +0000 More fixes to TODO. commit 3fd7c058e9fdb239e49259513ccc49ef530fba32 Author: Bart Massey Date: Tue Apr 24 18:23:28 2001 +0000 Updated TODO list off my whiteboard. Fixed missing bits in runbench.sh. commit af5429990b68ce4a90396f79c9dc86cc0fc4cb4d Author: Keith Packard Date: Fri Apr 20 09:12:41 2001 +0000 Natural addition divide helper is different than multiply helper commit fb2f68c5028b982d4c76ac352b3cda135f918bd2 Author: Keith Packard Date: Fri Apr 20 07:23:47 2001 +0000 Make run-time typechecking use represenations rather than types for arrays and pointers commit 5dae78f5ee4b04f37627cb323da1af7e49cae097 Author: Keith Packard Date: Wed Apr 18 15:50:05 2001 +0000 Handle break/continue/return from inside twixt/catch commit d0a1293de73015289dbbc16209ae6135d127fa9e Author: Keith Packard Date: Wed Apr 18 07:19:41 2001 +0000 Add Karatsuba multiply code, rearrange natural arthemetic commit 88f445b97fa4ea487bd3e308a1ae57bd32bb60ba Author: Bart Massey Date: Wed Apr 18 02:25:44 2001 +0000 Benchmarks for Nickle commit 952f8fa509cf55156f7bd1d379f05776beaca0d8 Author: Keith Packard Date: Tue Apr 17 20:55:09 2001 +0000 Set forward typedef references to reuse existing symbol commit 0498c0939467fef928d3f63f220e787d6f13e229 Author: Bart Massey Date: Tue Apr 17 09:20:53 2001 +0000 Changes for Solaris (and general portability): Fix pair of actions in gram.y with no symbol between them. Replace builtin.c setenv() and unsetenv() calls with putenv() + C code. (Arguably not done yet: should dispense with putenv() as well.) TODO: Is the variable passed to putenv() rooted properly? Instances of HAS_SIGACTION should be HAVE_SIGACTION TODO: Do systems with HAVE_SIGACTION false actually work? Replace uses of SIG_IGN and SIG_DFL with "UNIX98" sigignore(), sigrelse() when available: this avoids prototype hell, and may be "better". Completely revamp configure.in readline library support: now does a very complicated thing when e.g. --with-readline=/pkgs/gnu is given. In the process, split bloated readline code to AC_LIB_READLINE in acinclude.m4. TODO: Is this the right way to handle readline yet? Can this code be replaced with code that doesn't depend on semantics of -L and -R options to GCC/loader? commit c9b938c054fb66198dba610bb0c11617215dec5c Author: Bart Massey Date: Sat Apr 14 08:05:02 2001 +0000 5 bits == 62.5 cents commit 3dd60e0703dc1dbd495710aed7b3a9cd3710ed95 Author: Keith Packard Date: Fri Apr 13 23:45:09 2001 +0000 Get malloc/free definitions from stdlib.h commit 03b40c5b8ae225dfee9c3725bb207443e85aefd9 Author: Bart Massey Date: Thu Apr 12 08:23:11 2001 +0000 Added cribbage scoring example. commit 5488903ee244f520e6cdb0ec50ceedb5a24942d4 Author: Keith Packard Date: Tue Apr 10 07:57:36 2001 +0000 Block lexer until stdout is writable commit 6d9c8853ef4557c6b90e9c1489b283fdb75b74ef Author: Keith Packard Date: Tue Apr 10 06:17:38 2001 +0000 Run aclocal before autoheader commit 769c8bce229e1921e7ec9851beb39364afe8d16e Author: Keith Packard Date: Tue Apr 10 06:00:54 2001 +0000 Fix up builtin.5c to use installed version, fix configuration to set associated variable commit d896656d85c62ee1048f4b0538cdd4caf2d1d81d Author: Keith Packard Date: Tue Apr 10 05:12:52 2001 +0000 Make builtin.5c just use lex_library instead of embedding path names commit 42174a17fac9deec8c8a517d9dac839a31774efa Author: Keith Packard Date: Tue Apr 10 05:00:29 2001 +0000 pkgdatadir only exists in Makefile, not config script commit 7cfbaedefa728aaab2d6afb06ee8fc3568d04f0c Author: Keith Packard Date: Tue Apr 10 04:25:28 2001 +0000 Change default prefix dir to /usr/local commit a15041e8c3953bc1252e08a6e32b1beef95ed472 Author: Keith Packard Date: Tue Apr 10 04:18:11 2001 +0000 Prepare for RPM release commit 414fc6b58b1dbe7b2911f7962d24d78aede0c938 Author: Keith Packard Date: Tue Apr 10 03:56:35 2001 +0000 Add spec file to build rpms commit 01818ff505f336c66869097820605d457fc96f32 Author: Keith Packard Date: Tue Apr 10 03:55:50 2001 +0000 Fix data directory installation troubles (should have used pkgdata_DATA) commit 7354ae328a68c85c173fd4f3101435955dcd379d Author: Keith Packard Date: Mon Apr 9 06:49:56 2001 +0000 Pass -DVERSION on compile command line commit 72e087c85789ee639f39e6b8faaae0202f6f4aaa Author: Keith Packard Date: Mon Apr 9 06:37:43 2001 +0000 Make imprecise conversion to int fail with insufficient bits commit 54bb545dea04354c2dad94db102c9f1be1a75344 Author: Bart Massey Date: Mon Apr 9 05:45:33 2001 +0000 Finished all of manual except for fully-.5c namespaces. Changed the semantics of Environ slightly to tighten the type of get(). Since it's not used anywhere I can find, this probably won't hurt :-). commit 1c33db59f62dc3d33a3fa1402019a6308908488d Author: Keith Packard Date: Mon Apr 9 05:02:25 2001 +0000 Recognise commands only at start of line commit 67d73e27a6692b10484c15a16d038c0be8a10e74 Author: Keith Packard Date: Mon Apr 9 04:28:24 2001 +0000 + Detect void tail calls + Fix tail calls to builtin funcs + Make fork a low-precedence unary op + Fix factorial to avoid churning memory commit 1c5647ae0f83cd11408393ce05715ffa1b02e7c8 Author: Keith Packard Date: Mon Apr 9 03:24:53 2001 +0000 Eliminate spurious ReturnVoid in TailCall case commit a95557a8113f81f4a914ca08a344756a61280b05 Author: Keith Packard Date: Mon Apr 9 03:20:02 2001 +0000 Add tail calls commit aeb7f97e06ee00773880c7f9e6ec5942005f71b7 Author: Keith Packard Date: Mon Apr 9 02:26:09 2001 +0000 Automatically allocate fully specified composite types commit b4c9c3abbe7860942e11df26b9747c4e201a72df Author: Bart Massey Date: Mon Apr 9 02:09:22 2001 +0000 Got NICKLELIB out of the Makefile now that it's in configure.in properly. Took the default binding for NICKLELIB out of builtin.c, on the theory that something's wrong if configure doesn't build it. Added a couple of static types to math.5c. Finished File section of manual. commit b12dbbe23e7eee4e31493b53a2f0bcd3b7f2d849 Author: Keith Packard Date: Sun Apr 8 21:52:48 2001 +0000 + Move e and pi from builtin.c to math.5c + Delete gratuitous Syntax namespace from command.5c + Add protected scope - protected names are visable but not exported + Fix NewLexInput to set interactive value commit 78db835effd462826a68e4cc57133c88d334f46a Author: Bart Massey Date: Sun Apr 8 21:11:17 2001 +0000 Finally got config.h to have NICKLELIB defined. More fixes to argument parsing. commit 909021013f80b71a58f9c002c40866228072f2f8 Author: Bart Massey Date: Sun Apr 8 20:48:52 2001 +0000 *** empty log message *** commit b6ff671ae18c30d7b883cf346f96628462403ace Author: Keith Packard Date: Sun Apr 8 20:12:44 2001 +0000 Make lex_library builtin commit 1c0a8a2c466b89ef20047e0c50ead7e16988be4e Author: Bart Massey Date: Sun Apr 8 19:51:49 2001 +0000 More manual. Fixes and cleanups to some examples. Argument parsing implementing most of the spec. commit f08fc654e5ee7e1c1dc6ca02913c1a422ab18f1a Author: Keith Packard Date: Sun Apr 8 02:56:25 2001 +0000 Functions declarations werent equivalent to initialized variable declarations commit f56e2183cfdfb12e33cdb84750201e18599205da Author: Keith Packard Date: Sun Apr 8 01:23:01 2001 +0000 Raise exception on negative square root commit 4926f41d019fce50bd15c847627ade582cc067c7 Author: Keith Packard Date: Sun Apr 8 00:10:25 2001 +0000 Identify nesting of brackets in lexer commit e77206529e6d82414a6f89d26479f0476a5b999b Author: Keith Packard Date: Sat Apr 7 22:57:16 2001 +0000 Fix a few examples to track language changes. Add LexFileAfter commit bcf7e96f93dd1836d57a63e4cce472172c97b0b0 Author: Keith Packard Date: Sat Apr 7 19:21:25 2001 +0000 Unify attendnl/ignorenl on brackets commit d9f03bc5c8ea913a4aa3667be8ea5caba4ed6a60 Author: Keith Packard Date: Sat Apr 7 06:32:51 2001 +0000 Allow empty array/struct initializers in declarations. Fix rijndael example to match grammar changes commit 03121a0225301abbab024cfefb51802c3ae610f9 Author: Keith Packard Date: Sat Apr 7 06:21:36 2001 +0000 Allow empty array initializers (alas, requires {}) commit 9fed9e7b1bffcfea1fdd035fe6dbdaf5dd95a9bb Author: Keith Packard Date: Sat Apr 7 06:01:58 2001 +0000 + fix compile error bug in printing atom names + floating point printf was doing large rational computations + make newlines ignored during struct/array initialization + allow C-style initializers + fix precision errors in exp/log functions + track abort at top level operator functions commit eaa44f81d9b80907a9d794db9fe7dcdc69760255 Author: Keith Packard Date: Sat Apr 7 00:02:15 2001 +0000 Tune e format rational printing commit ffde1ab383266bcce0a99ef3868ea09679fb7dbf Author: Keith Packard Date: Fri Apr 6 23:08:26 2001 +0000 Add e format for rationals less than one commit 6ef33d1664047b8c56c6cb4ff27150c416b09193 Author: Keith Packard Date: Fri Apr 6 21:29:57 2001 +0000 + Provide FilePrintf format 'S' for pretty-printed strings + Display current token with syntax error message + Track and correctly reset top-level namespace on parse errors commit a7eff623ac7081daa6c8ecc919e834284b006e02 Author: Keith Packard Date: Fri Apr 6 20:26:28 2001 +0000 Use char * as Atom. Use SymbolPtr instead of NamePtr commit 9a85acd4ac32df1c6a1520c467aec947bf43ed8d Author: Keith Packard Date: Fri Apr 6 09:32:27 2001 +0000 Declare ParseCanonType before using it in the grammar commit 7452e7b2d6d6ffa8b489fc22ea757c51e087772a Author: Keith Packard Date: Fri Apr 6 09:30:23 2001 +0000 Syntax error in grammar (caught by bison) commit c214a0d0edeea757eb689500a3151499a2f0444d Author: Keith Packard Date: Fri Apr 6 09:21:55 2001 +0000 Broken some errors with symbol changes commit dbfc2e0051d8ea16508acc107d3ee8726574845c Author: Keith Packard Date: Fri Apr 6 09:16:03 2001 +0000 Remove bogus NameSymbol macro commit 2efbf5132e7a19db5d3f2989d332b3a174efea88 Author: Keith Packard Date: Fri Apr 6 09:10:44 2001 +0000 Move symbol creation into parser commit a3e7f3e97e5e8a6ce974418418bd146818d52581 Author: Keith Packard Date: Fri Apr 6 07:53:10 2001 +0000 Clean some things up now that typedefs are gone from the compiler commit 93ed6069c593f5f43de4b27b1d1927cb074c7aba Author: Keith Packard Date: Fri Apr 6 07:18:21 2001 +0000 Add Rijndael example commit e583cc398f41dff390c246940c962713d4a56b54 Author: Keith Packard Date: Fri Apr 6 06:30:09 2001 +0000 Import from even uncompiled namespaces by referencing the original namespace name commit 828179625dcbdbbed9d37fefb549ac5891a9c744 Author: Keith Packard Date: Fri Apr 6 00:27:08 2001 +0000 Add initializer example commit 3e1f0f43c4db50d974092dc67b8f5ecff8ac9f8b Author: Keith Packard Date: Fri Apr 6 00:10:47 2001 +0000 Add dynamics to static initializers, fix name scoping in initializers commit 410f2a89cfb0c5ae88b91071525e674c774c0a7f Author: Bart Massey Date: Thu Apr 5 10:13:36 2001 +0000 Previous changes don't appear to have committed. Go figure. commit 4b630cbc4abfb7bd9d9f3d764432358e072acd58 Author: Bart Massey Date: Thu Apr 5 10:11:52 2001 +0000 Limited the scope of definitions in initializers to the initializer. Added an interesting printf in prime.5c. commit ad690cfe2273f5b7343729d6d2f445ab14d81346 Author: Bart Massey Date: Thu Apr 5 09:40:50 2001 +0000 Clean up printing of namespace contents and namespace qualified typenames commit a4497aacc308854e923e568e400d8f762917c078 Author: Bart Massey Date: Thu Apr 5 09:40:06 2001 +0000 Eliminate LALR(1) ambiguity in parsing struct/array initializers commit 09c0f58d00ca559dc683735a6a6dd85add768bf8 Author: Bart Massey Date: Thu Apr 5 08:44:02 2001 +0000 Allow import to use namespace qualified names commit f6e0f0fab4d0a838d589c6cdde1291f17a7b8368 Author: Bart Massey Date: Thu Apr 5 06:55:40 2001 +0000 Minor makefile.am changes commit 8723da03a0e1a008a1dd4fdbd1b36fb123b59e4b Author: Bart Massey Date: Thu Apr 5 06:54:57 2001 +0000 Hide non-public symbols in namespaces commit c7b2d372e9d2e7fee0b75c0d6642dba7855d5359 Author: Keith Packard Date: Thu Apr 5 00:11:42 2001 +0000 Clean up pretty printing of array constants commit 90ad4ea429598576867b9d575ff427906527f001 Author: Keith Packard Date: Wed Apr 4 22:54:53 2001 +0000 Parse-time symbol lookup to fix typedefs/namespaces commit cc46b8c3eb73f3b4a3661cb4b8cebd35e4390931 Author: Keith Packard Date: Tue Apr 3 06:39:10 2001 +0000 set Command::library_path from NICKLELIB commit e077895c6bb595c661c16a9c30c437b59c5c5785 Author: Bart Massey Date: Tue Apr 3 05:51:09 2001 +0000 Added autoconfigure.sh to Makefile.am Added -c to automake in autoconfigure.sh Deleted extra include of is_void() in builtin.c Much more manual. commit c2be4a160db95d74c08ee3f0c3e3e5aaec343976 Author: Keith Packard Date: Tue Apr 3 05:35:23 2001 +0000 Fix return type of exit and sign implementation commit cd7f91dd11dd99a81064c32a2c46e04f48fb89c5 Author: Keith Packard Date: Tue Apr 3 05:18:20 2001 +0000 Pass constant types up from lexer commit 427620f63e35ed0bbef8552b1a463ef792476f1b Author: Keith Packard Date: Tue Apr 3 03:22:08 2001 +0000 Make %v enclose rational in parens commit 0660c63470e19cdebd29c69963d0bd989b332787 Author: Keith Packard Date: Tue Apr 3 02:12:24 2001 +0000 Clean up value exception names and factorial types commit 7ece5df7960047b515cc87de81cd18d2b6f6b5fe Author: Keith Packard Date: Mon Apr 2 20:22:57 2001 +0000 reduce representations to lowest form commit 035b07cdcc563f7b75c9f647d3a2e89703dd7d32 Author: Keith Packard Date: Mon Apr 2 09:40:40 2001 +0000 Fix for -pedantic commit a7c517fc780492690f8c126465a726a52969a413 Author: Keith Packard Date: Mon Apr 2 09:19:00 2001 +0000 Allow readline to be optional commit 50497e56f0b22153e4363549092f97fe99b63098 Author: Keith Packard Date: Mon Apr 2 08:50:50 2001 +0000 Explicit dependencies commit 9eb4bad8059058658af30c49827a6298d1b482b6 Author: Bart Massey Date: Mon Apr 2 08:45:19 2001 +0000 Get rid of useless automake -i option. commit 0004e3e3a4d4ce7a4f1cba49a92fdb43bbb09766 Author: Bart Massey Date: Mon Apr 2 08:40:45 2001 +0000 Need a script for this... commit a8c402d26a5bc173a7ff8588f68ad5f90587e636 Author: Keith Packard Date: Mon Apr 2 08:22:36 2001 +0000 Remove generated files commit 65b78e6d7811c4fbc1cdf30eea3862a588c8a40d Author: Keith Packard Date: Mon Apr 2 07:08:16 2001 +0000 + rename set_jump/long_jump to setjmp/longjmp + Add readline support (with autoconf magic) + Set type of argv to array of string + Rationals are sticky, no longer reduce to integers + Change div operator to floor (a/b) to make sure result is int commit 7845c427918a76cbd874bb4d491b924bb759b4e5 Author: Keith Packard Date: Mon Apr 2 05:33:56 2001 +0000 Clean up unit type mess, add readline support, fix scheduler a bit commit 3ed61d82ca801f617885038a229400284653a7d5 Author: Bart Massey Date: Mon Apr 2 05:23:24 2001 +0000 More manual. Fixed buglet where initializers like {0...} would be lexed improperly. commit 862d6028281cc833aa5ae0ef86e6a5af055a6386 Author: Keith Packard Date: Sun Apr 1 07:14:36 2001 +0000 Typecombine reference subtraction commit e8a1fa0cf42a5171c6a22137a5fdcd2f08378c33 Author: Keith Packard Date: Sun Apr 1 06:47:33 2001 +0000 + Boxes have 'array' attribute now. + References to different elements of non-array boxes are treated as references to entirely different objects. commit 2fab55d60dac14824b10a7a5f099153289979894 Author: Keith Packard Date: Sun Apr 1 05:07:40 2001 +0000 Fix typechecking with references by using type in referenced object. Now pointer arithmetic typechecks correctly (at least at runtime commit aa31209374232ba881210abd5b01da0ad6e4afac Author: Keith Packard Date: Sun Apr 1 04:31:43 2001 +0000 Add variable array initializers. Dimensions must match commit d50e71263cdd9adce86941fca6c4862fed2aa14e Author: Keith Packard Date: Sun Apr 1 03:52:56 2001 +0000 Add library command and make NICKLELIB a path instead of a filename commit 167a51bb4df9b3a1c31af243d844fa75fa1a1fe0 Author: Keith Packard Date: Sun Apr 1 00:02:25 2001 +0000 Clean up a couple of missing expr types. Dont close input on execution error commit 9c793442f28c3bd79351099e3ebf1281b4ce9754 Author: Keith Packard Date: Fri Mar 30 23:30:39 2001 +0000 Use binary operations for arc4 and prng, improve some ancillary gcd routines commit da38ee7b173da99db36dde9de19df953d2a6c007 Author: Keith Packard Date: Fri Mar 30 21:15:31 2001 +0000 Replace bdivmod with faster implementation commit 361d537a41707720349e5ebb6699e592a157d752 Author: Keith Packard Date: Fri Mar 30 20:53:23 2001 +0000 Add some simple numeric tests commit 7e4e8d21e20cf0a656bf730627d2513fcde18269 Author: Keith Packard Date: Thu Mar 29 19:09:50 2001 +0000 Make sure exprs always have typesPoly on error commit ad3626eb429c5d5014e0d5db442152fc5ecf7f66 Author: Keith Packard Date: Thu Mar 29 19:03:32 2001 +0000 Allow twixt enter block to be optional commit 7da079357bb091b922db742c3591f91816109a56 Author: Bart Massey Date: Thu Mar 29 11:27:26 2001 +0000 Fixed bug in continue handling for while and do loops. commit 03036d47babb6599ee5608693a561b4cf33d0f12 Author: Keith Packard Date: Thu Mar 29 08:12:01 2001 +0000 Fix gcd (again) commit 2a91424cc0119c26c58e127919a242a256181dc1 Author: Bart Massey Date: Thu Mar 29 07:23:23 2001 +0000 Added more manual. Fixed bug in twixt statement with empty leave and enter expressions. The break statement will now exit the nearest enclosing twixt statement when applicable. commit f0d153d1c7c7e9bdd5537402931c30323b859ed9 Author: Keith Packard Date: Thu Mar 29 05:26:54 2001 +0000 Allow untyped declarations commit 5fc394de2388d4782f8bc62c641253e466cbc25b Author: Keith Packard Date: Thu Mar 29 05:14:47 2001 +0000 Need args box even for exceptions without arguments commit 4f881c551651cacb6996a83e9eb396f452f928b4 Author: Keith Packard Date: Wed Mar 28 10:20:50 2001 +0000 Array bounds check exception was busted commit a32880ee51f31d3419c3521838b6706676f15a15 Author: Keith Packard Date: Wed Mar 28 10:11:23 2001 +0000 Complete weber gcd code commit 5c5c03aaf2df03341914e28181017f6e01830a6e Author: Bart Massey Date: Wed Mar 28 09:07:18 2001 +0000 Make double-quotes in strings and single-quotes in chars print escaped. commit dd9c2b1cb756a76fcc49b08fe63a02030b3bee2d Author: Keith Packard Date: Tue Mar 27 19:59:45 2001 +0000 + Add bdivmod accelerator for gcd + Unify natural helper routines in natural.c commit 5dda54cbdfd4410a907c0dc64af9425741d7e906 Author: Bart Massey Date: Tue Mar 27 08:10:16 2001 +0000 Some of the stuff I committed previously seems not to have happened. I hate CVS. commit bb6bb663319cfd92038c9e46714c9f6fd0f3d816 Author: Bart Massey Date: Tue Mar 27 08:08:07 2001 +0000 Fixed funny -W flag in Makefile.am. Cleaned up TODO list. Changed Strings type to String for consistency. Fixed miller-rabin prime-finder to probe randomly rather than sequentially. Added idiot-level random-number test. Added demo driver for rsa example. Regularized \r,\n,\b,\t,\f support. More of the manual is there. commit 5fd838f8d4bea566ec8747f15736cbe18dc6c5a3 Author: Keith Packard Date: Mon Mar 26 06:55:06 2001 +0000 add bit_width commit 8c17733e29ce487a52447dd07ab64ad7e5618070 Author: Keith Packard Date: Mon Mar 26 05:35:46 2001 +0000 + Clarify that 'void' means the same as the ML 'unit' type + Make void a subtype of poly + fix type testing functions to take poly arguments to avoid runtime errors commit cbf74e5bba51bc38d2177db4d360f4fd7ae987a2 Author: Keith Packard Date: Sun Mar 25 21:00:30 2001 +0000 + Now that declarations are expressions, they often need a type and value. Declarations uniformly have the current type and value of the last declared variable. This may not be reasonable for static/global variables, but other alternatives are less plausible: function foo () { int i = (static int k = 1); k++; return i; } k is initialized when the func is evaluated (i.e. when foo is assigned to). So, each time foo is called, that value will be incremented by 1 leaving foo returning an increasing sequence of values. commit f701f8515af61dafb8ca9b34a191812c3bb82c3b Author: Keith Packard Date: Sun Mar 25 20:02:00 2001 +0000 Clean up array/string referencing exceptions commit 68dff2a6fad3c046f92567e1ab661035476941b7 Author: Keith Packard Date: Sat Mar 24 05:26:12 2001 +0000 + Speed up 1 and 2 digit GCD (still need Ken Weber's algorithm for longer) + Shorten e/pi constants to dramatically reduce startup time. commit 0762caf93b8b99a20d2462d27c761cf16dcaf076 Author: Keith Packard Date: Fri Mar 23 19:12:00 2001 +0000 Cache small ints commit 32c82f47ae01f5ac8ce5574e62bc41cb9a40c927 Author: Keith Packard Date: Fri Mar 23 18:49:34 2001 +0000 Clean up startup file handling commit 3ff4c6e46d263f85e1770e0fa3fc9f8f049659a3 Author: Keith Packard Date: Fri Mar 23 08:24:44 2001 +0000 Add primitive -e command line processing commit 33474fe5ee5c282966cb98629b9f1c682c126d79 Author: Keith Packard Date: Fri Mar 23 07:30:30 2001 +0000 Pretty print exception declarations correctly commit db0421516383c76308addf668b6dcb73f0c1306a Author: Keith Packard Date: Fri Mar 23 07:04:49 2001 +0000 Add command.5c builtins commit 0aed09add6e57473540874dc4d926e748fd9a775 Author: Keith Packard Date: Fri Mar 23 07:04:23 2001 +0000 + Add syntax extension for new commands + replace existing commands with syntax extensions + Add real unit type + Fix top level expression evaluator to not print void function returns + Reduce error cascade from invalid function calls + Typecheck return values both runtime and compile time + Debugger variables were typed wrong + Add debugger commands when debugger is running + Reset to interactive input (if any, else close input) on unhandled exception + Fix edit to work with mkstemp + Allow ';' at end of commands + Pretty print decl expressions and statements commit 9f2a174947b7d87d845801187b001a1fce0b1249 Author: Keith Packard Date: Thu Mar 22 23:32:49 2001 +0000 Fix lex input to be a simple list commit 6d01b52e222de68f9a387f5d7b7ffb2adc282311 Author: Keith Packard Date: Thu Mar 22 08:18:03 2001 +0000 Switch array syntax around in examples commit dda4b856db68e246b4a7334491e2b208cf95fc97 Author: Keith Packard Date: Thu Mar 22 08:07:22 2001 +0000 Tagless GC isnt done yet commit 16a45e16c42997ab874ee65df3dec105f9723b8b Author: Keith Packard Date: Thu Mar 22 08:04:03 2001 +0000 More efficient lg implementation commit 6331583b27e3c4efbd667857375fdc7cb4f5222d Author: Keith Packard Date: Thu Mar 22 07:42:58 2001 +0000 Place declarations inside compound statements in nested namespace commit 4998124b1bd81fb44396944cd89e8f4659081a90 Author: Keith Packard Date: Thu Mar 22 07:24:50 2001 +0000 Change constant array syntax to make it sensible commit 2d3bff7b73ac382579760822be5cf5187c4ba80c Author: Keith Packard Date: Thu Mar 22 07:14:47 2001 +0000 Make declarations expressions so they can be used in more places commit 299881608e46b81ff8809a867a69a39bbe0c2146 Author: Keith Packard Date: Thu Mar 22 06:29:24 2001 +0000 Add string io and pipes, plus fix float ceil/floor to handle overflow case commit b40f94961f7bf25dac3b2c41e90594698cbb38b9 Author: Bart Massey Date: Thu Mar 22 04:28:56 2001 +0000 Added many new examples and cleaned up old ones. commit 8a88854dc695937439a95efc16cc7f42342408b5 Author: Bart Massey Date: Thu Mar 22 02:12:22 2001 +0000 Cleaned up Math a bit. Fixed bad bug in PRNG: low-order n%8 bits of random numbers were unset. commit 9115b1d2b4be0cca380d41ed194c118f73a1b78b Author: Bart Massey Date: Thu Mar 22 00:49:09 2001 +0000 Added crypto PRNG based on ARC4. Started docs update. commit 46b393b6fc97b7af7ebd61e403124921b0d0452e Author: Bart Massey Date: Thu Mar 22 00:36:50 2001 +0000 Commented out BSD_RANDOM support in builtin.c. Added crypto PRNG based on ARC4. Started examples cleanup. Started documentation update. commit 66baa73b7007b6f92217a97346d0fc3369ada07d Author: Keith Packard Date: Thu Mar 22 00:35:50 2001 +0000 Remove memleak files commit d7fc0c5e2aa8bb872916b0a5ba05feca77c18a25 Author: Keith Packard Date: Thu Mar 22 00:26:31 2001 +0000 Rename arc trig functions to asin et alia commit 8dcaa9ae626a5195d556e8553a35d258e80b9d5c Author: Keith Packard Date: Wed Mar 21 22:12:19 2001 +0000 Array initializers typechecked at compile time, built arrays get type set now commit 91a87f95001e63bbbaa63d23ed9723a7b6807898 Author: Keith Packard Date: Wed Mar 21 20:49:27 2001 +0000 Fix multi-dimensional array initializers commit 9758756f59191dcf59360bafd61f10d50d3e4013 Author: Keith Packard Date: Wed Mar 21 18:38:18 2001 +0000 Fix array constant syntax commit 1f706251addcd977886d65bfce039cce8be47a3d Author: Keith Packard Date: Sat Mar 17 07:04:00 2001 +0000 Add nickle great circle example commit 06f3293cd3b8d39fb00b9964adc526dc8d27b8df Author: Keith Packard Date: Sat Mar 17 07:03:34 2001 +0000 + Rename 'integer' to 'int' + Fix imprecise argument type to real + Use different tag in expr tree for character constants + Do both anonymous and tagged unions everywhere in typechecking + Update examples and library to use 'int' commit 78eb7f17b6e73d155d1da670d4a8c8bd034fa02f Author: Keith Packard Date: Sat Mar 17 05:50:09 2001 +0000 Make 0 be integer and *poly, allow circular typedefs commit 2d23889b8c7272514a98040e44200cd109ac4165 Author: Keith Packard Date: Fri Mar 16 20:31:22 2001 +0000 Compile-time catch typechecking fix commit f267e15b1014672986c28381fbef07dc7c899a17 Author: Keith Packard Date: Fri Mar 16 20:17:21 2001 +0000 Make mutex exceptions public commit 7a27cce7f0ff8551e365654d4e922d9fc8ecd501 Author: Keith Packard Date: Fri Mar 16 20:14:07 2001 +0000 Add mutex example commit 9b73505b3d3504b69257bdcb47e819760825d53e Author: Keith Packard Date: Fri Mar 16 20:13:50 2001 +0000 + Add mutex datatype in nickle + Fix syntax of 'raise' statement (missing ;) + Pretty print union constructors + Type system internally uses anonymous unions, make them not affect real unions commit 10bf2b9be833211d08543d9e7908a49b5ce5fb6f Author: Keith Packard Date: Fri Mar 16 18:57:12 2001 +0000 + Avoid type error cascade by setting failed type checks to poly + Add a few missing compile-time typechecks + Add void function "type" + Move runtime argument typechecking to also typecheck builtins commit 8af44eb07f4f58a95f10b29c15c3d3d0a26ec00d Author: Keith Packard Date: Fri Mar 16 17:23:47 2001 +0000 Add a few more examles commit f4682f8d6b73b50dca237e602d4c3dbe4e42b366 Author: Keith Packard Date: Fri Mar 16 17:23:24 2001 +0000 Back to tagged unions commit 233acc40aa2dab5cff754c4bec846539a4bd4f79 Author: Bart Massey Date: Fri Mar 16 07:29:01 2001 +0000 Auto-generated file. commit decfd312de11eaec1b670cfeab78604b1f841cbd Author: Keith Packard Date: Thu Mar 15 23:40:13 2001 +0000 Improve builtin typechecking commit 36d11ceee354f6af4692612b40a5b9ad686d5b93 Author: Keith Packard Date: Thu Mar 15 19:28:06 2001 +0000 + Fix new invalid_unop_type exception builtin defintion + Clean up formatted type printing code + Fix unary type combinations to use same structure as binary commit 79db4ca8b75809649728797267c752ee7fec5b54 Author: Keith Packard Date: Thu Mar 15 18:22:24 2001 +0000 + Clean up and unify internal formatted output code + Lexically identify assignment operators + Make '^' be xor and '**' be exponentiation + Add invalid_binop_types and invalid_unop_type exceptions + Fix type inheritance in binary operators for poly type commit f69fa953e80b3c0833d2347862c8f8b05fb281c4 Author: Keith Packard Date: Wed Mar 14 09:03:45 2001 +0000 + Clean up asychronous events and instruction restarting semantics + Switch to sigaction under #ifdef HAS_SIGACTION. No autoconf/automake yet + Replace binary semaphores with counting ones + Implement WakeOnce scheduling option commit 86c7aff4756c1b019fdcd92806c9693e96e5c7c0 Author: Keith Packard Date: Tue Mar 13 08:03:37 2001 +0000 ThreadStep was not inline in last patch commit 1e47e9d190d3ed25a78ae0e163797a28f8b00787 Author: Keith Packard Date: Tue Mar 13 08:02:17 2001 +0000 Fix array compile typechecking. Missing a couple MemReference calls for threads commit cc177c3eea93ec96ff3c7c31e01b652cb944bc8d Author: Keith Packard Date: Tue Mar 13 00:16:22 2001 +0000 Ad-hoc unions commit 4b819d61c8089c81ec611434b357bd977c395ed6 Author: Keith Packard Date: Mon Mar 12 08:20:46 2001 +0000 Add union.c for union types commit be76665a738eab693970d72c2b76515d21a601d8 Author: Keith Packard Date: Mon Mar 12 08:17:14 2001 +0000 + Add standard exceptions raised by bytecode machine and builtins + Use standard exceptions in some places. Lots more editing to do here. + Detect misplaced break/continue at compile time. + Change union type to tagged union. + Automatically build struct/union objects as needed + Add 'union switch' statement to allow run-time checking of union tag + Mark compile errors with file/line + Eliminate internal statement cruft from error printouts commit 13dc8e4a4f27846b4f8e1f0c4319f17220234fb6 Author: Keith Packard Date: Sun Mar 11 03:21:25 2001 +0000 Allow unset values in type checking commit ba87a810c19fd45a457335432fb6f03f5ef0aad9 Author: Keith Packard Date: Sun Mar 11 00:55:31 2001 +0000 Fix union type computations commit 6d9170e6df775ae538802c3a9d852d0685ec604a Author: Keith Packard Date: Sat Mar 10 21:15:29 2001 +0000 Add union types commit fc846542bff8216f8f0a4c5be4e1075daa4ba0d6 Author: Keith Packard Date: Sat Mar 10 18:46:04 2001 +0000 Avoid infinite recursion in typecheck (no unification yet), fix canonicalization of struct types commit 01fdfa6319182d749afe2a4dc22ca79b040b0462 Author: Keith Packard Date: Sat Mar 10 12:32:09 2001 +0000 Document recent additions commit 5bbe32c4cbf110bd567ba0b126b620c82d783a80 Author: Keith Packard Date: Sat Mar 10 12:22:11 2001 +0000 Forward typedefs, deep assignment type checking commit 8536b07f3f84257e153a1208c022986b95f76a15 Author: Keith Packard Date: Sat Mar 10 11:10:55 2001 +0000 Remove MakeOut again commit 3d4ebe28695d6148f557ec8534ddcd3ddb2db40e Author: Bart Massey Date: Sat Mar 10 09:15:02 2001 +0000 No default initialization commit c65481f78b5a7662476370602a76cb678faa5356 Author: Bart Massey Date: Sat Mar 10 05:43:35 2001 +0000 Add extend namespace statement commit 73981ec4d398328e0113078cd01a6ccb4c7678d3 Author: Bart Massey Date: Sat Mar 10 04:37:09 2001 +0000 Remove config.log commit cf9183822bbcd25c7566f8591a1af0d9400bae0a Author: Bart Massey Date: Sat Mar 10 04:33:32 2001 +0000 Fix gram.h dependencies commit 7be0b3407015b2e43eaa66180671807f86c2d9e4 Author: Keith Packard Date: Sat Mar 10 00:40:54 2001 +0000 Remove .tar.gz file commit 1cde98a331ae9fbd6c0e0a028e3ef9e338cbc12f Author: Keith Packard Date: Fri Mar 9 22:25:46 2001 +0000 + Add scanf.5c which has scanf, vscanf, fscanf and vfscanf + Remove bogus scanf builtin + Add File::ungetc + Fix compiler to catch jumping past end of function + Fix Debugger::dump to label branch targets + Fix aetov to work with base != 10 + Reimplement pretty printing of arrays and constructures commit 768a7504d1e8f4c0208a2c98af6ea73197f771b6 Author: Keith Packard Date: Fri Mar 9 18:52:33 2001 +0000 add switch statement, change namespace separator to :: commit d1e84c31276394101dceea194c63c249740fdce2 Author: Keith Packard Date: Fri Mar 9 01:50:31 2001 +0000 + Add some builtins to manipulate file status (end, error, clear_error) + Fix string typechecking commit 87912122d5491ee5ea0610f485eef290c4ff6621 Author: Keith Packard Date: Fri Mar 9 00:40:14 2001 +0000 Add string<->integer conversions commit 67a86554b24f62e0d08e93e81ada7d9a9f262344 Author: Keith Packard Date: Thu Mar 8 22:54:29 2001 +0000 Allow varargs param to have type and name commit 9e096e03f95125f41c775b6a55051116d635c816 Author: Keith Packard Date: Thu Mar 8 18:51:26 2001 +0000 Add varargs functions. commit 2531eefd9c86c144640ab9dbd5ad902f5b66c439 Author: Keith Packard Date: Thu Mar 8 08:00:09 2001 +0000 + Add shift operators (<<, >>) + Add logical operators to integer type + Add xor builtin function + Add log2 in math.5c commit 06443806da290859ce3af15fce1671824a6e1006 Author: Keith Packard Date: Thu Mar 8 01:42:17 2001 +0000 Add kaiser window filter design app commit 672b9260d1a2267fbadacd8d1c791cfc7a60894e Author: Keith Packard Date: Thu Mar 8 00:12:30 2001 +0000 + fix floating point floor/ceil when mantissa needs to change + Compiler was overwrting memory when error detected commit 98105000a0375c5bbfb824c3c046c62212078e70 Author: Keith Packard Date: Wed Mar 7 23:35:53 2001 +0000 Allow artificial precision increase for floats, take advantage of that to improve precision of trancendental math functions commit 5d79a6bf2ddac9a014678c423828a20e729108ba Author: Keith Packard Date: Wed Mar 7 18:24:10 2001 +0000 + Fix interactions between twixt and exceptions, this requires the exception arguments be saved during the twixt and pushed on the stack before the exception handler is invoked. + Clean up stack handling for long_jump/set_jump, now set_jump fixes the stack before returning so that long_jump gets a clean version + Pretty print additions for twixt, try and raise statements commit 452672e67c1f1bce9d2b97cc30be3dabe92decbe Author: Keith Packard Date: Wed Mar 7 08:50:46 2001 +0000 Twixt not active until *after* enter expr, clean up jumping down into twixted continuation commit 48cc53270799f697cd60318a7f044cf18fc3dbb2 Author: Keith Packard Date: Wed Mar 7 08:11:45 2001 +0000 Replace . with : for namespace separation commit e9eee80304b322c8ad8585b7e750a86dfc9ff665 Author: Keith Packard Date: Wed Mar 7 07:46:27 2001 +0000 Turn off divide checks commit 7e6e116caf1de76b4a2c32bac70512709fafcc26 Author: Keith Packard Date: Wed Mar 7 07:37:15 2001 +0000 + New symbols now always get dumped into the namespace before older ones. + Found and fixed a nasty divide bug caused by overflow in 64/32 division + Sped up math library, replacing arctan function and precision estimates commit 6c0fa57c597abea0dc99fb44af5e4b9170a429e9 Author: Keith Packard Date: Wed Mar 7 00:00:52 2001 +0000 Update TODO to remove ^ work commit 4a382f845630275ca3ad36451c3ffd1d4a449123 Author: Keith Packard Date: Tue Mar 6 23:58:37 2001 +0000 Fix adding names to existing namespace, have ^ call pow and ^= call assign_pow commit b42e586f10838d628b66e8f1ad3763ef82adb304 Author: Keith Packard Date: Tue Mar 6 19:52:20 2001 +0000 Update TODO commit 826c49e81e597512c8652c2389dbc3d540b6f682 Author: Keith Packard Date: Tue Mar 6 19:47:54 2001 +0000 Initial twixt implementation commit f041ce0c4b33e5b1f4ce05727de50646335c9225 Author: Keith Packard Date: Mon Mar 5 10:35:20 2001 +0000 Clean up math library dependencies commit 5819f01760151e5a0335e0cdfbb35daa4a71cc88 Author: Keith Packard Date: Mon Mar 5 10:16:35 2001 +0000 Box allocated incorrectly (used Type instead of Types *) commit 4e139e3c1d8a1c900bf47b077fc856aecc18b266 Author: Keith Packard Date: Mon Mar 5 10:04:21 2001 +0000 Add Debugger.collect() commit c530eb605b448666ed5572bc0c61222774231b0e Author: Keith Packard Date: Mon Mar 5 09:45:04 2001 +0000 Audit mem reference code commit 01ce5eb8f8cc9ad84afc6c3b66a195d0cb0b4e54 Author: Keith Packard Date: Mon Mar 5 09:43:58 2001 +0000 Audit mem reference code commit 72bbfe51f43d37695388be7828a7bc0960e37953 Author: Keith Packard Date: Mon Mar 5 09:12:23 2001 +0000 Missing tag in new typespace datatype commit 9c468c614f9888b587a797592ba2a2704c115b79 Author: Keith Packard Date: Sun Mar 4 22:14:28 2001 +0000 Update TODO list Track compilation errors better to avoid excuting garbage Replace thread in debugger with continuation Remove ThreadError state Poll for file read as well as write in non-blocking case Lexically scope typedef names to allow cleaner grammar commit 1858aec67558177a70f65e9d6783a25151727ae5 Author: Keith Packard Date: Sun Mar 4 01:06:38 2001 +0000 Implement try/catch commit 93b0e8893acc0270537cf648db966c9511c6be04 Author: Keith Packard Date: Fri Mar 2 22:39:45 2001 +0000 Comment out diagnostic printfs from exp commit c43cc27944fea4bef7b4be625994520b732ed3a6 Author: Keith Packard Date: Fri Mar 2 22:35:17 2001 +0000 + Clean up compile file, add comments, rationalize function names. + Fix struct/array typechecking + Allow function foo (a); declarations (again) + Add syntax for try/twixt statements + Limit iterations in math functions to reasonable length + Replace pi computation with arctan formula commit cd577792213c32eb5f5cdae833e4c14b410a4d2a Author: Bart Massey Date: Wed Feb 28 09:40:07 2001 +0000 Fixed things up to autoload DATADIR/nickle/builtin.5c on nickle startup. Fixed some bugs and problems with .nicklerc loading. commit f9b3f9f693d1fe8326d1e6f8610f519f126a6264 Author: Keith Packard Date: Wed Feb 28 08:24:32 2001 +0000 Names created while debugger is running must not be compiled into the running function context. Precision fixes for math.log commit 8d2b179e1aa87e0daaa9228956ba587b5ff9e0c0 Author: Keith Packard Date: Wed Feb 28 07:01:22 2001 +0000 Clean up builtin function names. Now all are of the form: do_Namespace_function Predicates are prefixed with 'is_'. More functions moved into separate namespaces. Global replacement of 'Namespace' for 'Scope' Add type predicate functions and functions to extract pieces of rationals Fixed a bug in compiling function declarations which left an extra func on the stack. Add Debugger.dump to examine compiler output. Trap /0 in FloatDivide. Compute necessary intermediate precision correctly as well. Implement FloatMod. Fix floating == 0 Allow 'print foo.bar.bletch' in grammar. Complain about comments left open at EOF. Implement lots of nifty math primitives in math.5c (sqrt, cbrt, exp, log, log10, sin, cos, tan, arcsin, arccos, arctan, arctan2) commit 08d68fc3b7c8491cf4c75d9ea39807ef7246837f Author: Keith Packard Date: Sat Feb 24 18:44:30 2001 +0000 Add beginings of math library. Add mantissa/exponent funcs commit b87fead3280f2e32e5321ec62997a409c16359e0 Author: Keith Packard Date: Sat Feb 24 17:54:17 2001 +0000 Do not automatically cooerce numeric datatypes to type_float when assigning to real variables. commit 8717eb060479830617126b7c2f875cde95a7bf37 Author: Keith Packard Date: Sat Feb 24 10:45:41 2001 +0000 Make FloatFloor return Integer when possible. Recover from variable definition botch in debugger, new variables are stuck into class_auto even though the frame is active, references to those variables trash the current frame. This may be hard to fix; the kludge here only avoids crashing. Clean up a bit more lint. commit 9df433f213a2b07b5abd09ca4f9cda0974c7ec25 Author: Keith Packard Date: Sat Feb 24 09:23:00 2001 +0000 Remove old machine-specific double code commit ca33ccd8a70da5c4f978a9546d722d25a2ecf09f Author: Keith Packard Date: Sat Feb 24 09:21:49 2001 +0000 Arbitrary precision floating point file addition commit cdbec56003023bed4b63de27021810862cbba961 Author: Keith Packard Date: Sat Feb 24 09:20:21 2001 +0000 Replace machine-specific 'double' with arbitrary precision floating point. Replace 'double' datatype with 'real'. Lots of math functions are missing now... commit b69157cb31b902a514daaf21096eb6003212a68f Author: Keith Packard Date: Fri Feb 23 18:00:49 2001 +0000 Argument typechecking was walking actuals in the wrong direction. Builds without warnings using -Wall -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs-Wall commit d3479e9cd167556c67c21b81f3986e14b9629904 Author: Keith Packard Date: Fri Feb 23 06:32:51 2001 +0000 Pretty massive rewrite of the syntax to allow for full type declarations, typedefs and cleaner initializers. Everything that can be typechecked at compile time is now done, still missing is full run-time typechecking using compound types. That should be easy to add. Still ugly: typedef int foo; type foo bar; <- yuck! The current compiler won't allow for lexical-based typedefs like C uses, so we're left with allowing 'NAME' to appear for a typedef name. Yes, this is ugly. commit 1091b65da366e0fb4d9800d7747680ec129d93ca Author: Keith Packard Date: Tue Feb 20 05:52:00 2001 +0000 Only cast to double in assignments (yes, this is a hack) commit 912357b80e3d362cf3df83d737bd2229f655984f Author: Keith Packard Date: Tue Feb 20 05:42:51 2001 +0000 Remove nickle binary commit cb12bdb8bcb9f5d5f29ce78edeb8698f1fe9c90b Author: Keith Packard Date: Tue Feb 20 05:40:38 2001 +0000 Add *[ operator for dealing with ref arrays commit eca1dc89f171f29e4dd3d4ff6fc509a7daa76c9d Author: Keith Packard Date: Tue Feb 20 05:33:36 2001 +0000 Fix copy routine to always deep copy and then cooerce commit 66eed23be636cc8067479cd6b7c2813e10311f6e Author: Keith Packard Date: Tue Feb 20 04:26:09 2001 +0000 Remove config.h from CVS commit fee9090ee68d6824d8bebd03a621a4c957cd3af7 Author: Keith Packard Date: Tue Feb 20 04:24:46 2001 +0000 Remove stamp-h commit 7538410ad3e0e75d9355ccfa8e318d850a4603ea Author: Keith Packard Date: Tue Feb 20 04:22:37 2001 +0000 Remove date-sh commit 83d4a0c765530f4a96619c60a8bcc28fd43c126e Author: Keith Packard Date: Tue Feb 20 04:21:47 2001 +0000 Remove more auto-built files commit b94c6ce93eedc23f714a443d27274c59d92bba2e Author: Keith Packard Date: Tue Feb 20 04:20:27 2001 +0000 Remove configure intermediate files commit d75c04a34410c7529066c2a28a17f29bc79904d1 Author: Bart Massey Date: Sun Feb 18 04:03:24 2001 +0000 + implemented dim(array), dims(array) + implemented strings package length(string) index(string,string) substr(string,int,int) + various cleanups and fixes commit 585f945b64fe8eaeab7f0a726af4a9a59caf15c3 Author: Bart Massey Date: Sat Feb 17 23:57:23 2001 +0000 Added more stuff to do commit e991d9010444639bc979dfda287668ef0b3f80f9 Author: Bart Massey Date: Mon Feb 12 09:10:22 2001 +0000 Added a few small examples. commit 60747cd946a3632e6fdd01ed7b1b7117140e5904 Author: Bart Massey Date: Mon Feb 12 09:07:51 2001 +0000 Added examples? added to TODO list commit 780726ae0a2270f5f25b1096987a7ae0bb474e6e Author: Bart Massey Date: Sun Feb 11 01:27:11 2001 +0000 Additional files for first release. commit bfba0920e13990d296bddee6329c60d22f07388e Author: Bart Massey Date: Sun Feb 11 01:23:40 2001 +0000 Autoconf, portability, licensing, release prep commit 74da035790d05aef208f4a556c31679525589c3f Author: Keith Packard Date: Sun Aug 15 00:44:59 1999 +0000 lint from egcs commit 37c896608075ff256dda47a170ac2a6d41589539 Author: Keith Packard Date: Mon Jan 25 20:19:13 1999 +0000 Use signal macros commit 707849807c832ef1fe1671344c9a4f0a47406ff0 Author: Keith Packard Date: Mon Jan 25 17:38:34 1999 +0000 Fix add-back to trim leading zeros commit 1154fd1cff7d0e536d4ff61e85f7bcba2eea39cf Author: Keith Packard Date: Mon Jan 25 07:00:54 1999 +0000 Change compression in .uu to gzip commit 3b430e608c8255b1f28e0470688887f0be4fd441 Author: Keith Packard Date: Mon Jan 25 06:59:30 1999 +0000 Fix continuations to keep copy of evaluation stack, start adding exceptions commit b89a8967dc22802d3fffe8878660e747ff3884d7 Author: Keith Packard Date: Sun Jan 24 08:47:45 1999 +0000 Have CHECK only include division check code commit f3c8a9cfd4db33b94813ecf29f08760c8262a82e Author: Keith Packard Date: Sun Jan 24 08:47:15 1999 +0000 Add a few INLINEs to reduce function calls per instruction commit 3e91c40addd78e2f3035386d2917c8542b506271 Author: Keith Packard Date: Sun Jan 24 07:44:52 1999 +0000 Fix NaturalMask commit 587c55c61a2151b0797eef2e447f8a6b8e60011a Author: Keith Packard Date: Sun Jan 24 07:36:27 1999 +0000 Remove unused greaterequal commit 0d7c0458261d1291d92dc8acecda3444bb7f7acd Author: Keith Packard Date: Sun Jan 24 07:34:32 1999 +0000 Optimize division by powers of two commit db64260a80919fbcf6f782b694d35e4bd2da63c4 Author: Keith Packard Date: Sun Jan 24 06:59:43 1999 +0000 Change history offset to start at one commit f27ab0cd37566b0c0037ee091961728677cd7a77 Author: Keith Packard Date: Sun Jan 24 06:56:10 1999 +0000 Change history offset to start at one commit 807fecd704d53963083a315022730eac023f9aaf Author: Keith Packard Date: Sun Jan 24 06:53:04 1999 +0000 Only auto-declare variables in assignement statements commit abeb9d88365adb810cfb61227105671074b98751 Author: Keith Packard Date: Sun Jan 24 06:26:18 1999 +0000 Add continuations, change builtin code to handle flow control commit 2aa348ba04361c241e03ec9fabe614c69185a618 Author: Keith Packard Date: Sun Jan 24 06:25:48 1999 +0000 Fix ref type to handle comparisons commit 0de4109be3c3277d3b79c09958837ef84f6a6d36 Author: Keith Packard Date: Sat Jan 23 00:15:47 1999 +0000 Fix add-back case in divide, add time() builtin commit e7b6b2b04457c6dad2b50c47b8cb48e3127b2090 Author: Keith Packard Date: Fri Jan 22 01:55:46 1999 +0000 Fix builtin scopes and debugger, add random/srandom commit 06dbbd565d6faba77d2ebf66295be3beb4c7615f Author: Keith Packard Date: Wed Jan 20 05:24:03 1999 +0000 Bump to 1.1.0, get rid of gratuitous atom for struct vars, fix scope for top-level expressions commit ab5ef9ce3f6f9cff79800a76e453701518ccb83b Author: Keith Packard Date: Tue Jan 19 18:10:47 1999 +0000 Allow chained scope references commit 3cc203d0184c730e4d69accf4ca4e619e7676b92 Author: Keith Packard Date: Mon Jan 18 06:10:11 1999 +0000 Dont create empty local box commit 1412e73e105ab5fbd2e85f77455a9f2a49ed8c39 Author: Keith Packard Date: Mon Jan 18 06:04:23 1999 +0000 Create type list for frames instead of walking symbol table commit 08c0f2ae10b9dfd91e3e2dce3849d4de1e393406 Author: Keith Packard Date: Sun Jan 17 05:26:48 1999 +0000 Add public/private symbols in scopes, make import bring all public symbols into current scope commit 7206ef66ebabec7a1f017a23be37340ddfdf1eb1 Author: Keith Packard Date: Sat Jan 16 22:55:26 1999 +0000 Eliminate scope types, unify static and local scopes commit 1545e9ed8e1cf82c539ca1d649212c4da0c94d44 Author: Keith Packard Date: Wed Jan 13 09:04:37 1999 +0000 Abort in middle of factorial and large rational print commit e2494f5199df069e8d3d56e122f8aea33417b559 Author: Keith Packard Date: Wed Jan 13 08:55:20 1999 +0000 Scope names cant be used as variables commit 7785df4d68fb7916c7e333443ea0c82af1beb965 Author: Keith Packard Date: Wed Jan 13 07:48:47 1999 +0000 Add namespaces commit bcf2a5ad7557a211f4da1fb04875a4bfa8e42d76 Author: Keith Packard Date: Wed Jan 13 06:22:12 1999 +0000 Original version from some time ago. commit cbd084571ad1bbe24bc88b85562e6c04f7c16c64 Author: Keith Packard Date: Wed Jan 13 06:22:12 1999 +0000 Initial revision nickle_2.81.orig/math.5c0000664000175000000620000005543412351455146014303 0ustar keithpstaffextend namespace Math { public real pi = imprecise (3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679, 256); public real Ï€ = pi; protected real e = imprecise (2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274, 256); public real sqrt (real v) /* * Returns square root of v to the same precision as 'v'. * If v is precise and has a precise square root, returns that. */ { if (v < 0) raise invalid_argument ("sqrt of negative number", 0, v); real real_sqrt(real v) { real err; real prev, cur; int n, iter; v = imprecise (v); err = 1/(2**(precision (v)+3)); prev = imprecise (1 / (2**(floor (exponent(v)/2))), precision(v)); iter = precision (v) + 15; while (iter-- > 0) { cur = 0.5 * prev * (3 - v * prev**2); if (abs (cur - prev) < err) break; prev = cur; } return abs (1/cur); } if (v == 0) return 0; if (is_rational (v)) { int num, den; real num_s, den_s; num = numerator (v); den = denominator (v); num_s = real_sqrt (imprecise (num, bit_width(num) + 128)); den_s = real_sqrt (imprecise (den, bit_width(den) + 128)); num = floor (num_s + 0.5); den = floor (den_s + 0.5); if (num * num == numerator (v) && den * den == denominator (v)) { return num/den; } } return real_sqrt (v); } public real cbrt (real v) /* * Returns cube root of v to the same precision as 'v'. * If v is precise and has a precise cube root, returns that. */ { real real_cbrt(real v) { real prev, cur; int s = sign (v); v = imprecise (abs (v)); int result_bits = precision (v); int intermediate_bits = result_bits + 10; v = imprecise (v, intermediate_bits); real err = imprecise (1/(2**(result_bits+3)), intermediate_bits); cur = imprecise (1 / (0.75 * 2**(floor (exponent(v)/3))), intermediate_bits); do { prev = cur; cur = 1/3 * (2 * prev + v / prev**2); } while (abs (cur - prev) > err); return s * imprecise (abs (cur), result_bits); } if (is_rational (v)) { int num, den; real num_s, den_s; num = numerator (v); den = denominator (v); num_s = real_cbrt (imprecise (num, bit_width(num) + 128)); den_s = real_cbrt (imprecise (den, bit_width(den) + 128)); num = floor (num_s + 0.5); den = floor (den_s + 0.5); /* printf ("num %g den %g\n", num, den); */ if (num ** 3 == numerator (v) && den ** 3 == denominator (v)) { return num/den; } } return real_cbrt (v); } public real exp (real v) /* * Return e ** v; */ { if (v < 0) return 1/exp(-v); if (v == 0) return 1; v = imprecise (v); /* * Emperically determined scale factor. This * reduces the computation to working on values * near zero so that the power series converges * rapidly. Increasing this further makes the * power series converge more rapidly, but * makes the expansion step more expensive. */ int prec = precision (v); int scale; if (prec > 50) scale = 27; else scale = 12; int div = (1 << scale); int iter = prec + 1; int iprec = prec + iter; real mant = imprecise (mantissa(v), prec + iter) / div; int expo = exponent(v) + scale; real e = imprecise (0, iprec); real num = imprecise (1, iprec); real den = imprecise (1, iprec); real loop = imprecise (0, iprec); /* * Traditional power series * * exp(n) = 1 + n/1 + n**2/2! + n**3/3! */ while (iter-- > 0) { real term = num/den; e = e + term; if (exponent (e) > exponent(term) + iprec) break; num *= mant; loop++; den *= loop; } e = imprecise (e, prec + expo); e = e ** (1 << expo); return imprecise (e, prec); } public real log (real a) /* * Return natural logarithm of 'a' */ { /* * Copyright (c) 1985 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* log__L(Z) * LOG(1+X) - 2S X * RETURN --------------- WHERE Z = S*S, S = ------- , 0 <= Z <= .0294... * S 2 + X * * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS) * KERNEL FUNCTION FOR LOG; TO BE USED IN LOG1P, LOG, AND POW FUNCTIONS * CODED IN C BY K.C. NG, 1/19/85; * REVISED BY K.C. Ng, 2/3/85, 4/16/85. * * Method : * 1. Polynomial approximation: let s = x/(2+x). * Based on log(1+x) = log(1+s) - log(1-s) * = 2s + 2/3 s**3 + 2/5 s**5 + ....., * * (log(1+x) - 2s)/s is computed by * * z*(L1 + z*(L2 + z*(... (L7 + z*L8)...))) * * where z=s*s. (See the listing below for Lk's values.) The * coefficients are obtained by a special Remez algorithm. * * Accuracy: * Assuming no rounding error, the maximum magnitude of the approximation * error (absolute) is 2**(-58.49) for IEEE double, and 2**(-63.63) * for VAX D format. * * Constants: * The hexadecimal values are the intended ones for the following constants. * The decimal values may be used, provided that the compiler will convert * from decimal to binary accurately enough to produce the hexadecimal values * shown. */ real log__L (real z) { global real L1 = imprecise (6.6666666666667340202E-1, 64); global real L2 = imprecise (3.9999999999416702146E-1, 64); global real L3 = imprecise (2.8571428742008753154E-1, 64); global real L4 = imprecise (2.2222198607186277597E-1, 64); global real L5 = imprecise (1.8183562745289935658E-1, 64); global real L6 = imprecise (1.5314087275331442206E-1, 64); global real L7 = imprecise (1.4795612545334174692E-1, 64); return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*L7))))))); } /* LOG(X) * RETURN THE LOGARITHM OF x * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS) * CODED IN C BY K.C. NG, 1/19/85; * REVISED BY K.C. NG on 2/7/85, 3/7/85, 3/24/85, 4/16/85. * * Required system supported functions: * scalb(x,n) * copysign(x,y) * logb(x) * finite(x) * * Required kernel function: * log__L(z) * * Method : * 1. Argument Reduction: find k and f such that * x = 2^k * (1+f), * where sqrt(2)/2 < 1+f < sqrt(2) . * * 2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) * = 2s + 2/3 s**3 + 2/5 s**5 + ....., * log(1+f) is computed by * * log(1+f) = 2s + s*log__L(s*s) * where * log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...))) * * See log__L() for the values of the coefficients. * * 3. Finally, log(x) = k*ln2 + log(1+f). (Here n*ln2 will be stored * in two floating point number: n*ln2hi + n*ln2lo, n*ln2hi is exact * since the last 20 bits of ln2hi is 0.) * * Special cases: * log(x) is NaN with signal if x < 0 (including -INF) ; * log(+INF) is +INF; log(0) is -INF with signal; * log(NaN) is that NaN with no signal. * * Accuracy: * log(x) returns the exact log(x) nearly rounded. In a test run with * 1,536,000 random arguments on a VAX, the maximum observed error was * .826 ulps (units in the last place). * * Constants: * The hexadecimal values are the intended ones for the following constants. * The decimal values may be used, provided that the compiler will convert * from decimal to binary accurately enough to produce the hexadecimal values * shown. */ real bsd_log (real x) { global real ln2hi = imprecise (6.9314718036912381649E-1, 64); global real ln2lo = imprecise (1.9082149292705877000E-10, 64); global real sqrt2 = imprecise (1.4142135623730951455E0, 64); global real negone = imprecise (-1.0, 64); global real half = imprecise (0.5, 64); global real two = imprecise (2, 64); real s,z,t; int k,n; /* argument reduction */ k=exponent(x); x=mantissa(x); if(x >= sqrt2 ) {k += 1; x *= half;} x += negone ; /* compute log(1+x) */ s = x/(two + x); t = x*x*half; z = k*ln2lo + s*(t+log__L(s*s)); x += (z - t); return (k*ln2hi+x); } /* * Bounds checking */ if (a <= 0) raise invalid_argument ("log: must be positive", 0, a); /* * Checks to bring a into range */ if (a == 1) return 0; if (a < 1) return -log(1/a); a = imprecise (a); int prec = precision(a); /* * estimate = bsd_log (a). This gives 53 bits */ real v = bsd_log (imprecise (a, 64)); /* * Precision doubles every time around, start * with 50 bits and compute how many doublings are * needed to get the desired precision */ int maxiter = 0; int rprec = 50; while (rprec < prec) { rprec *= 2; maxiter++; } /* printf ("maxiter %g\n", maxiter); */ if (maxiter > 0) { int iprec = prec + maxiter * 16; v = imprecise (v, iprec); a = imprecise (a, iprec); int epow = floor (v); /* * compute log(v) = log(v/(e**epow)) + epow; */ v = v - epow; a /= exp(imprecise (epow, iprec)); /* * Newton's method * * v' = v - 1 + a * exp(-v); */ real one = imprecise (1, iprec); while (maxiter-- > 0) { real term = a * exp (-v) - one; /* printf ("v: %g term: %g err: %g term*err: %g\n", v, term, err, term * err); */ v = v + term; } v = v + epow; } return imprecise (v, prec); } /* * log10(x) = log10(e) * log(x) * * log10(e) = log(e) / log(10) = 1/log(10) */ public real log10 (real a) /* * Return base-10 log of 'a' */ { static real loge = 0; a = imprecise (a); if (loge == 0 || precision (loge) < precision (a)) loge = 1/log(imprecise (10, precision (a))); return loge * log(a); } /* * log2(x) = log2(e) * log(x) * * log2(e) = log(e) / log(2) = 1/log(2) */ public real log2 (real a) /* * Return base-2 log of 'a' */ { static real loge = 0; a = imprecise (a); if (loge == 0 || precision (loge) < precision (a)) loge = 1/log(imprecise (2, precision (a))); return loge * log(a); } real calculate_pi (int prec) /* * Calculate pi using the formula: * * PI = 24*atan (1/8) + 8*atan (1/57) + 4*atan (1/239); */ { /* * Estimate the number of digits available for * the specified value (v) after a certain number of * loops (p) */ real avail_prec (real v, int p) { real ret; ret = bit_width (p) - p * exponent (imprecise (v)); /* printf ("v %g p %g avail %g\n", v, p, ret); */ return ret; } /* * Compute the number of loops needed to get * the desired precision */ int loops (real v, int prec) { int p, low, high; for (high = 1; ; high *= 2) { if (avail_prec (v, high) > prec) break; } low = 1; while (high - low > 1) { p = (high + low) // 2; if (avail_prec (v, p) > prec) high = p; else low = p; } return high; } /* * Compute atan near zero * * atan(x) = x - x**3/3 + x**5/5 - ... */ real atan (rational den, int digits) { int p, q; int l; int prec, mult; real partial, result; real pv, qv, mden; p = 3; q = 5; mden = imprecise (den, digits * 4) ** 4; l = loops (1 / den, digits) // 2; /* * Need at least digits + log10(loops) for all intermediate * computations */ /* printf ("loops %d\n", l); File.flush (stdout); */ result = 1 / den; pv = 1 / (den ** p); qv = 1 / (den ** q); while (l-- > 0) { partial = pv / p - qv / q; if (partial == 0) break; result = result - partial; /* if (l % 10 == 0) { printf ("."); File.flush (stdout); } */ p += 4; q += 4; pv = pv / mden; qv = qv / mden; } /* printf ("\n"); */ return result; } real value; real part1, part2, part3; part1 = 24 *atan (8, prec + 30); part2 = 8 * atan (57, prec + 30); part3 = 4 * atan (239, prec + 30); value = part1 + part2 + part3; return imprecise (value, prec); } public real pi_value (int prec) /* * Return pi at least as precise as 'prec' */ { static real local_pi = pi; if (precision (local_pi) < prec) local_pi = calculate_pi (prec); return imprecise (local_pi, prec); } /* Normalize angle to -Ï€ < aa <= Ï€ */ real limit_angle_to_pi (real aa) { real my_pi; aa = imprecise (aa); my_pi = pi_value (precision (aa)); aa %= 2 * my_pi; if (aa > my_pi) aa -= 2 * my_pi; return aa; } public real sin (real a) /* * return sine (a) */ { /* * sin(x) = x - x**3/3! + x**5/5! ... */ real raw_sin (real a) { real err; real v, term; real a4, aj, ai; int i, j; int iter; int prec; prec = precision(a); int iprec = prec * 2; a = imprecise(a,iprec); i = 1; j = 3; a4 = a**4; ai = a**i; aj = a**j; iter = prec + 8; v = 0; while (iter-- > 0) { term = ai/i! - aj/j!; /* printf ("sin iter %d term %d\n", iter, term);*/ v += term; if (exponent (v) > exponent (term) + iprec) break; ai *= a4; aj *= a4; i += 4; j += 4; } return imprecise (v + term, prec); } /* sin(5x) = 16 * sin**5(x) - 20 * sin**3(x) + 5 * sin(x) */ real do_5x (real a) { return 16 * a**5 - 20 * a**3 + 5 * a; } real big_sin (real a) { if (a > 0.01) return do_5x (big_sin (a/5)); return raw_sin (a); } a = limit_angle_to_pi (a); if (a == 0) return 0; return big_sin (a); } public real cos (real a) /* * return cosine (a) */ { /* * cos(x) = 1 - x**2/2! + x**4/4! - x**6/6! ... */ real raw_cos (real a) { real v, term; real ai, aj, a4; int i, j; int iter; int prec = precision(a); int iprec = prec * 2; a = imprecise(a, iprec); i = 0; j = 2; ai = 1; aj = a**2; a4 = a**4; iter = prec + 8; v = 0; while (iter-- > 0) { term = ai/i! - aj/j!; v += term; if (exponent (v) > exponent (term) + iprec) break; ai *= a4; aj *= a4; i += 4; j += 4; } return imprecise (v + term); } /* cos(4x) = 8 * (cos**4(x) - cos**2(x)) + 1 */ real do_4x (real c) { return 8 * (c**4 - c**2) + 1; } real big_cos (real a) { if (a > .01) return do_4x (big_cos (a/4)); return raw_cos (a); } a = limit_angle_to_pi (a); if (a == 0) return 1; return big_cos (limit_angle_to_pi (a)); } real cos_to_sin (real v) { return sqrt (1 - v**2); } public void sin_cos (real a, *real sinp, *real cosp) /* * Compute sine and cosine of 'a' simultaneously */ { real c, s; a = limit_angle_to_pi (a); c = cos (a); s = sign(a) * cos_to_sin(c); *cosp = c; *sinp = s; } public real tan (real a) /* * return tangent (a) */ { real c, s; a = imprecise(a); sin_cos (a, &s, &c); return s/c; } public real atan (real v) /* * return arctangent (v) */ { /* * atan(x) = x - x**3/3 + x**5/5 - ... */ real raw_atan (real v) { real a, term; real vi, vj, v4; int i, j; int iter; int prec = precision(v); int iprec = prec * 2; v = imprecise (v, iprec); i = 1; j = 3; vi = v**i; vj = v**j; v4 = v**4; a = 0; iter = prec + 8; while (iter-- > 0) { term = vi/i - vj/j; a += term; if (exponent (a) > exponent (term) + iprec) break; vi *= v4; vj *= v4; i += 4; j += 4; } return imprecise (a, prec); } real sqrt3; v = imprecise (v); /* * atan(v) = -atan(-v) */ if (v < 0) return -atan (-v); /* * atan(v) = pi/2 - atan(1/v) */ if (v > 1) return pi_value (precision(v))/2 - atan (1/v); /* * atan(v) = pi/6 + atan((v*sqrt(3) - 1) / (sqrt(3) + v)) */ if (v > .268) { sqrt3 = sqrt (imprecise (3,precision(v))); return (pi_value (precision(v)) / 6 + raw_atan ((v * sqrt3 - 1) / (sqrt3 + v))); } return raw_atan (v); } /* * atan (y/x) */ public real atan2 (real y, real x) /* * return atan (y/x), but adjust for quadrant correctly */ { y = imprecise (y); x = imprecise (x); if (x == 0) { if (y == 0) return 0; if (y >= 0) return pi_value(precision(y))/2; else return -pi_value(precision(y))/2; } real a = atan(y/x); if (x < 0) { real p = pi_value(precision(y)); if (y >= 0) a += p; else a -= p; } return a; } /* * atan(v) = asin(v/sqrt(1+v**2)) * * q = v/sqrt(1+v**2) * q*sqrt(1+v**2) = v * q**2*(1+v**2) = v**2 * q**2 + q**2v**2 = v**2 * q**2 = v**2 - q**2v**2 * q**2 = v**2 * (1 - q**2) * v**2 = q**2/(1-q**2) * v = q/sqrt(1-q**2) * * asin(q) = atan2(q, sqrt(1-q**2)) */ public real asin (real v) /* * return arcsine (v) */ { v = imprecise (v); if (abs (v) > 1) raise invalid_argument ("asin argument out of range", 0, v); if (v == 1) return pi_value (precision (v))/2; if (v == -1) return -pi_value (precision (v))/2; return atan2(v, sqrt(1-v**2)); } /* * acos(v) = asin (sqrt (1 - v**2)) * = atan (sqrt(1-v**2) / sqrt (1-(sqrt (1-v**2))**2)) * = atan (sqrt(1-v**2) / sqrt (1-(1-v**2))) * = atan2 (sqrt(1-v**2), v) */ public real acos (real v) /* * return arccosine (v) */ { v = imprecise(v); if (abs (v) > 1) raise invalid_argument ("acos argument out of range", 0, v); if (v == 1) return 0; if (v == -1) return pi_value(precision(v)); if (v == 0) return pi_value(precision(v))/2; return atan2 (sqrt (1-v**2), v); } /* * These two are used for the '**' and '**=' operators */ public real pow (real a, real b) /* * return a ** b; */ { real result; if (is_int (b)) { if (!is_int (a) && is_rational (a)) return pow (numerator(a), b) / pow (denominator (a), b); int flip = 0; if (b < 0) { flip = 1; b = -b; } result = 1; while (b > 0) { if (b % 2 != 0) result *= a; if ((b //= 2) != 0) a *= a; } if (flip != 0) result = 1/result; } else switch (b) { case .5: result = sqrt (a); break; case .{3}: result = cbrt (a); break; default: result = exp (b * log(a)); break; } return result; } public real assign_pow (*real a, real b) /* * return *a = *a ** b; */ { return *a = pow (*a, b); } public real max(real arg, real args ...) /* * Return maximum of all arguments */ { for (int i = 0; i < dim(args); i++) if (arg < args[i]) arg = args[i]; return arg; } public real min(real arg, real args ...) /* * Return minimum of all arguments */ { for (int i = 0; i < dim(args); i++) if (arg > args[i]) arg = args[i]; return arg; } /* * Fast integer logarithm via binary search from below (no division). * Returns floor(log(n)/log(base)) with no rounding error */ public int ilog(int base, int n) /* * Fast integer logarithm via binary search from below (no division). * Returns floor(log(n)/log(base)) with no rounding error */ { if (base <= 1) raise invalid_argument("ilog of bad base", 0, base); if (n <= 0) raise invalid_argument("ilog of bad value", 1, n); int below = 0; int above = 1; int k = base; while (k <= n) { k *= k; below = above; above *= 2; } while (true) { int q = base ** below; k = base; int nbelow = 0; int nabove = 1; while (q * k <= n) { k *= k; nbelow = nabove; nabove *= 2; } if (nbelow == 0) break; below += nbelow; } return below; } public exception lsb_0(); public int lsb(int b) /* * return the bit position of * the least significant bit of the int argument * via binary search */ { global bool mask(int b, int ul) { return (b & ((1 << (ul + 1)) - 1)) != 0; } if (b == 0) raise lsb_0(); if (b == -1) return 0; /* doubling phase */ int ul = 1; for (!mask(b, ul); ul *= 2) /* do nothing */; /* binary search phase */ int ll = 0; while (ul > ll + 1) { int step = (ul - ll) // 2; if (mask(b, ul - step)) { ul -= step; continue; } if (!mask(b, ll + step)) { ll += step; continue; } abort("error in binary search"); } if (mask(b, ll)) return ll; return ul; } public int choose(int n, int k) /* Number of ways of choosing k items from a set of n distinct items. */ { /* This keeps the size of the intermediate terms smaller below, and also makes the bounds check slightly easier. */ if (k > (n + 1) // 2) k = n - k; if (n < 0 || k < 0) return 0; int c = 1; /* This keeps the size of the intermediate terms down a bit compared to the traditional computation. It probably doesn't matter, but oh well. */ for (int i = n - k + 1; i <= n; i++) c *= i; return c / k!; } } /* XXX these shouldn't be here, but it was *convenient* */ &int(string, int ...) atoi = &string_to_integer; &rational(string) atof = &string_to_real; nickle_2.81.orig/builtin-file.c0000664000175000000620000004340112672350771015643 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * file.c * * provide builtin functions for the File namespace */ #include #include #include #include #include #include #include "builtin.h" NamespacePtr FileNamespace; void import_File_namespace() { ENTER (); static const struct fbuiltin_0 funcs_0[] = { { do_File_string_write, "string_write", "f", "", "\n" " file string_write ()\n" "\n" " Returns a writable file which can be converted to\n" " a string with string_string.\n" }, { do_File_mkpipe, "mkpipe", "A*f", "", "\n" " file[*] mkpipe ()\n" "\n" " Returns an array of two file objects representing\n" " the endpoints of a pipe.\n" " Data written to [1] will be available for reading on [0].\n" }, { 0 } }; static const struct fbuiltin_1 funcs_1[] = { { do_File_clear_error, "clear_error", "v", "f", "\n" " void clear_error (file f)\n" "\n" " Clear any error or end-of-file condition on 'f'.\n" }, { do_File_close, "close", "v", "f", "\n" " void close (file f)\n" "\n" " Close 'f'. Note that files will automatically be closed\n" " at some point after they become unreachable. This function\n" " simply provides a mechanism for causing it to happen at\n" " a specific point in time.\n" }, { do_File_end, "end", "b", "f", "\n" " bool end (file f)\n" "\n" " Returns true if 'f' is at the end of file.\n" " This often entails attempting to read a character from 'f'\n" " if the end has not already been discovered.\n" }, { do_File_error, "error", "b", "f", "\n" " bool error (file f)\n" "\n" " Returns true if 'f' has an error condition set.\n" }, { do_File_flush, "flush", "v", "f", "\n" " void flush (file f)\n" "\n" " Force any pending output to be delivered to the OS.\n" }, { do_File_getb, "getb", "i", "f", "\n" " int getb (file f)\n" "\n" " Return the next byte of data from 'f'.\n" }, { do_File_getc, "getc", "i", "f", "\n" " int getc (file f)\n" "\n" " Return the next character from 'f'.\n" }, { do_File_string_read, "string_read", "f", "s", "\n" " file string_read (string s)\n" "\n" " Create a file which when read will return successive" " characters from 's'.\n" }, { do_File_string_string, "string_string", "s", "f", "\n" " string string_string (file f)\n" "\n" " Returns the contents 'f', which must be a file that was\n" " created with string_write.\n" }, { do_File_isatty, "isatty", "b", "f", "\n" " bool isatty (file f)\n" "\n" " Return whether 'f' is associated with an interactive\n" " terminal device\n" }, { do_File_unlink, "unlink", "v", "s", "\n" " void unlink (string name)\n" "\n" " Delete the filename 'name'\n" }, { do_File_rmdir, "rmdir", "v", "s", "\n" " void rmdir (string name)\n" "\n" " Delete the directory 'name'\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_File_open, "open", "f", "ss", "\n" " file open (string name, string mode)\n" "\n" " Open file 'name' where 'mode' is one of:\n" " \"r\": read only\n" " \"r+\": read-write\n" " \"w\": write only (created or truncated)\n" " \"w+\": read-write (created or truncated)\n" " \"a\": write-only for appending (created if needed)\n" " \"a+\": read-write for appending (created if needed)\n" " Raises open_error if the file cannot be opened.\n" }, { do_File_putb, "putb", "i", "if", "\n" " int putb (int b, file f)\n" "\n" " Write the byte 'b' to 'f'.\n" }, { do_File_putc, "putc", "i", "if", "\n" " int putc (int c, file f)\n" "\n" " Write the character 'c' to 'f'.\n" }, { do_File_setbuf, "setbuffer", "i", "fi", "\n" " int setbuffer (file f, int mode)\n" "\n" " Change buffering of 'f' to 'mode', which is one of:\n" " 0: normal block buffering.\n" " 1: line buffering.\n" " 2: unbuffered.\n" " Returns 'mode'.\n" }, { do_File_ungetb, "ungetb", "i", "if", "\n" " int ungetb (int b, file f)\n" "\n" " Pushes the byte 'b' back on file 'f'.\n" }, { do_File_ungetc, "ungetc", "i", "if", "\n" " int ungetc (int c, file f)\n" "\n" " Pushes the character 'c' back on file 'f'.\n" }, { do_File_rename, "rename", "v", "ss", "\n" " void rename (string oldname, string newname)\n" "\n" " Renames a file\n" }, { do_File_mkdir, "mkdir", "v", "si", "\n" " void mkdir (string name, int mode)\n" "\n" " Create the new directory 'name'\n" }, { 0 } }; static const struct fbuiltin_3 funcs_3[] = { { do_File_filter, "filter", "i", "sA*sA*f", "\n" " int filter (string program, string[*] argv, file[3] f)\n" "\n" " Fork and execute 'program' using 'argv' for arguments and\n" " f as stdin, stdout and stderr (respectively).\n" }, { do_File_reopen, "reopen", "f", "ssf", "\n" " file reopen (string name, string mode, file f)\n" "\n" " Change which file 'f' is associated with to 'name',\n" " opening it with 'mode' as in the open function.\n" }, { 0 } }; static const struct fbuiltin_7 funcs_7[] = { { do_File_print, "print", "v", "fpsiiis", "\n" " void print (file f, poly v, string format, int base,\n" " int width, int precision, string fill)\n" "\n" " Print 'v' to 'f'.\n" " 'format' is one of:\n" " \"v\": Reparsable representation.\n" " \"g\": Human readable representation.\n" " \"d\": Integer portion of a number.\n" " \"f\": iii.fff format floating point.\n" " \"e\": i.fff'e'ee format floating point.\n" " \"c\": Integer printed as a character.\n" " \"s\": String printed without quotes.\n" " Any number will be represented using 'base' numerals.\n" " The output will be at most 'width' characters unless it\n" " won't fit in that size.\n" " Any decimal part will be limited to 'precision' characters.\n" " If 'precision' is -1, precision will be set to the default (10)\n" " If 'precision' is -2, precision will set to whatever is needed \n" " to precisely represent the number.\n" " Any extra characters will be filled with 'fill'.\n" }, { 0 } }; static const struct ebuiltin excepts[] = { {"open_error", exception_open_error, "sEs", "\n" " open_error (string message, error_type error, string name)\n" "\n" " Raised when an open attempt fails.\n" " 'message' is a printable error string.\n" " 'error' is a symbolic error code.\n" " 'name' is the filename which failed.\n" }, {"io_error", exception_io_error, "sEf", "\n" " io_error (string message, error_type error, file f)\n" "\n" " Raised when an i/o error occurs.\n" }, {"name_error", exception_name_error, "sEs", "\n" " name_error (string message, error_type error, string name)\n" "\n" " Raised when an operation involving a filename fails.\n" " 'message' is a printable error string.\n" " 'error' is a symbolic error code.\n" " 'name' is the filename which failed.\n" }, {"io_eof", exception_io_eof, "f", "\n" " io_eof (file f)\n" "\n" " Raised when reading at end-of-file.\n" " 'file' is the file at eof.\n" }, {0, 0 }, }; const struct ebuiltin *e; SymbolPtr s; FileNamespace = BuiltinNamespace (/*parent*/ 0, "File")->namespace.namespace; BuiltinFuncs0 (&FileNamespace, funcs_0); BuiltinFuncs1 (&FileNamespace, funcs_1); BuiltinFuncs2 (&FileNamespace, funcs_2); BuiltinFuncs3 (&FileNamespace, funcs_3); BuiltinFuncs7 (&FileNamespace, funcs_7); for (e = excepts; e->name; e++) BuiltinAddException (&FileNamespace, e->exception, e->name, e->args, e->doc); s = typeFileError->name.name; NamespaceAddName (FileNamespace, s, publish_public); s = NewSymbolType (AtomId("errorType"), typeFileError); NamespaceAddName (FileNamespace, s, publish_public); EXIT (); } Value do_File_print (Value file, Value value, Value format, Value base, Value width, Value prec, Value fill) { int ibase, iwidth, iprec; ibase = IntPart (base, "Illegal base"); if (aborting) return Void; if (ibase < 0 || ibase == 1) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Illegal base"), NewInt (0), base); return Void; } iwidth = IntPart (width, "Illegal width"); if (aborting) return Void; iprec = IntPart (prec, "Illegal precision"); if (aborting) return Void; if (file->file.flags & FileOutputBlocked) ThreadSleep (running, file, PriorityIo); else { Print (file, value, StringGet (StringChars (&format->string), format->string.length, 0), ibase, iwidth, iprec, StringGet (StringChars (&fill->string), fill->string.length, 0)); if (file->file.flags & FileOutputError) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (file->file.output_errno), FileGetError (file->file.output_errno), file); } } return Void; } Value do_File_open (Value name, Value mode) { ENTER (); char *n, *m; Value ret; int err; n = StrzPart (name, "invalid file name"); if (!n) RETURN (Void); m = StrzPart (mode, "invalid file mode"); if (!m) RETURN (Void); if (aborting) RETURN (Void); ret = FileFopen (n, m, &err); if (!ret) { RaiseStandardException (exception_open_error, 3, FileGetErrorMessage (err), FileGetError (err), name); RETURN (Void); } complete = True; RETURN (ret); } Value do_File_flush (Value f) { switch (FileFlush (f, False)) { case FileBlocked: ThreadSleep (running, f, PriorityIo); break; case FileError: RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.output_errno), FileGetError (f->file.output_errno), f); break; } return Void; } Value do_File_close (Value f) { if (aborting) return Void; switch (FileFlush (f, False)) { case FileBlocked: ThreadSleep (running, f, PriorityIo); break; case FileError: RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.output_errno), FileGetError (f->file.output_errno), f); break; default: if (FileClose (f) == FileError) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.output_errno), FileGetError (f->file.output_errno), f); } else complete = True; } return Void; } Value do_File_filter (Value path, Value argv, Value filev) { ENTER (); char *p = StrzPart (path, "invalid program path"); char **args; int argc; Value arg; Value ret; int err; if (!p) RETURN (Void); /* set up arguments */ args = AllocateTemp ((ArrayLimits(&argv->array)[0] + 1) * sizeof (char *)); for (argc = 0; argc < ArrayLimits(&argv->array)[0]; argc++) { arg = ArrayValue (&argv->array, argc); args[argc] = StrzPart (arg, "invalid argument"); if (!args[argc]) RETURN (Void); } args[argc] = 0; /* run the filter */ if (aborting) RETURN(Void); ret = FileFilter (p, args, filev, &err); if (!ret) { RaiseStandardException (exception_open_error, 3, FileGetErrorMessage (err), FileGetError (err), path); ret = Void; } complete = True; RETURN (ret); } Value do_File_mkpipe (void) { ENTER (); int err; Value ret; if (aborting) RETURN (Void); ret = FileMakePipe (&err); if (!ret) { RaiseStandardException (exception_open_error, 3, FileGetErrorMessage (err), FileGetError (err), Void); RETURN (Void); } RETURN (ret); } Value do_File_reopen (Value name, Value mode, Value file) { ENTER (); char *n, *m; Value ret; int err; n = StrzPart (name, "invalid file name"); if (!n) RETURN (Void); m = StrzPart (mode, "invalid file mode"); if (!m) RETURN (Void); if (aborting) RETURN (Void); ret = FileReopen (n, m, file, &err); if (!ret) { RaiseStandardException (exception_open_error, 3, FileGetErrorMessage (err), FileGetError (err), name); RETURN (Void); } complete = True; RETURN (ret); } Value do_File_string_read (Value s) { ENTER (); RETURN (FileStringRead (StringChars (&s->string), s->string.length)); } Value do_File_string_write (void) { ENTER (); RETURN (FileStringWrite ()); } Value do_File_string_string (Value f) { ENTER (); RETURN (FileStringString (f)); } Value do_File_isatty (Value file) { ENTER (); if (file->file.flags & FileString) return FalseVal; RETURN(isatty (file->file.fd) ? TrueVal : FalseVal); } Value do_File_getb (Value f) { ENTER (); int c; if (!aborting) { c = FileInput (f); switch (c) { case FileBlocked: ThreadSleep (running, f, PriorityIo); RETURN (Void); case FileError: RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.input_errno), FileGetError (f->file.input_errno), f); RETURN (Void); default: complete = True; RETURN (NewInt (c)); } } RETURN (Void); } Value do_File_getc (Value f) { ENTER (); int c; if (!aborting) { c = FileInchar (f); switch (c) { case FileBlocked: ThreadSleep (running, f, PriorityIo); RETURN (Void); case FileError: RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.input_errno), FileGetError (f->file.input_errno), f); RETURN (Void); case FileEOF: RaiseStandardException (exception_io_eof, 1, f); RETURN (Void); default: complete = True; RETURN (NewInt (c)); } } RETURN (Void); } Value do_File_end (Value f) { ENTER (); if (f->file.flags & FileEnd) RETURN (TrueVal); else { Value b = do_File_getb(f); if (b == Void) RETURN(Void); do_File_ungetb (b, f); if (f->file.flags & FileEnd) RETURN (TrueVal); RETURN (FalseVal); } } Value do_File_error (Value f) { ENTER (); if (f->file.flags & (FileInputError|FileOutputError)) RETURN (TrueVal); else RETURN (FalseVal); } Value do_File_clear_error (Value f) { ENTER (); f->file.flags &= ~(FileInputError|FileOutputError|FileEnd); RETURN (Void); } Value do_File_putb (Value v, Value f) { ENTER (); if (f->file.flags & FileOutputBlocked) ThreadSleep (running, f, PriorityIo); else { if (!aborting) { if (FileOutput (f, IntPart (v, "putb non integer")) == FileError) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.output_errno), FileGetError (f->file.output_errno), f); } else complete = True; } } RETURN (v); } Value do_File_putc (Value v, Value f) { ENTER (); if (f->file.flags & FileOutputBlocked) ThreadSleep (running, f, PriorityIo); else { if (!aborting) { if (FileOutchar (f, IntPart (v, "putc non integer")) == FileError) { RaiseStandardException (exception_io_error, 3, FileGetErrorMessage (f->file.output_errno), FileGetError (f->file.output_errno), f); } else complete = True; } } RETURN (v); } Value do_File_ungetb (Value v, Value f) { ENTER (); if (!aborting) { complete = True; FileUnput (f, IntPart (v, "ungetb: non integer")); } RETURN (v); } Value do_File_ungetc (Value v, Value f) { ENTER (); if (f->file.flags & FileOutputBlocked) ThreadSleep (running, f, PriorityIo); else { if (!aborting) { complete = True; FileUnchar (f, IntPart (v, "ungetc: non integer")); } } RETURN (v); } Value do_File_setbuf (Value f, Value v) { ENTER (); int i; i = IntPart (v, "setbuffer non integer"); if (!aborting) FileSetBuffer (f, i); RETURN (v); } Value do_File_unlink (Value name) { ENTER (); char *n; int ret; n = StrzPart (name, "invalid file name"); if (!n) RETURN (Void); ret = unlink (n); if (ret < 0) { int err = errno; RaiseStandardException (exception_name_error, 3, FileGetErrorMessage (err), FileGetError (err), name); RETURN (Void); } RETURN (Void); } Value do_File_rename (Value old, Value new) { ENTER (); char *o, *n; int ret; o = StrzPart (old, "invalid file name"); if (!o) RETURN (Void); n = StrzPart (new, "invalid file name"); if (!n) RETURN (Void); ret = rename (o, n); if (ret < 0) { int err = errno; RaiseStandardException (exception_name_error, 3, FileGetErrorMessage (err), FileGetError (err), new); RETURN (Void); } RETURN (Void); } Value do_File_mkdir (Value name, Value mode) { ENTER (); char *n; int m; int ret; n = StrzPart (name, "invalid file name"); if (!n) RETURN (Void); m = IntPart (mode, "invalid file mode"); if (aborting) RETURN (Void); ret = mkdir (n, m); if (ret < 0) { int err = errno; RaiseStandardException (exception_name_error, 3, FileGetErrorMessage (err), FileGetError (err), name); RETURN (Void); } RETURN (Void); } Value do_File_rmdir (Value name) { ENTER (); char *n; int ret; n = StrzPart (name, "invalid file name"); if (!n) RETURN (Void); ret = rmdir (n); if (ret < 0) { int err = errno; RaiseStandardException (exception_name_error, 3, FileGetErrorMessage (err), FileGetError (err), name); RETURN (Void); } RETURN (Void); } nickle_2.81.orig/Makefile.in0000664000175000000620000012607213202542702015152 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = nickle$(EXEEXT) subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(nickleinclude_HEADERS) \ $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(nickleincludedir)" PROGRAMS = $(bin_PROGRAMS) am_nickle_OBJECTS = alarm.$(OBJEXT) array.$(OBJEXT) atom.$(OBJEXT) \ box.$(OBJEXT) compile.$(OBJEXT) debug.$(OBJEXT) \ divide.$(OBJEXT) edit.$(OBJEXT) error.$(OBJEXT) \ execute.$(OBJEXT) expr.$(OBJEXT) file.$(OBJEXT) \ float.$(OBJEXT) foreign.$(OBJEXT) frame.$(OBJEXT) \ func.$(OBJEXT) gcd.$(OBJEXT) hash.$(OBJEXT) int.$(OBJEXT) \ integer.$(OBJEXT) io.$(OBJEXT) main.$(OBJEXT) mem.$(OBJEXT) \ natural.$(OBJEXT) pretty.$(OBJEXT) profile.$(OBJEXT) \ rational.$(OBJEXT) ref.$(OBJEXT) refer.$(OBJEXT) \ sched.$(OBJEXT) scope.$(OBJEXT) stack.$(OBJEXT) \ string.$(OBJEXT) struct.$(OBJEXT) symbol.$(OBJEXT) \ sync.$(OBJEXT) type.$(OBJEXT) union.$(OBJEXT) util.$(OBJEXT) \ value.$(OBJEXT) builtin-command.$(OBJEXT) \ builtin-debug.$(OBJEXT) builtin-environ.$(OBJEXT) \ builtin-file.$(OBJEXT) builtin-math.$(OBJEXT) \ builtin-semaphore.$(OBJEXT) builtin-sockets.$(OBJEXT) \ builtin-string.$(OBJEXT) builtin-thread.$(OBJEXT) \ builtin-toplevel.$(OBJEXT) builtin-pid.$(OBJEXT) \ builtin-date.$(OBJEXT) builtin.$(OBJEXT) \ builtin-foreign.$(OBJEXT) gram.$(OBJEXT) lex.$(OBJEXT) nickle_OBJECTS = $(am_nickle_OBJECTS) nickle_LDADD = $(LDADD) nickle_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(nickle_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap @MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ -e s/c++$$/h++/ -e s/c$$/h/ YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) AM_V_YACC = $(am__v_YACC_@AM_V@) am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) am__v_YACC_0 = @echo " YACC " $@; am__v_YACC_1 = SOURCES = $(nickle_SOURCES) DIST_SOURCES = $(nickle_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(pkgdata_DATA) HEADERS = $(nickleinclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ COPYING ChangeLog INSTALL NEWS README TODO compile depcomp \ gram.c gram.h install-sh lex.c missing ylwrap DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE := @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign SUBDIRS = bench test examples doc NICKLEFILES = builtin.5c math.5c scanf.5c mutex.5c \ arc4.5c prng.5c command.5c abort.5c \ printf.5c history.5c ctype.5c string.5c socket.5c \ file.5c parse-args.5c svg.5c process.5c \ prime_sieve.5c factorial.5c gamma.5c sort.5c list.5c skiplist.5c \ json.5c DEBIAN = debian/changelog debian/compat \ debian/control debian/copyright debian/rules debian/lintian.override EXTRA_DIST = README.name README.release autogen.sh ChangeLog \ $(NICKLEFILES) $(DEBIAN) nickle.1.in nickle.spec.in MAINTAINERCLEANFILES = ChangeLog nickleincludedir = $(includedir)/nickle nickleinclude_HEADERS = \ builtin.h config.h mem.h nickle.h ref.h value.h \ builtin-namespaces.h gram.h memp.h opcode.h stack.h nickle_SOURCES = \ alarm.c array.c atom.c box.c compile.c debug.c \ divide.c edit.c error.c execute.c expr.c file.c float.c \ foreign.c frame.c func.c gcd.c hash.c int.c integer.c io.c \ main.c mem.c natural.c pretty.c profile.c rational.c ref.c \ refer.c sched.c scope.c stack.c string.c struct.c \ symbol.c sync.c type.c union.c util.c value.c \ mem.h memp.h nickle.h opcode.h ref.h stack.h value.h \ builtin-command.c builtin-debug.c builtin-environ.c \ builtin-file.c builtin-math.c builtin-namespaces.h \ builtin-semaphore.c builtin-sockets.c builtin-string.c \ builtin-thread.c builtin-toplevel.c builtin-pid.c \ builtin-date.c builtin.c builtin.h \ builtin-foreign.c gram.y lex.l nickle_LDFLAGS = $(NICKLE_LDFLAGS) pkgdata_DATA = $(NICKLEFILES) COPYING man_MANS = nickle.1 AM_YFLAGS = -d AM_CPPFLAGS = \ -DBUILD=\""$(RELEASE_DATE)"\" \ -DBUILD_VERSION=\""$(VERSION)"\" \ -DLOCAL_BUILD \ -DNICKLELIBDIR=\"@nicklelibdir@\" AM_CFLAGS = \ -D_FORTIFY_SOURCE=2 \ -Wall -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs -fno-strict-aliasing -fwrapv USES_GRAM_H = \ array.o \ compile.o \ error.o \ expr.o \ file.o \ lex.o \ main.o \ pretty.o \ type.o TARFILE = $(PACKAGE)-$(VERSION).tar.gz DEBFILE = $(PACKAGE)_$(VERSION)-1_amd64.deb SRPMFILE = $(RPMDIR)/SRPMS/$(PACKAGE)-$(VERSION)-1.src.rpm RPMFILE = $(RPMDIR)/RPMS/$(PACKAGE)-$(VERSION)-1.x86_64.rpm RELEASE_FILES = $(TARFILE) $(DEBFILE) $(SRPMFILE) $(RPMFILE) DEB_TAR_DIR = $(PACKAGE)_$(VERSION).orig DEB_TAR = $(DEB_TAR_DIR).tar.gz # # This assumes you've got Mike Harris's rpmbuild-nonroot stuff installed # using the defaults # RPMDIR = $(HOME)/rpmbuild all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .l .o .obj .y am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) gram.h: gram.c @if test ! -f $@; then rm -f gram.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) gram.c; else :; fi nickle$(EXEEXT): $(nickle_OBJECTS) $(nickle_DEPENDENCIES) $(EXTRA_nickle_DEPENDENCIES) @rm -f nickle$(EXEEXT) $(AM_V_CCLD)$(nickle_LINK) $(nickle_OBJECTS) $(nickle_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alarm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/box.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-command.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-date.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-environ.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-foreign.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-math.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-pid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-semaphore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-sockets.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin-toplevel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/divide.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foreign.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/func.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gram.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/int.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/integer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/natural.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pretty.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rational.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ref.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sched.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scope.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/struct.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sync.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/union.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/value.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .l.c: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) .y.c: $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) install-nickleincludeHEADERS: $(nickleinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(nickleinclude_HEADERS)'; test -n "$(nickleincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(nickleincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(nickleincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(nickleincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(nickleincludedir)" || exit $$?; \ done uninstall-nickleincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(nickleinclude_HEADERS)'; test -n "$(nickleincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(nickleincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(nickleincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f gram.c -rm -f gram.h -rm -f lex.c -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-local mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-nickleincludeHEADERS \ install-pkgdataDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man1 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man \ uninstall-nickleincludeHEADERS uninstall-pkgdataDATA uninstall-man: uninstall-man1 .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-binPROGRAMS \ clean-cscope clean-generic clean-local cscope cscopelist-am \ ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-compile distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-nickleincludeHEADERS install-pdf \ install-pdf-am install-pkgdataDATA install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 \ uninstall-nickleincludeHEADERS uninstall-pkgdataDATA .PRECIOUS: Makefile .PHONY: ChangeLog ChangeLog: (GIT_DIR=$(top_srcdir)/.git git log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \ (touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2) dist-hook: ChangeLog $(USES_GRAM_H): gram.h builtin.o main.o: Makefile debuild: $(DEBFILE) $(DEBFILE): $(DEB_TAR) $(TARFILE) tar xzf $(TARFILE) (cd $(distdir) && pdebuild --buildresult $(abs_top_builddir) --auto-debsign) debuild-unsigned: $(DEB_TAR) $(TARFILE) tar xzf $(distdir).tar.gz (cd $(distdir)/debian && debuild -us -uc) $(DEB_TAR): $(TARFILE) rm -f $(DEB_TAR) rm -rf $(DEB_TAR_DIR) tar xzf $(TARFILE) mv $(distdir) $(DEB_TAR_DIR) rm -rf $(DEB_TAR_DIR)/debian tar czf $(DEB_TAR) $(DEB_TAR_DIR) nickle.1: nickle.1.in config.h sed -e 's,@''VERSION@,$(VERSION),' \ -e 's,@''BUILD_DATE@,$(BUILD_DATE),' \ -e 's,@''pkgdatadir@,$(pkgdatadir),' $(top_srcdir)/nickle.1.in > $@ nickle.spec: nickle.spec.in config.h sed -e 's,@''VERSION@,$(VERSION),' \ -e 's,@''pkgdatadir@,$(pkgdatadir),' $(top_srcdir)/nickle.spec.in > $@ clean-local: rm -f nickle.1 nickle.spec rpm: $(RPMFILE) $(SRPMFILE) $(RPMFILE): $(TARFILE) nickle.spec mkdir -p $(RPMDIR)/$(PACKAGE)-$(VERSION) cp $(TARFILE) $(RPMDIR)/$(PACKAGE)-$(VERSION) rpmbuild -ba nickle.spec $(SRPMFILE): $(RPMFILE) $(TARFILE): dist-gzip $(DISTFILES) touch $(TARFILE) echo $(TARFILE) ready release-files: $(RELEASE_FILES) release: $(RELEASE_FILES) scp $(RELEASE_FILES) nickle.org:/var/www/nickle/release .PHONY: debuild debuild-signed debuild-unsigned debuild-dirs rpm force # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/builtin-thread.c0000664000175000000620000000523010751355237016167 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * thread.c * * provide builtin functions for the Thread namespace */ #include #include #include #include "builtin.h" NamespacePtr ThreadNamespace; void import_Thread_namespace() { ENTER (); static const struct fbuiltin_0 funcs_0[] = { { do_Thread_current, "current", "t", "", "\n" " thread current ()\n" "\n" " Return the current thread\n" }, { do_Thread_list, "list", "v", "", "\n" " void list ()\n" "\n" " Display a list of the known threads.\n" }, { 0 } }; static const struct fbuiltin_1 funcs_1[] = { { do_Thread_get_priority, "get_priority", "i", "t", "\n" " int get_priority (thread t)\n" "\n" " Return the scheduling priority for 't'.\n" }, { do_Thread_id_to_thread, "id_to_thread", "t", "i", "\n" " thread id_to_thread (int id)\n" "\n" " Return the thread identified by 'id'.\n" }, { do_Thread_join, "join", "p", "t", "\n" " poly join (thread t)\n" "\n" " Await the completion of 't' and return its return value.\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_Thread_set_priority, "set_priority", "i", "ti", "\n" " int set_priority (thread t, int priority)\n" "\n" " Set 't's scheduling priority to 'priority'.\n" " Return 'priority.\n" }, { do_Thread_signal, "send_signal", "v", "ti", "\n" " void signal (thread t, int signal)\n" "\n" " Raise the signal exception in thread 't'\n" " passing 'signal' as the argument\n" }, { 0 } }; static const struct fbuiltin_v funcs_v[] = { { do_Thread_kill, "kill", "i", ".t", "\n" " int kill (thread t ...)\n" "\n" " If no threads are provided, kill a thread being debugged.\n" " Otherwise, kill all of the threads provided.\n" " Return the number of threads killed that weren't already\n" " finished.\n" }, { 0 } }; static const struct ebuiltin excepts[] = { {"signal", exception_signal, "i", "\n" " signal (int signal)\n" "\n" " Sent from the Thread::send_signal function.\n" }, { 0 }, }; ThreadNamespace = BuiltinNamespace (/*parent*/ 0, "Thread")->namespace.namespace; BuiltinFuncs0 (&ThreadNamespace, funcs_0); BuiltinFuncs1 (&ThreadNamespace, funcs_1); BuiltinFuncs2 (&ThreadNamespace, funcs_2); BuiltinFuncsV (&ThreadNamespace, funcs_v); BuiltinExceptions (&ThreadNamespace, excepts); EXIT (); } nickle_2.81.orig/divide.c0000664000175000000620000001562010414112462014507 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * divide.c * * perform natural number division */ #include "nickle.h" #undef CHECK #undef DEBUG #if defined(DEBUG) || defined(CHECK) void pr (Natural *n) { int i; for (i = 0; i < NaturalLength(n); i++) (void) printf ("%u ", (unsigned int) NaturalDigits(n)[i]); (void) putchar ('\n'); } void prs (char *s, Natural *n) { (void) printf ("%s ", s); pr (n); } #endif /* * Return shift amount needed to normalize d (MSB (d << shift) == 1) */ static int normalize (digit d) { int n; digit msb; n = 0; msb = 1 << (LBASE2 - 1); while (!(d & msb)) { n++; d <<= 1; } return n; } Natural * NaturalDivide (Natural *a, Natural *b, Natural **remp) { ENTER (); int quolen, remlen; Natural *quo, *rem; int index; double_digit temp; digit temp2; Natural *partial; int offset; digit dividend1; /* first digit of dividend */ digit dividend2; /* second digit of dividend */ digit dividend3; /* third digit of dividend */ digit dividend4; /* fourth digit of dividend */ digit divisor1; /* first digit of divisor */ digit divisor2; /* second digit of divisor */ digit divisor3; /* third digit of divisor */ digit divisorc; /* combination of first two digits */ digit divisorc2; /* combination of digits 2 and 3 */ digit d; digit carry; int normal; if (NaturalLess (a, b)) { quo = zero_natural; rem = a; } else if (oneNp (b)) { quo = a; rem = zero_natural; } else if ((offset = NaturalPowerOfTwo (b)) >= 0) { quo = NaturalRsl (a, offset); rem = NaturalMask (a, offset); } else { quolen = a->length - b->length + 1; quo = AllocNatural (quolen); NaturalDigits(quo)[a->length - b->length] = 0; partial = AllocNatural (b->length + 1); remlen = a->length + 1; rem = AllocNatural (remlen); NaturalCopy (a, rem); NaturalDigits(rem)[remlen - 1] = 0; divisor1 = NaturalDigits(b)[b->length - 1]; divisor2 = 0; divisor3 = 0; if (b->length > 1) { divisor2 = NaturalDigits(b)[b->length - 2]; if (b->length > 2) divisor3 = NaturalDigits(b)[b->length - 3]; } /* * Compute a scale factor to use as many bits of * the divisor as possible, then scale the * first and second digit of the divisor by that * scale factor */ normal = normalize (divisor1); divisorc = divisor1 << normal; if (normal) divisorc |= divisor2 >> (LBASE2 - normal); divisorc2 = divisor2 << normal; if (normal) divisorc2 |= divisor3 >> (LBASE2 - normal); #ifdef DEBUG printf ("divisor 1 %u divisor2 %u divisorc %u\n", (unsigned int) divisor1, (unsigned int) divisor2, (unsigned int) divisorc); #endif /* * division just like humans, estimate each digit, * correct by checking the partial product, * then subtract the resultant product from * the dividend (which has been copied into rem) */ for (index = remlen-1; rem->length > 0 && index >= b->length; index--) { #ifdef DEBUG prs ("rem: ", rem); prs ("b: ", b); #endif /* * estimate this digit */ #ifdef DEBUG printf ("digit1: %u digit2: %u divisorc: %u divisorc2: %u\n", (unsigned int) NaturalDigits(rem)[index], (unsigned int) NaturalDigits(rem)[index-1], (unsigned int) divisorc, (unsigned int) divisorc2); #endif /* * Using the scale factor and scaled divisor computed * above, compute an estimate for this digit * * This is computing * * d1 = top dividend digit * d2 = next dividend digit * v1 = top divisor digit * v2 = next divisor digit * * (d1 * base + d2) <- original temp * temp = ---------------- * (v1 + v2 / base) <- divisorc is scaled from this * * To make this computation work in integers, * the top and bottom are scaled by the largest amount * possible (base / (v1 + 1)); for powers of two, shift * the divisor until the MSB is one. */ dividend1 = NaturalDigits(rem)[index]; dividend2 = dividend3 = dividend4 = 0; if (index) { dividend2 = NaturalDigits(rem)[index - 1]; if (index > 1) { dividend3 = NaturalDigits(rem)[index - 2]; if (index > 2) dividend4 = NaturalDigits(rem)[index - 3]; } } temp = (double_digit) dividend1 << LBASE2; temp |= (double_digit) dividend2; if (normal) { temp = (temp << normal) | (dividend3 >> (LBASE2 - normal)); } if ((digit) (temp >> LBASE2) == divisorc) d = (digit) 0xffffffffL; else d = temp / divisorc; #ifdef DEBUG printf ("temp 0x%08x%08x divisorc 0x%08x d 0x%08x\n", (unsigned int) (temp >> 32), (unsigned int) temp, divisorc, d); #endif offset = index - b->length; if (d) { temp2 = dividend3; if (normal) temp2 = (temp2 << normal) | (dividend4 >> (LBASE2 - normal)); temp = temp - (double_digit) d * (double_digit) divisorc; while (temp < BASE && (double_digit) divisorc2 * d > temp * BASE + temp2) { --d; temp += (double_digit) divisorc; } if (d == 1) { carry = NaturalSubtractOffset (rem, b, offset); } else { NaturalDigitMultiply (b, d, partial); carry = NaturalSubtractOffset (rem, partial, offset); } if (carry) { #ifdef DEBUG printf ("add back 0x%x\n", (unsigned int) d); prs ("a", a); prs ("b", b); prs ("rem", rem); prs ("partial", partial); #endif NaturalAddOffset (rem, b, offset); #ifdef DEBUG prs ("rem", rem); #endif d--; } } #ifdef DEBUG prs ("partial", partial); printf ("result[%d] = %u\n", (int) offset, (unsigned int) d); #endif NaturalDigits(quo)[offset] = d; } /* * clean up the rest of the digits */ for (offset = index - b->length; offset >= 0; offset --) { #ifdef DEBUG printf ("result[%d] zeroed\n", offset); #endif NaturalDigits(quo)[offset] = 0; } for (index = quo->length - 1; index >= 0; index--) if (NaturalDigits(quo)[index] != 0) { quo->length = index + 1; break; } #ifdef DEBUG prs ("quo: ", quo); prs ("rem: ", rem); #endif } #ifdef CHECK { Natural *check; check = NaturalPlus (NaturalTimes (quo, b), rem); if (!NaturalEqual (check, a) || !NaturalLess (rem, b)) { prs ("a: ", a); prs ("b: ", b); prs ("quo: ", quo); prs ("rem: ", rem); prs ("check: ", check); printf ("divide failed\n"); } } #endif EXIT (); /* * Stack guaratees that this will work -- it saves a place * for pushing at least as far as the previous StackReset, or * a stack chunk, whichever is smaller. */ REFERENCE (quo); REFERENCE (rem); *remp = rem; return quo; } nickle_2.81.orig/printf.5c0000664000175000000620000001165110722454067014646 0ustar keithpstaff/* $Header$*/ /* * Copyright © 2002 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ extend namespace File { int default_output_precision = -1; int infinite_output_precision = -2; public exception too_many_arguments (string format, poly[*] args) /* * Raised when too many arguments are passed to a printf * function */; public exception too_few_arguments (string format, poly[*] args) /* * Raised when too few arguments are passed to a printf * function */; void to_utf8 (int c, void(int c) f) { int bits; if (c < 0x0) return; else if (c < 0x80) { f(c); bits= -6; } else if (c < 0x800) { f(((c >> 6) & 0x1F) | 0xC0); bits= 0; } else if (c < 0x10000) { f(((c >> 12) & 0x0F) | 0xE0); bits= 6; } else if (c < 0x200000) { f(((c >> 18) & 0x07) | 0xF0); bits= 12; } else if (c < 0x4000000) { f(((c >> 24) & 0x03) | 0xF8); bits= 18; } else if (c < 0x80000000) { f(((c >> 30) & 0x01) | 0xFC); bits= 24; } else return; for ( ; bits >= 0; bits-= 6) f(((c >> bits) & 0x3F) | 0x80); } public void fprintf (file f, string format, poly args...) /* * print 'args' to 'f' according to 'format' */ { /* * A private namespace to walk the format string */ namespace fmt { int i = 0; int len = String::length(format); /* * Return whether the end of the string has been reached */ public bool done () { return i >= len; } /* * Return current character, raising an exception if * the end of the string has been reached */ public int c() { if (done()) raise invalid_argument ("invalid format", 1, format); return format[i]; } /* * Step to next character */ public void step () { ++i; } /* * Return true and step if current character matches 'm' */ public bool match(int m) { if (c() == m) { step(); return true; } return false; } /* * Return a number from the format string */ public int number () { int n = 0; while ('0' <= c() && c() <= '9') { n = n * 10 + c() - '0'; step(); } return n; } } namespace arg { int n = 0; public poly next () { if (n == dim(args)) raise too_few_arguments (format, args); return args[n++]; } public void done () { if (n != dim(args)) raise too_many_arguments (format, args); } } while (!fmt::done() && !File::error (f)) { if (fmt::match ('%') && fmt::c() != '%') { /* * width */ string fill = " "; if (fmt::match('0')) fill = "0"; int width = 0; if (fmt::match('*')) width = arg::next (); else { int sign = 1; if (fmt::match('-')) sign = -1; width = fmt::number () * sign; } /* * precision */ int prec = default_output_precision; if (fmt::match ('.')) { if (fmt::match('-')) prec = infinite_output_precision; else if (fmt::match('*')) prec = arg::next (); else prec = fmt::number (); } /* * typecheck and select base */ const struct { string formats; bool(poly) test; string message; int base; }[*] fmts = { { .formats = "s", .test = is_string, .message = "string", .base = 10 }, { .formats = "dD", .test = is_int, .message = "int", .base = 10 }, { .formats = "bB", .test = is_int, .message = "int", .base = 2 }, { .formats = "oO", .test = is_int, .message = "int", .base = 8 }, { .formats = "xX", .test = is_int, .message = "int", .base = 16 }, { .formats = "efEF", .test = is_number, .message = "real", .base = 10 } }; poly this_arg = arg::next(); string this_fmt = String::new (fmt::c()); int this_base = 10; for (int i = 0; i < dim (fmts); i++) if (String::index (fmts[i].formats, this_fmt) >= 0) { if (!fmts[i].test (this_arg)) raise invalid_argument (fmts[i].message + "format with non-" + fmts[i].message, 1, this_arg); this_base = fmts[i].base; break; } print (f, this_arg, this_fmt, this_base, width, prec, fill); } else putc (fmt::c(), f); fmt::step (); } arg::done (); } public namespace PrintfGlobals { public void printf (string format, poly args...) /* * print 'args' to stdout according to 'format' */ { fprintf (stdout, format, args ...); } public string sprintf (string format, poly args...) /* * print 'args' to a string according to 'format' */ { file f = File::string_write (); fprintf (f, format, args ...); return File::string_string (f); } } public import PrintfGlobals; } public import File::PrintfGlobals; nickle_2.81.orig/svg.5c0000664000175000000620000000171410414112462014126 0ustar keithpstaff/* * SVG XML graphics output * ala http://www.w3schools.com/svg/svg_intro.asp * Bart Massey 2004/06 */ import File; namespace SVG { public void start(file f, int width, int height) { fprintf(f, "\n" + "\n" + "\n", width, height); } public void spot(file f, string color, int x, int y, int r) { fprintf(f, "\n", x, y, r, color); } public void segment(file f, string color, int x1, int y1, int x2, int y2) { fprintf(f, "\n", x1, y1, x2, y2, color); } public void stop(file f) { fprintf(f, "\n"); } } nickle_2.81.orig/file.c0000664000175000000620000012373513062260671014201 0ustar keithpstaff/* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include #include #include #include #include #include #include #include #include "nickle.h" #include "ref.h" #include "gram.h" #ifdef O_ASYNC #define ASYNC O_ASYNC #else #ifdef HAVE_STROPTS_H #define USE_STREAMS_ASYNC #define ASYNC 0 #include #endif #endif ReferencePtr fileBlockedReference; Value fileBlocked; Bool stdinOwned, stdinPolling; #ifdef NO_PIPE_SIGIO Bool anyPipeReadBlocked; #endif extern Bool ownTty[3]; typedef struct _FileErrorMap { int value; char *name; char *message; } FileErrorMap; #define EUTF8 -128 const FileErrorMap fileErrorMap[] = { #ifdef EPERM { EPERM, "PERM", "Operation not permitted" }, #endif #ifdef ENOENT { ENOENT, "NOENT", "No such file or directory" }, #endif #ifdef ESRCH { ESRCH, "SRCH", "No such process" }, #endif #ifdef EINTR { EINTR, "INTR", "Interrupted system call" }, #endif #ifdef EIO { EIO, "IO", "I/O error" }, #endif #ifdef ENXIO { ENXIO, "NXIO", "No such device or address" }, #endif #ifdef E2BIG { E2BIG, "2BIG", "Arg list too long" }, #endif #ifdef ENOEXEC { ENOEXEC, "NOEXEC", "Exec format error" }, #endif #ifdef EBADF { EBADF, "BADF", "Bad file number" }, #endif #ifdef ECHILD { ECHILD, "CHILD", "No child processes" }, #endif #ifdef EAGAIN { EAGAIN, "AGAIN", "Try again" }, #endif #ifdef ENOMEM { ENOMEM, "NOMEM", "Out of memory" }, #endif #ifdef EACCES { EACCES, "ACCES", "Permission denied" }, #endif #ifdef EFAULT { EFAULT, "FAULT", "Bad address" }, #endif #ifdef ENOTBLK { ENOTBLK, "NOTBLK", "Block device required" }, #endif #ifdef EBUSY { EBUSY, "BUSY", "Device or resource busy" }, #endif #ifdef EEXIST { EEXIST, "EXIST", "File exists" }, #endif #ifdef EXDEV { EXDEV, "XDEV", "Cross-device link" }, #endif #ifdef ENODEV { ENODEV, "NODEV", "No such device" }, #endif #ifdef ENOTDIR { ENOTDIR, "NOTDIR", "Not a directory" }, #endif #ifdef EISDIR { EISDIR, "ISDIR", "Is a directory" }, #endif #ifdef EINVAL { EINVAL, "INVAL", "Invalid argument" }, #endif #ifdef ENFILE { ENFILE, "NFILE", "File table overflow" }, #endif #ifdef EMFILE { EMFILE, "MFILE", "Too many open files" }, #endif #ifdef ENOTTY { ENOTTY, "NOTTY", "Not a typewriter" }, #endif #ifdef ETXTBSY { ETXTBSY, "TXTBSY", "Text file busy" }, #endif #ifdef EFBIG { EFBIG, "FBIG", "File too large" }, #endif #ifdef ENOSPC { ENOSPC, "NOSPC", "No space left on device" }, #endif #ifdef ESPIPE { ESPIPE, "SPIPE", "Illegal seek" }, #endif #ifdef EROFS { EROFS, "ROFS", "Read-only file system" }, #endif #ifdef EMLINK { EMLINK, "MLINK", "Too many links" }, #endif #ifdef EPIPE { EPIPE, "PIPE", "Broken pipe" }, #endif #ifdef EDOM { EDOM, "DOM", "Math argument out of domain of func" }, #endif #ifdef ERANGE { ERANGE, "RANGE", "Math result not representable" }, #endif #ifdef EDEADLK { EDEADLK, "DEADLK", "Resource deadlock would occur" }, #endif #ifdef ENAMETOOLONG { ENAMETOOLONG, "NAMETOOLONG", "File name too long" }, #endif #ifdef ENOLCK { ENOLCK, "NOLCK", "No record locks available" }, #endif #ifdef ENOSYS { ENOSYS, "NOSYS", "Function not implemented" }, #endif #ifdef ENOTEMPTY { ENOTEMPTY, "NOTEMPTY", "Directory not empty" }, #endif #ifdef ELOOP { ELOOP, "LOOP", "Too many symbolic links encountered" }, #endif #ifdef EWOULDBLOCK { EWOULDBLOCK, "WOULDBLOCK", "Operation would block" }, #endif #ifdef ENOMSG { ENOMSG, "NOMSG", "No message of desired type" }, #endif #ifdef EIDRM { EIDRM, "IDRM", "Identifier removed" }, #endif #ifdef ECHRNG { ECHRNG, "CHRNG", "Channel number out of range" }, #endif #ifdef EL2NSYNC { EL2NSYNC, "L2NSYNC", "Level 2 not synchronized" }, #endif #ifdef EL3HLT { EL3HLT, "L3HLT", "Level 3 halted" }, #endif #ifdef EL3RST { EL3RST, "L3RST", "Level 3 reset" }, #endif #ifdef ELNRNG { ELNRNG, "LNRNG", "Link number out of range" }, #endif #ifdef EUNATCH { EUNATCH, "UNATCH", "Protocol driver not attached" }, #endif #ifdef ENOCSI { ENOCSI, "NOCSI", "No CSI structure available" }, #endif #ifdef EL2HLT { EL2HLT, "L2HLT", "Level 2 halted" }, #endif #ifdef EBADE { EBADE, "BADE", "Invalid exchange" }, #endif #ifdef EBADR { EBADR, "BADR", "Invalid request descriptor" }, #endif #ifdef EXFULL { EXFULL, "XFULL", "Exchange full" }, #endif #ifdef ENOANO { ENOANO, "NOANO", "No anode" }, #endif #ifdef EBADRQC { EBADRQC, "BADRQC", "Invalid request code" }, #endif #ifdef EBADSLT { EBADSLT, "BADSLT", "Invalid slot" }, #endif #ifdef EDEADLOCK { EDEADLOCK, "DEADLOCK", "Resource deadlock would occur" }, #endif #ifdef EBFONT { EBFONT, "BFONT", "Bad font file format" }, #endif #ifdef ENOSTR { ENOSTR, "NOSTR", "Device not a stream" }, #endif #ifdef ENODATA { ENODATA, "NODATA", "No data available" }, #endif #ifdef ETIME { ETIME, "TIME", "Timer expired" }, #endif #ifdef ENOSR { ENOSR, "NOSR", "Out of streams resources" }, #endif #ifdef ENONET { ENONET, "NONET", "Machine is not on the network" }, #endif #ifdef ENOPKG { ENOPKG, "NOPKG", "Package not installed" }, #endif #ifdef EREMOTE { EREMOTE, "REMOTE", "Object is remote" }, #endif #ifdef ENOLINK { ENOLINK, "NOLINK", "Link has been severed" }, #endif #ifdef EADV { EADV, "ADV", "Advertise error" }, #endif #ifdef ESRMNT { ESRMNT, "SRMNT", "Srmount error" }, #endif #ifdef ECOMM { ECOMM, "COMM", "Communication error on send" }, #endif #ifdef EPROTO { EPROTO, "PROTO", "Protocol error" }, #endif #ifdef EMULTIHOP { EMULTIHOP, "MULTIHOP", "Multihop attempted" }, #endif #ifdef EDOTDOT { EDOTDOT, "DOTDOT", "RFS specific error" }, #endif #ifdef EBADMSG { EBADMSG, "BADMSG", "Not a data message" }, #endif #ifdef EOVERFLOW { EOVERFLOW, "OVERFLOW", "Value too large for defined data type" }, #endif #ifdef ENOTUNIQ { ENOTUNIQ, "NOTUNIQ", "Name not unique on network" }, #endif #ifdef EBADFD { EBADFD, "BADFD", "File descriptor in bad state" }, #endif #ifdef EREMCHG { EREMCHG, "REMCHG", "Remote address changed" }, #endif #ifdef ELIBACC { ELIBACC, "LIBACC", "Can not access a needed shared library" }, #endif #ifdef ELIBBAD { ELIBBAD, "LIBBAD", "Accessing a corrupted shared library" }, #endif #ifdef ELIBSCN { ELIBSCN, "LIBSCN", ".lib section in a.out corrupted" }, #endif #ifdef ELIBMAX { ELIBMAX, "LIBMAX", "Attempting to link in too many shared libraries" }, #endif #ifdef ELIBEXEC { ELIBEXEC, "LIBEXEC", "Cannot exec a shared library directly" }, #endif #ifdef EILSEQ { EILSEQ, "ILSEQ", "Illegal byte sequence" }, #endif #ifdef ERESTART { ERESTART, "RESTART", "Interrupted system call should be restarted" }, #endif #ifdef ESTRPIPE { ESTRPIPE, "STRPIPE", "Streams pipe error" }, #endif #ifdef EUSERS { EUSERS, "USERS", "Too many users" }, #endif #ifdef ENOTSOCK { ENOTSOCK, "NOTSOCK", "Socket operation on non-socket" }, #endif #ifdef EDESTADDRREQ { EDESTADDRREQ, "DESTADDRREQ", "Destination address required" }, #endif #ifdef EMSGSIZE { EMSGSIZE, "MSGSIZE", "Message too long" }, #endif #ifdef EPROTOTYPE { EPROTOTYPE, "PROTOTYPE", "Protocol wrong type for socket" }, #endif #ifdef ENOPROTOOPT { ENOPROTOOPT, "NOPROTOOPT", "Protocol not available" }, #endif #ifdef EPROTONOSUPPORT { EPROTONOSUPPORT, "PROTONOSUPPORT", "Protocol not supported" }, #endif #ifdef ESOCKTNOSUPPORT { ESOCKTNOSUPPORT, "SOCKTNOSUPPORT", "Socket type not supported" }, #endif #ifdef EOPNOTSUPP { EOPNOTSUPP, "OPNOTSUPP", "Operation not supported on transport endpoint" }, #endif #ifdef EPFNOSUPPORT { EPFNOSUPPORT, "PFNOSUPPORT", "Protocol family not supported" }, #endif #ifdef EAFNOSUPPORT { EAFNOSUPPORT, "AFNOSUPPORT", "Address family not supported by protocol" }, #endif #ifdef EADDRINUSE { EADDRINUSE, "ADDRINUSE", "Address already in use" }, #endif #ifdef EADDRNOTAVAIL { EADDRNOTAVAIL, "ADDRNOTAVAIL", "Cannot assign requested address" }, #endif #ifdef ENETDOWN { ENETDOWN, "NETDOWN", "Network is down" }, #endif #ifdef ENETUNREACH { ENETUNREACH, "NETUNREACH", "Network is unreachable" }, #endif #ifdef ENETRESET { ENETRESET, "NETRESET", "Network dropped connection because of reset" }, #endif #ifdef ECONNABORTED { ECONNABORTED, "CONNABORTED", "Software caused connection abort" }, #endif #ifdef ECONNRESET { ECONNRESET, "CONNRESET", "Connection reset by peer" }, #endif #ifdef ENOBUFS { ENOBUFS, "NOBUFS", "No buffer space available" }, #endif #ifdef EISCONN { EISCONN, "ISCONN", "Transport endpoint is already connected" }, #endif #ifdef ENOTCONN { ENOTCONN, "NOTCONN", "Transport endpoint is not connected" }, #endif #ifdef ESHUTDOWN { ESHUTDOWN, "SHUTDOWN", "Cannot send after transport endpoint shutdown" }, #endif #ifdef ETOOMANYREFS { ETOOMANYREFS, "TOOMANYREFS", "Too many references: cannot splice" }, #endif #ifdef ETIMEDOUT { ETIMEDOUT, "TIMEDOUT", "Connection timed out" }, #endif #ifdef ECONNREFUSED { ECONNREFUSED, "CONNREFUSED", "Connection refused" }, #endif #ifdef EHOSTDOWN { EHOSTDOWN, "HOSTDOWN", "Host is down" }, #endif #ifdef EHOSTUNREACH { EHOSTUNREACH, "HOSTUNREACH", "No route to host" }, #endif #ifdef EALREADY { EALREADY, "ALREADY", "Operation already in progress" }, #endif #ifdef EINPROGRESS { EINPROGRESS, "INPROGRESS", "Operation now in progress" }, #endif #ifdef ESTALE { ESTALE, "STALE", "Stale NFS file handle" }, #endif #ifdef EUCLEAN { EUCLEAN, "UCLEAN", "Structure needs cleaning" }, #endif #ifdef ENOTNAM { ENOTNAM, "NOTNAM", "Not a XENIX named type file" }, #endif #ifdef ENAVAIL { ENAVAIL, "NAVAIL", "No XENIX semaphores available" }, #endif #ifdef EISNAM { EISNAM, "ISNAM", "Is a named type file" }, #endif #ifdef EREMOTEIO { EREMOTEIO, "REMOTEIO", "Remote I/O error" }, #endif #ifdef EDQUOT { EDQUOT, "DQUOT", "Quota exceeded" }, #endif #ifdef ENOMEDIUM { ENOMEDIUM, "NOMEDIUM", "No medium found" }, #endif #ifdef EMEDIUMTYPE { EMEDIUMTYPE, "MEDIUMTYPE", "Wrong medium type" }, #endif #ifdef EUTF8 { EUTF8, "UTF8", "Invalid UTF-8 byte sequence" }, #endif }; #define NUM_FILE_ERRORS (sizeof (fileErrorMap) / sizeof (fileErrorMap[0])) Type *typeFileError; static int FileInitErrors (void) { ENTER (); StructType *st; Atom *atoms; int i; SymbolPtr error_type; error_type = NewSymbolType (AtomId("error_type"), 0); st = NewStructType (NUM_FILE_ERRORS); atoms = StructTypeAtoms (st); for (i = 0; i < NUM_FILE_ERRORS; i++) { AddBoxType (&st->types, typePrim[rep_void]); atoms[i] = AtomId (fileErrorMap[i].name); } error_type->symbol.type = NewTypeUnion (st, True); typeFileError = NewTypeName (NewExprAtom (AtomId ("error_type"), 0, False), error_type); MemAddRoot (typeFileError); EXIT (); return 1; } volatile Bool signalChild; static void sigchld (int sig) { resetSignal (SIGCHLD, sigchld); SetSignalChild (); } void ProcessInterrupt () { for (;;) { pid_t pid; int status; pid = wait3 (&status, WNOHANG, NULL); if (pid == 0) break; if (pid < 0 && errno == ECHILD) break; } } static FileChainPtr FileChainAlloc (FileChainPtr next, int size) { FileChainPtr ret; ret = malloc (sizeof (FileChain) + size); ret->next = next; ret->size = size; ret->used = 0; ret->ptr = 0; return ret; } static void FileChainFree (FileChainPtr ic) { while (ic) { FileChainPtr next = ic->next; free (ic); ic = next; } } int FileInit (void) { ENTER (); catchSignal (SIGCHLD, sigchld); fileBlockedReference = NewReference ((void **) &fileBlocked); MemAddRoot (fileBlockedReference); FileInitErrors (); EXIT (); return 1; } Value FileGetError (int err) { ENTER(); Value ret; int i; StructType *st; for (i = 0; i < NUM_FILE_ERRORS; i++) if (fileErrorMap[i].value == err) break; if (i == NUM_FILE_ERRORS) i = 0; /* XXX weird error */ st = TypeCanon (typeFileError)->structs.structs; ret = NewUnion (st, True); ret->unions.tag = StructTypeAtoms(st)[i]; BoxValueSet (ret->unions.value,0,Void); RETURN (ret); } Value FileGetErrorMessage (int err) { int i; for (i = 0; i < NUM_FILE_ERRORS; i++) if (fileErrorMap[i].value == err) return NewStrString (fileErrorMap[i].message); return NewStrString ("Unknown error"); } static void FileMark (void *object) { File *file = object; FileFlush ((Value) file, False); MemReference (file->next); } void FileFini (void) { MemCollect (); while (anyFileWriteBlocked) FileCheckBlocked (True); } static int FileFree (void *object) { File *file = object; if (file->fd == -1 || FileClose ((Value) file) != FileBlocked) { FileChainFree (file->input); file->input = NULL; FileChainFree (file->output); file->output = NULL; return 1; } return 0; } static Bool FilePrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePuts (f, "file"); return True; } ValueRep FileRep = { { FileMark, FileFree, "FileRep" }, rep_file, { 0, 0, 0, 0, 0, 0, 0, ValueEqual, 0, 0, }, { 0, }, 0, 0, FilePrint, }; Value NewFile (int fd) { ENTER (); Value ret; ret = ALLOCATE (&FileRep.data, sizeof (File)); ret->file.next = 0; ret->file.fd = fd; ret->file.pid = 0; ret->file.status = 0; ret->file.flags = 0; ret->file.error = 0; ret->file.input = 0; ret->file.output = 0; RETURN (ret); } void FileSetFd (int fd) { int flags; fcntl (fd, F_SETOWN, getpid()); flags = fcntl (fd, F_GETFL); flags |= ASYNC; (void) fcntl (fd, F_SETFL, flags); #ifdef USE_STREAMS_ASYNC (void) ioctl(fd, I_SETSIG, S_INPUT | S_OUTPUT | S_ERROR | S_HANGUP); #endif } void FileResetFd (int fd) { int flags; flags = fcntl (fd, F_GETFL); flags &= ~ASYNC; (void) fcntl (fd, F_SETFL, flags); #ifdef USE_STREAMS_ASYNC (void) ioctl(fd, I_SETSIG, 0); #endif } Value FileCreate (int fd, int flags) { ENTER (); Value file; file = NewFile (fd); file->file.flags |= flags; if (isatty (fd)) file->file.flags |= FileLineBuf; else if (lseek (fd, 0, 1) < 0) file->file.flags |= FileIsPipe; if (fd >= 3) FileSetFd (fd); file->file.sock_family = 0; RETURN (file); } Value FileFopen (char *name, char *mode, int *errp) { ENTER (); int oflags = 0; int flags = 0; int fd; switch (mode[0]) { case 'r': if (mode[1] == '+') { flags |= FileWritable; oflags = 2; } else oflags = 0; flags |= FileReadable; break; case 'w': if (mode[1] == '+') { oflags = 2; flags |= FileReadable; } else oflags = 1; oflags |= O_TRUNC|O_CREAT; flags |= FileWritable; break; case 'a': if (mode[1] == '+') { oflags = 2; flags |= FileReadable; } else oflags = 1; oflags |= O_CREAT|O_APPEND; flags |= FileWritable; break; } fd = open (name, oflags, 0666); if (fd < 0) { *errp = errno; RETURN (0); } RETURN (FileCreate (fd, flags)); } Value FileReopen (char *name, char *mode, Value file, int *errp) { ENTER (); int oflags = 0; int flags = 0; int fd; if (file->file.flags & FileString) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("Reopen: string file"), NewInt (0), file); RETURN (Void); } switch (mode[0]) { case 'r': if (mode[1] == '+') { flags |= FileWritable; oflags = 2; } else oflags = 0; flags |= FileReadable; break; case 'w': if (mode[1] == '+') { oflags = 2; flags |= FileReadable; } else oflags = 1; oflags |= O_TRUNC|O_CREAT; flags |= FileWritable; break; case 'a': if (mode[1] == '+') { oflags = 2; flags |= FileReadable; } else oflags = 1; oflags |= O_TRUNC|O_CREAT|O_APPEND; flags |= FileWritable; break; } fd = open (name, oflags, 0666); if (fd < 0) { *errp = errno; RETURN (0); } if (dup2 (fd, file->file.fd) < 0) { *errp = errno; close (fd); RETURN (0); } close (fd); RETURN (file); } Value FileFilter (char *program, char *args[], Value filev, int *errp) { ENTER (); int pid; int errcode, nread; int i; int errpipe[2]; int fdlimit; int fds[3]; /* set up process files */ for (i = 0; i < 3; i++) { Value f = ArrayValue (&filev->array, i); if (i == 0 && !(f->file.flags & FileReadable)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("File::filter: process input not readable"), NewInt (i), f); RETURN (Void); } if (i == 1 && !(f->file.flags & FileWritable)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("File::filter: process output not writable"), NewInt (i), f); RETURN (Void); } if (i == 2 && !(f->file.flags & FileWritable)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("File::filter: process error not writable"), NewInt (i), f); RETURN (Void); } fds[i] = f->file.fd; } if (pipe (errpipe) < 0) { *errp = errno; RETURN (0); } pid = fork (); if (pid == -1) { close (errpipe[0]); close (errpipe[1]); *errp = errno; RETURN (0); } if (pid == 0) { /* child */ for (i = 0; i < 3; i++) dup2 (fds[i], i); fdlimit = sysconf(_SC_OPEN_MAX); for (; i < fdlimit; i++) if (i != errpipe[1]) close (i); fcntl (errpipe[1], F_SETFD, FD_CLOEXEC); execvp (program, args); errcode = errno & 0xff; errcode = write (errpipe[1], &errcode, 1); (void) errcode; exit (1); } /* parent */ close (errpipe[1]); nread = read(errpipe[0], &errcode, 1); close (errpipe[0]); if (nread != 0) { *errp = errcode; assert (nread == 1); RETURN(0); } for (i = 0; i < 3; i++) { Value f = ArrayValue (&filev->array, i); if (f->file.flags & FilePipe) f->file.pid = pid; } RETURN (NewInt(pid)); } Value FileMakePipe (int *errp) { ENTER (); Value file, files; int two = 2; int fds[2]; if (pipe (fds) < 0) { *errp = errno; RETURN (0); } /* gather and return results */ files = NewArray (False, False, typePrim[rep_file], 1, &two); file = FileCreate (fds[0], FileReadable); file->file.flags |= FilePipe; ArrayValueSet (&files->array, 0, file); file = FileCreate (fds[1], FileWritable); file->file.flags |= FilePipe; ArrayValueSet (&files->array, 1, file); RETURN (files); } int FileStatus (Value file) { return file->file.status; } int FileClose (Value file) { file->file.flags |= FileClosed; return FileFlush (file, False); } Value FileStringRead (char *string, int len) { ENTER (); Value file; file = NewFile (-1); file->file.flags |= FileString|FileReadable; file->file.input = FileChainAlloc (0, len); memcpy (FileBuffer (file->file.input), string, len); file->file.input->used = len; RETURN (file); } Value FileStringWrite (void) { ENTER (); Value file; file = NewFile (-1); file->file.flags |= FileString|FileWritable; RETURN (file); } static char * write_chain(char *s, FileChainPtr out) { if (out->next) s = write_chain(s, out->next); memcpy(s, FileBuffer(out), out->used); return s + out->used; } Value FileStringString (Value file) { ENTER (); int len; FileChainPtr out; Value str; char *s; if (!(file->file.flags & FileString)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("string_string: not string file"), NewInt (0), file); RETURN (Void); } len = 0; for (out = file->file.output; out; out = out->next) len += out->used; str = NewString (len); StringChars (&str->string); s = write_chain(StringChars(&str->string), file->file.output); *s = '\0'; RETURN (str); } #define DontBlockIO (runnable && running) Bool FileIsReadable (int fd) { fd_set bits; int n; struct timeval tv; if (fd == 0 && !stdinOwned) { if (!stdinPolling) IoNoticeTtyUnowned (); return False; } do { FD_ZERO (&bits); FD_SET (fd, &bits); tv.tv_usec = 0; tv.tv_sec = 0; n = select (fd + 1, &bits, 0, 0, &tv); } while (n < 0 && errno == EINTR); return n > 0; } Bool FileIsWritable (int fd) { fd_set bits; int n; struct timeval tv; do { FD_ZERO (&bits); FD_SET (fd, &bits); tv.tv_usec = 0; tv.tv_sec = 0; n = select (fd + 1, 0, &bits, 0, &tv); } while (n < 0 && errno == EINTR); return n > 0; } int FileInput (Value file) { ENTER (); int c, n; unsigned char *buf; FileChainPtr ic; int err; if (file->file.flags & FileClosed) { EXIT (); return FileError; } if (!file->file.input) { if (!(file->file.flags & FileReadable)) { file->file.flags |= FileInputError; file->file.input_errno = EBADF; EXIT (); return FileError; } if (file->file.flags & FileString) { file->file.flags |= FileEnd; EXIT (); return FileEOF; } file->file.input = FileChainAlloc (NULL, FileBufferSize); } ic = file->file.input; for (;;) { if (ic->ptr < ic->used) { c = FileBuffer (ic)[ic->ptr++]; break; } else { if (ic->next) { file->file.input = ic->next; ic->next = NULL; FileChainFree (ic); ic = file->file.input; } else if (file->file.flags & FileString) { file->file.flags |= FileEnd; c = FileEOF; break; } else { buf = FileBuffer (ic); if (FileIsReadable (file->file.fd)) { n = ic->size; if (file->file.flags & FileUnBuf) n = 1; n = read (file->file.fd, buf, n); err = errno; file->file.flags &= ~FileEnd; } else { n = -1; err = EWOULDBLOCK; } if (n <= 0) { if (n == 0) { file->file.flags |= FileEnd; c = FileEOF; } else if (err == EWOULDBLOCK) { FileSetBlocked (file, FileInputBlocked); c = FileBlocked; } else { file->file.flags |= FileInputError; file->file.input_errno = err; c = FileError; } break; } ic->ptr = 0; ic->used = n; } } } EXIT (); return c; } void FileUnput (Value file, unsigned char c) { ENTER (); FileChainPtr ic; ic = file->file.input; if (!ic || ic->ptr == 0) { ic = file->file.input = FileChainAlloc (file->file.input, FileBufferSize); ic->ptr = ic->used = ic->size; } FileBuffer(ic)[--ic->ptr] = c; EXIT (); } static void FileWaitForWriteable (Value file) { int n; fd_set bits; FD_ZERO (&bits); for (;;) { FD_SET (file->file.fd, &bits); n = select (file->file.fd + 1, 0, &bits, 0, 0); if (n > 0) break; } } static int FileFlushChain (Value file, FileChainPtr ic, Bool block) { int n; int err; while (ic->ptr < ic->used) { if (FileIsWritable (file->file.fd)) { n = write (file->file.fd, &FileBuffer(ic)[ic->ptr], ic->used - ic->ptr); err = errno; } else { n = -1; err = EWOULDBLOCK; } if (n > 0) ic->ptr += n; else { if (n < 0 && err != EWOULDBLOCK) { file->file.flags |= FileOutputError; file->file.output_errno = err; return FileError; } if (!(file->file.flags & FileBlockWrites) && !block) { FileSetBlocked (file, FileOutputBlocked); return FileBlocked; } FileWaitForWriteable (file); } } return 0; } /* * May not allocate memory as it is called while garbage collecting */ int FileFlush (Value file, Bool block) { ENTER (); FileChainPtr ic, *prev; int n = 0; if (file->file.output) { if ((file->file.flags & FileString) == 0) { for (;;) { for (prev = &file->file.output; (ic = *prev)->next; prev = &ic->next); n = FileFlushChain (file, ic, block); if (n) break; /* * Leave a chain for new output */ if (prev == &file->file.output) { ic->used = ic->ptr = 0; break; } else FileChainFree (ic); *prev = 0; } } } if (file->file.flags & FileClosed && n != FileBlocked) { if (file->file.fd != -1) { FileResetFd (file->file.fd); close (file->file.fd); file->file.fd = -1; } } EXIT (); return n; } int FileOutput (Value file, char c) { ENTER (); FileChainPtr ic; if (file->file.flags & FileClosed) { file->file.flags |= FileOutputError; file->file.output_errno = EBADF; EXIT (); return FileError; } if (!(file->file.flags & FileWritable)) { file->file.flags |= FileOutputError; file->file.output_errno = EBADF; EXIT (); return FileError; } ic = file->file.output; if (!ic) ic = file->file.output = FileChainAlloc (0, FileBufferSize); if (ic->used == ic->size) { if (FileFlush (file, False) == FileError) { EXIT (); return FileError; } ic = file->file.output; if (ic->used == ic->size) ic = file->file.output = FileChainAlloc (file->file.output, FileBufferSize); } ic = file->file.output; FileBuffer(ic)[ic->used++] = c; if ((c == '\n' && file->file.flags & FileLineBuf) || file->file.flags & FileUnBuf) { if (FileFlush (file, False) == FileError) { EXIT (); return FileError; } } EXIT (); return 0; } void FilePuts (Value file, char *s) { while (*s) FileOutput (file, *s++); } void FilePutsc (Value file, char *s, long length) { while (length--) FileOutput (file, *s++); } void FilePutDoubleDigitBase (Value file, double_digit a, int base) { int digit; char space[64], *s; s = space + sizeof (space); *--s = '\0'; if (!a) *--s = '0'; else { while (a) { digit = a % base; if (digit <= 9) digit = '0' + digit; else digit = 'a' + digit - 10; *--s = digit; a /= base; } } FilePuts (file, s); } void FilePutUIntBase (Value file, unsigned int a, int base) { FilePutDoubleDigitBase (file, (double_digit) a, base); } void FilePutIntBase (Value file, int a, int base) { if (a < 0) { FileOutput (file, '-'); a = -a; } FilePutUIntBase (file, a, base); } void FilePutInt (Value file, int a) { FilePutIntBase (file, a, 10); } int FileStringWidth (char *string, long length, char format) { if (format == 's') return StringLength (string, length); else { int width = 2; unsigned c; while ((string = StringNextChar (string, &c, &length))) { if (c < ' ' || '~' < c) switch (c) { case '\n': case '\r': case '\t': case '\b': case '\f': case '\v': case '\0': width += 2; break; default: width += 4; break; } else if (c == '"') width += 2; else width++; } return width; } } void FilePutString (Value f, char *string, long length, char format) { if (format == 's') FilePutsc (f, string, length); else { unsigned c; FileOutput (f, '"'); while ((string = StringNextChar (string, &c, &length))) { if (c < ' ') switch (c) { case '\n': FilePuts (f, "\\n"); break; case '\r': FilePuts (f, "\\r"); break; case '\b': FilePuts (f, "\\b"); break; case '\t': FilePuts (f, "\\t"); break; case '\f': FilePuts (f, "\\f"); break; case '\v': FilePuts (f, "\\v"); case '\0': FilePuts (f, "\\0"); break; default: FileOutput (f, '\\'); Print (f, NewInt (c), 'o', 8, 3, -1, '0'); break; } else if (c == '"') FilePuts (f, "\\\""); else if (c == '\\') FilePuts (f, "\\\\"); else { char dest[7]; int l = StringPutChar (c, dest); dest[l] = '\0'; FilePuts (f, dest); } } FileOutput (f, '"'); } } void FilePutRep (Value f, Rep tag, Bool minimal) { switch (tag) { case rep_undef: if (!minimal) FilePuts (f, "poly"); break; case rep_int: case rep_integer: FilePuts (f, "int"); break; case rep_rational: FilePuts (f, "rational"); break; case rep_float: FilePuts (f, "real"); break; case rep_string: FilePuts (f, "string"); break; case rep_file: FilePuts (f, "file"); break; case rep_thread: FilePuts (f, "thread"); break; case rep_semaphore: FilePuts (f, "semaphore"); break; case rep_continuation: FilePuts (f, "continuation"); break; case rep_bool: FilePuts (f, "bool"); break; case rep_foreign: FilePuts (f, "foreign"); break; case rep_void: FilePuts (f, "void"); break; case rep_array: FilePuts (f, "array"); break; case rep_ref: FilePuts (f, "ref"); break; case rep_struct: FilePuts (f, "struct"); break; case rep_func: FilePuts (f, "function"); break; default: FilePrintf (f, "bad type %d", tag); break; } if (minimal && tag != rep_undef) FilePuts (f, " "); } void FilePutClass (Value f, Class storage, Bool minimal) { switch (storage) { case class_undef: if (!minimal) FilePuts (f, "undefined"); break; case class_const: FilePuts (f, "const"); break; case class_global: FilePuts (f, "global"); break; case class_arg: FilePuts (f, "argument"); break; case class_auto: FilePuts (f, "auto"); break; case class_static: FilePuts (f, "static"); break; case class_typedef: FilePuts (f, "typedef"); break; case class_namespace: FilePuts (f, "namespace"); break; case class_exception: FilePuts (f, "exception"); break; } if (minimal && storage != class_undef) FilePuts (f, " "); } void FilePutPublish (Value f, Publish publish, Bool minimal) { switch (publish) { case publish_private: if (!minimal) FilePuts (f, "private"); break; case publish_protected: FilePuts (f, "protected"); break; case publish_public: FilePuts (f, "public"); break; case publish_extend: FilePuts (f, "extend"); break; } if (minimal && publish != publish_private) FilePuts (f, " "); } void FilePutArgType (Value f, ArgType *at) { FilePuts (f, "("); while (at) { if (at->type) FilePutType (f, at->type, at->name != 0); if (at->name) FilePuts (f, AtomName (at->name)); if (at->varargs) FilePuts (f, " ..."); at = at->next; if (at) FilePuts (f, ", "); } FilePuts (f, ")"); } static void FilePutDimensions (Value f, ExprPtr dims, Bool resizable) { while (dims) { if (dims->tree.left) PrettyExpr (f, dims->tree.left, -1, 0, False); else if (resizable) FilePuts (f, "..."); else FilePuts (f, "*"); if (dims->tree.right) FilePuts (f, ", "); dims = dims->tree.right; } } static void FilePutTypename (Value f, ExprPtr e) { switch (e->base.tag) { case COLONCOLON: if (e->tree.left) { FilePutTypename (f, e->tree.left); FilePuts (f, "::"); } FilePutTypename (f, e->tree.right); break; case NAME: FilePuts (f, AtomName (e->atom.atom)); break; } } void FilePutBaseType (Value f, Type *t, Bool minimal) { switch (t->base.tag) { case type_func: FilePutBaseType (f, t->func.ret, minimal); break; case type_array: FilePutBaseType (f, t->array.type, minimal); break; case type_hash: FilePutBaseType (f, t->hash.type, minimal); break; default: FilePutType (f, t, minimal); break; } } void FilePutSubscriptType (Value f, Type *t, Bool minimal) { switch (t->base.tag) { case type_func: FilePutArgType (f, t->func.args); FilePutSubscriptType (f, t->func.ret, minimal); break; case type_array: FilePuts (f, "["); FilePutDimensions (f, t->array.dimensions, t->array.resizable); FilePuts (f, "]"); FilePutSubscriptType (f, t->array.type, minimal); break; case type_hash: FilePuts (f, "["); FilePutType (f, t->hash.keyType, False); FilePuts (f, "]"); FilePutSubscriptType (f, t->hash.type, minimal); break; default: break; } } void FilePutType (Value f, Type *t, Bool minimal) { int i; StructType *st; Bool spaceit = minimal; TypeElt *elt; if (!t) { FilePuts (f, ""); return; } switch (t->base.tag) { case type_prim: if (t->prim.prim != rep_undef || !minimal) FilePutRep (f, t->prim.prim, False); else spaceit = False; break; case type_name: FilePutTypename (f, t->name.expr); break; case type_ref: if (t->ref.pointer) FilePuts (f, "*"); else FilePuts (f, "&"); FilePutType (f, t->ref.ref, False); break; case type_func: case type_array: case type_hash: FilePutBaseType (f, t, False); FilePutSubscriptType (f, t, False); break; case type_struct: case type_union: if (t->structs.left && t->structs.right) { FilePutType (f, t->structs.left, False); FilePuts (f, " + "); FilePutType (f, t->structs.right, False); } else if (t->structs.enumeration) { FilePuts (f, "enum { "); st = t->structs.structs; for (i = 0; i < st->nelements; i++) { if (i) FilePuts (f, ", "); FilePuts (f, AtomName (StructTypeAtoms(st)[i])); } FilePuts (f, " }"); } else { if (t->base.tag == type_struct) FilePuts (f, "struct { "); else FilePuts (f, "union { "); st = t->structs.structs; for (i = 0; i < st->nelements; i++) { FilePutType (f, BoxTypesElements(st->types)[i], True); FilePuts (f, AtomName (StructTypeAtoms (st)[i])); FilePuts (f, "; "); } FilePuts (f, "}"); } break; case type_types: for (elt = t->types.elt; elt; elt = elt->next) { FilePutType (f, elt->type, False); if (elt->next) FilePuts (f, ", "); } break; } if (spaceit) FilePuts (f, " "); } static void FilePutBinOp (Value f, BinaryOp o) { switch (o) { case PlusOp: FilePuts (f, "+"); break; case MinusOp: FilePuts (f, "-"); break; case TimesOp: FilePuts (f, "*"); break; case DivideOp: FilePuts (f, "/"); break; case DivOp: FilePuts (f, "//"); break; case ModOp: FilePuts (f, "%"); break; case LessOp: FilePuts (f, "<"); break; case EqualOp: FilePuts (f, "=="); break; case LandOp: FilePuts (f, "&"); break; case LorOp: FilePuts (f, "|"); break; default: break; } } static void FilePutUnaryOp (Value f, UnaryOp o) { switch (o) { case NegateOp: FilePuts (f, "-"); break; case FloorOp: FilePuts (f, "floor"); break; case CeilOp: FilePuts (f, "ceil"); break; default: break; } } void FileVPrintf (Value file, char *fmt, va_list args) { Value v; for (;*fmt;) { switch (*fmt) { case '\0': continue; case '%': switch (*++fmt) { case '\0': continue; case 'd': FilePutIntBase (file, va_arg (args, int), 10); break; case 'u': FilePutUIntBase (file, va_arg (args, unsigned int), 10); break; case 'o': FilePutUIntBase (file, va_arg (args, unsigned int), 8); break; case 'x': FilePutUIntBase (file, va_arg (args, unsigned int), 16); break; case 'D': FilePutDoubleDigitBase (file, va_arg (args, double_digit), 10); break; case 'v': case 'g': v = va_arg (args, Value); if (!v) (void) FilePuts (file, ""); else Print (file, v, *fmt, 0, 0, DEFAULT_OUTPUT_PRECISION, ' '); break; case 'G': v = va_arg (args, Value); if (!v) (void) FilePuts (file, ""); else { if (ValueRep(v)->tag <= rep_void) { Print (file, v, 'g', 0, 0, DEFAULT_OUTPUT_PRECISION, ' '); } else { (void) FilePuts (file, ""); } } break; case 'n': FilePuts (file, NaturalSprint (0, va_arg (args, Natural *), 10, 0)); break; case 'N': FilePuts (file, NaturalSprint (0, va_arg (args, Natural *), 16, 0)); break; case 's': (void) FilePuts (file, va_arg (args, char *)); break; case 'S': { char *s = va_arg (args, char *); FilePutString (file, s, strlen(s), 'v'); break; } case 'A': (void) FilePuts (file, AtomName (va_arg (args, Atom))); break; case 't': FilePutType (file, va_arg (args, Type *), True); break; case 'T': FilePutType (file, va_arg (args, Type *), False); break; case 'k': /* sic */ FilePutClass (file, (Class) (va_arg (args, int)), True); break; case 'C': FilePutClass (file, (Class) (va_arg (args, int)), False); break; case 'p': FilePutPublish (file, (Publish) (va_arg (args, int)), True); break; case 'P': FilePutPublish (file, (Publish) (va_arg (args, int)), False); break; case 'O': FilePutBinOp (file, va_arg (args, BinaryOp)); break; case 'U': FilePutUnaryOp (file, va_arg (args, UnaryOp)); break; case 'c': (void) FileOutchar (file, va_arg (args, int)); break; default: (void) FileOutput (file, *fmt); break; } break; default: (void) FileOutput (file, *fmt); break; } ++fmt; } } void FilePrintf (Value file, char *fmt, ...) { va_list args; va_start (args, fmt); FileVPrintf (file, fmt, args); va_end (args); } void FileCheckBlocked (Bool block) { ENTER (); fd_set readable, writable; int n, fd; Value blocked, *prev; Bool ready; Bool writeBlocked; #ifdef NO_PIPE_SIGIO Bool readPipeBlocked; #endif FD_ZERO (&readable); FD_ZERO (&writable); n = 0; for (prev = &fileBlocked; (blocked = *prev); ) { fd = blocked->file.fd; if (fd < 0) { *prev = blocked->file.next; continue; } prev = &blocked->file.next; if (fd == 0 && !stdinOwned) continue; if (blocked->file.flags & FileInputBlocked) FD_SET (fd, &readable); if (blocked->file.flags & FileOutputBlocked) FD_SET (fd, &writable); if (fd >= n) n = fd + 1; } if (n > 0) { struct timeval tv, *tvp; if (block) tvp = 0; else { tv.tv_usec = 0; tv.tv_sec = 0; tvp = &tv; } n = select (n, &readable, &writable, 0, tvp); } else { anyFileWriteBlocked = False; #ifdef NO_PIPE_SIGIO anyPipeReadBlocked = False; #endif if (block) { sigset_t set, oset; sigfillset (&set); sigprocmask (SIG_SETMASK, &set, &oset); if (!signaling && !running) sigsuspend(&oset); sigprocmask (SIG_SETMASK, &oset, &set); } } if (n > 0) { writeBlocked = False; #ifdef NO_PIPE_SIGIO readPipeBlocked = False; #endif if (block) signaling = True; for (prev = &fileBlocked; (blocked = *prev); ) { fd = blocked->file.fd; ready = False; if (FD_ISSET (fd, &readable)) { ready = True; blocked->file.flags &= ~FileInputBlocked; } if (FD_ISSET (fd, &writable)) { if (FileFlush (blocked, False) != FileBlocked) { blocked->file.flags &= ~FileOutputBlocked; ready = True; } } if (blocked->file.flags & FileOutputBlocked) writeBlocked = True; #ifdef NO_PIPE_SIGIO if (blocked->file.flags & FileInputBlocked && blocked->file.flags & FileIsPipe) readPipeBlocked = True; #endif if (ready) ThreadsWakeup (blocked, WakeAll); if ((blocked->file.flags & (FileOutputBlocked|FileInputBlocked)) == 0) *prev = blocked->file.next; else prev = &blocked->file.next; } anyFileWriteBlocked = writeBlocked; #ifdef NO_PIPE_SIGIO anyPipeReadBlocked = readPipeBlocked; #endif } EXIT (); } void FileSetBlocked (Value file, int flag) { if (flag == FileOutputBlocked && !anyFileWriteBlocked) { anyFileWriteBlocked = True; IoNoticeWriteBlocked (); } #ifdef NO_PIPE_SIGIO if (flag == FileInputBlocked && (file->file.flags & FileIsPipe) && !anyPipeReadBlocked) { anyPipeReadBlocked = True; IoNoticeReadBlocked (); } #endif if (file->file.flags & (FileOutputBlocked|FileInputBlocked)) { file->file.flags |= flag; return; } file->file.flags |= flag; file->file.next = fileBlocked; fileBlocked = file; } void FileSetBuffer (Value file, int mode) { file->file.flags &= ~(FileLineBuf|FileUnBuf); switch (mode) { case 0: break; case 1: file->file.flags |= FileLineBuf; break; case 2: file->file.flags |= FileUnBuf; break; } } /* * Output one character in UTF-8 format */ int FileOutchar (Value file, int c) { char d; int bits; if (c < 0x80) { d = c; bits= -6; } else if (c < 0x800) { d= ((c >> 6) & 0x1F) | 0xC0; bits= 0; } else if (c < 0x10000) { d= ((c >> 12) & 0x0F) | 0xE0; bits= 6; } else if (c < 0x200000) { d= ((c >> 18) & 0x07) | 0xF0; bits= 12; } else if (c < 0x4000000) { d= ((c >> 24) & 0x03) | 0xF8; bits= 18; } else if (c < 0x80000000) { d= ((c >> 30) & 0x01) | 0xFC; bits= 24; } else return FileError; if (FileOutput (file, d) < 0) return FileError; for ( ; bits >= 0; bits-= 6) if (FileOutput (file, ((c >> bits) & 0x3F) | 0x80) < 0) return FileError; return 0; } int FileInchar (Value file) { char buf[6]; int n = 0; int result; int mask; int extra; result = FileInput (file); if (result < 0) return result; buf[n++] = result; if ((result & 0x80) != 0) { if ((result & 0xc0) != 0xc0) { file->file.input_errno = EUTF8; return FileError; } mask = 0x20; extra = 1; while ((result & mask) != 0) { extra++; mask >>= 1; } result &= (mask - 1); while (extra-- > 0) { int c = FileInput (file); if (c < 0) { while (--n >= 0) FileUnput (file, buf[n]); return c; } buf[n++] = c; if ((c & 0xc0) != 0x80) { file->file.input_errno = EUTF8; return FileError; } result = (result << 6) | (c & 0x3f); } } return result; } void FileUnchar (Value file, int c) { char d; int bits; if (c < 0x80) { d = c; bits= -6; } else if (c < 0x800) { d= ((c >> 6) & 0x1F) | 0xC0; bits= 0; } else if (c < 0x10000) { d= ((c >> 12) & 0x0F) | 0xE0; bits= 6; } else if (c < 0x200000) { d= ((c >> 18) & 0x07) | 0xF0; bits= 12; } else if (c < 0x4000000) { d= ((c >> 24) & 0x03) | 0xF8; bits= 18; } else if (c < 0x80000000) { d= ((c >> 30) & 0x01) | 0xFC; bits= 24; } else return; for ( ; bits >= 0; bits-= 6) { FileUnput (file, (c & 0x3F) | 0x80); c >>= 6; } FileUnput (file, d); } nickle_2.81.orig/value.h0000664000175000000620000010556713202522675014407 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2007 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * value.h * * type definitions for functions returning values */ #ifndef _VALUE_H_ #define _VALUE_H_ #include #include #include #include #include #include #include #include typedef enum { False = 0, True = 1 } Bool; typedef char *Atom; #ifndef MEM_TRACE typedef const struct _valueType ValueRep; #else typedef struct _valueType ValueRep; #endif typedef struct _box *BoxPtr; typedef union _code *CodePtr; typedef struct _frame *FramePtr; typedef struct _thread *ThreadPtr; typedef struct _continuation *ContinuationPtr; typedef union _value *Value; typedef struct _obj *ObjPtr; typedef union _inst *InstPtr; typedef union _symbol *SymbolPtr; extern Atom AtomId (char *name); #define AtomName(a) (a) extern int AtomInit (void); typedef struct _AtomList *AtomListPtr; typedef union _type *TypePtr; typedef struct _structType *StructTypePtr; typedef union _expr *ExprPtr; typedef struct _catch *CatchPtr; typedef struct _twixt *TwixtPtr; typedef struct _jump *JumpPtr; typedef struct _AtomList { DataType *data; AtomListPtr next; Atom atom; } AtomList; AtomListPtr NewAtomList (AtomListPtr next, Atom atom); /* * computational radix for natural numbers. Make sure the * definitions for digit, double_digit and signed_digit will * still work correctly. */ #if HAVE_STDINT_H # include #define PtrToInt(p) ((int) (intptr_t) (p)) #define PtrToUInt(p) ((unsigned) (uintptr_t) (p)) #define IntToPtr(i) ((void *) (intptr_t) (i)) #define UIntToPtr(u) ((void *) (uintptr_t) (u)) # if HAVE_UINT64_T /* * If stdint.h defines a 64 bit datatype, use 32 bit * chunks */ # define DIGITBITS 32 typedef uint64_t double_digit; typedef int64_t signed_digit; typedef uint32_t digit; # else # define DIGITBITS 16 typedef uint32_t double_digit; typedef uint16_t digit; typedef int32_t signed_digit; # endif #else #define PtrToInt(p) ((int) (p)) #define PtrToUInt(p) ((unsigned) (p)) #define IntToPtr(i) ((void *) (i)) #define UIntToPtr(u) ((void *) (u)) # if SIZEOF_UNSIGNED_LONG_LONG == 8 || SIZEOF_UNSIGNED_LONG == 8 # define DIGITBITS 32 # else # define DIGITBITS 16 # endif # if DIGITBITS == 32 # if SIZEOF_UNSIGNED_LONG_LONG == 8 typedef unsigned long long double_digit; typedef long long signed_digit; # else # if SIZEOF_UNSIGNED_LONG == 8 typedef unsigned long double_digit; typedef long signed_digit; # endif # endif # if SIZEOF_UNSIGNED_LONG == 4 typedef unsigned long digit; # else # if SIZEOF_UNSIGNED_INT == 4 typedef unsigned int digit; # endif # endif # else # if SIZEOF_UNSIGNED_LONG == 4 typedef unsigned long double_digit; typedef long signed_digit; # else # if SIZEOF_UNSIGNED_INT == 4 typedef unsigned int double_digit; typedef int signed_digit; # endif # endif # if SIZEOF_UNSIGNED_INT == 2 typedef unsigned int digit; # else # if SIZEOF_UNSIGNED_SHORT == 2 typedef unsigned short digit; # endif # endif # endif #endif #define MAXDIGIT ((digit) (BASE - 1)) #if DIGITBITS == 32 # define BASE ((double_digit) 65536 * (double_digit) 65536) # define LBASE2 32 # define LLBASE2 5 #else # define BASE ((double_digit) 65536) # define LBASE2 16 # define LLBASE2 4 #endif #define TwoDigits(n,i) ((double_digit) NaturalDigits(n)[i-1] | \ ((double_digit) NaturalDigits(n)[i] << LBASE2)) #define ModBase(t) ((t) & (((double_digit) 1 << LBASE2) - 1)) #define DivBase(t) ((t) >> LBASE2) /* HashValues are stored in rep_int */ typedef int HashValue; /* * Natural numbers form the basis for both the Integers and Rationals, * but needn't ever be exposed to the user */ typedef struct _natural { DataType *type; int length; digit digits[0]; } Natural; static inline int NaturalLength(Natural *n) { return n->length; } static inline digit * NaturalDigits(Natural *n) { return n->digits; } Natural *NewNatural (unsigned value); Natural *NewDoubleDigitNatural (double_digit dd); Natural *AllocNatural (int size); Bool NaturalEqual (Natural *, Natural *); Bool NaturalLess (Natural *, Natural *); Natural *NaturalPlus (Natural *, Natural *); Natural *NaturalMinus (Natural *, Natural *); Natural *NaturalTimes (Natural *, Natural *); Natural *NaturalLand (Natural *, Natural *); Natural *NaturalLor (Natural *, Natural *); Natural *NaturalCompliment (Natural *, int len); Natural *NaturalNegate (Natural *, int len); Natural *NaturalDivide (Natural *a, Natural *b, Natural **remp); Natural *NaturalGcd (Natural *a, Natural *b); char *NaturalSprint (char *, Natural *, int base, int *width); Natural *NaturalSqrt (Natural *); Natural *NaturalFactor (Natural *n, Natural *max); Natural *NaturalIntPow (Natural *n, int p); Natural *NaturalPow (Natural *n, Natural *); Natural *NaturalPowMod (Natural *n, Natural *p, Natural *m); Natural *NaturalRsl (Natural *v, int shift); Natural *NaturalLsl (Natural *v, int shift); Natural *NaturalMask (Natural *v, int bits); int NaturalPowerOfTwo (Natural *v); int NaturalEstimateLength (Natural *, int base); void NaturalCopy (Natural *, Natural *); Bool NaturalZero (Natural *); Bool NaturalEven (Natural *); void NaturalDigitMultiply (Natural *a, digit i, Natural *result); digit NaturalSubtractOffset (Natural *a, Natural *b, int offset); digit NaturalSubtractOffsetReverse (Natural *a, Natural *b, int offset); Bool NaturalGreaterEqualOffset (Natural *a, Natural *b, int offset); void NaturalAddOffset (Natural *a, Natural *b, int offset); Natural *NaturalBdivmod (Natural *u_orig, Natural *v); Natural *NaturalKaryReduction (Natural *u_orig, Natural *v); int NaturalWidth (Natural *u); digit DigitBmod (digit u, digit v, int s); int IntWidth (int i); int DoubleDigitWidth (double_digit i); HashValue NaturalHash (Natural *a); extern Natural *max_signed_digit_natural; extern Natural *max_int_natural; extern Natural *zero_natural; extern Natural *one_natural; extern Natural *two_natural; typedef enum _sign { Positive = 0, Negative = 1 } Sign; static inline Sign SignNegate(Sign sign) { return 1 - sign; } typedef enum _signcat { BothPositive = 0, FirstPositive = 1, SecondPositive = 2, BothNegative = 3 } Signcat; static inline Signcat catagorize_signs(Sign s1, Sign s2) { return (s1 << 1) | s2; } typedef enum _binaryOp { PlusOp, MinusOp, TimesOp, DivideOp, DivOp, ModOp, LessOp, EqualOp, LandOp, LorOp, NumBinaryOp } BinaryOp; typedef enum _unaryOp { NegateOp, FloorOp, CeilOp, NumUnaryOp } UnaryOp; /* * Value representations. * * Values are represented by one of several data structures, * the first element of each value is a pointer back to a * data structure which contains the representation tag along * with functions that operate on the value */ typedef enum _rep { /* unknown type */ rep_undef = -1, /* primitive types */ rep_int = 0, rep_integer = 1, rep_rational = 2, rep_float = 3, rep_string = 4, rep_file = 5, rep_thread = 6, rep_semaphore = 7, rep_continuation = 8, rep_bool = 9, rep_foreign = 10, rep_void = 11, /* composite types */ rep_ref = 12, rep_func = 13, /* mutable type */ rep_array = 14, rep_struct = 15, rep_union = 16, rep_hash = 17 } Rep; /* because rep_undef is -1, using (unsigned) makes these a single compare */ #define Numericp(t) ((unsigned) (t) <= (unsigned) rep_float) #define Integralp(t) ((unsigned) (t) <= (unsigned) rep_integer) #define Mutablep(t) ((t) >= rep_array) extern ValueRep IntRep, IntegerRep, RationalRep, FloatRep; extern ValueRep StringRep, ArrayRep, FileRep; extern ValueRep RefRep, StructRep, UnionRep, HashRep; extern ValueRep FuncRep, ThreadRep; extern ValueRep SemaphoreRep, ContinuationRep, UnitRep, BoolRep; extern ValueRep ForeignRep; static inline Value NewInt(int i) { return (Value) IntToPtr ((((i) << 1) | 1)); } static inline Sign IntSign(int i) { return (i) < 0 ? Negative : Positive; } /* * Use all but one bit to hold immediate integer values */ #define NICKLE_INT_BITS ((sizeof (int) * 8) - 1) #define NICKLE_INT_SIGN (1U << (NICKLE_INT_BITS - 1)) /* * this bit holds any overflow; when different from SIGN, * an addition/subtraction has overflowed */ #define NICKLE_INT_CARRY (1U << NICKLE_INT_BITS) /* * An int fits in a 'nickle int' if the top two bits * are the same. There are four initial values: * * 00 + 01 = 01 * 01 + 01 = 10 * 10 + 01 = 11 * 11 + 01 = 00 * * So, the two 'naughty' ones end up with the high bit set */ #define NICKLE_INT_CARRIED(r) (((r) + NICKLE_INT_SIGN) & NICKLE_INT_CARRY) #define MAX_NICKLE_INT ((int) ((unsigned) NICKLE_INT_SIGN - 1)) #define MIN_NICKLE_INT (-MAX_NICKLE_INT - 1) #define MAX_NICKLE_SIGNED_DIGIT ((signed_digit) (((double_digit) 1 << (sizeof(signed_digit) * 8 - 1)) - 1)) #define One NewInt(1) #define Zero NewInt(0) static inline Bool ValueIsPtr (Value v) { return (PtrToInt(v) & 1) == 0; } static inline Bool ValueIsInt (Value v) { return !ValueIsPtr(v); } static inline int ValueInt(Value v) { return PtrToInt (v) >> 1; } static inline ValueRep *_ValueRep(Value v); #define ValueRep(v) _ValueRep(v) #define ValueIsInteger(v) (ValueRep(v) == &IntegerRep) #define ValueIsRational(v) (ValueRep(v) == &RationalRep) #define ValueIsFloat(v) (ValueRep(v) == &FloatRep) #define ValueIsString(v) (ValueRep(v) == &StringRep) #define ValueIsArray(v) (ValueRep(v) == &ArrayRep) #define ValueIsFile(v) (ValueRep(v) == &FileRep) #define ValueIsRef(v) (ValueRep(v) == &RefRep) #define ValueIsStruct(v) (ValueRep(v) == &StructRep) #define ValueIsUnion(v) (ValueRep(v) == &UnionRep) #define ValueIsHash(v) (ValueRep(v) == &HashRep) #define ValueIsFunc(v) (ValueRep(v) == &FuncRep) #define ValueIsThread(v) (ValueRep(v) == &ThreadRep) #define ValueIsSemaphore(v) (ValueRep(v) == &SemaphoreRep) #define ValueIsContinuation(v) (ValueRep(v) == &ContinuationRep) #define ValueIsUnit(v) (ValueRep(v) == &UnitRep) #define ValueIsBool(v) (ValueRep(v) == &BoolRep) #define ValueIsForeign(v) (ValueRep(v) == &ForeignRep) /* * Aggregate types */ typedef struct _argType { DataType *data; TypePtr type; Bool varargs; Atom name; SymbolPtr symbol; struct _argType *next; } ArgType; ArgType *NewArgType (TypePtr type, Bool varargs, Atom name, SymbolPtr symbol, ArgType *next); typedef enum _typeTag { type_prim, type_name, type_ref, type_func, type_array, type_struct, type_union, type_types, type_hash } TypeTag; typedef struct _typeBase { DataType *data; TypeTag tag; } TypeBase; typedef struct _typePrim { TypeBase base; Rep prim; } TypePrim; typedef struct _typeName { TypeBase base; ExprPtr expr; SymbolPtr name; } TypeName; typedef struct _typeRef { TypeBase base; TypePtr ref; Bool pointer; } TypeRef; typedef struct _typeFunc { TypeBase base; TypePtr ret; ArgType *args; } TypeFunc; typedef enum _dimStorage { DimStorageNone, DimStorageGlobal, DimStorageStatic, DimStorageAuto } DimStorage; typedef struct _typeArray { TypeBase base; TypePtr type; ExprPtr dimensions; int dims; DimStorage storage; Bool resizable; union { BoxPtr global; struct { int element; Bool staticScope; CodePtr code; } frame; } u; } TypeArray; typedef struct _typeHash { TypeBase base; TypePtr type; TypePtr keyType; } TypeHash; typedef struct _typeStruct { TypeBase base; StructTypePtr structs; Bool enumeration; TypePtr left, right; } TypeStruct; typedef struct _typeElt { DataType *data; struct _typeElt *next; union _type *type; } TypeElt; typedef struct _typeTypes { TypeBase base; TypeElt *elt; } TypeTypes; typedef union _type { TypeBase base; TypePrim prim; TypeName name; TypeRef ref; TypeFunc func; TypeArray array; TypeHash hash; TypeStruct structs; TypeTypes types; } Type; typedef struct _argDecl { Type *type; Atom name; } ArgDecl; typedef struct _argList { ArgType *argType; Bool varargs; } ArgList; extern Type *typePoly; extern Type *typeRefPoly; extern Type *typeFileError; extern Type *typeArrayInt; extern Type *typePrim[rep_void + 1]; Type *NewTypeName (ExprPtr expr, SymbolPtr name); Type *NewTypeRef (Type *ref, Bool pointer); Type *NewTypePlus (Type *left, Type *right); Type *NewTypePointer (Type *ref); Type *NewTypeFunc (Type *ret, ArgType *args); Type *NewTypeArray (Type *type, ExprPtr dimensions, Bool resizable); Type *NewTypeHash (Type *type, Type *keyType); Type *NewTypeStruct (StructTypePtr structs); Type *NewTypeUnion (StructTypePtr structs, Bool enumeration); Type *NewTypeTypes (TypeElt *elt); Type *TypeCanon (Type *type); void TypeTypesAdd (Type *list, Type *type); void TypeTypesRemove (Type *list, Type *type); Bool TypeTypesMember (Type *list, Type *type); int TypeInit (void); SymbolPtr TypeNameName (Type *t); Type *TypeCombineBinary (Type *left, int tag, Type *right); Type *TypeCombineUnary (Type *down, int tag); Type *TypeCombineStruct (Type *type, int tag, Atom atom); Type *TypeCombineReturn (Type *type); Type *TypeCombineFunction (Type *type); Type *TypeCombineArray (Type *array, int ndim, Bool lvalue); /* can assign value 'v' to variable of type 'dest' */ Bool TypeCompatibleAssign (Type *dest, Value v); /* is value 'v' a subtype of 't' */ Bool ValueIsType (Value b, TypePtr a); /* super is a supertype of sub */ Bool TypeIsSupertype (Type *super, Type *sub); /* a is a supertype of b or b is a supertype of a */ Bool TypeIsOrdered (Type *a, Type *b); /* a and b are 'cotypes' */ Bool TypeIsCotype (Type *a, Type *b); #define TypePoly(t) ((t)->base.tag == type_prim && (t)->prim.prim == rep_undef) #define TypeBool(t) ((t)->base.tag == type_prim && (t)->prim.prim == rep_bool) #define TypeString(t) ((t)->base.tag == type_prim && (t)->prim.prim == rep_string) Bool TypeNumeric (Type *t); Bool TypeIntegral (Type *t); int TypeCountDimensions (ExprPtr dims); /* * storage classes */ typedef enum _class { class_global, class_static, class_arg, class_auto, class_const, class_typedef, class_namespace, class_exception, class_undef } Class; #define ClassLocal(c) ((c) == class_arg || (c) == class_auto) #define ClassFrame(c) ((c) == class_static || ClassLocal(c)) #define ClassStorage(c) ((c) <= class_const) #define ClassLvalue(c) ((c) <= class_auto) typedef enum _publish { publish_private, publish_protected, publish_public, publish_extend } Publish; static inline Rep ValueTag(Value v); typedef struct _baseValue { ValueRep *type; } BaseValue; typedef struct _integer { BaseValue base; Natural *magn; } Integer; typedef struct _rational { BaseValue base; Sign sign; Natural *num; Natural *den; } Rational; typedef struct _fpart { DataType *data; Natural *mag; Sign sign; } Fpart; typedef struct _float { BaseValue base; Fpart *mant; Fpart *exp; unsigned prec; } Float; typedef struct _string { BaseValue base; long length; char chars[0]; } String; static inline char * StringChars (String *s) { return s->chars; } typedef struct _foreign { BaseValue base; const char *id; void *data; void (*mark)(void *); void (*free)(void *); } Foreign; /* * Resizable arrays are actually vectors of single entry * boxes. Otherwise shrinking the array leaves old references * dangling. */ typedef struct _boxVector { DataType *data; int nvalues; TypePtr type; BoxPtr boxes[0]; } BoxVector, *BoxVectorPtr; static inline BoxPtr *BoxVectorBoxes(BoxVector *v) { return (BoxPtr *) v->boxes; } typedef struct _array { BaseValue base; unsigned int resizable : 1; unsigned int ndim : (sizeof (int) * 8 - 1); union { BoxPtr fix; BoxVectorPtr resize; } u; int dims[0]; } Array; typedef struct _io_chain { struct _io_chain *next; int size; int used; int ptr; unsigned char buffer[0]; } FileChain, *FileChainPtr; typedef struct _file { BaseValue base; union _value *next; /* used to chain blocked files together */ int fd; int pid; /* for pipes, process id */ int status; /* from wait */ int input_errno; /* last input errno */ int output_errno; /* last output errno */ int flags; int error; FileChainPtr input; FileChainPtr output; int sock_family; } File; #define FileBufferSize 4096 #define FileEOF -1 #define FileBlocked -2 #define FileError -3 #define FileBuffer(ic) ((ic)->buffer) #define FileReadable 0x0001 #define FileWritable 0x0002 #define FileOutputBlocked 0x0004 #define FileInputBlocked 0x0008 #define FileLineBuf 0x0010 #define FileUnBuf 0x0020 #define FileInputError 0x0040 #define FileOutputError 0x0080 #define FileClosed 0x0100 #define FileBlockWrites 0x0200 #define FileEnd 0x0400 #define FileString 0x0800 #define FilePipe 0x1000 #define FileIsPipe 0x2000 typedef struct _boxTypes { DataType *data; int count; int size; TypePtr elements[0]; } BoxTypes, *BoxTypesPtr; static inline TypePtr *BoxTypesElements(BoxTypes *bt) { return bt->elements; } static inline TypePtr BoxTypesValue(BoxTypes *bt, int e) { return BoxTypesElements(bt)[e]; } static inline void BoxTypesValueSet(BoxTypes *bt, int e, TypePtr t) { BoxTypesElements(bt)[e] = t; } extern BoxTypesPtr NewBoxTypes (int size); extern int AddBoxType (BoxTypesPtr *btp, TypePtr t); typedef struct _ref { BaseValue base; BoxPtr box; int element; } Ref; typedef struct _structType { DataType *data; int nelements; BoxTypesPtr types; Atom atoms[0]; } StructType; #define StructTypeAtoms(st) ((st)->atoms) typedef struct _struct { BaseValue base; StructType *type; BoxPtr values; } Struct; typedef struct _union { BaseValue base; StructType *type; Atom tag; BoxPtr value; Type *types[0]; } Union; typedef struct _func { BaseValue base; CodePtr code; FramePtr staticLink; BoxPtr statics; } Func; /* * This is a continuation, the same structure is also used within * threads, twixts and catches to hold an execution context */ typedef struct _continuation { union { BaseValue value; DataType *data; } type; Value value; /* accumulator */ InstPtr pc; /* program counter */ ObjPtr obj; /* reference to obj containing pc */ FramePtr frame; /* function call frame list */ StackObject *stack; /* value stack */ CatchPtr catches; /* handled exceptions */ TwixtPtr twixts; /* pending twixts */ } Continuation; typedef enum _ThreadState { ThreadRunning, ThreadSuspended, ThreadFinished } ThreadState; typedef struct _thread { /* * Execution continuation */ Continuation continuation; /* * Currently executing jump */ JumpPtr jump; /* * Thread status */ ThreadState state; int priority; Value sleep; int id; int partial; /* * Lower priority threads */ Value next; } Thread; #define PriorityMin 0 #define PriorityStart 100 #define PrioritySync 200 #define PriorityIo 300 typedef struct _semaphore { BaseValue value; int count; int id; } Semaphore; /* * Set the continuation at dst to that at src. Return the src * continuation instruction pointer */ InstPtr ContinuationSet (ContinuationPtr dst, ContinuationPtr src); /* * Jump through a continuation, unwinding or rewinding appropriate twixt blocks */ Value ContinuationJump (Value thread, ContinuationPtr src, Value ret, InstPtr *next); /* * Mark memory referenced from a continuation, */ void ContinuationMark (void *object); /* * Initialize a continuation to default values */ void ContinuationInit (ContinuationPtr continuation); #ifdef DEBUG_JUMP void ContinuationTrace (char *where, Continuation *continuation, int indent); void ThreadCatches (Value thread); #endif /* * Hash tables. Indexed by multiple typed values */ typedef const struct _HashSet { HashValue entries; HashValue size; HashValue rehash; } HashSetRec, *HashSetPtr; /* * Hash elements are stored in boxes, with three elements * for each element (hash, key, value) * * Hash element states: * * key value * 0 0 empty * v 0 reference to uninitialized element * 0 v deleted * v v valid entry * * So: * key != 0 -> hash table includes * value != 0 -> hash chain includes */ #define HashEltHash(e) ((e)[0]) #define HashEltKey(e) ((e)[1]) #define HashEltValue(e) ((e)[2]) #define HashEltSize 3 #define HashEltStep(e) ((e) += HashEltSize) #define HashEltCopy(d,s) (((d)[0] = (s)[0]), \ ((d)[1] = (s)[1]), \ ((d)[2] = (s)[2])) #define HashEltValid(e) (HashEltKey(e) != 0) #define HashEltChained(e) (HashEltValue(e) != 0) typedef struct _hashTable { BaseValue base; HashSetRec *hashSet; HashValue count; TypePtr type; TypePtr keyType; BoxPtr elts; Value def; } HashTable, *HashTablePtr; typedef union _value { BaseValue value; Integer integer; Rational rational; Float floats; String string; Array array; File file; Ref ref; Foreign foreign; Struct structs; Union unions; Func func; Thread thread; Semaphore semaphore; Continuation continuation; HashTable hash; } ValueRec; typedef Value (*Binary) (Value, Value, int); typedef Value (*Unary) (Value, int); typedef Value (*Promote) (Value, Value); typedef Value (*Coerce) (Value); typedef int (*Hash) (Value); #define DEFAULT_OUTPUT_PRECISION -1 #define INFINITE_OUTPUT_PRECISION -2 typedef Bool (*Output) (Value, Value, char format, int base, int width, int prec, int fill); typedef ValueRep *(*TypeCheck) (BinaryOp, Value, Value, int); struct _valueType { DataType data; Rep tag; Binary binary[NumBinaryOp]; Unary unary[NumUnaryOp]; Promote promote; Coerce reduce; Output print; TypeCheck typecheck; Hash hash; }; static inline ValueRep *_ValueRep(Value v) { if (ValueIsInt(v)) return &IntRep; return v->value.type; } static inline Rep ValueTag(Value v) { return ValueRep(v)->tag; } static inline Natural *IntegerMag(Value i) { return (Natural *) ((long) (i->integer.magn) & ~1); } static inline Sign IntegerSign(Value i) { return (Sign) ((long) (i->integer.magn) & 1); } typedef struct _boxReplace { DataType *data; BoxPtr new; int oldstride; int newstride; } BoxReplace, *BoxReplacePtr; typedef struct _box { DataType *data; unsigned long constant : 1; unsigned long homogeneous : 1; unsigned long replace : 1; unsigned long nvalues : (sizeof (unsigned long) * 8) - 3; union { BoxTypesPtr types; TypePtr type; BoxReplacePtr replace; } u; Value values[0]; } Box; #if 1 #define BoxCheck(box) assert (!(box)->replace) #else #define BoxCheck(box) #endif static inline Value *BoxElements(Box *box) { BoxCheck(box); return box->values; } static inline Value BoxValueSet(Box *box, long e, Value v) { return BoxElements(box)[e] = v; } static inline Value BoxValueGet(Box *box, long e) { return BoxElements(box)[e]; } static inline Bool BoxConstant(Box *box, int e) { return box->constant; } static inline Bool _BoxReplace(Box *box) { return box->replace; } #define BoxReplace(box) _BoxReplace(box) static inline TypePtr _BoxType(Box *box, long e) { BoxCheck(box); if (box->homogeneous) return box->u.type; else return BoxTypesValue(box->u.types, e); } #define BoxType(box, e) _BoxType(box, e) extern BoxPtr NewBox (Bool constant, Bool array, int nvalues, TypePtr type); extern BoxPtr NewTypedBox (Bool array, BoxTypesPtr types); void BoxSetReplace (BoxPtr old, BoxPtr new, int oldstride, int newstride); BoxPtr BoxRewrite (BoxPtr box, int *ep); typedef struct { DataType *data; int size; union { double d; double_digit dd; void *p; } values[0]; } DataCache, *DataCachePtr; DataCachePtr NewDataCache (int size); static inline void *DataCacheValues(DataCache *vc) { return (void *) vc->values; } static inline int *ArrayDims (Array *a) { return a->dims; } #define ArrayLimits(a) (ArrayDims(a) + (a)->ndim) #define ArrayConstant static inline long ArrayNvalues(Array *a) { if (a->resizable) return a->u.resize->nvalues; else return a->u.fix->nvalues; } static inline BoxPtr ArrayValueBox(Array *a, long i) { if (a->resizable) return BoxVectorBoxes(a->u.resize)[i]; else return a->u.fix; } static inline int ArrayValueElt(Array *a, long i) { if (a->resizable) return 0; else return i; } static inline TypePtr ArrayType(Array *a) { if (a->resizable) return a->u.resize->type; else return a->u.fix->u.type; } #define ArrayValue(a,i) (BoxValue(ArrayValueBox(a,i),ArrayValueElt(a,i))) #define ArrayValueGet(a,i) (BoxValueGet(ArrayValueBox(a,i),ArrayValueElt(a,i))) static inline void ArrayValueSet(Array *a, long i, Value v) { BoxValueSet(ArrayValueBox(a,i),ArrayValueElt(a,i), v); } void RefRewrite (Value r); static inline void RefCheck(Value r) { if (BoxReplace(r->ref.box)) RefRewrite(r); } static inline void RefValueSet(Value r, Value v) { RefCheck(r); BoxValueSet(r->ref.box, r->ref.element, v); } static inline Value RefValueGet(Value r) { RefCheck(r); return BoxValueGet(r->ref.box, r->ref.element); } static inline TypePtr RefType (Value r) { RefCheck(r); return BoxType(r->ref.box, r->ref.element); } static inline Bool RefConstant(Value r) { return BoxConstant(r->ref.box, r->ref.element); } Value NewInteger (Sign sign, Natural *mag); Value NewIntInteger (int value); Value NewSignedDigitInteger (signed_digit d); Value NewRational (Sign sign, Natural *num, Natural *den); Value NewIntRational (int value); Value NewIntegerRational (Integer *); Value NewFloat (Fpart *mant, Fpart *exp, unsigned prec); Value NewIntFloat (int i, unsigned prec); Value NewIntegerFloat (Integer *i, unsigned prec); Value NewNaturalFloat (Sign sign, Natural *n, unsigned prec); Value NewRationalFloat (Rational *r, unsigned prec); Value NewValueFloat (Value av, unsigned prec); Value NewDoubleFloat (double d); Value NewContinuation (ContinuationPtr continuation, InstPtr pc); Value NewForeign (const char *id, void *data, void (*mark)(void *data), void (*free)(void *data)); unsigned FpartLength (Fpart *a); #define DEFAULT_FLOAT_PREC 256 #define REF_CACHE_SIZE 1031 extern DataCachePtr refCache; Value NewString (long length); Value NewStrString (const char *); Value NewCharString (int c); Value NewArray (Bool constant, Bool resizable, TypePtr type, int ndim, int *dims); void ArrayResize (Value av, int dim, int size); void ArraySetDimensions (Value av, int *dims); Value NewHash (Bool constant, TypePtr keyType, TypePtr valueType); Value HashGet (Value hv, Value key); void HashSet (Value hv, Value key, Value value); void HashSetDef (Value hv, Value def); Value HashKeys (Value hv); Value HashRef (Value hv, Value key); Value HashTest (Value hv, Value key); void HashDelete (Value hv, Value key); Value HashCopy (Value hv); Value NewFile (int fd); Value NewRefReal (BoxPtr box, int element, Value *re); char *StringNextChar (char *src, unsigned *dst, long *length); int StringPutChar (unsigned c, char *dest); int StringLength (char *src, long length); int StringCharSize (unsigned c); unsigned StringGet (char *src, long len, int i); char *StrzPart (Value, char *error); static inline Value NewRef (BoxPtr box, int element) { int c = (PtrToUInt (&BoxElements(box)[element])) % REF_CACHE_SIZE; Value *re = (Value *) (DataCacheValues(refCache)) + c; Value ret = *re; if (ret && ret->ref.box == box && ret->ref.element == element) { REFERENCE (ret); return ret; } return NewRefReal (box, element, re); } Value NewStruct (StructType *type, Bool constant); StructType *NewStructType (int nelements); Type *BuildStructType (int nelements, ...); Type *StructMemType (StructType *st, Atom name); Value StructMemRef (Value sv, Atom name); Value StructMemValue (Value sv, Atom name); Value NewUnion (StructType *type, Bool constant); Type *BuildUnionType (int nelements, ...); Type *BuildEnumType (int nelements, ...); Value UnionValue (Value uv, Atom name); Value UnionRef (Value uv, Atom name); Type *BuildArrayType (Type *type, int ndim, ...); Value BinaryOperate (Value av, Value bv, BinaryOp operator); Value UnaryOperate (Value v, UnaryOp operator); Value NumericDiv (Value av, Value bv, int expandOk); Value NumericMod (Value av, Value bv, int expandOk); # define OK_TRUNC 1 extern Value Blank, Elementless, Void, TrueVal, FalseVal; # define True(v) ((v) == TrueVal) # define False(v) ((v) != TrueVal) Value FileGetError (int err); Value FileGetErrorMessage (int err); int FileInput (Value); int FileOutput (Value, char); void FileUnput (Value, unsigned char); int FileInchar (Value); int FileOutchar (Value, int); void FileUnchar (Value, int); Value FileCreate (int fd, int flags); int FileFlush (Value, Bool block); int FileClose (Value); Value FileStringRead (char *string, int len); Value FileStringWrite (void); Value FileStringString (Value file); void FileSetFd (int fd), FileResetFd (int fd); Bool FileIsReadable (int fd); Bool FileIsWritable (int fd); void FilePutsc (Value, char *, long length); void FilePuts (Value, char *); void FilePutDoubleDigitBase (Value file, double_digit a, int base); void FilePutUIntBase (Value file, unsigned int a, int base); void FilePutIntBase (Value file, int a, int base); void FilePutInt (Value, int); int FileStringWidth (char *string, long length, char format); void FilePutString (Value f, char *string, long length, char format); void FilePutRep (Value f, Rep tag, Bool minimal); void FilePutClass (Value f, Class storage, Bool minimal); void FilePutPublish (Value f, Publish publish, Bool minimal); void FilePutType (Value f, Type *t, Bool minimal); void FilePutBaseType (Value f, Type *t, Bool minimal); void FilePutSubscriptType (Value f, Type *t, Bool minimal); Value FileFilter (char *program, char *args[], Value filev, int *errp); Value FileFopen (char *name, char *mode, int *errp); Value FileReopen (char *name, char *mode, Value file, int *errp); Value FileMakePipe (int *errp); void FilePutArgType (Value f, ArgType *at); int FileStatus (Value file); void FileCheckBlocked (Bool block); void FileSetBlocked (Value file, int flag); void FilePrintf (Value, char *, ...); void FileVPrintf (Value, char *, va_list); void FileSetBuffer (Value file, int buf); extern Bool anyFileWriteBlocked; extern Bool anyPipeReadBlocked; extern Value FileStdin, FileStdout, FileStderr; typedef Value (*BinaryFunc) (Value, Value); typedef Value (*UnaryFunc) (Value); #define Plus(av,bv) BinaryOperate (av, bv, PlusOp) #define Minus(av,bv) BinaryOperate (av, bv, MinusOp) #define Times(av,bv) BinaryOperate (av, bv, TimesOp) #define Divide(av,bv) BinaryOperate (av, bv, DivideOp) #define Div(av,bv) BinaryOperate (av, bv, DivOp) #define Mod(av,bv) BinaryOperate (av, bv, ModOp) #define Less(av,bv) BinaryOperate (av, bv, LessOp) #define Equal(av,bv) BinaryOperate (av, bv, EqualOp) #define Land(av,bv) BinaryOperate (av, bv, LandOp) #define Lor(av,bv) BinaryOperate (av, bv, LorOp) int logbase2(int a); Value Greater (Value, Value), LessEqual (Value, Value); Value GreaterEqual (Value, Value), NotEqual (Value, Value); Value Not (Value); Value Negate (Value), Floor (Value), Ceil (Value); Value Truncate (Value); Value Round (Value); Value Pow (Value, Value), Factorial (Value), Reduce (Value); Value ShiftL (Value, Value), ShiftR (Value, Value); Value Gcd (Value, Value); #undef GCD_DEBUG #ifdef GCD_DEBUG Value Bdivmod (Value av, Value bv); Value KaryReduction (Value av, Value bv); #endif Value Lxor(Value, Value), Lnot (Value); Value Popcount(Value); Bool Print (Value, Value, char format, int base, int width, int prec, int fill); void PrintError (char *s, ...); HashValue HashCrc32 (unsigned char *bytes, int nbytes); Value CopyMutable (Value v); static inline Value Copy (Value v) { if (v && Mutablep (ValueTag(v))) return CopyMutable (v); return v; } Value ValueEqual (Value a, Value b, int expandOk); Value ValueHash (Value a); /* * There are two kinds of signals: * * aborting current instruction should be suspended * non-aborting current instruction should be completed * * SIGIO and SIGALRM are non-aborting; otherwise computation would probably * never make progress * * SIGINTR is aborting * All internal signals are aborting * * An aborting signal marks 'aborting, signaling' and itself, this way * low-level computations can check 'aborting' and the interpreter can * check 'signaling' and then check the individual signals */ extern volatile Bool aborting; /* abort current instruction */ extern volatile Bool signaling; /* some signal is pending */ /* * Any signal state set by an signal handler must be volatile */ extern volatile Bool signalInterrupt; /* keyboard interrupt */ extern volatile Bool signalTimer; /* timer interrupt */ extern volatile Bool signalIo; /* i/o interrupt */ extern volatile Bool signalProfile; /* vtimer interrupt */ extern volatile Bool signalChild; /* sub process interrupt */ #define SetSignalInterrupt()(aborting = signaling = signalInterrupt = True) #define SetSignalTimer() (signaling = signalTimer = True) #define SetSignalIo() (signaling = signalIo = True) #define SetSignalProfile() (signaling = signalProfile = True) #define SetSignalChild() (signaling = signalChild = True) /* * Any signal state set by regular code doesn't need to be volatile */ extern Bool signalSuspend; /* current thread suspend */ extern Bool signalFinished; /* current thread done */ extern Bool signalException; /* current thread exception pending */ extern Bool signalError; /* current thread run time error */ #define SetSignalSuspend() (aborting = signaling = signalSuspend = True) #define SetSignalFinished() (aborting = signaling = signalFinished = True) #define SetSignalException()(aborting = signaling = signalException = True) #define SetSignalError() (aborting = signaling = signalError = True) int NaturalToInt (Natural *n); double_digit NaturalToDoubleDigit(Natural *n); int IntegerToInt (Integer *i); int IntegerFitsSignedDigit(Integer *i); signed_digit IntegerToSignedDigit(Integer *i); int IntPart (Value, char *error); int BoolPart (Value, char *error); signed_digit SignedDigitPart(Value v, char *error); double DoublePart (Value av, char *error); Bool Zerop (Value); Bool Negativep (Value); Bool Evenp (Value); int ArrayInit (void); int AtomInit (void); int FileInit (void); int IntInit (void); int HashInit (void); int NaturalInit (void); int IntegerInit (void); int RationalInit (void); int FpartInit (void); int StringInit (void); int StructInit (void); int RefInit (void); int ForeignInit (void); int ValueInit (void); static inline Bool oneNp (Natural *n) { return n->length == 1 && NaturalDigits(n)[0] == 1; } static inline Bool zeroNp (Natural *n) { return n->length == 0; } void ferr(int); void ignore_ferr (void); #endif /* _VALUE_H_ */ nickle_2.81.orig/func.c0000664000175000000620000000716110414112462014177 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static void MarkFuncCode (void *object) { FuncCodePtr fc = object; MemReference (fc->base.type); MemReference (fc->base.args); MemReference (fc->base.name); MemReference (fc->base.previous); MemReference (fc->base.func); MemReference (fc->base.doc); MemReference (fc->code); MemReference (fc->body.obj); MemReference (fc->body.dynamics); MemReference (fc->staticInit.obj); MemReference (fc->staticInit.dynamics); MemReference (fc->statics); } DataType FuncCodeType = { MarkFuncCode, 0, "FuncCodeType" }; static Bool HasVarargs (ArgType *args) { while (args) { if (args->varargs) return True; args = args->next; } return False; } CodePtr NewFuncCode (Type *type, ArgType *args, ExprPtr code, Value doc) { ENTER (); CodePtr fc; fc = ALLOCATE (&FuncCodeType, sizeof (FuncCode)); fc->base.builtin = False; fc->base.type = type; fc->base.argc = 0; fc->base.varargs = HasVarargs (args); fc->base.args = args; fc->base.name = 0; fc->base.previous = 0; fc->base.func = fc; fc->base.doc = doc; fc->func.code = code; fc->func.body.dynamics = 0; fc->func.body.obj = 0; fc->func.staticInit.obj = 0; fc->func.staticInit.dynamics = 0; fc->func.statics = 0; fc->func.inStaticInit = False; fc->func.inGlobalInit = False; RETURN (fc); } static void MarkBuiltinCode (void *object) { BuiltinCodePtr bc = object; MemReference (bc->base.type); MemReference (bc->base.args); MemReference (bc->base.name); MemReference (bc->base.previous); MemReference (bc->base.func); MemReference (bc->base.doc); } DataType BuiltinCodeType = { MarkBuiltinCode, 0, "BuiltinCodeType" }; CodePtr NewBuiltinCode (Type *type, ArgType *args, int argc, BuiltinFunc builtin, Bool needsNext, char *doc) { ENTER (); CodePtr bc; bc = ALLOCATE (&BuiltinCodeType, sizeof (BuiltinCode)); bc->base.builtin = True; bc->base.type = type; bc->base.argc = argc; bc->base.varargs = HasVarargs (args); bc->base.args = args; bc->base.name = 0; bc->base.previous = 0; bc->base.func = 0; bc->base.doc = doc ? NewStrString (doc) : Void; bc->builtin.needsNext = needsNext; bc->builtin.b = builtin; RETURN (bc); } static void FuncMark (void *object) { Func *f = object; MemReference (f->code); MemReference (f->staticLink); MemReference (f->statics); } void printCode (Value f, CodePtr code, int level); static Bool FuncPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { Bool nest = False; if (format == 'v') nest = True; PrettyCode (f, av->func.code, 0, class_undef, publish_private, 0, nest); return True; } ValueRep FuncRep = { { FuncMark, 0, "FuncRep" }, /* base */ rep_func, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, ValueEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, FuncPrint, 0, }; Value NewFunc (CodePtr code, FramePtr staticLink) { ENTER (); Value ret; ret = ALLOCATE (&FuncRep.data, sizeof (Func)); ret->func.code = code; ret->func.staticLink = staticLink; ret->func.statics = 0; /* * Create the box containing static variables for this closure */ if (!code->base.builtin && code->func.statics) ret->func.statics = NewTypedBox (False, code->func.statics); RETURN (ret); } nickle_2.81.orig/ylwrap0000755000175000000620000001531213064666316014357 0ustar keithpstaff#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2013-01-12.17; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard () { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input=$1 shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case $input in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input=`pwd`/$input ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test $# -ne 0; do if test x"$1" = x"--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog=$1 shift # Make any relative path in $prog absolute. case $prog in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog=`pwd`/$prog ;; esac dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target=../$to;; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget=$target target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: nickle_2.81.orig/sync.c0000664000175000000620000000400711724214756014232 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" extern Bool complete; Value do_Semaphore_wait (Value s) { ENTER (); if (aborting) RETURN (Void); if (!running->thread.partial) { --s->semaphore.count; if (s->semaphore.count < 0) { running->thread.partial = 1; ThreadSleep (running, s, PrioritySync); RETURN (Void); } } complete = True; RETURN (Void); } Value do_Semaphore_test (Value s) { ENTER (); if (s->semaphore.count <= 0) RETURN (FalseVal); do_Semaphore_wait (s); RETURN (TrueVal); } Value do_Semaphore_count (Value s) { ENTER(); RETURN (NewInt(s->semaphore.count)); } Value do_Semaphore_signal (Value s) { ENTER (); if (aborting) RETURN (Void); ++s->semaphore.count; if (s->semaphore.count <= 0) ThreadsWakeup (s, WakeOne); complete = True; RETURN (Void); } static Bool SemaphorePrint (Value f, Value av, char format, int base, int width, int prec, int fill) { FilePrintf (f, "semaphore %d (%d)", av->semaphore.id, av->semaphore.count); return True; } ValueRep SemaphoreRep = { { 0, 0, "SemaphoreRep" }, /* base */ rep_semaphore, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, ValueEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, SemaphorePrint, 0, }; Value do_Semaphore_new (int n, Value *value) { ENTER (); Value ret; int count; static int id; switch (n) { case 0: count = 0; break; case 1: count = IntPart (value[0], "Illegal initial semaphore count"); break; default: RaiseStandardException (exception_invalid_argument, 3, NewStrString ("new: wrong number of arguments"), NewInt (1), NewInt (n)); RETURN(Void); } ret = ALLOCATE (&SemaphoreRep.data, sizeof (Semaphore)); ret->semaphore.count = count; ret->semaphore.id = ++id; RETURN (ret); } nickle_2.81.orig/socket.5c0000664000175000000620000000125510414112462014617 0ustar keithpstaffextend namespace Socket { public string addr_to_string (int addr) /* * Return a dotted quad from 'addr' */ { return sprintf ("%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, (addr) & 0xff); } public int string_to_addr (string addr) /* * Parse a dotted quad */ { int r = File::sscanf (addr, "%d.%d.%d.%d", &(int a), &(int b), &(int c), &(int d)); if (r != 4) raise invalid_argument ("invalid network address format", r, addr); return (a << 24) + (b << 16) + (c << 8) + d; } } /* * backwards compatibility for old namespace name */ namespace Sockets { public import Socket; } nickle_2.81.orig/stack.c0000664000175000000620000001126011765451133014357 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include #include #include "mem.h" #include "stack.h" static void stackMark (void *); DataType stackType = { stackMark, 0, "stackType" }; DataType stackChunkType = { 0, 0, "stackChunkType" }; static void addChunk (StackObject *stack) { StackChunk *chunk; if (stack->save) { chunk = stack->save; stack->save = 0; } else chunk = MemAllocate (&stackChunkType, sizeof (StackChunk)); chunk->previous = stack->current; stack->current = chunk; STACK_TOP(stack) = CHUNK_MAX(chunk); } StackObject * StackCreate (void) { StackObject *stack; stack = MemAllocate (&stackType, sizeof (StackObject)); stack->current = 0; stack->save = 0; stack->temp = 0; stack->stackPointer = 0; TemporaryData = stack; addChunk (stack); TemporaryData = 0; return stack; } void * StackPush (StackObject *stack, StackElement object) { STACK_ASSERT (stack); if (STACK_TOP(stack) == STACK_MIN(stack)) { stack->temp = object; addChunk (stack); stack->temp = 0; } return *--STACK_TOP(stack) = object; } void * StackPop (StackObject *stack) { STACK_ASSERT (stack); if (STACK_TOP(stack) == STACK_MAX(stack)) { StackChunk *previous = stack->current->previous; if (!stack->save) { stack->save = stack->current; stack->save->previous = 0; } stack->current = previous; if (!stack->current) panic ("Stack underflow\n"); STACK_TOP(stack) = previous->elements; } return *STACK_TOP(stack)++; } void StackDrop (StackObject *stack, int i) { int this; StackChunk *previous; STACK_ASSERT (stack); while (i) { this = STACK_MAX(stack) - STACK_TOP(stack); if (this >= i) { STACK_TOP(stack) += i; break; } i -= this; previous = stack->current->previous; if (!stack->save) { stack->save = stack->current; stack->save->previous = 0; } stack->current = previous; if (!stack->current) panic ("Stack underflow\n"); STACK_TOP(stack) = CHUNK_MIN(previous); } STACK_ASSERT (stack); } void StackReset (StackObject *stack, StackPointer stackPointer) { STACK_ASSERT (stack); while (!(STACK_TOP(stack) <= stackPointer && stackPointer <= STACK_MAX(stack))) { StackChunk *previous = stack->current->previous; if (!stack->save) { stack->save = stack->current; stack->save->previous = 0; } stack->current = previous; if (!stack->current) panic ("Stack underflow\n"); STACK_TOP(stack) = CHUNK_MIN(previous); } STACK_TOP(stack) = stackPointer; STACK_ASSERT (stack); } StackElement StackReturn (StackObject *stack, StackPointer stackPointer, StackElement object) { STACK_ASSERT (stack); STACK_RESET(stack, stackPointer); return STACK_PUSH(stack,object); } StackElement StackElt (StackObject *stack, int i) { StackChunk *chunk; StackPointer stackPointer; STACK_ASSERT (stack); chunk = stack->current; stackPointer = STACK_TOP(stack); while (stackPointer + i >= CHUNK_MAX(chunk)) { i -= CHUNK_MAX(chunk) - stackPointer; chunk = chunk->previous; if (!chunk) panic ("StackElt underflow\n"); stackPointer = CHUNK_MIN(chunk); } return stackPointer[i]; } StackObject * StackCopy (StackObject *stack) { StackObject *new; StackChunk *chunk, *nchunk, **prev; STACK_ASSERT (stack); new = StackCreate (); REFERENCE (new); chunk = stack->current; nchunk = new->current; prev = &new->current; while (chunk) { STACK_ASSERT (new); STACK_ASSERT (stack); if (!nchunk) nchunk = MemAllocate (&stackChunkType, sizeof (StackChunk)); else STACK_TOP(new) = (new->current->elements + (STACK_TOP(stack) - stack->current->elements)); /* * Copy stack data and fix stack pointer */ *nchunk = *chunk; STACK_CHUNK_ASSERT(chunk->type == &stackChunkType); /* * Link into chain */ *prev = nchunk; prev = &nchunk->previous; *prev = 0; chunk = chunk->previous; nchunk = 0; } STACK_ASSERT (new); return new; } static void stackMark (void *object) { StackObject *stack = object; StackChunk *chunk; StackPointer stackPointer; STACK_ASSERT (stack); MemReference (stack->temp); MemReference (stack->save); chunk = stack->current; if (chunk) { stackPointer = STACK_TOP(stack); for (;;) { MemReference (chunk); while (stackPointer != CHUNK_MAX(chunk)) MemReference (*stackPointer++); chunk = chunk->previous; if (!chunk) break; stackPointer = CHUNK_MIN(chunk); } } } nickle_2.81.orig/bench/0002775000175000000620000000000013202543025014155 5ustar keithpstaffnickle_2.81.orig/bench/Makefile.am0000664000175000000620000000044710414112462016213 0ustar keithpstaffCFILES=choose.c \ composite.c \ ifact.c \ rfact.c BCFILES=choose.bc \ composite.bc \ ifact.bc \ rfact.bc NICKLEFILES = choose.5c \ composite.5c \ ifact.5c \ rfact.5c HARNESS=runbench.sh EXTRA_DIST=$(CFILES) $(BCFILES) $(NICKLEFILES) $(HARNESS) CLEANFILES=choose composite ifact rfact nickle_2.81.orig/bench/composite.5c0000664000175000000620000000122010414112462016400 0ustar keithpstaff/* Miller-Rabin test from Corwin/Rivest/Leiserson */ int function witnessexp(int b, int e, int m) { if (e == 0) return -1; if (e == 1) return b % m; int res = witnessexp(b, e // 2, m); if (res == -1) return res; int t = (res * res) % m; if (t == 1 && res != 1 && res != m - 1) return -1; if (e % 2 == 0) return t; return (t * b) % m; } /* Note that rather than trying random bases, we try *all* bases[*]... */ /* ([*] Don't even think it.) */ public int function composite(int n) { for (int j = 0; j < n - 1; j++) { if (witnessexp(j + 1, n - 1, n) != 1) return j + 1; } return 0; } composite(39157) nickle_2.81.orig/bench/rfact.c0000664000175000000620000000102510414112462015413 0ustar keithpstaff#include #include void rfact(mpz_t res, mpz_t n) { mpz_t tmp; if (mpz_cmp_si(n, 0) <= 0) { mpz_set_si(res, 1); return; } mpz_init_set(tmp, n); mpz_sub_ui(tmp, tmp, 1); rfact(res, tmp); mpz_clear(tmp); mpz_mul(res, res, n); } void do_rfact(signed long int xa) { mpz_t a, res; mpz_init_set_si(a, xa); mpz_init(res); rfact(res, a); mpz_clear(a); mpz_out_str(stdout, 10, res); putchar('\n'); mpz_clear(res); } int main(void) { do_rfact(20000); exit(0); } nickle_2.81.orig/bench/rfact.5c0000664000175000000620000000014310414112462015500 0ustar keithpstaffint function rfact(int n) { if (n <= 0) return 1; return n * rfact(n - 1); } rfact(20000) nickle_2.81.orig/bench/runbench.sh0000664000175000000620000000057210414112462016316 0ustar keithpstaff#!/bin/sh while read bmname do gcc -O4 -o "$bmname" "$bmname.c" -lgmp > /dev/null 2>&1 || exit 1 echo "../nickle $bmname.5c" echo "bc $bmname.bc" echo "./$bmname /dev/null" done <<'EOF' | ifact rfact choose composite EOF while read lang input do echo "$lang $input" for i in 1 2 3 4 5 do echo -n "$i. " ( time $lang < $input > /dev/null ) 2>&1 done done nickle_2.81.orig/bench/choose.bc0000664000175000000620000000030210414112462015733 0ustar keithpstaffdefine ifact(n) { auto f; f = 1; while(n >= 2) { f *= n; n -= 1; } return (f); } define choose(n, r) { return (ifact(n) / (ifact(r) * ifact(n - r))); } choose(20000, 5000) nickle_2.81.orig/bench/rfact.bc0000664000175000000620000000013510414112462015556 0ustar keithpstaffdefine rfact(n) { if (n <= 0) return (1); return (n * rfact(n - 1)); } rfact(20000) nickle_2.81.orig/bench/ifact.5c0000664000175000000620000000016010414112462015466 0ustar keithpstaffint function ifact(int n) { int f = 1; while(n >= 2) { f *= n; --n; } return f; } ifact(20000) nickle_2.81.orig/bench/Makefile.in0000664000175000000620000002662713202542702016236 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = bench ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CFILES = choose.c \ composite.c \ ifact.c \ rfact.c BCFILES = choose.bc \ composite.bc \ ifact.bc \ rfact.bc NICKLEFILES = choose.5c \ composite.5c \ ifact.5c \ rfact.5c HARNESS = runbench.sh EXTRA_DIST = $(CFILES) $(BCFILES) $(NICKLEFILES) $(HARNESS) CLEANFILES = choose composite ifact rfact all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bench/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign bench/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/bench/choose.c0000664000175000000620000000165710414112462015607 0ustar keithpstaff#include #include void ifact(mpz_t res, mpz_t n) { mpz_t count; mpz_init_set(count, n); mpz_set_si(res, 1); while(mpz_cmp_si(count, 2) >= 0) { mpz_mul(res, res, count); mpz_sub_ui(count, count, 1); } mpz_clear(count); } void choose(mpz_t res, mpz_t n, mpz_t r) { mpz_t ifr, ifnr, diff; mpz_init(ifr); mpz_init(ifnr); mpz_init_set(diff, n); mpz_sub(diff, diff, r); ifact(res, n); ifact(ifr, r); ifact(ifnr, diff); mpz_mul(ifnr, ifnr, ifr); mpz_fdiv_q(res, res, ifnr); mpz_clear(ifr); mpz_clear(ifnr); mpz_clear(diff); } void do_choose(signed long int xa1, signed long int xa2) { mpz_t a1, a2, res; mpz_init_set_si(a1, xa1); mpz_init_set_si(a2, xa2); mpz_init(res); choose(res, a1, a2); mpz_clear(a1); mpz_clear(a2); mpz_out_str(stdout, 10, res); putchar('\n'); mpz_clear(res); } int main(void) { do_choose(20000, 5000); exit(0); } nickle_2.81.orig/bench/ifact.c0000664000175000000620000000101410414112462015400 0ustar keithpstaff#include #include void ifact(mpz_t res, mpz_t n) { mpz_t count; mpz_init_set(count, n); mpz_set_si(res, 1); while(mpz_cmp_si(count, 2) >= 0) { mpz_mul(res, res, count); mpz_sub_ui(count, count, 1); } mpz_clear(count); } void do_ifact(signed long int xa) { mpz_t a, res; mpz_init_set_si(a, xa); mpz_init(res); ifact(res, a); mpz_clear(a); mpz_out_str(stdout, 10, res); putchar('\n'); mpz_clear(res); } int main(void) { do_ifact(20000); exit(0); } nickle_2.81.orig/bench/composite.bc0000664000175000000620000000121110414112462016455 0ustar keithpstaff/* Miller-Rabin test from Corwin/Rivest/Leiserson */ define witnessexp(b, e, m) { auto res, t; if (e == 0) return (-1); if (e == 1) return (b % m); res = witnessexp(b, e / 2, m); if (res == -1) return (res); t = (res * res) % m; if (t == 1 && res != 1 && res != m - 1) return (-1); if (e % 2 == 0) return (t); return ((t * b) % m); } /* Note that rather than trying random bases, we try *all* bases[*]... */ /* ([*] Don't even think it.) */ define composite(n) { auto j; for (j = 0; j < n - 1; j++) { if (witnessexp(j + 1, n - 1, n) != 1) return (j + 1); } return (0); } composite(39157) nickle_2.81.orig/bench/choose.5c0000664000175000000620000000013410414112462015661 0ustar keithpstaffint function choose(int n, int r) { return (n! // (r! * (n - r)!)); } choose(20000,5000) nickle_2.81.orig/bench/ifact.bc0000664000175000000620000000016110414112462015544 0ustar keithpstaffdefine ifact(n) { auto f; f = 1; while(n >= 2) { f *= n; n -= 1; } return (f); } ifact(20000) nickle_2.81.orig/bench/composite.c0000664000175000000620000000376610414112462016334 0ustar keithpstaff#include #include /* Miller-Rabin test from Corwin/Rivest/Leiserson */ void witnessexp(mpz_t res, mpz_t b, mpz_t e, mpz_t m) { mpz_t xres, tmp, rem, m1; if (mpz_cmp_si(e, 0) == 0) { mpz_set_si (res, -1); return; } if (mpz_cmp_si(e, 1) == 0) { mpz_fdiv_r (res, b, m); return; } mpz_init(tmp); mpz_init(rem); mpz_fdiv_qr_ui(tmp, rem, e, 2); mpz_init(xres); witnessexp(xres, b, tmp, m); if (mpz_cmp_si(xres, -1) == 0) { mpz_set(res, xres); mpz_clear(tmp); mpz_clear(rem); mpz_clear(xres); return; } mpz_mul(tmp, xres, xres); mpz_fdiv_r(tmp, tmp, m); mpz_init(m1); mpz_sub_ui(m1, m, 1); if (mpz_cmp_si(tmp, 1) == 0 && mpz_cmp_si(xres, 1) != 0 && mpz_cmp(xres, m1) != 0) { mpz_set_si(res, -1); mpz_clear(tmp); mpz_clear(rem); mpz_clear(xres); mpz_clear(m1); return; } if (mpz_cmp_si(rem, 0) == 0) { mpz_set(res, tmp); mpz_clear(tmp); mpz_clear(rem); mpz_clear(xres); mpz_clear(m1); return; } mpz_mul(tmp, tmp, b); mpz_fdiv_r(res, tmp, m); mpz_clear(tmp); mpz_clear(rem); mpz_clear(xres); mpz_clear(m1); } /* Note that rather than trying random bases, we try _all_ bases[!]... */ /* ([!] Don't even _think_ it.) */ void composite(mpz_t res, mpz_t n) { mpz_t n1, j; mpz_init(n1); mpz_sub_ui(n1, n, 1); for (mpz_init_set_si(j, 1); mpz_cmp(j, n) < 0; mpz_add_ui(j, j, 1)) { mpz_t xres; mpz_init(xres); witnessexp(xres, j, n1, n); if (mpz_cmp_si(xres, 1) != 0) { mpz_set(res, j); mpz_clear(n1); mpz_clear(j); mpz_clear(xres); return; } mpz_clear(xres); } mpz_set_si(res, 0); mpz_clear(n1); mpz_clear(j); return; } void do_composite(signed long int xa) { mpz_t a, res; mpz_init_set_si(a, xa); mpz_init(res); composite(res, a); mpz_clear(a); mpz_out_str(stdout, 10, res); putchar('\n'); mpz_clear(res); } int main(void) { do_composite(39157); exit(0); } nickle_2.81.orig/scanf.5c0000664000175000000620000000767411720620261014436 0ustar keithpstaff/* * Scanf code. Extend File namespace with reading code */ extend namespace File { public int fscanf (file f, string format, *poly args ...) /* * According to 'format', read from 'f' to 'args' */ { exception bad_conversion(); /* Skip whitespace */ void whitespace () { int c; while (!end (f)) if (!Ctype::isspace (c = getc (f))) { ungetc (c, f); break; } } bool isbinary (int c) { if ('0' <= c && c <= '1') return true; if (c == '-') return true; return false; } bool isoctal (int c) { if ('0' <= c && c <= '7') return true; if (c == '-') return true; return false; } bool isdecimal (int c) { if ('0' <= c && c <= '9') return true; if (c == '-') return true; return false; } bool ishex (int c) { if ('0' <= c && c <= '9') return true; if ('a' <= c && c <= 'f') return true; if ('A' <= c && c <= 'F') return true; if (c == '-') return true; return false; } bool isfloat (int c) { if ('0' <= c && c <= '9') return true; if (c == 'e') return true; if (c == '-') return true; if (c == '.') return true; if (c == '{' || c == '}') return true; return false; } /* return next integer in input */ int integer (bool(int c) test, int base) { int c; string s = ""; whitespace(); while (!end (f)) { if (!test (c = getc (f))) { ungetc (c, f); break; } s = s + String::new(c); } if (String::length(s) == 0) raise bad_conversion(); return string_to_integer (s, base); } /* return next number in input */ real number (bool(int c) test) { int c; string s = ""; whitespace(); while (!end (f)) { if (!test (c = getc (f))) { ungetc (c, f); break; } s = s + String::new(c); } if (String::length(s) == 0) raise bad_conversion(); return string_to_real (s); } string word () { whitespace(); string s = ""; while (!end (f)) { int c = getc(f); if (!Ctype::isgraph (c)) { ungetc (c, f); break; } s = s + String::new(c); } if (String::length(s) == 0) raise bad_conversion(); return s; } int i = 0; int argc = 0; int c; while (i < String::length (format) && !end(f) && !error(f)) { try { switch (format[i]) { case ' ': case '\t': whitespace (); break; case '%': i++; switch (format[i]) { case 'b': case 'B': *args[argc] = integer (isbinary, 2); argc++; break; case 'o': case 'O': *args[argc] = integer (isoctal, 8); argc++; break; case 'd': case 'D': *args[argc] = integer (isdecimal, 10); argc++; break; case 'x': case 'X': *args[argc] = integer (ishex, 16); argc++; break; case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': *args[argc] = number(isfloat); argc++; break; case 'c': *args[argc] = getc(f); argc++; break; case 's': *args[argc] = word(); argc++; break; default: if (end (f)) return argc; c = getc(f); if (c != format[i]) { ungetc (c, f); return argc; } break; } break; default: if (end (f)) return argc; c = getc(f); if (c != format[i]) { ungetc (c, f); return argc; } break; } i++; } catch bad_conversion() { } } return argc; } public int sscanf (string s, string format, *poly args...) /* * According to 'format', read from 's' to 'args' */ { file sf = string_read(s); int n = fscanf (sf, format, args ...); close(sf); return n; } public namespace ScanfGlobals { public int scanf (string format, *poly args...) /* * According to 'format', read from stdin to 'args' */ { return fscanf (stdin, format, args ...); } } public import ScanfGlobals; } import File::ScanfGlobals; nickle_2.81.orig/union.c0000664000175000000620000000604610414112462014375 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" Value UnionRef (Value uv, Atom name) { ENTER (); Union *u = &uv->unions; StructType *st = u->type; int i; for (i = 0; i < st->nelements; i++) if (StructTypeAtoms(st)[i] == name) { u->tag = name; RETURN (NewRef (u->value, 0)); } RETURN (0); } Value UnionValue (Value uv, Atom name) { ENTER (); Union *u = &uv->unions; if (u->tag != name) RETURN (0); RETURN (BoxValue (u->value, 0)); } static Bool UnionPrint (Value f, Value av, char format, int base, int width, int prec, int fill) { Union *u = &av->unions; if (format == 'v') FileOutput (f, '{'); if (u->tag) { Type *t = StructMemType (u->type, u->tag); FilePuts (f, AtomName (u->tag)); if (t != (Type*) 1) { FilePuts (f, " = "); if (!Print (f, BoxValue (u->value, 0), format, base, width, prec, fill)) return False; } } else FilePuts (f, ""); if (format == 'v') FileOutput (f, '}'); return True; } static void UnionMark (void *object) { Union *u = object; MemReference (u->type); MemReference (u->value); } static Value UnionEqual (Value av, Value bv, int expandOk) { Union *a = &av->unions, *b = &bv->unions; if (!ValueIsUnion(av)) return Equal (av, BoxValue (b->value, 0)); if (!ValueIsUnion(bv)) return Equal (BoxValue (a->value, 0), bv); if (a->tag != b->tag) return FalseVal; return Equal (BoxValue (a->value, 0), BoxValue (b->value, 0)); } ValueRep UnionRep = { { UnionMark, 0, "UnionRep" }, /* base */ rep_union, /* tag */ { /* binary */ 0, 0, 0, 0, 0, 0, 0, UnionEqual, 0, 0, }, { /* unary */ 0, 0, 0, }, 0, 0, UnionPrint, 0, }; Value NewUnion (StructType *type, Bool constant) { ENTER (); Value ret; ret = ALLOCATE (&UnionRep.data, sizeof (Union)); ret->unions.type = type; ret->unions.tag = 0; ret->unions.value = 0; ret->unions.value = NewBox (constant, False, 1, 0); RETURN (ret); } Type * BuildUnionType (int nelements, ...) { ENTER (); StructType *st; int i; char *name; Type *type; va_list ap; st = NewStructType (nelements); va_start (ap, nelements); for (i = 0; i < nelements; i++) { type = va_arg (ap, Type *); name = va_arg (ap, char *); AddBoxType (&st->types, type); StructTypeAtoms (st)[i] = AtomId (name); } va_end (ap); RETURN (NewTypeUnion (st, False)); } Type * BuildEnumType (int nelements, ...) { ENTER (); StructType *st; int i; char *name; va_list ap; st = NewStructType (nelements); va_start (ap, nelements); for (i = 0; i < nelements; i++) { name = va_arg (ap, char *); AddBoxType (&st->types, typePrim[rep_void]); StructTypeAtoms (st)[i] = AtomId (name); } va_end (ap); RETURN (NewTypeUnion (st, True)); } nickle_2.81.orig/autogen.sh0000775000175000000620000000036210414112462015075 0ustar keithpstaff#! /bin/sh # # $Id$ # # runs autotools to create ./configure and friends # # configure depends on version.m4, but autoreconf does not realize this rm configure autoreconf -Wall -v --install || exit 1 ./configure --enable-maintainer-mode "$@" nickle_2.81.orig/debug.c0000664000175000000620000001132410770315535014341 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static void DebugAddVar (NamespacePtr namespace, char *string, Value v, Type *type) { ENTER (); SymbolPtr symbol; symbol = NamespaceAddName (namespace, NewSymbolGlobal (AtomId (string), type), publish_private); BoxValueSet (symbol->global.value, 0, v); EXIT (); } static void DebugAddCommand (char *function, Bool names) { SymbolPtr symbol; symbol = NamespaceFindName (CurrentNamespace, AtomId (function), True); if (symbol && symbol->symbol.class == class_global) { CurrentCommands = NewCommand (CurrentCommands, symbol->symbol.name, BoxValue (symbol->global.value, 0), names); } } static void DebugDeleteCommand (char *function) { CurrentCommands = CommandRemove (CurrentCommands, AtomId (function)); } static const struct { char *function; Bool names; } debugCommands[] = { { "trace", False, }, { "up", False, }, { "down", False, }, { "done", False, }, { "help", False, }, }; #define NUM_DEBUG_COMMANDS (sizeof (debugCommands) / sizeof (debugCommands[0])) static void DebugAddCommands (void) { int i; for (i = 0; i < NUM_DEBUG_COMMANDS; i++) DebugAddCommand (debugCommands[i].function, debugCommands[i].names); } static void DebugDeleteCommands (void) { int i; for (i = 0; i < NUM_DEBUG_COMMANDS; i++) DebugDeleteCommand (debugCommands[i].function); } Bool DebugSetFrame (Value continuation, int offset) { ENTER (); FramePtr frame = continuation->continuation.frame; ObjPtr obj = continuation->continuation.obj; InstPtr pc = continuation->continuation.pc; ExprPtr stat = obj ? ObjStatement (obj, pc) : 0; NamespacePtr namespace; int n = offset; Bool ret; while (frame && frame->function->func.code->base.builtin) { stat = ObjStatement (frame->saveObj, frame->savePc); frame = frame->previous; } while (frame && n--) { stat = ObjStatement (frame->saveObj, frame->savePc); frame = frame->previous; } if (stat) namespace = stat->base.namespace; else namespace = GlobalNamespace; ret = False; if (frame && namespace) { ret = True; TopNamespace = CurrentNamespace = NewNamespace (namespace); CurrentFrame = frame; NamespaceImport (CurrentNamespace, DebugNamespace, publish_public); DebugAddVar (CurrentNamespace, "cont", continuation, typePrim[rep_continuation]); DebugAddVar (CurrentNamespace, "frame", NewInt (offset), typePrim[rep_integer]); } EXIT (); return ret; } void DebugStart (Value continuation) { if (LexResetInteractive ()) { if (DebugSetFrame (continuation, 0)) DebugAddCommands (); } } Value do_Debug_done (void) { ENTER (); TopNamespace = CurrentNamespace = GlobalNamespace; CurrentFrame = 0; DebugDeleteCommands (); RETURN (Void); } Value do_Debug_help (void) { ENTER (); FilePrintf (FileStderr, "debug commands: trace, up, down, done, help\n"); RETURN (Void); } Value do_Debug_up (void) { ENTER (); Value frame; Value continuation; continuation = lookupVar (0, "cont"); frame = lookupVar (0, "frame"); if (ValueIsContinuation(continuation) && ValueIsInt(frame)) { if (DebugSetFrame (continuation, ValueInt(frame) + 1)) RETURN (TrueVal); FilePrintf (FileStderr, "Already at top\n"); } RETURN (FalseVal); } Value do_Debug_down (void) { ENTER (); Value frame; Value continuation; continuation = lookupVar (0, "cont"); frame = lookupVar (0, "frame"); if (ValueIsContinuation(continuation) && ValueIsInt(frame)) { if (ValueInt(frame) <= 0) FilePrintf (FileStderr, "Already at bottom\n"); else if (DebugSetFrame (continuation, ValueInt(frame) - 1)) RETURN (TrueVal); } RETURN (FalseVal); } Value do_Debug_dump (Value f) { ENTER (); CodePtr code; if (!ValueIsFunc (f)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("dump: not a function"), NewInt (0), f); RETURN (Void); } code = f->func.code; if (code->base.builtin) { FilePuts (FileStdout, "\n"); RETURN (Void); } if (code->func.staticInit.obj) { FilePuts (FileStdout, "Static initializers\n"); ObjDump (code->func.staticInit.obj, 2); FilePuts (FileStdout, "\n"); } FilePuts (FileStdout, "Function body\n"); ObjDump (code->func.body.obj, 1); RETURN (Void); } #ifdef MEM_TRACE Value do_Debug_dump_active (void) { MemCollect (); MemActiveDump (); return Void; } #endif nickle_2.81.orig/INSTALL0000664000175000000620000001722710414112462014135 0ustar keithpstaffBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. nickle_2.81.orig/memp.h0000664000175000000620000000253610414112462014210 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #ifndef _MEMP_H_ #define _MEMP_H_ /* * memp.h * * definitions for the memory manager */ # define TYPE(o) (*((DataType **) (o))) # define MINBLOCKSIZE (MAXHUNK + MINHUNK + HEADSIZE) # define GOODBLOCKSIZE (0x2000) # define BLOCKSIZE (GOODBLOCKSIZE < MINBLOCKSIZE ? \ MINBLOCKSIZE : GOODBLOCKSIZE) # define DATASIZE (BLOCKSIZE - HEADSIZE) # define NUMHUNK(i) (DATASIZE / HUNKSIZE(i)) # define NUMHUNK_ALL(i) ((i) >= NUMSIZES ? 1 : NUMHUNK(i)) # define HUNKSIZE_ALL(i) ((i) >= NUMSIZES ? (i) : HUNKSIZE(i)) # define GARBAGETIME 1000 #if HAVE_STDINT_H #include #define PtrToInt(p) ((int) (intptr_t) (p)) typedef intptr_t IntPtr; #else #define PtrToInt(p) ((int) (p)) typedef int IntPtr; #endif /* * Reference bits are stored in the low bit of the DataType pointer * which exists at the head of each object */ #define fetchRefInt(a) ((IntPtr) (*(DataType **) (a))) #define storeRefInt(a,v) ((*(DataType **) (a)) = (DataType *) (v)) #define isReferenced(a) (fetchRefInt(a) & 1) #define clrReference(a) (storeRefInt(a,fetchRefInt(a) & ~1)) #define setReference(a) (storeRefInt(a,fetchRefInt(a) | 1)) #endif /* _MEMP_H_ */ nickle_2.81.orig/examples/0002775000175000000620000000000013202543025014714 5ustar keithpstaffnickle_2.81.orig/examples/cribbage.5c0000664000175000000620000000162010770315535016712 0ustar keithpstaff/* * Cribbage scoring aid * Counts only runs and 15s * * Copyright © 1997 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ namespace Cribbage { int countsum(int c, int[*] v, int n) { if (c < 0) return 0; int t = 0; for (int i = 0; i < n; i++) t += v[i]; if (t == c) return 1; if (t < c) return 0; return countsum(c, v, n - 1) + countsum(c - v[n - 1], v, n - 1); } int countpairs(int[*] v, int n) { if (n < 2) return 0; int c = 0; for (int i = 1; i < n; i++) if (v[i] == v[0]) c++; int[n - c - 1] w; int j = 0; for (int i = 1; i < n; i++) if (v[i] != v[0]) w[j++] = v[i]; return c * (c + 1) // 2 + countpairs(w, n - c - 1); } public int score(int[*] v) { int n = dim(v); return 2 * countsum(15, v, n) + 2 * countpairs(v, n); } } nickle_2.81.orig/examples/is-prime.5c0000664000175000000620000000636710414112462016703 0ustar keithpstaff/* * implementation of * Agrawal, Kayal, and Saxena's * deterministic polytime primality test * * Copyright © 2002 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart Massey 2002/8/16 */ /* The algorithm (from page 4 of the original abstract) * * Input: integer n > 1 * 1. if ( n is of the form a ** b , b > 1 ) output COMPOSITE; * 2. r = 2; * 3. while(r < n) { * 4. if ( gcd(n,r) =/= 1 ) output COMPOSITE; * 5. if (r is prime) * 6. let q be the largest prime factor of r - 1; * 7. if (q >= 4 sqrt(r) log(n)) and ((n ** ((r-1)/q)) =/= 1) (mod r)) * 8. break; * 9. r = r + 1; * 10. } * 11. for a = 1 to 2 sqrt(r) log(n) * 12. if ( (x - a) ** n =/= x**n - a (mod x**r - 1, n) ) output COMPOSITE; * 13. output PRIME; */ load "numbers.5c"; import Numbers; load "polynomial.5c"; import Polynomial; /* Returns the largest factor of n, computed the dumbest way. */ int max_factor(int n) { int factor = 1; for (int i = 2; i * i <= n; i++) { if (n % i == 0) { factor = i; n /= factor; } } return factor; } /* * returns true iff n is of the form * a ** b for some integers a > 1, b > 1. */ bool is_xn(int n) { /* Could just do prime powers, but this is about as cheap and easier. */ int b = 2; real a = exp(log(n) / b); while (a > 1.9) { if (floor(a) ** b == n || ceil(a) ** b == n) return true; a = exp(log(n) / ++b); } return false; } /* * The polytime algorithm below is painfully slow * in the small case. It's only a constant, but * a big-deal one. */ bool is_small_prime(int n) { if (n < 2) abort("small prime test below 2"); global int small = 50; if (n >= small) return false; global bool[*] init_sieve() { bool[small] sieve = {true ...}; int k = 2; while (k < small) { for (int i = k + k; i < small; i += k) sieve[i] = false; k++; while(k < small && !sieve[k]) k++; } return sieve; } global bool[small] sieve = init_sieve(); return sieve[n]; } bool is_prime(int n) { if (n < 2) abort("prime test below 2"); if (is_small_prime(n)) return true; if (is_xn(n)) return false; int r; for (r = 2; r < n; r++) { if (gcd(n, r) != 1) return false; if (!is_prime(r)) continue; int q = max_factor(r - 1); if (q ** 2 >= 16 * r * (log2(n) ** 2) && bigpowmod(n, ((r - 1) / q), r) != 1) break; } int[r + 1] m1 = {-1, 0...}; m1[r] = 1; polynomial mn = m1; mn[0] = -n; for (int a = 1; a ** 2 <= 4 * r * (log2(n) ** 2); a++) { bool eqn(polynomial m) { polynomial lhs = power_mod((polynomial){-a, 1}, n, m); int[n + 1] rhsp = {-a, 0...}; rhsp[n] = 1; polynomial rhs = div_mod(rhsp, m).rem; return lhs == rhs; } if (eqn(m1) && eqn(mn)) return false; } return true; } autoload MillerRabin; void test_is_prime() { for (int i = 2; i < 1000; i++) { if (is_prime(i) == MillerRabin::composite(i, 24)) { string msg; if (MillerRabin::composite(i, 24)) msg = sprintf("%d: false prime\n"); else msg = sprintf("%d: false composite\n"); abort(msg); } if (true || i % 100 == 0) printf("tested to %d\n", i); } } test_is_prime(); nickle_2.81.orig/examples/miller-rabin.5c0000664000175000000620000000426010770315535017534 0ustar keithpstaff/* * Miller-Rabin probabilistic test for composite numbers * as described in Corman/Leiserson/Rivest * * composite(n,d): returns false for all prime n, * and true for most composite n * (failure probability 1/2**d) * primebits(n,d): returns a random n-bit number k where !composite(k,d) * * Copyright © 1999 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart Massey 1999/1 */ autoload PRNG; namespace MillerRabin { int[*] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; int nprimes = dim(primes); typedef struct { int pow, wit; } witness_result; /* * Modified version of bigpowmod() from numbers.5c. * Computes core of Miller-Rabin test * as suggested by Cormen/Leiserson/Rivest. */ witness_result witnessexp(int b, int e, int m) { switch (e) { case 0: return (witness_result){ .pow = 0, .wit = 1}; case 1: return (witness_result){ .pow = b % m, .wit = 0}; } witness_result tmp = witnessexp(b, e // 2, m); if (tmp.wit != 0) return tmp; int t = (tmp.pow * tmp.pow) % m; if (t == 1 && tmp.pow != 1 && tmp.pow != m - 1) { tmp.wit = tmp.pow; tmp.pow = t; return tmp; } if (e % 2 == 0) tmp.pow = t; else tmp.pow = (t * b) % m; return tmp; } /* Rest of Miller-Rabin test */ bool witness(int a, int n) { witness_result we = witnessexp(a, n - 1, n); if (we.wit != 0) return true; if (we.pow != 1) return true; return false; } /* Try small primes, then Miller-Rabin */ public bool composite(int n, int d) { int i, j; for (i = 0; i < nprimes && primes[i] < n; i++) if (n % primes[i] == 0) return true; for (j = 0; j < d; j++) { int a = 1 + PRNG::randint(n - 1); if (witness(a, n)) return true; } return false; } /* generate an n-bit prime (with probability 1-(2**-d)) number */ public int primebits(int n, int d) { while (true) { int q = PRNG::randbits(n - 1) + 2**(n - 1); bool why = composite(q, d); if (!why) return q; # printf("*\n"); } } } nickle_2.81.orig/examples/COPYING0000664000175000000620000000245210414112462015747 0ustar keithpstaffCopyright © 1988-2004 Keith Packard and Bart Massey. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the names of the authors or their institutions shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. nickle_2.81.orig/examples/Makefile.am0000664000175000000620000000067512046344771016772 0ustar keithpstaffSUBDIRS=smlng turtle NICKLEFILES=\ comb.5c \ cribbage.5c \ erat.5c \ fourfours.5c \ initializer.5c \ is-prime.5c \ kaiser.5c \ menace2.5c \ miller-rabin.5c \ mutextest.5c \ numbers.5c \ polynomial.5c \ prime.5c \ qbrating.5c \ randtest.5c \ restart.5c \ roman.5c \ rsa-demo.5c \ rsa.5c \ skiplisttest.5c \ sudoku.5c exampledir=$(pkgdatadir)/examples example_DATA=$(NICKLEFILES) COPYING EXTRA_DIST=$(NICKLEFILES) COPYING nickle_2.81.orig/examples/polynomial.5c0000664000175000000620000001202610722455071017336 0ustar keithpstaff/* * Arithmetic on polynomials with (integer) coefficients * * Copyright © 2002 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ namespace Polynomial { /* * Change the typedef to rational for rational * coefficients, then walk carefully through code below. */ typedef int coefficient; /* * Polynomials are stored as an array of * coefficients indexed by degree. There * is always a constant term, and the leading * term of a polynomial is always nonzero (except * for the zero polynomial). */ public typedef coefficient[*] polynomial; /* * Bug: There's currently no Nickle way to normalize the * polynomial by shortening the array. This should be * fixed. In the meantime, we will just make a copy. */ polynomial normalize(polynomial p) { int n = dim(p) - 1; if (p[n] != 0) return p; while (n > 0 && p[n] == 0) --n; coefficient[n + 1] q = { [i] = p[i] }; return q; } /* * Addition is performed using an array comprehension * block. I'm not sure whether this is better or worse * than just doing it with a loop. */ public polynomial add(polynomial a, polynomial b) { coefficient na = dim(a); coefficient nb = dim(b); coefficient nc = max(na, nb); coefficient[nc] c = { [i] { coefficient get_coeff(coefficient[*] a) { if (i < dim(a)) return a[i]; return 0; } coefficient ai = get_coeff(a); coefficient bi = get_coeff(b); return ai + bi; } }; return normalize(c); } /* * Multiplication efficiency might be minutely improved by * avoiding the all-zeros initialization. Or it might * not... */ public polynomial mult(polynomial a, polynomial b) { coefficient na = dim(a); coefficient nb = dim(b); coefficient nc = na + nb - 1; coefficient[nc] c = {0 ...}; for (coefficient i = 0; i < na; i++) for (coefficient j = 0; j < nb; j++) c[i + j] += a[i] * b[j]; return c; } /* * The quotient and remainder for polynomial division are * computed simultaneously, and thus should be returned * together. */ public typedef struct { polynomial quot; polynomial rem; } quot_rem; /* * Return quotient and remainder of a div b. This code * assumes that with integer coefficients, leading * coefficient of b must be 1. */ public quot_rem div_mod(polynomial a, polynomial b) { coefficient na = dim(a); coefficient nb = dim(b); if (b[nb - 1] != 1) abort("leading integer coefficient in divisor should be 1"); coefficient nq = na - nb + 1; if (nq <= 0) return (quot_rem) { .quot = (polynomial){0}, .rem = b }; coefficient[nq] q = {0 ...}; while (na >= nb) { coefficient xn = na - nb; coefficient cx = a[na - 1] / b[nb - 1]; for (int i = 0; i < nb; i++) a[i + xn] -= cx * b[i]; q[xn] += cx; if (a[na - 1] != 0) abort("leading coefficient error"); --na; while (na >= 1 && a[na - 1] == 0) --na; } return (quot_rem) { .quot = q, .rem = normalize(a) }; } /* * Returns b ** e computed using the usual fast algorithm * (O(log e) multiplies). */ public polynomial power(polynomial b, int e) { if (e < 0) abort("negative exponent error"); if (e == 0) return (polynomial) {1}; if (e == 1) return b; polynomial tmp = power(b, e // 2); polynomial tmp2 = mult(tmp, tmp); if (e % 2 == 0) return tmp2; return mult(tmp2, b); } /* * Returns b ** e (mod m) computed using the usual * fast algorithm (O(log e) multiplies, each requiring * O(|m|*|b**2|) primitive steps). */ public polynomial power_mod(polynomial b, int e, polynomial m) { if (e < 0) abort("negative exponent error"); if (e == 0) return (polynomial) {1}; if (e == 1) return div_mod(b, m).rem; polynomial tmp = power_mod(b, e // 2, m); polynomial tmp2 = mult(tmp, tmp); if (e % 2 == 0) return div_mod(tmp2, m).rem; return div_mod(mult(tmp2, b), m).rem; } /* * Returns a string representation of p suitable for Maple * input. x is the name of the polynomial basis variable * (usually just "x"). There's a lot of boundary cases * here. */ public string maple(polynomial p, string x) { string s = ""; bool started = false; for (int i = 0; i < dim(p); i++) { /* Don't print absent terms. */ if (p[i] == 0) continue; /* If a term has already been printed, this one must be added or subtracted */ if (started) { if (p[i] > 0) { s += " + "; } else { s += " - "; p[i] = -p[i]; } } /* Don't print 1*x or 1*x^n. */ string star = "*"; if (p[i] == 1 && i > 0) star = ""; else s += sprintf("%d", p[i]); /* Don't print x^0 or x^1. If there's no leading coefficient due to previous logic, don't print the multiply symbol. */ if (i == 1) s += sprintf("%s%s", star, x); else if (i > 1) s += sprintf("%s%s^%d", star, x, i); /* A term has now been printed */ started = true; } return s; } } nickle_2.81.orig/examples/qbrating.5c0000664000175000000620000000403510535235017016761 0ustar keithpstaff/* * Official NFL QB rating * * Copyright © 1999, 2006 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Info from * http://www.nfl.com/news/981202qbrate.html * http://www.bluedonut.com/qbrating.htm * As per reference 1, you should get * qbrating(461,324,3969,35,10) ~= 112.79 * for Steve Young. Reference 2 refers to the * formula as a "quadratic" equation; it's actually * a linear equation in the averages, hence the * Nickle exact rational implementation. */ /* * The "QB Rating" is only a rating of passing * effectiveness, and it's pretty marginal at that. See the * references above for details. The basic rationale is * that there are four categories considered: completions, * passing yards, passing touchdowns, and interceptions. * For each category, the interesting statistic is the * average over the number of passing attempts. * * The category scores are first scaled such that a score of * 1 is roughly average. The scaling is then tweaked to * attempt to make a score of 0 awful and of 2 exceptional. * A maximum of 2.375 and minimum of 0 seem mostly to be a * guard against anomalies. The sum of the categorie scores * is the QB score. * * The QB score is then scaled such that a score of 1 * (average) in each category gives a scaled score of * 66.{6}%. This is the QB rating. A rating of 100 is * considered quite good. */ rational qbrating (int attempts, int completions, int yards, int touchdowns, int interceptions) { rational cat_max = 2.375; rational cat_score(rational base, rational offset, rational scale) { rational avg = base / attempts; rational score = (avg * 100 + offset) * scale; if (score < 0) return 0; if (score > cat_max) return cat_max; return score; } rational total = cat_score(completions, -30, 0.05); total += cat_score(yards, -300, 0.0025); total += cat_score(touchdowns, 0, 0.2); total += cat_max - cat_score(interceptions, 0, 0.25); return total * 100 / 6; } nickle_2.81.orig/examples/turtle/0002775000175000000620000000000013202543025016233 5ustar keithpstaffnickle_2.81.orig/examples/turtle/COPYING0000664000175000000620000000242310414112462017264 0ustar keithpstaffCopyright © 2001 Bart Massey. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the names of the authors or their institutions shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. nickle_2.81.orig/examples/turtle/Makefile.am0000664000175000000620000000105713062265667020311 0ustar keithpstaff# # Draw "snowflake" fractal # # Copyright © 2001 Bart Massey. # All Rights Reserved. See the file COPYING in this directory # for licensing information. NICKLEFILES=\ snowflake.5c \ turtle.5c exampledir=$(pkgdatadir)/examples/turtle example_DATA=$(NICKLEFILES) snowflake.tex COPYING EXTRA_DIST=$(example_DATA) COPYING TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir):$(top_srcdir)/$(subdir) TESTS=snowflake.5c LOG_COMPILER=$(top_builddir)/nickle CLEANFILES=snowflake.eepic snowflake.aux snowflake.dvi snowflake.log nickle_2.81.orig/examples/turtle/turtle.5c0000664000175000000620000000416010414112462020001 0ustar keithpstaff/* * Turtle Graphics for LaTeX eepic * Bart 2001/05/28 * * Copyright © 2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ namespace Turtle { import File; /* configuration */ file target; int scale; /* current turtle state */ struct { real x, y; } pos; rational theta; /* keep theta in range */ void function normalize_theta() { while (theta < 0) theta += 1; while (theta >= 1) theta -= 1; } /* angles used by trig functions */ real function radians(rational angle) { return 2 * pi * (1 - angle) + pi / 2; } /* for various conversions */ int function round(real arg) { return floor(arg + 0.5); } /* * Create a new turtle drawing. * Sizes are in inches. * Coordinates normalized s.t. given x_size is 1.0 */ public void function start_turtle(string outfile, real x_size, real y_size) { target = open(outfile, "w"); scale = floor(x_size * 1000); int yscale = floor(y_size * 1000); pos.x = 0; pos.y = 0; theta = 0; fprintf(target, "\\setlength{\\unitlength}{0.001in}\n"); fprintf(target, "\\begin{picture}(%d,%d)\n", scale, yscale); } /* finish the drawing */ public void function stop_turtle() { fprintf(target, "\\end{picture}\n"); close(target); } /* move to normalized absolute position */ public void function move_turtle(real x, real y) { pos.x = x * scale; pos.y = y * scale; } /* turn *to* normalized rational angle */ public void function aim_turtle(rational angle) { theta = angle; normalize_theta(); } /* turn *by* angle */ public void function turn_turtle(rational angle) { theta += angle; normalize_theta(); } /* travel turtle while making mark */ public void function stroke_turtle(rational dist) { real dx = scale * dist * cos(radians(theta)); real dy = scale * dist * sin(radians(theta)); fprintf(target, "\\path(%d,%d)(%d,%d)\n", round(pos.x), round(pos.y), round(pos.x + dx), round(pos.y + dy)); pos.x += dx; pos.y += dy; } } nickle_2.81.orig/examples/turtle/snowflake.5c0000664000175000000620000000171411747625042020472 0ustar keithpstaff# von Koch / Snowflake curves # Bart 2001/05/28 # # Copyright © 2001 Bart Massey. # All Rights Reserved. See the file COPYING in this directory # for licensing information. # usage: ./snowflake.5c # where is the curve width in inches # and is the iteration depth autoimport Turtle; void do_flake(int depth, rational scale) { if (depth == 0) { stroke_turtle(scale); return; } do_flake(depth - 1, scale / 3); turn_turtle(-1/6); do_flake(depth - 1, scale / 3); turn_turtle(1/3); do_flake(depth - 1, scale / 3); turn_turtle(-1/6); do_flake(depth - 1, scale / 3); } if (dim(argv) < 3) argv = (string[*]) { "snowflake.5c", "3", "3" }; int width = string_to_integer(argv[1]); real height = sqrt((width / 3) ** 2 - (width / 6) ** 2) + 0.05 * width; start_turtle("snowflake.eepic", width, height); move_turtle(0.0, 0.025); aim_turtle(0.25); do_flake(string_to_integer(argv[2]), 1.0); stop_turtle(); nickle_2.81.orig/examples/turtle/Makefile.in0000664000175000000620000006424713202542702020314 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Draw "snowflake" fractal # # Copyright © 2001 Bart Massey. # All Rights Reserved. See the file COPYING in this directory # for licensing information. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = examples/turtle ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(exampledir)" DATA = $(example_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver \ COPYING DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ NICKLEFILES = \ snowflake.5c \ turtle.5c exampledir = $(pkgdatadir)/examples/turtle example_DATA = $(NICKLEFILES) snowflake.tex COPYING EXTRA_DIST = $(example_DATA) COPYING TESTS_ENVIRONMENT = NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir):$(top_srcdir)/$(subdir) TESTS = snowflake.5c LOG_COMPILER = $(top_builddir)/nickle CLEANFILES = snowflake.eepic snowflake.aux snowflake.dvi snowflake.log all: all-am .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/turtle/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/turtle/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-exampleDATA: $(example_DATA) @$(NORMAL_INSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exampledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(exampledir)" || exit $$?; \ done uninstall-exampleDATA: @$(NORMAL_UNINSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(exampledir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? snowflake.5c.log: snowflake.5c @p='snowflake.5c'; \ b='snowflake.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(exampledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-exampleDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-exampleDATA .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am clean clean-generic \ cscopelist-am ctags-am distclean distclean-generic distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exampleDATA install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am recheck tags-am \ uninstall uninstall-am uninstall-exampleDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/examples/turtle/snowflake.tex0000664000175000000620000000036310414112462020745 0ustar keithpstaff%% Copyright © 2001 Bart Massey. %% All Rights Reserved. See the file COPYING in this directory %% for licensing information. \documentclass{article} \usepackage{epic,eepic} \begin{document} \fbox{ \input{snowflake.eepic} } \end{document} nickle_2.81.orig/examples/sudoku.5c0000775000175000000620000001512712051051157016467 0ustar keithpstaff#!/usr/bin/env nickle # Sudoku generator/solver # Copyright © 2005 Bart Massey # This code is distributed under the MIT license. Please # see the file COPYING in this distribution for license # details. autoimport PRNG; import File; autoimport ParseArgs; int unit, side; typedef int[*] grid; void print_grid(file f, grid g) { for (int i = 0; i < dim(g); i++) { if (g[i] == 0) fprintf(f, "."); else fprintf(f, "%d", g[i]); if (i % side == side - 1) fprintf(f, "\n"); } } # return true iff cells p1 and p2 # may not have the same value bool edge(int p1, int p2) { if (p1 == p2) return false; if (p1 // side == p2 // side) return true; if (p1 % side == p2 % side) return true; # XXX if it is in the same horizontal "stripe" # and the same vertical "stripe", it is in the # same "cell" if (p1 // (side * unit) == p2 // (side * unit) && (p1 % side) // unit == (p2 % side) // unit) return true; return false; } bool[*, *] edges; void init_edges() { edges = (bool[side**2, side**2]){[i, j] = edge(i, j)}; } # check whether the value in g at p is consistent with every # other value in g bool check(&grid g, int p) { for (int p2 = 0; p2 < dim(g); p2++) if (g[p2] == g[p] && edges[p, p2]) return false; return true; } # simple-minded DFS solver doesnt scale. assumes it is # passed a grid whose filled cells conform to constraints. # returns a solution count which is a lower bound on the # true number of solutions, accurate if 0 or 1. the # preserve parameter says whether to preserve (true) or # clear (false) cells of the solution: if preserve is true, # the first solution found is returned. the randomize # parameter says to try the values in random order; this is # useful for puzzle construction. int solve(&grid g, bool preserve, bool randomize) { int p = 0; for (p < dim(g); p++) if (g[p] == 0) break; if (p >= dim(g)) return 1; int[*] vals; if (randomize) { vals = (int[side]){ [i] = i + 1 }; shuffle(&vals); } int answer = 0; int i = 0; for (i < side; i++) { if (randomize) g[p] = vals[i]; else g[p] = i + 1; if (!check(&g, p)) continue; int result = solve(&g, preserve, randomize); if (preserve && result > 0) return result; answer += result; if (answer > 1) break; } g[p] = 0; return answer; } # deletion-based puzzle creation algorithm # suggested by ksudoku. # g is assumed to be a partial solution void del_soln(&grid g) { int[dim(g)] delns = { [i] = i }; shuffle(&delns); for (int i = 0; i < dim(delns); i++) { print_grid(stdout, g); printf("\n"); &int d = &g[delns[i]]; int save = d; d = 0; int s = solve(&g, false, false); if (s >= 2) d = save; assert (s != 0, "clearing cell removed solutions!"); } } # start by creating a random solution. a slight variant # of the solver can do this. grid create_soln() { grid g = (int[side**2]){0, ...}; int nsolns = solve(&g, true, true); assert(nsolns > 0, "cannot create puzzle"); return g; } void make_std_puzzle(file prob, file soln) { grid g = create_soln(); del_soln(&g); print_grid(prob, g); int nsolns = solve(&g, false, false); assert(nsolns == 1, "found %d solns", nsolns); solve(&g, true, false); print_grid(soln, g); } void make_quadrant_puzzle(file prob, file soln) { grid g = create_soln(); int xoff = randint(unit); int yoff = randint(unit); for (int x = 0; x < unit; x++) for (int y = 0; y < unit; y++) g[x + unit * xoff + (y + unit * yoff) * side] = 0; print_grid(prob, g); int nsolns = solve(&g, false, false); assert(nsolns == 1, "found %d solutions", nsolns); solve(&g, true, false); print_grid(soln, g); } grid read_prob(file prob) { int[...] g = {}; int i = 0; side = 0; while (side == 0 || i < side**2) { int ch = getc(prob); if (ch == '\n') { if (side == 0) { side = i; unit = sqrt(side); } continue; } if (ch == '.') { g[i++] = 0; continue; } if (ch >= 'a' && ch <= 'z') { g[i++] = 10 + ch - 'a'; continue; } g[i++] = ch - '0'; } print_grid(stdout, g); return g; } if (dim(argv) > 0) { argdesc argd = { args = { { var = (arg_var.arg_flag) &(bool quadrant = false), name = "quadrant", abbr = 'q', desc = "Construct puzzle with missing quadrant" }, { var = (arg_var.arg_flag) &(bool count_solns = false), name = "count", abbr = 'c', desc = "Count number of solutions to puzzle" }, { var = (arg_var.arg_int) &unit, name = "unit", abbr = 'u', expr_name = "size", desc = "Unit cell size" } }, posn_args = { { var = (arg_var.arg_string) &(string basename), name = "basename" } } }; parseargs(&argd, &argv); dev_srandom(16); if (count_solns) { twixt(file prob = open(basename + "-prob.txt", "r"); close(prob)) { grid g = read_prob(prob); init_edges(); printf("%d\n", solve(&g, false, false)); } exit(0); } side = unit ** 2; init_edges(); twixt((file prob = open(basename + "-prob.txt", "w")), (file soln = open(basename + "-soln.txt", "w")); close(prob), close(soln)) { if (quadrant) make_quadrant_puzzle(prob, soln); else make_std_puzzle(prob, soln); } exit(0); } # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated # documentation files (the "Software"), to deal in the # Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, # sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall # be included in all copies or substantial portions of the # Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. nickle_2.81.orig/examples/fourfours.5c0000664000175000000620000000532410770517743017220 0ustar keithpstaff# # Using four '4's, find # equations using unary and binary operators # which compute ever integer from 1 to 100 # typedef struct { string s; /* string equation */ rational v; /* equation value */ int p; /* higher are preferred forms */ } v_t; /* generator for primitive operands */ poly() argloop() { int i = 0; static poly[] a = { (v_t) { .s = "4", .v = 4, .p = 25 }, (v_t) { .s = ".4", .v = .4, .p = 5 }, (v_t) { .s = ".{4}", .v =.{4}, .p = 1 }, (v_t) { .s = "4!", .v = 4!, .p = 25 }, (v_t) { .s = "√4", .v = sqrt(4), .p = 25 }, (v_t) { .s = "√.{4}", .v = sqrt(.{4}), .p = 1 }, â—Š }; return poly func() = a[i++ % dim(a)]; } /* generator for binary operators */ poly () binloop(poly() l, poly() r) { int i = 0; poly la = â—Š, ra = â—Š; static (poly(poly, poly))[] a = { poly func(x,y) = (v_t) { .s = "(" + x.s + " + " + y.s + ")", .v = x.v + y.v, .p = x.p + y.p }, poly func(x,y) = (v_t) { .s = "(" + x.s + " - " + y.s + ")", .v = x.v - y.v, .p = x.p + y.p }, poly func(x,y) = (v_t) { .s = "(" + x.s + " * " + y.s + ")", .v = x.v * y.v, .p = x.p + y.p }, poly func(x,y) = (v_t) { .s = "(" + x.s + " / " + y.s + ")", .v = x.v / y.v, .p = x.p + y.p }, poly func(x,y) { if (y.v > 4) raise invalid_argument ("rhs of ** too large", 1, y.v); return (v_t) { .s = "(" + x.s + " ^ " + y.s + ")", .v =x.v ** y.v, .p = x.p + y.p }; } }; return poly func() { for (;;) try { if (i % dim(a) == 0) { ra = r (); if (ra == â—Š || la == â—Š) { la = l (); if (la == â—Š) return â—Š; if (ra == â—Š) ra = r (); } } return a[i++ % dim(a)](la, ra); } catch divide_by_zero (real x, real y) { continue; } catch invalid_argument (string a, int i, poly p) { continue; } catch invalid_binop_values (string a, poly l, poly r) { continue; } }; } /* generator for associating operations */ poly() parenloop(poly() x, poly() y, poly() z) { int i = 0; (poly())[] a = { binloop (x, binloop(y,z)), binloop (binloop(x,y), z) }; return poly func() { for (;;) { poly v = a[i](); if (v != â—Š) return v; if (++i == dim(a)) {i = 0; return â—Š; } } }; } /* find equations which compute all values */ void main () { int limit = 100; v_t[limit + 1] values = { { .s = "no solution", .v = 0, .p = 0 } ... }; poly() f = parenloop (binloop(argloop(), argloop()), argloop(), argloop()); while (((poly value) = f()) != â—Š) { if (is_int(value.v) && 1 <= value.v && value.v <= limit) { if (values[value.v].p < value.p) values[value.v] = value; } } for (int i = 1; i <= limit; i++) printf ("%3d (score %3d) = %s\n", i, values[i].p, values[i].s); } main(); nickle_2.81.orig/examples/erat.5c0000664000175000000620000000054610414112462016102 0ustar keithpstaff/* * Copyright © 2002 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ bool[*] make_sieve(int size) { bool[size] sieve = {true ...}; for (int k = 2; k < size; k++) { if (!sieve[k]) continue; for (int i = 2 * k; i < size; i += k) sieve[i] = false; } return sieve; } nickle_2.81.orig/examples/smlng/0002775000175000000620000000000013202543025016034 5ustar keithpstaffnickle_2.81.orig/examples/smlng/COPYING0000664000175000000620000000244410414112462017070 0ustar keithpstaffCopyright © 2001 Keith Packard and Carl Worth. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the names of the authors or their institutions shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the authors. nickle_2.81.orig/examples/smlng/Makefile.am0000664000175000000620000000104113062265602020070 0ustar keithpstaff# # SGML-like parser # # Copyright © 2001 Keith Packard and Carl Worth # All Rights Reserved. See the file COPYING in this directory # for licensing information. # NICKLEFILES=\ context.5c \ generate.5c \ parse.5c \ test.5c exampledir=$(pkgdatadir)/examples/smlng example_DATA=$(NICKLEFILES) COPYING TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir):$(top_srcdir)/$(subdir) LOG_COMPILER=$(top_builddir)/nickle < $(top_srcdir)/$(subdir)/data.sgml TESTS=test.5c EXTRA_DIST=$(NICKLEFILES) data.sgml COPYING nickle_2.81.orig/examples/smlng/context.5c0000664000175000000620000000364610722454243017767 0ustar keithpstaff/* * Copyright © 2001 Keith Packard and Carl Worth * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ int style_b = 1; int style_em = 2; int style_i = 4; int style_s = 8; int style_tt = 16; int[*] colornames = {'r', 'g', 'b', 'c', 'm', 'y', 'k', 'w'}; typedef struct { int styles; int underline; /* "root underline" is 0 */ int color; /* "root color" is -1 */ int size; /* "root size" is -1 */ } context; *context no_context = reference ((context) {}); context root_context = (context) { .styles=0, .underline=0, .color=-1, .size=-1 }; public exception UnknownColor (int name); int function color_index_for_name(int n) { int i; for (i=0; istyles |= style_b; break; case "EM": if ((c->styles & style_s) == 0) { c->styles ^= style_em; } break; case "I": c->styles |= style_i; break; case "PL": c->styles &= ~(style_s | style_em | style_i | style_b | style_tt); c->underline = 0; break; case "S": c->styles |= style_s; c->styles &= ~style_em; break; case "TT": c->styles |= style_tt; break; case "U": if (c->underline < 3) { c->underline++; } break; default: if (value[0] >= '0' && value[0] <= '9') { c->size = string_to_integer(value); } else { c->color = color_index_for_name(value[0]); } } } function context_dump (context c) { printf("%s %s %s %s %s %d %s %s ", (c.styles & style_b) != 0 ? "B" : "-", (c.styles & style_em) != 0 ? "EM" : "--", (c.styles & style_i) != 0 ? "I" : "-", (c.styles & style_s) != 0 ? "S" : "-", (c.styles & style_tt) != 0 ? "TT" : "--", c.underline, (c.color >= 0) ? String::new (colornames[c.color]) : "-", (c.size >= 0) ? String::new (c.size) : "-"); } nickle_2.81.orig/examples/smlng/generate.5c0000664000175000000620000000343310414112462020057 0ustar keithpstaff/* * Copyright © 2001 Keith Packard and Carl Worth * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ autoload PRNG; int function iswhite (int c) { switch (c) { case ' ': case '\t': case '\n': case '\r': return 1; default: return 0; } } string function word (file in) { string w = ""; int c; while ((c = File::getc (in)) != -1) { w += String::new (c); if (!iswhite (c)) break; } if (c == -1) return w; while ((c = File::getc (in)) != -1) { w += String::new (c); if (iswhite (c)) break; } return w; } string[*] tags = { "B", "EM", "I", "PL", "S", "TT", "U", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "r", "g", "b", "c", "m", "y", "k", "w" }; typedef tagstack; typedef struct { *tagstack prev; string tag; } tagstack; void function tagfile (file in) { string w; int d, t; *tagstack stack = 0; int function dotag () { if (PRNG::randint (100) > 50) { int end = PRNG::randint(2); if (stack != 0 && end) return -1; return 1; } return 0; } int function picktag () { return PRNG::randint (dim (tags)); } void function start_tag () { stack = reference ((tagstack) { prev = stack, tag = tags[picktag()] }); printf ("<%s>", stack->tag); } void function end_tag () { if (stack) { printf ("", stack->tag); stack = stack->prev; } } for (;;) { d = dotag (); switch (d) { case 1: start_tag (); break; case 0: break; case -1: end_tag (); break; } string s = word (in); if (s == "") break; printf ("%s", s); } while (stack) end_tag (); } tagfile (stdin); nickle_2.81.orig/examples/smlng/data.sgml0000664000175000000620000000005410414112462017625 0ustar keithpstaffhello blue green world nickle_2.81.orig/examples/smlng/Makefile.in0000664000175000000620000006412113202542702020104 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = examples/smlng ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(exampledir)" DATA = $(example_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver \ COPYING DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # SGML-like parser # # Copyright © 2001 Keith Packard and Carl Worth # All Rights Reserved. See the file COPYING in this directory # for licensing information. # NICKLEFILES = \ context.5c \ generate.5c \ parse.5c \ test.5c exampledir = $(pkgdatadir)/examples/smlng example_DATA = $(NICKLEFILES) COPYING TESTS_ENVIRONMENT = NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir):$(top_srcdir)/$(subdir) LOG_COMPILER = $(top_builddir)/nickle < $(top_srcdir)/$(subdir)/data.sgml TESTS = test.5c EXTRA_DIST = $(NICKLEFILES) data.sgml COPYING all: all-am .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/smlng/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/smlng/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-exampleDATA: $(example_DATA) @$(NORMAL_INSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exampledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(exampledir)" || exit $$?; \ done uninstall-exampleDATA: @$(NORMAL_UNINSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(exampledir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test.5c.log: test.5c @p='test.5c'; \ b='test.5c'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(exampledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-exampleDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-exampleDATA .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am clean clean-generic \ cscopelist-am ctags-am distclean distclean-generic distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exampleDATA install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am recheck tags-am \ uninstall uninstall-am uninstall-exampleDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/examples/smlng/test.5c0000664000175000000620000000034310414112462017241 0ustar keithpstaff/* * Copyright © 2001 Keith Packard and Carl Worth * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ library "parse.5c" *Parse::element e = Parse::get(stdin); Parse::dump(e); nickle_2.81.orig/examples/smlng/parse.5c0000664000175000000620000001232310770315535017410 0ustar keithpstaff/* * Parse simple sgml-style grammar * * Copyright © 2001 Keith Packard and Carl Worth * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ library "context.5c" public namespace Lexc { public global int Eof = 0; public global int Printable = 1; public global int White = 2; public global int Left = 3; public global int Right = 4; public global int Slash = 5; public typedef struct { int id; int c; } char; public exception InvalidChar (int c); public char function get (file in) { char ch; if (File::end (in)) return (char) { c = 0, id = Eof }; ch.c = File::getc (in); printf ("got %d\n", ch.c); if (ch.c == '<') ch.id = Left; else if (ch.c == '>') ch.id = Right; else if (ch.c == '/') ch.id = Slash; else if (' ' < ch.c) ch.id = Printable; else switch (ch.c) { case ' ': case '\t': case '\n': case '\r': ch.id = White; break; case -1: ch.id = Eof; break; default: raise InvalidChar (ch.c); } return ch; } public void function unget (int c, file in) { File::ungetc (c, in); } } public namespace Lex { public global int Eof = 0; public global int Text = 1; public global int Space = 2; public global int Start = 3; public global int End = 4; public typedef struct { int id; string value; } token; public exception Syntax (int c); global int StateStart = 0; global int StateSeenLeft = 1; global int StateStartTag = 2; global int StateEndTag = 3; global int StateString = 4; global int StateSpace = 5; public token function get (file in) { Lexc::char c; token t; int state = StateStart; for (;;) { c = Lexc::get (in); switch (state) { case StateStart: switch (c.id) { case Lexc::Eof: return (token) { .id = Eof, .value = "" }; case Lexc::Printable: case Lexc::Slash: state = StateString; t = (token) { .id = Text, .value = String::new (c.c) }; continue; case Lexc::White: state = StateSpace; t = (token) { .id = Space, .value = String::new (c.c) }; continue; case Lexc::Left: state = StateSeenLeft; continue; } break; case StateSeenLeft: switch (c.id) { case Lexc::Printable: state = StateStartTag; t = (token) { .id = Start, .value = String::new (c.c) }; continue; case Lexc::Slash: state = StateEndTag; t = (token) { .id = End, .value = "" }; continue; } break; case StateStartTag: case StateEndTag: switch (c.id) { case Lexc::Printable: t.value += String::new (c.c); continue; case Lexc::Right: return t; } break; case StateString: switch (c.id) { case Lexc::Printable: t.value += String::new (c.c); continue; case Lexc::White: case Lexc::Left: Lexc::unget (c.c, in); case Lexc::Eof: return t; } break; case StateSpace: switch (c.id) { case Lexc::White: t.value += String::new (c.c); continue; case Lexc::Printable: case Lexc::Left: Lexc::unget (c.c, in); case Lexc::Eof: return t; } break; } raise Syntax (c.c); } } } public namespace Parse { public exception Syntax (string token); public typedef element; public typedef struct { *element next; string data; *context ctxt; } element; public *element element_end = reference ((element){}); public typedef c_list; public typedef struct { string active_tag; *context ctxt; *c_list prev; } c_list; public *c_list c_list_end = reference ((c_list) {}); function clist_show(*c_list c) { printf ("clist show...\n"); while (c != c_list_end && c->ctxt != no_context) { context_dump(*c->ctxt); printf("\n"); c = c->prev; } } public *element function get (file in) { *element first = element_end; * *element p = &first; *c_list c = reference ( (c_list) { .ctxt=&root_context, .prev=c_list_end}); for (;;) { Lex::token t = Lex::get (in); printf ("lexed: %v\n", t); switch (t.id) { case Lex::Eof: if (c->ctxt != &root_context) raise Syntax ("At Eof but not back to root context"); return first; case Lex::Text: *p = reference ((element) { .next = element_end, .data = t.value, .ctxt = c->ctxt }); p = &(*p)->next; break; case Lex::Space: *p = reference ((element) { .next = element_end, .data = t.value, .ctxt = c->ctxt }); p = &(*p)->next; break; case Lex::Start: c = reference ((c_list) { .ctxt = reference (*c->ctxt), .prev = c, .active_tag = t.value }); context_set (c->ctxt, t.value); break; case Lex::End: if (c->ctxt == &root_context) raise Syntax ("Closing tag encountered with no remaining open tags"); if (t.value != c->active_tag) raise Syntax ("Illegal closing tag (expected active_tag+">)"); c = c->prev; break; } } } public void function dump (*element e) { if (e != element_end) { context_dump (*e->ctxt); printf ("%v\n", e->data); dump (e->next); } } } nickle_2.81.orig/examples/randtest.5c0000664000175000000620000000060510770315535017002 0ustar keithpstaff/* * Check the PRNG for a balanced low bit * * Copyright © 2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart 2001/3 */ autoimport PRNG; int[*] t(int n) { int[2] s = {0, 0}; int i; for (i = 0; i < n; i++) s[randint(2)]++; return s; } File::printf ("%d %d\n", t (string_to_integer (argv[1]))...); nickle_2.81.orig/examples/rsa.5c0000664000175000000620000000262210770315535015744 0ustar keithpstaff/* * RSA cryptosystem * * Copyright © 2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart Massey 1999/1 * * Must first load numbers.5c * * [note that encryption and decryption commute] * * set_private_key(p,q,e) * call with p and q prime, e small random, less than (p-1) * (q-1), * relatively prime to this quantity. The primes can be * conveniently generated using the supplied Miller-Rabin code: * see the function primebits(). * * set_public_key(n,e) * set just the public key information for encryption * * encrypt(m) * return the encryption of m * * decrypt(c) * return the decryption of c */ autoimport Numbers namespace RSA { global int e; /* encryption exponent */ global int n; /* public key */ global int d = 0; /* decryption exponent (0 for encrypt-only) */ public int encrypt(int m) { return bigpowmod(m, e, n); } public int decrypt(int c) { exception decrypt_public_key(); if (d == 0) raise decrypt_public_key(); return bigpowmod(c, d, n); } public void set_private_key(int p, int q, int e0) { int phi = (p - 1) * (q - 1); n = p * q; if (e0 % 2 == 0) e0++; while (gcd(e0, phi) > 1) e0 += 2; e = e0; d = zminv(e, phi); } public void set_public_key(int n0, int e0) { n = n0; e = e0; d = 0; } } nickle_2.81.orig/examples/mutextest.5c0000664000175000000620000000345610722455363017230 0ustar keithpstaff/* * Let a potentially large number of threads wait * for a mutex. * * Copyright © 2001 Keith Packard * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ autoimport Mutex; bool die; typedef struct { mutex mut_ex; string name; } named_mutex; int[*] owned; named_mutex[*] mutexes; mutex owned_mutex = Mutex::new(); semaphore started = Semaphore::new (0); void status () { int nt = dim (owned); int i; twixt (acquire (owned_mutex); release (owned_mutex)) { for (i = 0; i < nt; i++) { if (owned[i] >= 0) printf ("%s", mutexes[owned[i]].name); else printf (" "); } printf ("\n"); } } void t (*(named_mutex[*]) mutexes, int self, int delay) { int i; Semaphore::signal (started); die = false; while (!die) { for (i = 0; !die && i < dim (*mutexes); i++) { twixt (acquire ((*mutexes)[i].mut_ex); release ((*mutexes)[i].mut_ex)) { twixt (acquire (owned_mutex); release (owned_mutex)) owned[self] = i; /* status(); */ sleep (delay); twixt (acquire (owned_mutex); release (owned_mutex)) owned[self] = -1; } /* printf ("Thread %v done with %v\n", Thread::current (), (*mutexes)[i].mut_ex);*/ } } } void start (int nthread, int nmut_ex, int delay) { int i; owned = (int [nthread]) {}; for (i = 0; i < nthread; i++) owned[i] = -1; mutexes = (named_mutex [nmut_ex]) {}; for (i = 0; i < nmut_ex; i++) { mutexes[i] = (named_mutex) { .mut_ex = new (), .name = String::new('A' + i) }; } for (i = 0; i < nthread; i++) { fork (t (&mutexes, i, delay)); Semaphore::wait (started); } } void monitor (int delay) { for (;;) { status (); sleep (delay); } } start (20, 10, 100); monitor (200); nickle_2.81.orig/examples/skiplisttest.5c0000664000175000000620000000446310722456340017723 0ustar keithpstaff/* $Header$ */ /* * Test skiplist implementation * * Copyright © 2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ autoload Skiplist; autoload PRNG; int gt_count = 0; bool int_gt (int a, int b) { ++gt_count; return a > b; } public int[*] rand_array (int n) { int[n] a = { [i] = i }; PRNG::shuffle (&a); return a; } public void validate (Sortlist::List l) { bool first = true; poly prev; void visit (poly x) { if (!first) assert (int_gt (x, prev), "list out of order"); assert (x == Sortlist::search (l, x), "list missing element"); } Sortlist::walk (l, visit); } public void insert_int (Sortlist::List l, int i) { Sortlist::insert (l, i); } public void insert_ints (Sortlist::List l, int[*] i) { for (int j = 0; j < dim(i); j++) insert_int (l, i[j]); } public Sortlist::List rand_ints (int n) { Sortlist::List l = Sortlist::new (int_gt); insert_ints (l, rand_array(n)); return l; } public int search_len (Sortlist::List l, int i) { int old_count = gt_count; Sortlist::search (l, i); return gt_count - old_count; } public void dump (Sortlist::List l) { for (bool (&poly) next = Sortlist::iterate (l); next (&(int value));) { printf ("%4d", value); for (int i = Sortlist::storage (l, value); i > 0; i--) printf (" |"); printf ("\n"); } } public void histogram (real[*] l) { int largest = 0; for (int i = 0; i < dim (l); i++) if (l[i] > largest) largest = l[i]; int width = 80 - 17; real scale = width / largest; for (int i = 0; i < dim (l); i++) { printf ("%5d %10g ", i, l[i]); int lim = floor (l[i] * scale + 0.5); for (int j = 0; j < lim; j++) printf ("*"); printf ("\n"); } } public void analyse (Sortlist::List l) { int[...] store = {}; int[...] search = {}; void inc_array(&int[...] a, int i) { while (dim(a) <= i) a[dim(a)] = 0; a[i]++; } for (bool (&poly) next = Sortlist::iterate (l); next (&(int value));) { inc_array (&store, Sortlist::storage (l, value)); inc_array (&search, search_len (l, value)); } printf ("storage distribution\n"); histogram (store); printf ("search distribution\n"); histogram (search); } nickle_2.81.orig/examples/kaiser.5c0000664000175000000620000000402310770315535016432 0ustar keithpstaff/* * Kaiser Window digital filter * * Copyright © 2001, Keith Packard * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ real i0(real x) { real ds, d, s; ds = 1; d = 0; s = 0; do { d = d + 2; ds = ds * x**2 / d**2; s = s + ds; # printf ("ds %g s %g dist %g\n", ds, s, # ds - 0.2e-8 * s); } while (ds - 0.2e-8 * s > 0); return s; } real highpass (real n, real m, real wc) { real alpha = m/2; real dist; dist = n - alpha; if (dist == 0) return (pi/2 - wc) / pi; return -sin(dist * (pi/2-wc)) / (pi * dist); } real lowpass (real n, real m, real wc) { real alpha = m/2; real dist; dist = n - alpha; if (dist == 0) return wc / pi; return sin (wc * dist) / (pi * dist); } real kaiser (real n, real m, real beta) { real alpha = m / 2; return i0 (beta * sqrt (1 - ((n - alpha) / alpha)**2)) / i0(beta); } void write_high (string filename, real m, real wc, real beta, real step) { real n; file f; f = File::open (filename, "w"); for (n = 0; n <= m; n += step) File::fprintf (f, "%g,\n", highpass (n, m, wc) * kaiser (n, m, beta)); File::close (f); } void write_low (string filename, real m, real wc, real beta, real step) { real n; file f; f = File::open (filename, "w"); for (n = 0; n <= m; n += step) File::fprintf (f, "%g,\n", lowpass (n, m, wc) * kaiser (n, m, beta)); File::close (f); } real Beta (real A) { if (A > 50) return 0.1102 * (A - 8.7); else if (A >= 21) return 0.5842 * (A - 21) ** 0.4 + 0.07886 * (A - 21); else return 0.0; } int M (real A, real deltaw) { return ceil ((A - 8) / (2.285 * deltaw)); } real filter (real wpass, real wstop, real error, *int mp) { real deltaw = wstop - wpass; real A = -20 * log10 (error); real beta; beta = Beta (A); *mp = M (A, deltaw); printf ("Beta %g M %g\n", beta, *mp); return beta; } nickle_2.81.orig/examples/numbers.5c0000664000175000000620000000216110770315535016630 0ustar keithpstaff/* * Some number-theoretic algorithms * * Copyright © 1999 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart Massey 1999/1 * * bigpowmod(b,e,m): returns (b**e) mod m * [gcd(a,b): accelerated greatest-common-divisor (built-in)] * extgcd(a,b): extended GCD returns struct coeff * zminv(a,n): inverse of a in Z*n */ namespace Numbers { public int bigpowmod(int b, int e, int m) { if (e == 0) return 1; if (e == 1) return b % m; int tmp = bigpowmod(b, e // 2, m); int tmp2 = (tmp * tmp) % m; if (e % 2 == 0) return tmp2; return (tmp2 * b) % m; } public typedef struct { int d, x, y; } coeff; /* Extended Euclid's Algorithm */ public coeff extgcd(int a, int b) { if (b == 0) return (coeff) { .d = a, .x = 1, .y = 0}; coeff t = extgcd(b, a % b); int x = t.x; t.x = t.y; t.y = x - (a // b) * t.y; return t; } /* multiplicative inverse of a mod n */ public int zminv(int a, int n) { coeff e = extgcd(a, n); if (e.x < 0) return n + e.x; return e.x; } } nickle_2.81.orig/examples/menace2.5c0000775000175000000620000001271010722455265016475 0ustar keithpstaff/* * MENACE was a 1960 construction by Michie which * learned to play Tic-Tac-Toe. Remarkably, it did this * using only a large number of matchboxes and * colored glass beads: no computer was involved. * http://www.atarimagazines.com/v3n1/matchboxttt.html * * MENACE2 is a simulation of this system in Nickle. * http://www.cs.pdx.edu/~bart/cs541-fall2001/homework/3-learn.html * * * Copyright © 2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart Massey 2001/11/21 */ autoload PRNG; /* initial weight */ const int initial_weight = 32; /* move weights for legal moves */ typedef int[3,3] weights; /* pieces/players */ typedef enum { x, o, none } piece; /* board positions */ typedef piece[3,3] position; /* all rotations and reflections of a board position */ typedef position[8] poslist; /* transposition table (memory) entry */ typedef ttent; typedef union { *ttent ref; void end; } ttentref; typedef struct { piece on_move; poslist posns; int nmoves; int tweight; weights val; ttentref next; } ttent; /* the transposition table (memory) */ ttentref ttable = ttentref.end; /* whose turn it is: piece.none == board full */ piece side_on_move(*position b) { int n = 0; for(int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (b*[i,j] != piece.none) n++; if (n == 9) return piece.none; if (n % 2 == 1) return piece.o; return piece.x; } /* number of explored states */ int nttstates = 0; /* lookup or create the current pos in the ttable */ ttentref ttable_lookup(position pos) { /* return all rotations/reflections of pos */ poslist all_posns(position pos) { /* a transformation: elems are in 3 * y + x form */ typedef int[9] xform; xform rot = {2,5,8,1,4,7,0,3,6}; xform refl = {0,3,6,1,4,7,2,5,8}; /* return the x-transformed version of p */ position do_xform(xform x, position p) { position np; for (int i = 0; i < 9; i++) np[x[i] % 3, x[i] // 3] = p[i % 3, i // 3]; return np; } poslist result; int j = 0; for (int i = 0; i < 4; i++) { result[j++] = pos; position reflpos = do_xform(refl, pos); result[j++] = reflpos; pos = do_xform(rot, pos); } return result; } /* first, try to look up an old entry */ for (ttentref t = ttable; t != ttentref.end; t = t.ref->next) for (int i = 0; i < 8; i++) if (t.ref->posns[i] == pos) return t; /* nope: create a new entry */ nttstates++; ttent t = { .on_move = side_on_move(&pos), .posns = all_posns(pos), .next = ttable }; /* count legal moves */ int nmoves = 0; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (pos[i, j] == piece.none) nmoves++; t.nmoves = nmoves; /* set up initial weights */ t.tweight = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (pos[i, j] == piece.none) { t.val[i, j] = initial_weight; t.tweight += initial_weight; } else { t.val[i, j] = 0; } } } /* insert the new entry into the table */ ttable = (ttentref.ref) (&t); return ttable; } /* actually run a game from the given position and adjust the weights */ piece menace2(position b) { /* check for a win */ piece win(*position b) { /* check for a row, given delta and base in x and y */ piece row(*position b, int dx, int dy, int bx, int by) { if (b*[dx + bx,dy + by] == b*[bx,by] && b*[dx + dx + bx,dy + dy + by] == b*[bx,by]) return b*[bx,by]; return piece.none; } /* check rows and columns */ for (int i = 0; i < 3; i++) { piece w = row(b, 0, 1, i, 0); if (w != piece.none) return w; piece w = row(b, 1, 0, 0, i); if (w != piece.none) return w; } /* check diagonals */ piece w = row(b, 1, 1, 0, 0); if (w != piece.none) return w; return row(b, 1, -1, 0, 2); } piece w = win(&b); if (w != piece.none) return w; piece us = side_on_move(&b); if (us == piece.none) return us; *ttent t = ttable_lookup(b).ref; b = t->posns[0]; int r = PRNG::randint(t->tweight) + 1; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (b[i, j] == piece.none) { r -= t->val[i, j]; if (r <= 0) { b[i, j] = us; piece w = menace2(b); b[i, j] = piece.none; if (t->nmoves <= 1) return w; rational delta; switch (w) { case us: t->val[i,j] += 3; t->tweight += 3; return w; case piece.none: return w; } if (t->val[i,j] <= 1) return w; --t->val[i,j]; --t->tweight; return w; } } } } abort("menace2: weird t->val"); } void go(int n) { position b; for (int i = 0; i < 9; i++) { int j; scanf("%d", &j); switch (j) { case -1: b[i % 3, i // 3] = piece.o; break; case 1: b[i % 3, i // 3] = piece.x; break; case 0: b[i % 3, i // 3] = piece.none; break; default: abort("bad piece on input"); } } for(int i = 0; i < n; i++) piece w = menace2(b); *ttent t = ttable_lookup(b).ref; for(int j = 0; j < 3; j++) { for(int i = 0; i < 3; i++) { string label(piece p) { union switch (p) { case x: return "X"; case o: return "O"; case none: abort("label: blank label"); return ""; } } if (b[i,j] == piece.none) printf("%8d", t->val[i,j]); else printf("%8s", label(b[i,j])); } printf("\n"); } printf("%d states explored\n", nttstates); } int n = string_to_integer(argv[1]); go(n); nickle_2.81.orig/examples/rsa-demo.5c0000664000175000000620000000144710414112462016657 0ustar keithpstaff/* * Demo of RSA implementation * * Copyright © 2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart 2001/03 */ autoload Numbers; autoimport RSA; autoimport MillerRabin; autoload PRNG; nbits = 512; /* number of bits in each prime of key: >= 65 */ prec = 64; /* lg probability that some prime is not */ int p = primebits(nbits, prec); printf("p = %d\n", p); int q = primebits(nbits, prec); printf("q = %d\n", q); int e = primebits(12, prec); printf("e = %d\n", e); int m = PRNG::randbits(128); printf("m = %d\n", m); set_public_key(p * q, e); int c = encrypt(m); printf("c = %d\n", c); set_private_key(p, q, e); int m1 = decrypt(c); if (m1 == m) printf("decryption successful\n"); else printf("decryption failed\n"); nickle_2.81.orig/examples/Makefile.in0000664000175000000620000004767013202542702016776 0ustar keithpstaff# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(exampledir)" DATA = $(example_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in COPYING DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCBOOK2PDF = @DOCBOOK2PDF@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NICKLE_LDFLAGS = @NICKLE_LDFLAGS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE_DATE = @RELEASE_DATE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ nicklelibdir = @nicklelibdir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = smlng turtle NICKLEFILES = \ comb.5c \ cribbage.5c \ erat.5c \ fourfours.5c \ initializer.5c \ is-prime.5c \ kaiser.5c \ menace2.5c \ miller-rabin.5c \ mutextest.5c \ numbers.5c \ polynomial.5c \ prime.5c \ qbrating.5c \ randtest.5c \ restart.5c \ roman.5c \ rsa-demo.5c \ rsa.5c \ skiplisttest.5c \ sudoku.5c exampledir = $(pkgdatadir)/examples example_DATA = $(NICKLEFILES) COPYING EXTRA_DIST = $(NICKLEFILES) COPYING all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-exampleDATA: $(example_DATA) @$(NORMAL_INSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exampledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(exampledir)" || exit $$?; \ done uninstall-exampleDATA: @$(NORMAL_UNINSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(exampledir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(exampledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-exampleDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-exampleDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exampleDATA \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-exampleDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: nickle_2.81.orig/examples/prime.5c0000664000175000000620000000472310770315535016277 0ustar keithpstaff/* * factor(): Return an array of factors of a number * * Copyright © 2001 Keith Packard. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Very inefficient, but demonstrates the use of disjoint unions * and dynamic arrays. */ namespace Factor { public bool is_prime (int i) { if (i == 1) return false; if (i == 2) return true; if ((i & 1) == 0) return false; int limit = floor (sqrt (i)) + 1; int f; for (f = 3; f <= limit; f++) { if ((i % f) == 0) return false; } return true; } typedef int_list_struct; typedef union { *int_list_struct ref; void end; } int_list; typedef struct { int_list next; int v; } int_list_struct; public int_list primes (int i) { bool prime_wrt (int_list l, int i) { if (l == int_list.end) return true; if (i % l.ref->v == 0) return false; return prime_wrt (l.ref->next, i); } if (i < 3) return (int_list.ref) reference ((int_list_struct) { .next = int_list.end, .v = 2 }); int_list l = primes (i-1); if (prime_wrt (l, i)) return (int_list.ref) reference ((int_list_struct) { .next = l, .v = i }); return l; } int[*] list_to_array (int_list l) { int list_length (int_list l) { return l != int_list.end ? 1+list_length(l.ref->next) : 0; } int[*] a = (int [list_length (l)]) {}; int i = 0; while (l != int_list.end) { a[i] = l.ref->v; l = l.ref->next; i++; } return a; } typedef union { int[*] array; void none; } array_or_none; public array_or_none factor (int i) { array_or_none array_append (array_or_none a, int v) { union switch (a) { case array: int[*] n = (int [dim(a.array)+1]) {}; int i; for (i = 0; i < dim(a.array); i++) n[i] = a.array[i]; n[i] = v; return (array_or_none.array) n; case none: int[*] n = (int [1]) { v }; return (array_or_none.array) n; } } if (i < 0) return array_append (factor (-i), -1); array_or_none result = array_or_none.none; int one_factor (int i) { if (i == 1) return 1; if ((i & 1) == 0) return 2; int limit = floor (sqrt (i)) + 1; int f; for (f = 3; f <= limit; f += 2) { if (!is_prime (f)) continue; if ((i % f) == 0) return f; } return i; } while (i > 1) { int factor = one_factor (i); result = array_append (result, factor); i /= factor; } return result; } } nickle_2.81.orig/examples/roman.5c0000664000175000000620000000243310770315535016273 0ustar keithpstaff/* * Convert integer to string of roman numerals * * Copyright © 2001 Keith Packard * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * A classic, plus a good illustration of some * of the structuring, typing, and nesting * capabilities of the language. */ string roman (int i) { if (i < 0) return "-" + roman (-i); typedef struct { string ones, five, tens; int base; } digit; digit[*] digits = { (digit) { .ones = "C", .five = "D", .tens = "M", .base = 100 }, (digit) { .ones = "X", .five = "L", .tens = "C", .base = 10 }, (digit) { .ones = "I", .five = "V", .tens = "X", .base = 1 } }; string place (int i, digit dig) { string lots (int i, string s) { if (i != 0) return s + lots (i-1,s); return ""; } if (i < 4) return lots (i, dig.ones); if (i == 4) return dig.ones + dig.five; if (i < 9) return dig.five + lots (i-5, dig.ones); if (i == 9) return dig.ones + dig.tens; return lots (i // 10, dig.tens) + place (i % 10, dig); } int d; for (d = 0; d < dim(digits); d++) if (i >= digits[d].base) return (place (i // digits[d].base, digits[d]) + roman(i % digits[d].base)); return ""; } printf ("%s\n", roman (string_to_integer (argv[1]))); nickle_2.81.orig/examples/initializer.5c0000664000175000000620000000405710770315535017506 0ustar keithpstaff/* * An example of initializers and scoping rules * * Copyright © 2001 Keith Packard * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ continuation c; /* * Static initializer example */ int stat () { int x = 1; int bar () { static int qq = 37; /* * Create an array containing two objects. * * During the evaluation of the first initializer, * a continuation is captured. Thus the initializer * can be reentered at this point. * * The second continuation demonstrates creating an * anonymous lambda and using a variety of values * which are in scope */ static int[*] y = (int[2]) { (int l = setjmp (&c, 1)), l + (func (a) { return a + ++l + x; }) (++x) + ++qq }; return ++y[0] + ++y[1]; } return bar () + bar(); } /* * Some sample values from this function. These are rather * hard to figure out from the code above. */ stat () /* 98 */ longjmp (c, 0) /* 98 */ longjmp (c, 1) /* 110 */ /* * Global initializer example */ int glob_x = 2; int glob () { int x = 2; int bar () { int z = 3; global q = 7; int bletch () { /* * This initializer is run in glob's static initializer context * Again, an anonymous lambda is used to create a local name * context to hold a variety of name types */ global y = (func (a) { static l_s = 7; global l_g = 8; auto l_a = 9; return a + q + l_s + l_g + l_a; }) (glob_x); /* * This initializer is run in bletch's static initializer context * Hence it can reference dynamic variables anywhere above * bletch, static variables within bletch and global variables * anywhere */ static u = z + glob_x; static t = u + q; return ++y + u + t; } return bletch () + x; } return bar (); } /* * Sample output from this function */ glob() /* 53 */ glob() /* 54 */ glob() /* 55 */ /* * Modify current glob_x value, has no effect on y value, * but does change u value */ glob_x = 47; glob () /* 146 */ nickle_2.81.orig/examples/comb.5c0000664000175000000620000000066210770315535016101 0ustar keithpstaff/* * Basic combinatorics * Copyright © 1995-2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ namespace Comb { public int perm(n, r) { return n! // r!; } public int choose(n, r) { return n! // (r! * (n - r)!); } public int binom(n, k) { int sum, i; sum = 1; for (i = 1; i <= k; i++) sum += choose(n, i); return sum; } } nickle_2.81.orig/examples/restart.5c0000664000175000000620000000153610770315535016646 0ustar keithpstaff/* * Demonstrates using continuations to * restart execution after correcting * an exceptional condition. * * Copyright © 2001 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart 2001/06/03 */ exception div0_attempt(continuation c); rational f(int x) { continuation c; int y; if ((y = setjmp(&c, 0)) != 0) { printf("restarted after exception\n"); x = y; } else { if (x == 0) { printf("raising exception\n"); raise div0_attempt(c); } } printf("returning value\n"); return 1 / x; } rational protected_f(int x) { try { return f(x); } catch div0_attempt(c) { printf("restarting after exception\n"); longjmp(c, 1); } printf("internal error\n"); return 0; } printf("%g\n", protected_f(2)); printf("%g\n", protected_f(0)); nickle_2.81.orig/natural.c0000664000175000000620000006471113202411374014720 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * natural.c * * arithmetic for natural numbers */ #include #include #include "nickle.h" # define length(n) ((n)->length) # define data(n) NaturalDigits(n) # define max(a,b) ((a) > (b) ? (a) : (b)) # define zerop(n) (length(n) == 0) #define BIGDOUBLE ((double)1.79769313486231470e+308) #ifndef MAXDOUBLE # define MAXDOUBLE ((double)1.79769313486231470e+308) #endif Natural *zero_natural; Natural *one_natural; Natural *two_natural; Natural *max_int_natural; Natural *max_signed_digit_natural; #ifndef LBASE10 static Natural *max_tenpow_natural; static int tenpow_digits; #endif DataCachePtr naturalCache; int NaturalToInt (Natural *n) { int i; digit *d; int index; d = data(n) + length (n); i = 0; for (index = 0; index < length(n); index++) i = i * BASE + (int) *--d; return i; } double_digit NaturalToDoubleDigit(Natural *n) { double_digit i; digit *d; int index; d = data(n) + length (n); i = 0; for (index = 0; index < length(n); index++) i = i * BASE + (double_digit) *--d; return i; } void NaturalCopy (Natural *a, Natural *b) { digit *ad, *bd; int index; length(b) = length(a); ad = data(a); bd = data(b); for (index = 0; index < length(a); index++) *bd++ = *ad++; } #if 0 static void NaturalClear (Natural *n) { int i; for (i = 0; i < length(n); i++) data(n)[i] = 0; } #endif Bool NaturalEven (Natural *n) { if (!length (n) || (data(n)[0] & 1) == 0) return True; return False; } Bool NaturalZero (Natural *n) { return length (n) == 0; } #if 0 static int NaturalOne (Natural *n) { return length (n) == 1 && data(n)[0] == 1; } #endif Bool NaturalLess (Natural *a, Natural *b) { int index; digit *at, *bt; if (length (a) < length (b)) return True; else if (length (b) < length (a)) return False; else { at = data(a) + length(a) - 1; bt = data(b) + length(b) - 1; for (index = 0; index < length(a); index++) { if (*at < *bt) return True; else if (*bt < *at) return False; at--; bt--; } return False; } } Bool NaturalEqual (Natural *a, Natural *b) { int index; digit *at, *bt; if (length (a) == length (b)) { at = data(a); bt = data(b); for (index = 0; index < length(a); index++) if (*at++ != *bt++) return False; return True; } return False; } /* * Primitive functions that operate on sequences * of digits */ static int DigitsLen (digit *x, int len) { x += (len - 1); while (len && *x == 0) { len--; x--; } return len; } static int DigitsAdd (digit *x, int xlen, digit *y, int ylen, digit *r_orig) { digit *r = r_orig; int rlen; digit carry = 0; digit xv, yv, rv; while (xlen && ylen) { xlen--; ylen--; rv = xv = *x++; yv = *y++ + carry; if (yv) { carry = 0; if ((rv = xv + yv) < xv) carry = 1; } *r++ = rv; } while (ylen) { ylen--; yv = *y++ + carry; if (yv) carry = 0; *r++ = yv; } while (xlen) { xlen--; rv = xv = *x++; if (carry) { yv = carry; carry = 0; if ((rv = xv + yv) < xv) carry = 1; } *r++ = rv; } if (carry) *r++ = carry; rlen = r - r_orig; r--; while (rlen && *r == 0) { r--; rlen--; } return rlen; } static int DigitsAddInPlace (digit *x_orig, int xlen, digit *y, int ylen, int off) { digit *x = x_orig; digit carry = 0; digit xv, yv; x += off; xlen -= off; if (xlen < 0) { x += xlen; while (xlen++) *x++ = 0; } while (xlen && ylen) { xlen--; ylen--; yv = *y++ + carry; if (yv) { carry = 0; xv = *x; if ((*x = xv + yv) < xv) carry = 1; } x++; } while (ylen) { ylen--; yv = *y++ + carry; if (yv) carry = 0; *x++ = yv; } while (xlen && carry) { xlen--; xv = *x; yv = carry; carry = 0; if ((*x = xv + yv) < xv) carry = 1; x++; } if (carry) *x++ = carry; return xlen + (x - x_orig); } static int DigitsSubInPlace (digit *x_orig, int xlen, digit *y, int ylen, int off) { digit *x = x_orig; digit carry = 0; digit xv, yv; x += off; xlen -= off; while (ylen--) { xlen--; xv = *x; yv = *y++ + carry; if (yv) { carry = 0; if ((*x = xv - yv) > xv) carry = 1; } x++; } while (carry) { xlen--; xv = *x; yv = carry; carry = 0; if ((*x = xv - yv) > xv) carry = 1; x++; } return xlen + (x - x_orig); } static int DigitTimes (digit *x, int xlen, digit y, digit *result) { double_digit q; digit carry; int rlen = xlen; if (y == 1) { memcpy (x, result, xlen * sizeof (digit)); return xlen; } carry = 0; while (xlen--) { q = (double_digit) y * (double_digit) *x++ + (double_digit) carry; carry = DivBase (q); *result++ = ModBase (q); } if (carry) { *result++ = carry; rlen++; } return rlen; } static int DigitsGradeSchool (digit *x_orig, int xlen, digit *y_orig, int ylen, digit *result) { digit *x, *y, *r, *rbase, *rloop; double_digit temp; digit carry; digit xd; int xindex, yindex; int rlen; if (xlen == 0 || ylen == 0) return 0; if (xlen == 1) return DigitTimes (y_orig, ylen, *x_orig, result); if (ylen == 1) return DigitTimes (x_orig, xlen, *y_orig, result); memset (result, 0, (xlen + ylen + 1) * sizeof (digit)); rbase = 0; x = x_orig; xindex = xlen; rbase = result; while (xindex--) { carry = 0; rloop = rbase++; xd = *x++; y = y_orig; yindex = ylen; while (yindex--) { temp = (double_digit) xd * (double_digit) *y++ + (double_digit) carry; carry = DivBase (temp); temp = ModBase (temp); r = rloop++; while (temp) { temp += (double_digit) *r; *r++ = ModBase (temp); temp = DivBase (temp); } } if (carry) { r = rloop; temp = carry; while (temp) { temp += (double_digit) *r; *r++ = ModBase (temp); temp = DivBase (temp); } } } rlen = xlen + ylen + 1; r = result + (rlen - 1); while (rlen && *r == 0) { rlen--; r--; } return rlen; } #define KARATSUBA_LIMIT 100 /* * Karatsuba multiplication as found in @article{ karatsuba62multiplication, author = "A. Karatsuba and Yu Ofman", title = "Multiplication of multidigit numbers on automata", journal = "Doklady Akademii Nauk SSSR", volume = "145", number = "2", pages = "293--294", year = "1962" } */ static int DigitsKaratsuba (digit *x, int xlen, digit *y, int ylen, digit *result, digit *tmp) { /* * x * y = (x1 * b + x0) * (y1 * b + y0); * = b^2 x1 y1 + b (x1 y0 + x0 y1) + x0 y0 * = b^2 x1 y1 + b (x1 y0 + x0 y1 + x1 y1 + x0 y0) + x0 y0 - b x1 y1 - b x0 y0 * = (b^2 - b) x1 y1 + b (x1 + x0) (y0 + y1) + (1 - b) x0 y0 */ int off; int off2; digit *x1, *x0, *y1, *y0; digit *f, *m1, *m2; digit *next_tmp; int x1len, x0len, y1len, y0len; int flen, m1len, m2len; int rlen; if (aborting) return 0; if (xlen < KARATSUBA_LIMIT || ylen < KARATSUBA_LIMIT) return DigitsGradeSchool (x, xlen, y, ylen, result); off = xlen > ylen ? (xlen >> 1) : (ylen >> 1); off2 = off << 1; /* * Normalize partial quotients */ x0 = x; x0len = xlen; if (x0len > off) x0len = DigitsLen (x0, off); if (off < xlen) { x1 = x + off; x1len = DigitsLen (x1, xlen - off); } else { x1 = x0; x1len = 0; } y0 = y; y0len = ylen; if (y0len > off) y0len = DigitsLen (y0, off); if (off < ylen) { y1 = y + off; y1len = DigitsLen (y1, ylen - off); } else { y1 = y0; y1len = 0; } /* * Allocate temp space */ m1 = tmp; m2 = m1 + off + 1; f = tmp; /* overlay first factor on minuends */ next_tmp = m2 + off + 1; /* * Generate middle factor first */ m1len = DigitsAdd (x0, x0len, x1, x1len, m1); m2len = DigitsAdd (y0, y0len, y1, y1len, m2); /* * Compute middle factor */ rlen = 0; if (m1len && m2len) { memset (result, 0, off * sizeof (digit)); rlen = DigitsKaratsuba (m1, m1len, m2, m2len, result + off, next_tmp) + off; if (aborting) return rlen; } /* * Compute first factor */ if (x1len && y1len) { flen = DigitsKaratsuba (x1, x1len, y1, y1len, f, next_tmp); if (aborting) return rlen; rlen = DigitsAddInPlace (result, rlen, f, flen, off2); rlen = DigitsSubInPlace (result, rlen, f, flen, off); } /* * Compute third factor */ if (x0len && y0len) { flen = DigitsKaratsuba (x0, x0len, y0, y0len, f, next_tmp); if (aborting) return rlen; rlen = DigitsAddInPlace (result, rlen, f, flen, 0); rlen = DigitsSubInPlace (result, rlen, f, flen, off); } return rlen; } Natural * NaturalPlus (Natural *a, Natural *b) { ENTER (); Natural *result; result = AllocNatural (max(length(a), length(b)) + 1); result->length = DigitsAdd (data(a), length(a), data(b), length(b), data(result)); RETURN (result); } Natural * NaturalMinus (Natural *a, Natural *b) { ENTER (); int resultlen; Natural *result; signed_digit temp, carry; digit *at, *bt, *rt; int index; int len; resultlen = length(a); result = AllocNatural (resultlen); at = data(a); bt = data(b); rt = data(result); carry = 0; len = -1; for (index = 0; index < resultlen; index++) { temp = ((signed_digit) (index < length(a) ? *at++ : 0) - (signed_digit) (index < length(b) ? *bt++ : 0) - (signed_digit) carry); carry = 0; if (temp < 0) { temp += BASE; carry = 1; } if (temp > 0) len = index; *rt++ = temp; } length(result) = len + 1; RETURN(result); } Natural * NaturalTimes (Natural *a, Natural *b) { ENTER (); Natural *result; int rlen; digit *tmp; int tmp_len; if (length (a) < KARATSUBA_LIMIT || length (b) < KARATSUBA_LIMIT) { if (zeroNp (a) || zeroNp (b)) RETURN (zero_natural); if (oneNp (a)) RETURN(b); if (oneNp (b)) RETURN (a); result = AllocNatural (length(a) + length (b) + 1); result->length = DigitsGradeSchool (data(a), length(a), data(b), length (b), data(result)); } else { if (length (a) > length (b)) rlen = length (a) << 1; else rlen = length (b) << 1; result = AllocNatural (rlen); tmp_len = rlen << 3; tmp = AllocateTemp (tmp_len * sizeof (digit)); rlen = DigitsKaratsuba (data(a), length (a), data(b), length (b), data(result), tmp); if (aborting) RETURN(zero_natural); tmp = data(result) + (rlen - 1); while (rlen && *tmp == 0) { rlen--; tmp--; } result->length = rlen; } RETURN (result); } Natural * NaturalLand (Natural *a, Natural *b) { ENTER (); digit *at, *bt, *rt; Natural *result; int resultlen; resultlen = length (a); if (resultlen > length(b)) resultlen = length(b); at = data(a) + (resultlen-1); bt = data(b) + (resultlen-1); while (resultlen > 0 && (*at & *bt) == 0) { resultlen--; at--; bt--; } if (resultlen == 0) RETURN (zero_natural); result = AllocNatural (resultlen); rt = data(result) + (resultlen-1); while (resultlen-- > 0) *rt-- = *at-- & *bt--; RETURN (result); } Natural * NaturalLor (Natural *a, Natural *b) { ENTER (); digit *at, *bt, *rt; Natural *result; int alength; int blength; alength = length(a); blength = length(b); if (alength < blength) { result = a; a = b; b = result; alength = length(a); blength = length(b); } if (alength == 0) RETURN (zero_natural); result = AllocNatural (alength); at = data(a); bt = data(b); rt = data(result); alength -= blength; while (blength--) *rt++ = *at++ | *bt++; while (alength--) *rt++ = *at++; RETURN (result); } Natural * NaturalCompliment (Natural *a, int len) { ENTER (); digit *at, *rt; Natural *result; int resultlen; resultlen = length (a); at = data(a) + (resultlen-1); while (resultlen > len && ~*at == 0) { resultlen--; at--; } if (resultlen == 0) RETURN (zero_natural); if (resultlen > len) len = resultlen; result = AllocNatural (len); rt = data(result) + (len-1); while (len > resultlen) { *rt-- = ~0; len--; } while (resultlen-- > 0) *rt-- = ~*at--; RETURN (result); } Natural * NaturalNegate (Natural *n, int len) { ENTER (); RETURN (NaturalPlus (NaturalCompliment (n, len), one_natural)); } Natural * NaturalSqrt (Natural *n) { ENTER (); Natural *l, *h, *m, *rem; l = two_natural; h = NaturalDivide (n, two_natural, &rem); while (NaturalLess (one_natural, NaturalMinus (h, l))) { m = NaturalDivide (NaturalPlus (l, h), two_natural, &rem); if (NaturalLess (NaturalTimes (m, m), n)) l = m; else h = m; } RETURN (h); } Natural * NaturalFactor (Natural *n, Natural *max) { ENTER (); Natural *v, *lim, *rem; if (zerop (n)) RETURN(zero_natural); if ((data(n)[0] & 1) == 0) RETURN(two_natural); lim = NaturalSqrt (n); for (v = NewNatural (3); !NaturalLess (lim, v); v = NaturalPlus (v, two_natural)) { (void) NaturalDivide (n, v, &rem); if (zerop (rem)) RETURN (v); if (aborting) break; if (max && NaturalLess (max, v)) RETURN (0); } RETURN (n); } Natural * NaturalIntPow (Natural *n, int p) { ENTER (); Natural *result; result = one_natural; while (p) { if (p & 1) result = NaturalTimes (result, n); p >>= 1; if (p) n = NaturalTimes (n, n); if (aborting) break; } RETURN (result); } Natural * NaturalPow (Natural *n, Natural *p) { ENTER (); Natural *result; result = one_natural; while (!zerop (p)) { if (data(p)[0] & 1) result = NaturalTimes (result, n); p = NaturalRsl(p, 1); if (!zerop (p)) n = NaturalTimes (n, n); if (aborting) break; } RETURN (result); } #define evenp(n) ((zerop (n) || ((data(n)[0] & 1) == 0))) Natural * NaturalPowMod (Natural *n, Natural *p, Natural *m) { ENTER (); Natural *result; Natural *rem; result = one_natural; while (!zerop (p)) { if (!evenp (p)) (void) NaturalDivide (NaturalTimes (result, n), m, &result); p = NaturalDivide (p, two_natural, &rem); if (!zerop(p)) (void) NaturalDivide (NaturalTimes (n, n), m, &n); if (aborting) break; } RETURN (result); } static int digit_width (digit d, int base) { int width = 1; while (d >= base) { width++; d /= base; } return width; } int NaturalEstimateLength (Natural *a, int base) { if (length (a) == 0) return 2; return length(a) * digit_width (MAXDIGIT, base) + 1; } char *naturalBuffer; int naturalBufferSize; static char * NaturalBottom (char *result, digit partial, int base, int digits, Bool fill) { digit dig; do { dig = partial % base; if (dig < 10) dig = '0' + dig; else dig = 'a' + dig - 10; *--result = dig; digits--; partial = partial / base; } while (partial); if (fill) while (digits-- > 0) *--result = '0'; return result; } static char * NaturalSplit (char *result, Natural *a, Natural **divisors, int base, int digits, Bool fill) { ENTER (); Natural *q, *r; Bool rfill; if (aborting) return 0; if (zerop (a)) { if (fill) while (digits--) *--result = '0'; } else if (!divisors[0]) { result = NaturalBottom (result, data(a)[0], base, digits, fill); } else { q = NaturalDivide (a, divisors[0], &r); digits = digits / 2; divisors--; rfill = True; if (zerop (q)) rfill = fill; result = NaturalSplit (result, r, divisors, base, digits, rfill); if (rfill) result = NaturalSplit (result, q, divisors, base, digits, fill); } EXIT (); return result; } char * NaturalSprint (char *result, Natural *a, int base, int *width) { ENTER (); int len; double_digit max_base; int digits; digit *t; Natural *divisor; char *r; digit partial; int print_width; Natural **divisors; int ndivisors; int idivisor; if (!result) { /* * Allocate temporary space for the string of digits */ print_width = NaturalEstimateLength (a, base); if (naturalBufferSize < print_width) { if (naturalBuffer) free (naturalBuffer); naturalBuffer = malloc (print_width); if (!naturalBuffer) { naturalBufferSize = 0; EXIT (); return 0; } naturalBufferSize = print_width; } result = naturalBuffer + naturalBufferSize; } r = result; *--r = '\0'; len = length (a); if (len == 0) { *--r = '0'; if (width) *width = 1; EXIT (); return r; } /* * Compute the number of base digits which can be * held in BASE */ max_base = base; digits = 0; while (max_base <= BASE) { max_base *= base; digits++; } max_base /= base; t = 0; divisor = 0; if (max_base == BASE) { t = data(a); while (len) { if (aborting) { r = 0; break; } partial = *t++; len--; r = NaturalBottom (r, partial, base, digits, len != 0); } } else { divisor = NewNatural ((unsigned) max_base); divisors = 0; ndivisors = 0; idivisor = 0; do { if (idivisor >= ndivisors - 1) { ndivisors += 128; if (divisors) divisors = realloc (divisors, ndivisors * sizeof (Natural *)); else divisors = malloc (ndivisors * sizeof (Natural *)); if (!divisors) return 0; } if (!idivisor) divisors[idivisor++] = 0; divisors[idivisor++] = divisor; divisor = NaturalTimes (divisor, divisor); digits = digits * 2; if (aborting) { r = 0; break; } } while (NaturalLess (divisor, a)); if (!aborting) r = NaturalSplit (r, a, divisors + idivisor - 1, base, digits, False); free (divisors); } if (width && r) *width = (result - 1) - r; EXIT (); return r; } DataType NaturalType = { 0, 0, "NaturalType" }; Natural * AllocNatural (int size) { Natural *result; result = ALLOCATE (&NaturalType, sizeof (Natural) + size * sizeof (digit)); result->length = size; return result; } static Natural * NewDoubleDigitNaturalReal (double_digit dd) { Natural *result; int len; double_digit temp; digit *d; len = 0; temp = dd; while (temp) { len++; temp = DivBase (temp); } result = AllocNatural (len); temp = dd; d = data(result); while (temp) { *d++ = ModBase (temp); temp = DivBase (temp); } return result; } #define NATURAL_CACHE_SIZE 8191 Natural * NewDoubleDigitNatural (double_digit dd) { switch (dd) { case 0: return zero_natural; case 1: return one_natural; case 2: return two_natural; case MAX_NICKLE_INT: return max_int_natural; default: { digit l = ModBase(dd), u = DivBase(dd); unsigned c = l % NATURAL_CACHE_SIZE; Natural **re = (Natural **) DataCacheValues(naturalCache) + c; Natural *ret = *re; digit *d; if (ret) { d = data(ret); if (l == d[0] && u == (ret->length == 1 ? 0 : d[1])) { REFERENCE (ret); return ret; } } ret = NewDoubleDigitNaturalReal (dd); *re = ret; return ret; } } } Natural * NewNatural (unsigned value) { return NewDoubleDigitNatural ((double_digit) value); } Natural * NaturalRsl (Natural *v, int shift) { ENTER (); Natural *r; digit *vt, *rt; digit d1, d2; int length; int dshift; int index, last; if (v->length == 0) RETURN (zero_natural); #ifdef LLBASE2 dshift = (shift >> LLBASE2); shift = (shift & (LBASE2 - 1)); #else dshift = shift / LBASE2; shift = shift % LBASE2; #endif length = v->length - dshift; index = length; last = 1; if ((NaturalDigits(v)[v->length - 1] >> shift) == 0) { length--; last = 0; } if (length <= 0) RETURN (zero_natural); r = AllocNatural (length); rt = NaturalDigits (r); vt = NaturalDigits (v) + dshift; if (shift) { d2 = *vt++; while (--index) { d1 = d2; d2 = *vt++; *rt++ = (d1 >> shift) | (d2 << (LBASE2 - shift)); } if (last) *rt++ = (d2 >> shift); } else { while (length--) { *rt++ = *vt++; } } RETURN (r); } Natural * NaturalLsl (Natural *v, int shift) { ENTER (); Natural *r; digit *vt, *rt; digit d1, d2; int length; int dshift; int index; int last; if (v->length == 0) RETURN (zero_natural); #ifdef LLBASE2 dshift = (shift >> LLBASE2); shift = (shift & (LBASE2 - 1)); #else dshift = shift / LBASE2; shift = shift % LBASE2; #endif length = v->length + dshift; index = v->length; last = 0; if (shift) { if ((NaturalDigits(v)[v->length - 1] >> (LBASE2 - shift)) != 0) { length++; last = 1; } } r = AllocNatural (length); rt = NaturalDigits (r); while (dshift--) *rt++ = 0; vt = NaturalDigits (v); if (shift) { d2 = *vt++; *rt++ = d2 << shift; while (--index) { d1 = d2; d2 = *vt++; *rt++ = (d1 >> (LBASE2 - shift)) | (d2 << shift); } if (last) *rt++ = (d2 >> (LBASE2 - shift)); } else { while (index--) *rt++ = *vt++; } RETURN (r); } Natural * NaturalMask (Natural *v, int bits) { ENTER (); Natural *r; digit *vt, *rt; digit mask; int length; #ifdef LLBASE2 length = (bits + LBASE2) >> LLBASE2; mask = bits & (LBASE2 - 1); #else length = (bits + LBASE2) / LBASE2; mask = bits % LBASE2; #endif mask = (1 << mask) - 1; if (length > v->length) { length = v->length; mask = (digit) ~0; } while (length && (NaturalDigits(v)[length - 1] & mask) == 0) { length--; mask = (digit) ~0; } r = AllocNatural (length); rt = NaturalDigits (r); vt = NaturalDigits (v); if (length) { length--; while (length--) *rt++ = *vt++; *rt = *vt & mask; } RETURN (r); } int NaturalPowerOfTwo (Natural *v) { int bit; int l; digit *vt, last; if (!v->length) return -1; vt = NaturalDigits(v); l = v->length - 1; while (l--) { if (*vt++ != 0) return -1; } last = *vt; if (last & (last - 1)) return -1; bit = (v->length - 1) * LBASE2; while (!(last & 1)) { bit++; last >>= 1; } return bit; } void NaturalDigitMultiply (Natural *a, digit i, Natural *result) { result->length = DigitTimes (data(a), length(a), i, data(result)); } /* * subtract b from a in place with offset implied zeros to the * right of b. Return if a carry out occured */ digit NaturalSubtractOffset (Natural *a, Natural *b, int offset) { int index; digit carry; digit *at, *bt; digit av, bv; int len; carry = 0; at = NaturalDigits(a) + offset; bt = NaturalDigits(b); index = a->length - offset; if (index > b->length) index = b->length; while (index--) { av = *at; bv = *bt++ + carry; if (bv) { carry = 0; if ((*at = av - bv) > av) carry = 1; } at++; } if (carry && a->length > b->length + offset) { *at = *at - carry; carry = 0; } len = a->length; at = NaturalDigits(a) + len; while (len > 0 && *--at == 0) len--; a->length = len; return carry; } digit NaturalSubtractOffsetReverse (Natural *a, Natural *b, int offset) { int index; digit carry; digit *at, *bt; digit av, bv; int len; carry = 0; at = NaturalDigits(a) + offset; bt = NaturalDigits(b); index = a->length - offset; if (index > b->length) index = b->length; while (index--) { av = *at + carry; bv = *bt++; if (bv) { carry = 0; if ((*at = bv - av) > bv) carry = 1; } at++; } if (carry && a->length > b->length + offset) { *at = carry; carry = 0; } len = a->length; at = NaturalDigits(a) + len; while (len > 0 && *--at == 0) len--; a->length = len; return carry; } void NaturalAddOffset (Natural *a, Natural *b, int offset) { int index; digit carry; digit *at, *bt; digit av, bv; carry = 0; at = NaturalDigits(a) + offset; bt = NaturalDigits(b); index = b->length; while (index--) { bv = *bt++ + carry; if (bv) { carry = 0; av = *at; if ((*at = av + bv) < av) carry = 1; } at++; } if (carry) *at = *at + carry; if (at == NaturalDigits(a) + a->length - 1) { while (a->length && *at == 0) { at--; a->length--; } } } Bool NaturalGreaterEqualOffset (Natural *a, Natural *b, int offset) { digit *ad, *bd; int index; if (a->length > b->length + offset) return True; if (a->length < b->length + offset) return False; ad = NaturalDigits(a) + a->length - 1; bd = NaturalDigits(b) + b->length - 1; index = b->length; while (index--) { if (*ad > *bd) return True; if (*ad < *bd) return False; --ad; --bd; } return True; } HashValue NaturalHash (Natural *a) { return HashCrc32 ((unsigned char *) &a->length, sizeof (int) + sizeof (digit) * a->length); } int NaturalInit (void) { ENTER (); #ifndef LBASE10 int max_tenpow, i; #endif naturalCache = NewDataCache (NATURAL_CACHE_SIZE); zero_natural = NewDoubleDigitNaturalReal (0); MemAddRoot (zero_natural); one_natural = NewDoubleDigitNaturalReal (1); MemAddRoot (one_natural); two_natural = NewDoubleDigitNaturalReal (2); MemAddRoot (two_natural); max_int_natural = NewDoubleDigitNaturalReal (MAX_NICKLE_INT); MemAddRoot (max_int_natural); max_signed_digit_natural = NewDoubleDigitNaturalReal (MAX_NICKLE_SIGNED_DIGIT); MemAddRoot(max_signed_digit_natural); #ifndef LBASE10 tenpow_digits = (int) floor (log10 ((double) MAX_NICKLE_INT)); max_tenpow = 1; for (i = 0; i < tenpow_digits; i++) max_tenpow *= 10; #ifdef DEBUG printf ("max_tenpow: %d\n", max_tenpow); #endif max_tenpow_natural = NewNatural (max_tenpow); MemAddRoot (max_tenpow_natural); #endif EXIT (); return 1; } nickle_2.81.orig/README.release0000664000175000000620000000132312046273776015414 0ustar keithpstaffIf you're going to package nickle for release, there are several important steps: 1. Create new version edit configure.in, changing the version number in the AC_INIT line 2. rebuild the configuration files with autogen.sh sh autogen.sh --prefix=/usr --mandir=/usr/share/man 3. make distcheck 4. Update debian/changelog git log --pretty=oneline 2...master 5. Build the release make release-files 6. Commit these changes git-commit -m'Update to version 2.' -a 7. Tag git-tag -s -m 'Version 2.' 2. 8. Push out changes to the repo git-push origin master 2. 9. Push out the release make release 10. Push debian bits dput nickle_2.-1_i386.changes nickle_2.81.orig/configure.ac0000664000175000000620000000671113202542632015372 0ustar keithpstaffdnl Process this file with autoconf to produce a configure script. dnl Copyright © 1988-2004 Keith Packard and Bart Massey. dnl All Rights Reserved. See the file COPYING in this directory dnl for licensing information. AC_PREREQ([2.69]) AC_INIT([nickle],[2.81],[http://nickle.org],[nickle]) RELEASE_DATE="2017-11-14" AC_CONFIG_SRCDIR([nickle.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR(.) AM_INIT_AUTOMAKE([foreign]) AM_MAINTAINER_MODE AC_SUBST([RELEASE_DATE]) dnl Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_LN_S AM_PROG_LEX dnl AC_PROG_YACC AC_CHECK_PROGS([YACC], byacc yacc bison, yacc) case "$YACC" in *bison) YACC="$YACC -y" ;; esac dnl Checks for libraries. AC_CHECK_FUNC(log,,AC_CHECK_LIB(m, log)) AC_CHECK_FUNC(gethostbyname,,AC_CHECK_LIB(nsl, gethostbyname)) AC_CHECK_FUNC(socket,,AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(resolv, hstrerror)) AC_CHECK_LIB(dl, dlopen) dnl as-compiler-flag.m4 0.0.1 dnl autostars m4 macro for detection of compiler flags dnl dnl ds@schleef.org AC_DEFUN([AS_COMPILER_FLAG], [ AC_MSG_CHECKING([to see if compiler understands $1]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[return 0])], [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes; then $2 true else $3 true fi AC_MSG_RESULT([$flag_ok]) ]) AS_COMPILER_FLAG([-Wl,-E], GCC_EXTERN="yes", GCC_EXTERN="no") if test $GCC_EXTERN = yes; then NICKLE_LDFLAGS="-Wl,-E" AC_DEFINE([HAVE_EXTERN_SYMS], 1, [C compilers can extern program symbols]) else NICKLE_LDFLAGS="" fi AC_SUBST(NICKLE_LDFLAGS) dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h strings.h time.h sys/time.h unistd.h sys/resource.h) AC_CHECK_HEADERS(stropts.h) AC_CHECK_HEADERS(dlfcn.h) dnl Checks for precise integer types AC_CHECK_HEADERS(stdint.h) case "$ac_cv_header_stdint_h" in no) AC_CHECK_SIZEOF([unsigned long long], 0) AC_CHECK_SIZEOF([unsigned long], 0) AC_CHECK_SIZEOF([unsigned int], 0) AC_CHECK_SIZEOF([unsigned short], 0) ;; yes) AC_MSG_CHECKING([for uint64_t]) AC_EGREP_HEADER([uint64_t], stdint.h, AC_MSG_RESULT(yes) AC_DEFINE([HAVE_UINT64_T], 1, [Has uint64_t datatype]), AC_MSG_RESULT(no)) ;; esac dnl Checks for library functions. AC_FUNC_VPRINTF AC_CHECK_FUNCS(unsetenv setenv putenv gettimeofday hstrerror select) AC_CHECK_FUNCS(sigaction sigrelse sigignore setrlimit getrlimit) AC_CHECK_FUNCS(dlopen dlsym dlerror dlclose) AC_PATH_PROGS([DOCBOOK2PDF],[docbook2pdf]) AM_CONDITIONAL(HASDOCBOOK,test -n "$DOCBOOK2PDF") AC_FUNC_GETPGRP dnl The readline test is complicated enough to rate its own file AC_LIB_READLINE if test "x$ac_cv_header_readline_readline_h" = xyes; then AC_CHECK_DECL(rl_catch_signals, AC_DEFINE(HAVE_RL_CATCH_SIGNALS,1,[Has rl_catch_signals]),,[#include ]) AC_CHECK_DECL(rl_reset_after_signal, AC_DEFINE(HAVE_RL_RESET_AFTER_SIGNAL,1,[Has rl_reset_after_signal]),,[#include ]) AC_CHECK_DECL(rl_cleanup_after_signal, AC_DEFINE(HAVE_RL_CLEANUP_AFTER_SIGNAL,1,[Has rl_cleanup_after_signal]),,[#include ]) fi if test "x$prefix" = xNONE; then prefix="$ac_default_prefix" fi nicklelibdir=`eval echo ${datadir}`/nickle AC_SUBST(nicklelibdir) AC_CONFIG_FILES( Makefile test/Makefile bench/Makefile examples/Makefile examples/smlng/Makefile examples/turtle/Makefile doc/Makefile doc/tutorial/Makefile) AC_OUTPUT nickle_2.81.orig/scope.c0000664000175000000620000001475610770315535014400 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include "ref.h" static void NamespaceMark (void *object) { NamespacePtr namespace = object; MemReference (namespace->previous); MemReference (namespace->names); } DataType namespaceType = { NamespaceMark, 0, "namespaceType" }; NamespacePtr NewNamespace (NamespacePtr previous) { ENTER (); NamespacePtr namespace; namespace = ALLOCATE (&namespaceType, sizeof (Namespace)); namespace->previous = previous; namespace->names = 0; namespace->publish = publish_public; RETURN (namespace); } static void NamelistMark (void *object) { NamelistPtr namelist = object; MemReference (namelist->next); MemReference (namelist->symbol); } DataType namelistType = { NamelistMark, 0, "namelistType" }; static NamelistPtr NewNamelist (NamelistPtr next, SymbolPtr symbol, Publish publish) { ENTER (); NamelistPtr namelist; namelist = ALLOCATE (&namelistType, sizeof (Namelist)); namelist->next = next; namelist->symbol = symbol; namelist->publish = publish; RETURN (namelist); } NamespacePtr GlobalNamespace, TopNamespace, CurrentNamespace; ReferencePtr TopNamespaceReference; ReferencePtr CurrentNamespaceReference; CommandPtr CurrentCommands; ReferencePtr CurrentCommandsReference; void NamespaceInit (void) { ENTER (); GlobalNamespace = NewNamespace (0); MemAddRoot (GlobalNamespace); TopNamespace = GlobalNamespace; TopNamespaceReference = NewReference ((void **) &TopNamespace); MemAddRoot (TopNamespaceReference); CurrentNamespace = GlobalNamespace; CurrentNamespaceReference = NewReference ((void **) &CurrentNamespace); MemAddRoot (CurrentNamespaceReference); CurrentCommands = 0; CurrentCommandsReference = NewReference ((void **) &CurrentCommands); MemAddRoot (CurrentCommandsReference); EXIT (); } static NamelistPtr NamespaceFindNamelist (NamespacePtr namespace, Atom atom, Bool search, Bool allow_private) { NamelistPtr namelist; do { for (namelist = namespace->names; namelist; namelist = namelist->next) if (namelist->symbol->symbol.name == atom && (allow_private || namespace->publish != publish_private || namelist->publish != publish_private)) return namelist; namespace = namespace->previous; } while (search && namespace); return 0; } SymbolPtr NamespaceFindName (NamespacePtr namespace, Atom atom, Bool search) { NamelistPtr namelist; namelist = NamespaceFindNamelist (namespace, atom, search, False); if (namelist) return namelist->symbol; return 0; } Bool NamespaceIsNamePrivate (NamespacePtr namespace, Atom atom, Bool search) { return NamespaceFindNamelist (namespace, atom, search, True) != 0; } SymbolPtr NamespaceAddName (NamespacePtr namespace, SymbolPtr symbol, Publish publish) { NamelistPtr namelist; NamelistPtr *prev; /* * Remove old symbol */ for (prev = &namespace->names; (namelist = *prev); prev = &namelist->next) if (namelist->symbol->symbol.name == symbol->symbol.name) { *prev = namelist->next; break; } namelist = NewNamelist (namespace->names, symbol, publish); namespace->names = namelist; return symbol; } Bool NamespaceRemoveName (NamespacePtr namespace, Atom atom) { NamelistPtr namelist, *prev; for (prev = &namespace->names; (namelist = *prev); prev = &namelist->next) if (namelist->symbol->symbol.name == atom) { *prev = namelist->next; return True; break; } return False; } void NamespaceImport (NamespacePtr namespace, NamespacePtr import, Publish publish) { NamelistPtr namelist; for (namelist = import->names; namelist; namelist = namelist->next) if (namelist->publish == publish_public) NamespaceAddName (namespace, namelist->symbol, publish); } static void CommandMark (void *object) { CommandPtr command = object; MemReference (command->previous); MemReference (command->func); } DataType commandType = { CommandMark, 0, "commandType" }; CommandPtr NewCommand (CommandPtr previous, Atom name, Value func, Bool names) { ENTER (); CommandPtr command; command = ALLOCATE (&commandType, sizeof (*command)); command->previous = previous; command->name = name; command->func = func; command->names = names; RETURN (command); } CommandPtr CommandFind (CommandPtr command, Atom name) { for(; command; command = command->previous) if (command->name == name) return command; return 0; } CommandPtr CommandRemove (CommandPtr command, Atom name) { ENTER (); CommandPtr *prev; for (prev = &command; *prev; prev = &(*prev)->previous) if ((*prev)->name == name) { *prev = (*prev)->previous; break; } RETURN (command); } Bool NamespaceLocate (Value names, NamespacePtr *namespacep, SymbolPtr *symbolp, Publish *publishp, Bool complain) { int i; NamespacePtr namespace; FramePtr f; CodePtr c; Value string; NamelistPtr namelist = 0; SymbolPtr symbol; Bool search = True; if (!ValueIsArray(names) || names->array.ndim != 1 || ArrayLimits(&names->array)[0] == 0) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("not non-empty array of strings"), NewInt (0), names); return False; } GetNamespace (&namespace, &f, &c); for (i = 0; i < ArrayLimits(&names->array)[0]; i++) { string = ArrayValue (&names->array, i); if (aborting) return False; if (!ValueIsString(string)) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("not string"), NewInt (0), string); return False; } namelist = NamespaceFindNamelist (namespace, AtomId (StringChars (&string->string)), search, True); search = False; if (!namelist) { if (complain) FilePrintf (FileStdout, "No symbol %v in namespace\n", string); return False; } symbol = namelist->symbol; if (i != ArrayLimits(&names->array)[0] - 1) { if (symbol->symbol.class != class_namespace) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("not namespace"), NewInt(i), string); return False; } namespace = symbol->namespace.namespace; } } *namespacep = namespace; *symbolp = namelist->symbol; *publishp = namelist->publish;; return True; } nickle_2.81.orig/gamma.5c0000664000175000000620000000570211711660230014414 0ustar keithpstaff extend namespace Math { public real gamma(real n) /* * Stieljes continuing fraction method of computing * gamma */ { real Stieltjes(real n, int ord, int bits) { /* * Compute the continuing fraction coefficients */ real[*] StieltjesCF(int len, int bits) { /* Compute a set of Bernouli numbers * using the Akiyama-Tanigawa algorithm */ real[*] AkiyamaTanigawa(int l, int bits) { int n = 2 * l + 1; real[n] t = { imprecise(1, bits) }; real[l] a; int k = 1; for (int m = 2; m <= n; m++) { t[m-1] = 1/imprecise(m, bits); for (int j = m-1; j >= 1; j--) t[j-1] = j * (t[j-1] - t[j]); if ((m & 1) != 0) { real rk = imprecise(k, bits); real v = t[0]/((2*rk-1)*(2*rk)); if ((k & 1) == 0) a[k-1] = -v; else a[k-1] = v; k++; } } return a; } real[*] s = AkiyamaTanigawa(len, bits); real[len,len] m; for (int n = 0; n < len; n++) m[n,0] = 0; for (int n = 0; n < len-1; n++) m[n,1] = s[n+1]/s[n]; for (int k = 3; k <= len; k++) { for (int n = 1; n <= len - k + 1; n++) { real a = m[n,k-3]; real b = m[n,k-2]; real c = m[n-1,k-2]; if ((k & 1) != 0) m[n-1,k-1] = a + b - c; else m[n-1,k-1] = a * b / c; } } m[0,0] = s[0]; return (real[len]) { [k] = m[0,k] }; } real N = imprecise(n + 1, bits); real q = N; real[*] c = StieltjesCF(ord, bits); real one = imprecise(1, bits); for (int i = ord; i >= 2; i--) q = N + c[i-1] / q; return sqrt(2 * pi_value(bits)/N) * (N/exp(one)) ** N * exp(one/(12*q)); } /* * For positive integers, just use factorial */ if (is_int(n)) { if (n <= 0) raise invalid_argument("gamma of non-positive integer", 0, n); return (floor(n)-1)!; } /* * Use Γ(z) = Γ(z+1)/z * to solve for negative arguments */ if (n < 0) { int i = -floor(n) + 1; real g = gamma(n + i); while (i-- > 0) { g = g / n; n++; } return g; } n = imprecise(n); int bits = precision(n); /* * Smaller numbers take a lot more coefficients to * get the desired number of bits. Make the value * larger, and increase the desired precision to match, * to make the result converge faster. */ if (n < 10000) { int new_bits = bits + 14 - floor(log2(n)); real n_new = imprecise(n, new_bits) + 10000; real g = gamma(n_new); for (int i = 0; i < 10000; i++) { n_new -= 1; g = g / n_new; } return imprecise(g, bits); } /* This is a rough approximation of the * number of coefficients in the fraction * needed to produce the desired precision, it's * good for any value larger than 10000. Larger numbers * could use a smaller number of coefficients, but we * don't know how much smaller */ int ord = ceil(bits / 20); return imprecise(Stieltjes(n-1, ord, bits + 20), bits); } public real(real n) Γ = gamma; } nickle_2.81.orig/gram.c0000664000175000000620000056422213064744544014220 0ustar keithpstaff/* original parser id follows */ /* yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93" */ /* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */ #define YYBYACC 1 #define YYMAJOR 1 #define YYMINOR 9 #define YYPATCH 20140715 #define YYEMPTY (-1) #define yyclearin (yychar = YYEMPTY) #define yyerrok (yyerrflag = 0) #define YYRECOVERING() (yyerrflag != 0) #define YYENOMEM (-2) #define YYEOF 0 #define YYPREFIX "yy" #define YYPURE 0 #line 2 "gram.y" /* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" #include /* * This grammar generates 1 shift/reduce conflict and 4 reduce/reduce: * * 2 reduce/reduce conflicts on: * * *int . func * **int . func * * Is the '*' a dereference operator or a pointer type modifier? * The grammar is ordered to make this a type modifier since * the other way is less common. Use parens when you want this. * * 2 reduce/reduce conflicts on: * * &int . func * &&int . func * * Is the '&' a reference operator or a reference type modifier? * The grammar is ordered to make this a type modifier since * the other way is less common. Use parens when you want this. * * shift/reduce conflict in ASSIGN in initializers * * That's because struct initializers look like assignment * expressions while array initializers permit any expression. * Shift yields struct initialization, so the effect is * to make assignment expressions invalid in array initializers. * (Of course, you can always enclose an assignment in parens.) * (I can't see any obvious way to use operator precedence to * get rid of this: seems like you'd need to duplicate simpleexpr * with different precedence. --BCM) * */ int ignorenl; int notCommand; int seeComment; NamespacePtr LexNamespace; int funcDepth; void ParseError (char *fmt, ...); void yyerror (char *msg); typedef enum _CanonTypeResult { CanonTypeUndefined, CanonTypeForward, CanonTypeDefined, } CanonTypeResult; static Expr * ParseCanonFor (Expr *expr); static CanonTypeResult ParseCanonType (TypePtr type, Bool forwardAllowed); static SymbolPtr ParseNewSymbol (Publish publish, Class class, Type *type, Atom name); #line 72 "gram.y" #ifdef YYSTYPE #undef YYSTYPE_IS_DECLARED #define YYSTYPE_IS_DECLARED 1 #endif #ifndef YYSTYPE_IS_DECLARED #define YYSTYPE_IS_DECLARED 1 typedef union { int ints; Value value; Class class; ArgType *argType; Type *type; Publish publish; ExprPtr expr; Atom atom; DeclListPtr declList; MemListPtr memList; Fulltype fulltype; ArgDecl argDecl; SymbolPtr symbol; NamespacePtr namespace; CodePtr code; Bool bool; AtomListPtr atomList; FuncDecl funcDecl; } YYSTYPE; #endif /* !YYSTYPE_IS_DECLARED */ #line 118 "gram.c" /* compatibility with bison */ #ifdef YYPARSE_PARAM /* compatibility with FreeBSD */ # ifdef YYPARSE_PARAM_TYPE # define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) # else # define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) # endif #else # define YYPARSE_DECL() yyparse(void) #endif /* Parameters sent to lex. */ #ifdef YYLEX_PARAM # define YYLEX_DECL() yylex(void *YYLEX_PARAM) # define YYLEX yylex(YYLEX_PARAM) #else # define YYLEX_DECL() yylex(void) # define YYLEX yylex() #endif /* Parameters sent to yyerror. */ #ifndef YYERROR_DECL #define YYERROR_DECL() yyerror(const char *s) #endif #ifndef YYERROR_CALL #define YYERROR_CALL(msg) yyerror(msg) #endif extern int YYPARSE_DECL(); #define VAR 257 #define EXPR 258 #define ARRAY 259 #define STRUCT 260 #define UNION 261 #define ENUM 262 #define COMP 263 #define HASH 264 #define SEMI 265 #define MOD 266 #define OC 267 #define CC 268 #define DOLLAR 269 #define DOTDOTDOT 270 #define ENDFILE 271 #define GLOBAL 272 #define AUTO 273 #define STATIC 274 #define CONST 275 #define POLY 276 #define INTEGER 277 #define NATURAL 278 #define RATIONAL 279 #define REAL 280 #define STRING 281 #define FOREIGN 282 #define FILET 283 #define MUTEX 284 #define SEMAPHORE 285 #define CONTINUATION 286 #define THREAD 287 #define VOID 288 #define BOOL 289 #define FUNCTION 290 #define FUNC 291 #define EXCEPTION 292 #define RAISE 293 #define TYPEDEF 294 #define IMPORT 295 #define NEW 296 #define ANONINIT 297 #define NAMESPACE 298 #define PUBLIC 299 #define PROTECTED 300 #define EXTEND 301 #define WHILE 302 #define DO 303 #define FOR 304 #define SWITCH 305 #define BREAK 306 #define CONTINUE 307 #define RETURNTOK 308 #define FORK 309 #define CASE 310 #define DEFAULT 311 #define TWIXT 312 #define NAME 313 #define TYPENAME 314 #define NAMESPACENAME 315 #define COMMAND 316 #define NAMECOMMAND 317 #define TEN_NUM 318 #define OCTAL0_NUM 319 #define OCTAL_NUM 320 #define BINARY_NUM 321 #define HEX_NUM 322 #define TEN_FLOAT 323 #define OCTAL0_FLOAT 324 #define OCTAL_FLOAT 325 #define BINARY_FLOAT 326 #define HEX_FLOAT 327 #define CHAR_CONST 328 #define STRING_CONST 329 #define POLY_CONST 330 #define THREAD_CONST 331 #define COMMENT_CONST 332 #define VOIDVAL 333 #define BOOLVAL 334 #define DARROW 335 #define ISTYPE 336 #define HASMEMBER 337 #define POUND 338 #define COMMA 339 #define ASSIGN 340 #define ASSIGNPLUS 341 #define ASSIGNMINUS 342 #define ASSIGNTIMES 343 #define ASSIGNDIVIDE 344 #define ASSIGNDIV 345 #define ASSIGNMOD 346 #define ASSIGNPOW 347 #define ASSIGNSHIFTL 348 #define ASSIGNSHIFTR 349 #define ASSIGNLXOR 350 #define ASSIGNLAND 351 #define ASSIGNLOR 352 #define ASSIGNOR 353 #define ASSIGNAND 354 #define QUEST 355 #define COLON 356 #define OR 357 #define AND 358 #define LOR 359 #define LXOR 360 #define LAND 361 #define EQ 362 #define NE 363 #define LT 364 #define GT 365 #define LE 366 #define GE 367 #define SHIFTL 368 #define SHIFTR 369 #define PLUS 370 #define MINUS 371 #define TIMES 372 #define DIVIDE 373 #define DIV 374 #define POW 375 #define STARSTAR 376 #define POW2 377 #define POW3 378 #define UNIONCAST 379 #define UMINUS 380 #define BANG 381 #define FACT 382 #define LNOT 383 #define INC 384 #define DEC 385 #define STAR 386 #define AMPER 387 #define THREADID 388 #define OS 389 #define CS 390 #define DOT 391 #define ARROW 392 #define STAROS 393 #define CALL 394 #define OP 395 #define CP 396 #define POINTER 397 #define COLONCOLON 398 #define IF 399 #define TRY 400 #define NONL 401 #define ELSE 402 #define CATCH 403 #define NL 404 #define YYERRCODE 256 typedef short YYINT; static const YYINT yylhs[] = { -1, 0, 0, 96, 96, 99, 99, 99, 100, 101, 98, 102, 103, 103, 104, 104, 105, 105, 97, 97, 97, 97, 97, 97, 97, 3, 3, 5, 5, 4, 7, 7, 7, 6, 6, 27, 27, 1, 1, 2, 2, 28, 28, 60, 60, 106, 107, 8, 108, 109, 14, 14, 17, 17, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 111, 16, 16, 16, 16, 70, 70, 19, 19, 18, 12, 12, 13, 9, 9, 112, 10, 20, 20, 110, 110, 113, 81, 82, 82, 21, 22, 22, 23, 23, 24, 25, 25, 26, 26, 37, 37, 33, 33, 35, 35, 40, 40, 34, 34, 36, 43, 38, 39, 39, 39, 41, 41, 41, 42, 42, 42, 46, 46, 46, 46, 46, 46, 45, 45, 45, 45, 45, 45, 47, 47, 47, 47, 47, 47, 44, 44, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 49, 49, 50, 50, 52, 52, 53, 53, 54, 54, 56, 56, 55, 55, 55, 55, 57, 57, 58, 58, 59, 59, 61, 61, 62, 62, 63, 63, 66, 64, 64, 65, 65, 67, 67, 68, 68, 69, 69, 71, 71, 77, 77, 72, 72, 73, 73, 75, 75, 76, 76, 11, 114, 11, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 79, 79, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 80, 80, 80, 80, 80, 83, 83, 83, 84, 84, 29, 29, 30, 30, 31, 32, 85, 85, 86, 86, 87, 87, 87, 88, 89, 89, 90, 90, 91, 91, 92, 93, 93, 94, 94, 94, 94, 95, 95, 95, 95, }; static const YYINT yylen[] = { 2, 2, 0, 1, 3, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 4, 6, 4, 6, 6, 1, 1, 1, 0, 3, 1, 2, 1, 1, 1, 3, 0, 2, 1, 2, 1, 1, 3, 3, 2, 1, 1, 0, 0, 3, 2, 2, 2, 0, 7, 9, 1, 1, 3, 9, 10, 9, 9, 10, 2, 2, 3, 2, 1, 4, 10, 6, 6, 7, 0, 9, 6, 2, 11, 3, 1, 1, 3, 4, 2, 0, 7, 1, 1, 0, 2, 1, 4, 1, 1, 0, 2, 1, 0, 3, 2, 0, 4, 3, 3, 2, 0, 7, 3, 1, 0, 3, 1, 3, 1, 1, 1, 4, 2, 1, 1, 4, 3, 4, 4, 2, 2, 0, 4, 3, 2, 2, 4, 4, 4, 4, 0, 2, 2, 2, 2, 2, 3, 1, 4, 4, 4, 3, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 1, 3, 1, 3, 1, 4, 0, 4, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 3, 2, 3, 2, 2, 1, 3, 2, 1, 3, 2, 2, 1, 1, 0, 1, 0, 1, 2, 1, 3, 1, 0, 3, 1, 1, 0, 3, 2, 3, 0, 2, 3, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 6, 8, 8, 8, 3, 6, 2, 1, 3, 3, 4, 4, 4, 6, 6, 3, 3, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 5, 9, 2, 1, 3, 1, 1, 0, 3, 1, 1, 1, 1, 2, 0, 4, 3, 1, 3, 2, 1, 1, 4, 3, 1, 3, 3, 4, 4, 1, 1, 1, 2, }; static const YYINT yydefred[] = { 2, 0, 10, 24, 23, 1, 3, 0, 0, 0, 0, 0, 66, 0, 45, 0, 176, 177, 178, 179, 149, 150, 151, 152, 153, 161, 154, 155, 156, 157, 158, 159, 160, 8, 0, 182, 183, 185, 8, 8, 8, 8, 0, 0, 0, 0, 8, 43, 36, 0, 0, 0, 258, 260, 259, 261, 262, 263, 265, 264, 266, 267, 268, 269, 270, 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 0, 8, 8, 257, 55, 10, 54, 46, 9, 146, 0, 93, 45, 0, 0, 0, 0, 141, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 6, 7, 5, 4, 0, 0, 0, 307, 309, 308, 310, 311, 220, 48, 279, 290, 0, 0, 0, 45, 45, 45, 45, 62, 63, 0, 0, 0, 0, 0, 201, 0, 0, 45, 42, 10, 207, 0, 10, 0, 25, 0, 0, 0, 138, 0, 139, 0, 0, 136, 0, 137, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 45, 0, 0, 9, 75, 35, 0, 37, 0, 0, 8, 0, 0, 204, 0, 45, 0, 0, 12, 128, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 174, 0, 8, 65, 0, 0, 0, 306, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 242, 228, 230, 232, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 64, 0, 0, 0, 0, 34, 30, 32, 31, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 281, 0, 0, 79, 83, 20, 56, 41, 86, 46, 85, 0, 95, 94, 0, 0, 0, 120, 0, 0, 0, 140, 277, 167, 0, 0, 0, 0, 0, 187, 0, 0, 0, 129, 138, 139, 136, 137, 0, 0, 127, 0, 0, 0, 0, 0, 10, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 289, 0, 0, 0, 211, 0, 0, 0, 47, 50, 45, 0, 142, 0, 143, 0, 144, 122, 0, 0, 0, 0, 0, 0, 14, 0, 209, 0, 27, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 89, 88, 0, 119, 0, 0, 193, 0, 121, 0, 0, 344, 346, 345, 124, 118, 0, 8, 93, 0, 0, 0, 0, 0, 190, 186, 199, 0, 189, 145, 45, 114, 0, 0, 0, 0, 0, 0, 126, 44, 72, 0, 0, 284, 283, 0, 214, 285, 49, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 21, 22, 0, 0, 45, 164, 45, 45, 168, 0, 46, 0, 80, 0, 82, 0, 197, 0, 196, 347, 0, 0, 0, 0, 0, 0, 324, 0, 332, 0, 339, 326, 115, 0, 0, 133, 130, 166, 131, 132, 188, 0, 9, 0, 113, 0, 0, 9, 0, 19, 0, 213, 0, 170, 172, 69, 0, 0, 0, 0, 0, 0, 286, 287, 0, 0, 0, 0, 273, 0, 45, 0, 195, 0, 0, 334, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 46, 0, 0, 46, 70, 111, 9, 40, 74, 0, 0, 46, 0, 77, 46, 46, 0, 0, 0, 46, 327, 0, 46, 0, 46, 312, 0, 0, 90, 0, 341, 321, 322, 0, 0, 333, 0, 323, 0, 0, 331, 330, 0, 0, 338, 337, 219, 0, 217, 93, 71, 0, 0, 9, 46, 9, 9, 0, 0, 46, 0, 0, 328, 276, 274, 313, 275, 0, 93, 0, 0, 0, 343, 315, 0, 0, 9, 46, 0, 57, 9, 59, 60, 0, 0, 97, 98, 46, 53, 0, 0, 319, 9, 73, 9, 45, 0, 46, 0, 58, 0, 101, 9, 46, 0, 318, 46, 68, 61, 0, 0, 102, 103, 100, 76, 84, 317, 0, 0, 106, 316, 107, 0, 0, 46, 105, }; static const YYINT yydgoto[] = { 1, 82, 447, 145, 146, 147, 148, 285, 83, 305, 306, 557, 408, 484, 259, 260, 85, 86, 87, 300, 411, 572, 616, 617, 634, 654, 655, 88, 89, 663, 589, 590, 626, 268, 182, 443, 183, 679, 90, 91, 444, 315, 92, 426, 93, 138, 191, 95, 321, 290, 323, 96, 291, 264, 266, 97, 206, 98, 99, 100, 101, 192, 327, 328, 310, 416, 428, 417, 438, 466, 467, 261, 142, 143, 103, 370, 371, 104, 257, 121, 119, 177, 309, 581, 421, 495, 496, 576, 422, 497, 498, 545, 423, 499, 500, 501, 5, 6, 8, 110, 311, 173, 7, 188, 392, 551, 120, 374, 105, 375, 106, 518, 307, 178, 559, }; static const YYINT yysindex[] = { 0, -242, 0, 0, 0, 0, 0, 1203, -233, -198, -185, -123, 0, 327, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, 0, 0, 0, 0, 0, -69, 60, 5386, 6574, 0, 0, 0, -140, 6574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -63, -60, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, -18, 0, 5254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, -87, 62, -34, -15, 0, 5088, 127, 142, 87, 0, -218, 7042, 67, 1339, 122, 0, 0, 0, 0, 5088, 5088, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 57, -165, 0, 0, 0, 0, 0, 0, -185, -123, 152, 142, 205, 0, -46, 2124, 0, 0, 0, 0, 6638, 0, 136, 0, 159, 6574, 6574, 0, 866, 0, 866, 866, 0, 866, 0, 866, 866, 866, 866, 866, 0, 5914, 91, 16, 99, 0, 1475, 94, 0, 0, 0, 107, 0, 243, 180, 0, 203, 123, 0, 185, 0, 5088, 216, 0, 0, 6046, 3788, 0, -15, -140, 5088, 5088, 5088, 5088, 5088, 25, 94, 167, 0, 0, 0, 0, 5088, 0, 0, 5386, 131, 6574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 6574, 0, 0, 0, 0, 0, 6574, 225, 228, 6574, 6574, 6574, 6574, 0, 1339, 277, 0, 128, 276, 128, 278, 206, 279, 155, 6574, 156, 1339, 161, 166, 0, 0, 168, 295, 6574, 295, 0, 0, 0, 0, 164, 6695, 6752, 6574, 14, -290, 176, 6809, 0, 254, 0, 0, 182, 1339, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 183, 5088, 189, 0, 6178, 237, 192, 0, 0, 0, 68, 198, 251, -172, 201, 0, -253, 207, -162, 0, 0, 0, 0, 0, -53, 107, 0, 281, 3999, -200, 94, 153, 0, 0, 845, 6865, 2237, 2350, 2463, 2576, 2689, 589, 589, 440, 440, 440, 440, 316, 316, 736, 736, 845, 845, 845, 845, 211, 0, 0, 214, 2010, 209, 0, 7042, 7042, 338, 0, 0, 0, 343, 0, 347, 0, 128, 0, 0, 217, 5386, 314, 5386, 5386, 5386, 0, 220, 0, 221, 0, 0, 5088, 307, 226, 261, 227, 241, 6574, 242, 372, 5386, 375, 248, 0, 0, 0, 300, 0, 339, 167, 0, -135, 0, 5518, 7042, 0, 0, 0, 0, 0, 152, 0, 0, -15, -15, 383, -15, -15, 0, 0, 0, 5088, 0, 0, 0, 0, 0, 389, 317, -261, 319, 394, 0, 0, 0, 258, 6574, 0, 0, 6574, 0, 0, 0, 273, 5088, 5088, 0, 404, 274, 280, 406, 282, 284, 407, 0, 0, -37, 286, 0, 0, 0, 0, 0, 6574, 0, 287, 0, -200, 0, 6574, 0, 5088, 0, 0, 334, 6178, -18, 363, 6926, 346, 0, 352, 0, 356, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 301, 0, 165, 0, 412, -200, 0, 436, 0, 2124, 0, 5386, 0, 0, 0, 1339, 5386, 5386, 1339, 308, 5386, 0, 0, 437, 443, 445, 866, 0, 1339, 0, 1613, 0, 6178, 7042, 0, 0, 400, 374, 6178, 6178, 446, 6310, 447, -216, 449, 0, 0, 380, 308, 0, 0, 0, 0, 0, 0, 1339, 325, 0, 326, 0, 0, 0, 100, 330, 5650, 0, 0, 6442, 0, 5782, 0, 0, 321, 192, 0, 7042, 0, 0, 0, 408, 6178, 0, 7042, 0, 460, 6926, 0, 0, 334, 363, 0, 0, 0, 6574, 0, 0, 0, 465, 308, 0, 0, 0, 0, 5386, 410, 0, 100, 1339, 0, 0, 0, 0, 0, 1339, 0, 349, 400, 7042, 0, 0, 7042, 534, 0, 0, 181, 0, 0, 0, 0, 444, 1339, 0, 0, 0, 0, 308, -234, 0, 0, 0, 0, 0, 448, 0, 181, 0, 1339, 0, 0, 0, 6178, 0, 0, 0, 0, 488, 1339, 0, 0, 0, 0, 0, 0, 539, 502, 0, 0, 0, 463, 1339, 0, 0, }; static const YYINT yyrindex[] = { 0, 1067, 0, 0, 0, 0, 0, 219, 0, 0, 515, 517, 0, 0, 0, 1548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 532, 0, 0, 0, 1680, -252, -149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 532, 532, 532, 532, 532, 532, 532, 532, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 328, 0, -267, 528, 891, 0, 0, 424, -245, -235, 97, 0, 0, 0, 0, 0, -57, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 931, 0, 0, 543, 5066, 0, 0, 0, 0, -176, 0, -173, 0, 0, 532, 532, 0, 2076, 0, 2190, 2304, 0, 2418, 0, 2532, 2646, 2760, 2874, 2988, 0, 532, 0, -228, 0, 0, 219, 765, 0, 0, 0, 1680, 0, -133, 15, 0, 0, -52, 0, -220, 0, 0, 0, 0, 0, -250, 0, 0, 328, 0, 0, 0, 0, 0, 0, 0, 74, -265, 0, 0, 0, 0, -267, 0, 0, 532, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 0, 0, 0, 0, 0, 532, 0, 0, 532, -249, 532, 532, 0, 145, 0, 0, 0, 0, 0, 0, -38, 0, 0, -247, 0, 219, 0, 0, 0, 0, 0, 432, 532, 432, 0, 0, 0, 0, -244, 0, 0, -85, 543, 0, 0, 452, 0, 0, 240, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, -282, 0, 0, 532, -55, 0, 0, 0, 0, 543, 0, 453, 0, 0, 0, -73, 0, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 3216, 0, 5043, 4949, 4924, 4828, 4800, 4602, 4701, 4190, 4293, 4396, 4499, 3980, 4085, 3766, 3873, 3326, 3436, 3546, 3656, 0, 0, 0, 0, 442, 0, 0, -211, -67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 0, -181, 532, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 6985, 0, 532, 0, 469, 0, 0, 0, 0, 0, 0, -171, 0, 442, 0, 532, 38, 0, 0, 0, 0, 0, 0, 0, 0, 328, 328, 0, 328, 328, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 579, 0, 581, 0, 0, 0, 0, 0, 532, 0, 0, 532, 0, 0, 0, 0, -57, 17, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 532, 0, 535, 0, 0, 1876, 532, 536, 1746, 30, 218, 0, 583, 0, 583, 0, 0, 0, 0, -72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5156, 0, 532, 0, 0, 0, 219, 532, -181, 219, 0, -195, 0, 0, 1812, 0, 1944, 3102, 0, 219, 0, 0, 0, 532, -139, 0, 0, 0, 0, 532, 105, 588, 135, 0, 591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 593, 0, 532, 0, 0, 532, 0, 532, 0, 0, 614, 0, 0, 11, 0, 0, 0, 467, 532, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 593, 219, 0, 0, 0, 0, 0, 219, 0, 0, 0, 24, 0, 0, -182, 0, 0, 0, 594, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 594, 0, 145, 0, 0, 0, 532, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 145, 0, 0, }; static const YYINT yygindex[] = { 0, -19, 350, 0, 0, 584, 0, 0, -78, 0, 0, 0, 0, 0, -232, -3, 697, 0, 0, 0, 0, 0, 255, 0, 0, 222, 0, 0, 112, 0, 257, 0, 0, -239, 466, -411, 0, 0, 0, 0, 0, 0, -28, 0, -94, -7, -156, 0, 0, 689, 0, 0, -184, 450, 483, 212, 0, 0, 43, 0, -82, 434, 474, 0, 519, 462, 368, 0, -359, -42, 441, 12, 694, 692, 5, 0, 513, 0, 0, 0, 961, -420, 0, 0, -8, 0, -538, 0, 454, 0, 425, 430, 0, 0, 429, -279, 0, 0, -75, 0, 92, -166, 0, -160, 707, 7, 187, 21, -508, -326, 0, 0, 0, 0, 0, }; #define YYTABLESIZE 7437 static const YYINT yytable[] = { 94, 166, 136, 200, 84, 324, 302, 176, 504, 171, 456, 301, 594, 208, 2, 124, 134, 263, 265, 102, 205, 29, 573, 148, 378, 147, 380, 210, 376, 3, 203, 148, 107, 14, 515, 424, 329, 94, 108, 148, 336, 148, 148, 176, 148, 125, 148, 208, 147, 400, 139, 134, 441, 514, 218, 144, 137, 218, 488, 218, 434, 151, 153, 147, 156, 158, 407, 278, 365, 111, 280, 368, 167, 152, 154, 155, 157, 159, 160, 161, 162, 163, 112, 215, 202, 13, 215, 135, 215, 210, 201, 168, 28, 205, 205, 29, 148, 599, 94, 198, 401, 635, 562, 203, 201, 201, 661, 172, 436, 185, 148, 205, 340, 47, 194, 49, 26, 185, 125, 125, 209, 203, 135, 673, 218, 123, 480, 218, 218, 335, 126, 127, 128, 129, 87, 436, 125, 148, 140, 147, 163, 412, 147, 462, 113, 218, 125, 212, 47, 208, 175, 205, 208, 215, 286, 287, 215, 215, 289, 205, 29, 203, 4, 94, 34, 34, 34, 431, 198, 203, 292, 109, 169, 170, 215, 600, 125, 437, 317, 218, 448, 134, 320, 326, 125, 218, 632, 330, 331, 332, 333, 334, 595, 218, 292, 216, 130, 191, 206, 201, 335, 202, 94, 180, 487, 646, 148, 87, 215, 199, 116, 171, 546, 117, 215, 202, 344, 414, 432, 478, 210, 342, 215, 199, 199, 198, 181, 110, 210, 410, 110, 28, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 135, 94, 165, 26, 148, 292, 141, 450, 292, 369, 372, 373, 587, 94, 191, 451, 9, 387, 546, 206, 206, 505, 506, 144, 508, 509, 179, 340, 96, 156, 96, 116, 144, 173, 117, 117, 117, 206, 642, 94, 342, 157, 337, 338, 339, 199, 325, 341, 325, 116, 199, 123, 415, 165, 199, 199, 199, 199, 199, 205, 629, 271, 272, 273, 274, 185, 199, 420, 446, 13, 147, 191, 185, 131, 409, 277, 668, 206, 148, 445, 149, 185, 608, 150, 185, 206, 558, 174, 335, 116, 202, 439, 13, 186, 561, 205, 469, 116, 340, 565, 117, 184, 377, 96, 297, 186, 134, 532, 134, 134, 134, 342, 13, 51, 263, 265, 148, 325, 187, 316, 164, 16, 189, 16, 123, 123, 134, 94, 190, 94, 94, 94, 185, 207, 185, 13, 148, 181, 472, 181, 181, 414, 123, 181, 148, 607, 464, 94, 137, 468, 137, 16, 399, 186, 258, 294, 292, 658, 614, 615, 295, 51, 16, 17, 18, 19, 481, 202, 187, 203, 204, 199, 494, 670, 148, 262, 113, 135, 326, 135, 135, 135, 123, 676, 148, 181, 185, 181, 181, 267, 123, 181, 636, 269, 638, 639, 681, 135, 199, 125, 270, 201, 201, 51, 51, 520, 429, 186, 369, 47, 174, 175, 540, 275, 47, 650, 449, 81, 276, 656, 282, 283, 284, 281, 36, 36, 441, 514, 415, 605, 405, 664, 537, 665, 17, 293, 17, 574, 541, 652, 653, 671, 134, 296, 544, 446, 187, 134, 134, 538, 113, 134, 553, 303, 555, 45, 304, 199, 148, 181, 308, 181, 181, 94, 312, 181, 313, 94, 94, 94, 94, 568, 94, 314, 571, 579, 582, 318, 145, 145, 94, 36, 567, 343, 583, 185, 366, 569, 137, 367, 208, 137, 379, 382, 381, 383, 586, 199, 384, 386, 36, 145, 544, 593, 388, 596, 36, 94, 391, 389, 396, 390, 459, 135, 402, 404, 660, 662, 135, 135, 199, 199, 135, 14, 425, 406, 603, 413, 596, 606, 211, 593, 418, 593, 134, 427, 430, 610, 400, 433, 612, 613, 440, 125, 628, 620, 134, 199, 621, 453, 623, 435, 454, 457, 458, 94, 460, 631, 145, 94, 461, 463, 52, 644, 465, 94, 134, 134, 473, 645, 474, 476, 470, 471, 640, 511, 125, 145, 145, 145, 637, 475, 94, 145, 145, 477, 479, 419, 485, 134, 134, 482, 145, 114, 115, 116, 117, 118, 94, 483, 486, 507, 512, 651, 513, 135, 516, 517, 94, 534, 519, 535, 536, 659, 593, 134, 522, 525, 526, 528, 531, 94, 543, 527, 548, 563, 529, 547, 530, 672, 533, 539, 674, 550, 241, 242, 243, 244, 245, 552, 246, 247, 248, 554, 190, 249, 134, 556, 250, 251, 682, 566, 575, 252, 211, 253, 254, 255, 578, 256, 580, 588, 591, 598, 436, 602, 134, 134, 604, 609, 611, 624, 134, 81, 618, 584, 630, 81, 81, 81, 134, 633, 81, 81, 81, 81, 81, 647, 81, 81, 81, 81, 81, 81, 81, 627, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 13, 641, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 649, 657, 675, 81, 81, 667, 81, 81, 677, 239, 240, 241, 242, 243, 244, 245, 678, 246, 247, 248, 680, 91, 249, 92, 148, 250, 251, 184, 81, 10, 252, 81, 253, 254, 255, 147, 256, 15, 9, 200, 666, 81, 81, 169, 162, 112, 81, 39, 78, 148, 45, 81, 17, 81, 81, 81, 211, 200, 320, 81, 16, 81, 99, 104, 108, 81, 395, 564, 299, 81, 81, 52, 81, 643, 81, 52, 52, 52, 669, 322, 52, 52, 52, 52, 52, 648, 52, 52, 52, 52, 52, 52, 52, 502, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 523, 510, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 524, 560, 503, 52, 52, 542, 52, 52, 625, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 385, 246, 247, 248, 521, 570, 249, 393, 52, 250, 251, 52, 122, 597, 252, 592, 253, 254, 255, 601, 256, 52, 52, 394, 577, 0, 52, 0, 0, 0, 0, 52, 0, 52, 52, 52, 0, 0, 211, 52, 0, 52, 0, 0, 0, 52, 0, 0, 0, 52, 52, 0, 0, 52, 52, 0, 0, 13, 0, 0, 0, 13, 13, 13, 0, 0, 13, 13, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 13, 13, 0, 13, 13, 0, 0, 0, 0, 0, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 0, 0, 250, 251, 0, 13, 0, 252, 13, 253, 254, 255, 0, 256, 0, 0, 0, 0, 13, 13, 0, 0, 0, 13, 0, 0, 0, 0, 13, 0, 13, 13, 13, 175, 175, 175, 13, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13, 13, 0, 175, 175, 0, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 0, 180, 0, 180, 180, 0, 0, 180, 0, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, 175, 175, 175, 0, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 246, 247, 248, 0, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 175, 175, 175, 249, 0, 175, 250, 251, 175, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 175, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 175, 0, 0, 175, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 11, 11, 11, 0, 0, 11, 11, 11, 175, 11, 0, 0, 11, 11, 11, 11, 11, 11, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 0, 11, 11, 0, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 0, 0, 0, 11, 0, 0, 0, 0, 11, 0, 11, 11, 11, 0, 0, 0, 11, 0, 11, 0, 0, 0, 11, 9, 10, 11, 11, 11, 12, 13, 14, 0, 15, 0, 0, 16, 17, 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 34, 0, 0, 0, 0, 0, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 0, 0, 0, 79, 9, 10, 11, 80, 81, 12, 13, 14, 0, 15, 0, 0, 16, 17, 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 34, 0, 0, 0, 0, 0, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, 46, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 0, 0, 0, 79, 9, 10, 11, 80, 81, 12, 13, 298, 0, 15, 0, 0, 16, 17, 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 34, 0, 0, 0, 0, 0, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, 46, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 291, 291, 0, 291, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 0, 0, 0, 79, 0, 0, 0, 80, 81, 0, 0, 585, 211, 0, 0, 0, 291, 0, 0, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 0, 291, 291, 291, 0, 0, 291, 0, 0, 291, 291, 0, 0, 0, 291, 291, 291, 291, 291, 0, 291, 291, 44, 44, 0, 44, 0, 44, 0, 291, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 280, 0, 280, 44, 280, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 44, 0, 0, 44, 0, 0, 44, 44, 0, 0, 0, 44, 44, 44, 44, 44, 0, 44, 44, 329, 329, 0, 329, 280, 329, 0, 44, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 0, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 0, 280, 280, 280, 0, 0, 280, 0, 0, 280, 280, 0, 0, 0, 280, 0, 280, 280, 280, 0, 280, 43, 0, 43, 0, 43, 329, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 329, 329, 329, 0, 0, 329, 0, 0, 329, 329, 0, 0, 0, 329, 329, 329, 329, 329, 0, 329, 329, 314, 314, 43, 314, 0, 314, 43, 329, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, 0, 0, 43, 0, 0, 43, 43, 0, 0, 0, 43, 0, 43, 43, 43, 0, 43, 0, 0, 0, 0, 211, 0, 0, 314, 436, 0, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 0, 314, 314, 314, 0, 0, 314, 0, 0, 314, 314, 0, 0, 0, 314, 314, 314, 314, 314, 0, 314, 314, 224, 224, 0, 224, 0, 224, 0, 314, 455, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 211, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 224, 0, 0, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 0, 224, 224, 224, 223, 223, 0, 223, 0, 223, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 227, 224, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 211, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 223, 0, 0, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 0, 223, 223, 223, 225, 225, 0, 225, 0, 225, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 223, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 211, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, 225, 0, 0, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 0, 225, 225, 225, 221, 221, 0, 221, 0, 221, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 225, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 211, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, 0, 221, 0, 0, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 0, 221, 221, 221, 222, 222, 0, 222, 0, 222, 0, 0, 0, 0, 0, 221, 0, 0, 0, 0, 0, 221, 0, 0, 0, 0, 0, 0, 0, 221, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 211, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 222, 0, 0, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 0, 222, 222, 222, 227, 227, 0, 227, 0, 227, 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 222, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 211, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 0, 227, 227, 227, 226, 226, 0, 226, 0, 226, 0, 0, 0, 0, 0, 227, 0, 0, 0, 0, 0, 227, 0, 0, 0, 0, 0, 0, 0, 227, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 0, 226, 226, 226, 229, 229, 0, 229, 0, 229, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 0, 229, 229, 229, 231, 231, 0, 231, 0, 231, 0, 0, 0, 0, 0, 229, 0, 0, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 0, 231, 231, 231, 278, 278, 0, 278, 0, 278, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 0, 278, 278, 278, 239, 239, 0, 239, 0, 239, 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 236, 236, 0, 236, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 0, 237, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 0, 238, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 240, 240, 0, 240, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 234, 0, 0, 234, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 9, 132, 133, 0, 240, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 48, 193, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235, 0, 0, 235, 0, 235, 0, 0, 194, 0, 0, 195, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 196, 0, 234, 0, 197, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 0, 0, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 243, 0, 0, 243, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 9, 132, 133, 0, 235, 0, 0, 0, 0, 0, 235, 0, 0, 0, 0, 0, 20, 21, 235, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 441, 442, 193, 243, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 244, 0, 0, 244, 0, 244, 0, 194, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 196, 0, 0, 0, 197, 243, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 253, 0, 0, 253, 0, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 0, 0, 254, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 256, 0, 0, 256, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 251, 0, 0, 251, 0, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 252, 0, 0, 252, 0, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 247, 0, 0, 247, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 246, 0, 0, 246, 252, 246, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 0, 246, 0, 0, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 248, 247, 0, 248, 0, 248, 0, 247, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 249, 246, 249, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 249, 0, 0, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 250, 0, 0, 250, 0, 250, 248, 0, 0, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 233, 0, 0, 233, 0, 233, 0, 0, 249, 0, 0, 0, 0, 0, 249, 0, 0, 9, 132, 133, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 250, 0, 0, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 233, 48, 193, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 245, 233, 0, 245, 0, 245, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 194, 250, 0, 195, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 196, 0, 233, 0, 197, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 0, 245, 0, 9, 132, 133, 0, 0, 0, 13, 14, 0, 15, 0, 0, 16, 17, 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 245, 0, 0, 0, 0, 0, 245, 35, 36, 0, 0, 0, 0, 0, 245, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 165, 0, 78, 9, 132, 133, 79, 0, 0, 13, 0, 0, 15, 0, 0, 16, 17, 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 9, 132, 133, 79, 0, 0, 13, 419, 489, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 490, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 491, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 492, 0, 493, 9, 132, 133, 79, 0, 0, 13, 0, 619, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 491, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 9, 132, 133, 79, 0, 0, 13, 419, 622, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 492, 0, 78, 9, 132, 133, 79, 0, 0, 13, 0, 0, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 288, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 164, 78, 9, 132, 133, 79, 0, 0, 13, 0, 0, 15, 319, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 288, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 9, 132, 133, 79, 0, 0, 13, 419, 0, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 9, 132, 133, 79, 0, 0, 13, 0, 0, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 491, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 77, 0, 78, 9, 132, 133, 79, 0, 0, 13, 419, 0, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 0, 0, 492, 0, 78, 9, 132, 133, 79, 0, 0, 13, 0, 0, 15, 0, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47, 48, 49, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 211, 0, 0, 64, 65, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 72, 0, 0, 0, 0, 73, 0, 74, 75, 76, 0, 211, 0, 77, 0, 78, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 279, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 211, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 397, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 211, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 398, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 211, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 403, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 0, 211, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 452, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 0, 0, 250, 251, 277, 0, 0, 252, 0, 253, 254, 255, 0, 256, 549, 0, 0, 0, 0, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 211, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 0, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 0, 277, 277, 277, 0, 0, 277, 0, 0, 277, 277, 0, 0, 0, 277, 0, 277, 277, 277, 0, 277, 0, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 0, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, 0, 0, 249, 0, 0, 250, 251, 0, 0, 0, 252, 0, 253, 254, 255, 0, 256, }; static const YYINT yycheck[] = { 7, 79, 44, 97, 7, 189, 172, 89, 428, 84, 369, 171, 550, 265, 256, 34, 44, 111, 112, 7, 265, 265, 530, 290, 263, 290, 265, 102, 260, 271, 265, 313, 265, 267, 445, 314, 192, 44, 271, 291, 200, 291, 291, 125, 291, 265, 313, 265, 313, 339, 45, 79, 313, 314, 265, 50, 44, 268, 417, 270, 313, 68, 69, 291, 71, 72, 298, 142, 252, 267, 145, 255, 79, 68, 69, 70, 71, 72, 73, 74, 75, 76, 267, 265, 265, 313, 268, 44, 270, 265, 97, 79, 265, 338, 339, 339, 291, 313, 105, 270, 390, 609, 513, 338, 111, 112, 340, 86, 270, 370, 291, 356, 206, 313, 396, 315, 265, 370, 338, 339, 338, 356, 79, 661, 335, 33, 405, 338, 339, 268, 38, 39, 40, 41, 267, 270, 356, 404, 46, 404, 390, 307, 313, 382, 267, 356, 34, 396, 313, 396, 315, 396, 404, 335, 149, 150, 338, 339, 165, 404, 404, 396, 404, 170, 313, 314, 315, 339, 339, 404, 165, 404, 80, 81, 356, 391, 396, 339, 185, 390, 340, 209, 189, 190, 404, 396, 606, 194, 195, 196, 197, 198, 551, 404, 189, 267, 265, 270, 265, 206, 339, 396, 209, 290, 339, 625, 291, 340, 390, 97, 265, 268, 491, 265, 396, 396, 211, 311, 390, 403, 396, 209, 404, 111, 112, 396, 313, 265, 404, 307, 268, 404, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 209, 260, 339, 404, 313, 252, 398, 341, 255, 256, 257, 258, 543, 272, 339, 342, 340, 272, 549, 338, 339, 429, 430, 270, 432, 433, 91, 268, 265, 288, 267, 338, 279, 268, 338, 339, 340, 356, 616, 298, 268, 288, 202, 203, 204, 185, 268, 207, 270, 356, 190, 265, 311, 390, 194, 195, 196, 197, 198, 99, 591, 126, 127, 128, 129, 370, 206, 314, 339, 290, 291, 396, 370, 265, 305, 140, 654, 396, 313, 338, 395, 370, 566, 395, 370, 404, 504, 314, 315, 396, 265, 396, 313, 391, 512, 135, 390, 404, 339, 517, 404, 291, 262, 340, 169, 391, 386, 396, 388, 389, 390, 339, 290, 268, 460, 461, 291, 339, 404, 184, 390, 268, 389, 270, 338, 339, 406, 386, 395, 388, 389, 390, 370, 298, 370, 313, 291, 292, 397, 294, 295, 487, 356, 298, 291, 563, 386, 406, 388, 389, 390, 268, 390, 391, 339, 391, 403, 641, 310, 311, 396, 268, 272, 273, 274, 275, 406, 292, 404, 294, 295, 311, 419, 657, 291, 305, 265, 386, 437, 388, 389, 390, 396, 667, 291, 292, 370, 294, 295, 313, 404, 298, 610, 313, 612, 613, 680, 406, 338, 339, 395, 460, 461, 310, 311, 452, 390, 391, 455, 313, 314, 315, 483, 313, 313, 633, 315, 0, 265, 637, 313, 314, 315, 339, 313, 314, 313, 314, 487, 559, 295, 649, 479, 651, 268, 396, 270, 531, 485, 310, 311, 659, 522, 396, 491, 516, 404, 527, 528, 480, 339, 531, 497, 398, 499, 267, 265, 397, 291, 292, 332, 294, 295, 522, 313, 298, 395, 526, 527, 528, 529, 526, 531, 340, 529, 535, 536, 313, 290, 291, 539, 370, 522, 404, 539, 370, 313, 527, 528, 313, 265, 531, 268, 339, 268, 268, 543, 437, 395, 395, 389, 313, 549, 550, 395, 552, 395, 566, 265, 395, 398, 395, 377, 522, 390, 313, 646, 647, 527, 528, 460, 461, 531, 267, 339, 395, 557, 396, 575, 560, 266, 578, 395, 580, 614, 395, 390, 568, 339, 390, 571, 572, 313, 483, 591, 576, 270, 487, 579, 390, 581, 396, 390, 396, 268, 614, 265, 604, 370, 618, 265, 396, 0, 618, 302, 624, 290, 291, 313, 624, 396, 396, 404, 404, 614, 440, 516, 389, 390, 391, 611, 372, 641, 395, 396, 396, 396, 267, 340, 313, 314, 268, 404, 318, 319, 320, 321, 322, 657, 403, 313, 270, 265, 634, 339, 614, 339, 265, 667, 474, 404, 476, 477, 644, 661, 339, 395, 265, 396, 265, 265, 680, 340, 395, 313, 265, 396, 492, 396, 660, 396, 396, 663, 339, 370, 371, 372, 373, 374, 339, 376, 377, 378, 339, 395, 381, 370, 396, 384, 385, 681, 267, 267, 389, 266, 391, 392, 393, 267, 395, 267, 313, 340, 268, 270, 268, 390, 391, 340, 396, 396, 402, 396, 256, 396, 540, 268, 260, 261, 262, 404, 268, 265, 266, 267, 268, 269, 390, 271, 272, 273, 274, 275, 276, 277, 339, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 0, 356, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 265, 356, 313, 333, 334, 356, 336, 337, 268, 368, 369, 370, 371, 372, 373, 374, 313, 376, 377, 378, 356, 305, 381, 305, 291, 384, 385, 298, 358, 404, 389, 361, 391, 392, 393, 291, 395, 404, 340, 396, 652, 371, 372, 390, 390, 265, 376, 265, 396, 313, 313, 381, 268, 383, 384, 385, 266, 268, 390, 389, 268, 391, 268, 268, 356, 395, 281, 516, 170, 399, 400, 256, 402, 617, 404, 260, 261, 262, 655, 189, 265, 266, 267, 268, 269, 627, 271, 272, 273, 274, 275, 276, 277, 426, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 460, 437, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 461, 511, 427, 333, 334, 487, 336, 337, 584, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 270, 376, 377, 378, 455, 528, 381, 279, 358, 384, 385, 361, 15, 552, 389, 549, 391, 392, 393, 554, 395, 371, 372, 280, 534, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, 266, 389, -1, 391, -1, -1, -1, 395, -1, -1, -1, 399, 400, -1, -1, 403, 404, -1, -1, 256, -1, -1, -1, 260, 261, 262, -1, -1, 265, 266, 267, -1, 269, -1, 271, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, -1, -1, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, -1, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, 358, -1, 389, 361, 391, 392, 393, -1, 395, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, 260, 261, 262, 389, -1, 391, -1, -1, -1, 395, -1, -1, -1, 399, 400, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, -1, 292, -1, 294, 295, -1, -1, 298, -1, 260, 261, 262, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 313, 314, 315, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, 313, 314, 315, 381, -1, 358, 384, 385, 361, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, 372, -1, -1, -1, 376, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 395, -1, -1, 358, -1, -1, 361, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, 372, -1, -1, -1, 376, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 395, 260, 261, 262, -1, -1, 265, 266, 267, 404, 269, -1, -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, -1, -1, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, -1, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, -1, -1, -1, 395, 260, 261, 262, 399, 400, 265, 266, 267, -1, 269, -1, -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, -1, -1, 293, -1, -1, -1, -1, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, -1, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, -1, -1, -1, 395, 260, 261, 262, 399, 400, 265, 266, 267, -1, 269, -1, -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, -1, -1, 293, -1, -1, -1, -1, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, -1, 312, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, -1, -1, -1, 395, 260, 261, 262, 399, 400, 265, 266, 267, -1, 269, -1, -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, -1, -1, 293, -1, -1, -1, -1, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, -1, 312, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, -1, -1, -1, 395, -1, -1, -1, 399, 400, -1, -1, 265, 266, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, 390, 391, 392, 393, -1, 395, 396, 265, 266, -1, 268, -1, 270, -1, 404, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, 266, -1, 268, 335, 270, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, 390, 391, 392, 393, -1, 395, 396, 265, 266, -1, 268, 335, 270, -1, 404, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, 266, -1, 268, -1, 270, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, 390, 391, 392, 393, -1, 395, 396, 265, 266, 335, 268, -1, 270, 339, 404, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, 266, -1, -1, 335, 270, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, 390, 391, 392, 393, -1, 395, 396, 265, 266, -1, 268, -1, 270, -1, 404, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, 266, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, 355, 404, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 266, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 266, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 266, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 266, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 266, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 265, 266, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, 260, 261, 262, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, 314, 315, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 265, -1, -1, 268, -1, 270, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, 372, -1, 396, -1, 376, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 395, 396, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, 260, 261, 262, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, 276, 277, 404, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 313, 314, 315, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 265, -1, -1, 268, -1, 270, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, 372, -1, -1, -1, 376, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, 395, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 265, -1, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 390, -1, 265, -1, -1, 268, 396, 270, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 265, 390, -1, 268, -1, 270, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, 265, -1, -1, 268, 390, 270, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 265, -1, -1, 268, -1, 270, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, -1, 404, -1, -1, 265, -1, -1, 268, -1, 270, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, 260, 261, 262, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 335, 314, 315, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 265, 356, -1, 268, -1, 270, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, -1, -1, 396, -1, -1, -1, -1, -1, -1, 358, 404, -1, 361, -1, -1, -1, -1, -1, -1, 390, -1, -1, -1, 372, -1, 396, -1, 376, -1, -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 395, -1, -1, -1, -1, -1, -1, -1, 335, -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, -1, 356, -1, 260, 261, 262, -1, -1, -1, 266, 267, -1, 269, -1, -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, 390, -1, -1, -1, -1, -1, 396, 299, 300, -1, -1, -1, -1, -1, 404, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, -1, -1, 269, -1, -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, 299, 300, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, 267, 268, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, 335, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, -1, 268, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, 335, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, 267, 268, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, -1, -1, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, 390, 391, 260, 261, 262, 395, -1, -1, 266, -1, -1, 269, 270, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, 267, -1, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, -1, -1, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, 335, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, 267, -1, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, -1, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, -1, -1, 389, -1, 391, 260, 261, 262, 395, -1, -1, 266, -1, -1, 269, -1, -1, -1, -1, -1, -1, 276, 277, -1, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, 313, 314, 315, -1, -1, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 266, -1, -1, 333, 334, -1, 336, 337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, -1, -1, -1, -1, 371, 372, -1, -1, -1, 376, -1, -1, -1, -1, 381, -1, 383, 384, 385, -1, 266, -1, 389, -1, 391, -1, -1, -1, 395, -1, -1, -1, -1, -1, -1, -1, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, 266, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, 266, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, 266, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, 266, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, 266, -1, -1, 389, -1, 391, 392, 393, -1, 395, 335, -1, -1, -1, -1, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, 266, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, -1, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, -1, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, 376, 377, 378, -1, -1, 381, -1, -1, 384, 385, -1, -1, -1, 389, -1, 391, 392, 393, -1, 395, }; #define YYFINAL 1 #ifndef YYDEBUG #define YYDEBUG 0 #endif #define YYMAXTOKEN 404 #define YYUNDFTOKEN 521 #define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a)) #if YYDEBUG static const char *const yyname[] = { "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"VAR","EXPR","ARRAY","STRUCT", "UNION","ENUM","COMP","HASH","SEMI","MOD","OC","CC","DOLLAR","DOTDOTDOT", "ENDFILE","GLOBAL","AUTO","STATIC","CONST","POLY","INTEGER","NATURAL", "RATIONAL","REAL","STRING","FOREIGN","FILET","MUTEX","SEMAPHORE","CONTINUATION", "THREAD","VOID","BOOL","FUNCTION","FUNC","EXCEPTION","RAISE","TYPEDEF","IMPORT", "NEW","ANONINIT","NAMESPACE","PUBLIC","PROTECTED","EXTEND","WHILE","DO","FOR", "SWITCH","BREAK","CONTINUE","RETURNTOK","FORK","CASE","DEFAULT","TWIXT","NAME", "TYPENAME","NAMESPACENAME","COMMAND","NAMECOMMAND","TEN_NUM","OCTAL0_NUM", "OCTAL_NUM","BINARY_NUM","HEX_NUM","TEN_FLOAT","OCTAL0_FLOAT","OCTAL_FLOAT", "BINARY_FLOAT","HEX_FLOAT","CHAR_CONST","STRING_CONST","POLY_CONST", "THREAD_CONST","COMMENT_CONST","VOIDVAL","BOOLVAL","DARROW","ISTYPE", "HASMEMBER","POUND","COMMA","ASSIGN","ASSIGNPLUS","ASSIGNMINUS","ASSIGNTIMES", "ASSIGNDIVIDE","ASSIGNDIV","ASSIGNMOD","ASSIGNPOW","ASSIGNSHIFTL", "ASSIGNSHIFTR","ASSIGNLXOR","ASSIGNLAND","ASSIGNLOR","ASSIGNOR","ASSIGNAND", "QUEST","COLON","OR","AND","LOR","LXOR","LAND","EQ","NE","LT","GT","LE","GE", "SHIFTL","SHIFTR","PLUS","MINUS","TIMES","DIVIDE","DIV","POW","STARSTAR","POW2", "POW3","UNIONCAST","UMINUS","BANG","FACT","LNOT","INC","DEC","STAR","AMPER", "THREADID","OS","CS","DOT","ARROW","STAROS","CALL","OP","CP","POINTER", "COLONCOLON","IF","TRY","NONL","ELSE","CATCH","NL",0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"illegal-symbol", }; static const char *const yyrule[] = { "$accept : lines", "lines : lines pcommand", "lines :", "pcommand : command", "pcommand : error reset eend", "eend : NL", "eend : SEMI", "eend : ENDFILE", "ignorenl :", "attendnl :", "reset :", "not_command :", "opt_nl : NL", "opt_nl :", "opt_semi : SEMI", "opt_semi :", "opt_comma : COMMA", "opt_comma :", "command : not_command expr reset NL", "command : not_command expr POUND expr reset NL", "command : not_command statement reset opt_nl", "command : not_command COMMAND opt_exprs reset opt_semi NL", "command : not_command NAMECOMMAND opt_rawnames reset opt_semi NL", "command : NL", "command : ENDFILE", "opt_rawnames : rawnames", "opt_rawnames :", "rawnames : rawname COMMA rawnames", "rawnames : rawname", "rawname : rawnamespace rawatom", "rawatom : NAME", "rawatom : NAMESPACENAME", "rawatom : TYPENAME", "rawnamespace : rawnamespace rawatom COLONCOLON", "rawnamespace :", "fulltype : namespace TYPENAME", "fulltype : TYPENAME", "fullname : namespace namespacename", "fullname : namespacename", "fullnames : fullname", "fullnames : fullname COMMA fullnames", "namespace : namespace NAMESPACENAME COLONCOLON", "namespace : NAMESPACENAME COLONCOLON", "namespacename : NAME", "namespacename : NAMESPACENAME", "namespace_start :", "namespace_end :", "block : block_start statements block_end", "block_start : OC namespace_start", "block_end : namespace_end CC", "statements : statement statements", "statements :", "if_statement : IF ignorenl namespace_start OP expr CP statement", "if_statement : IF ignorenl namespace_start OP expr CP statement ELSE statement", "statement : simple_statement", "statement : block", "simple_statement : if_statement namespace_end attendnl", "simple_statement : WHILE ignorenl namespace_start OP expr CP statement namespace_end attendnl", "simple_statement : DO ignorenl namespace_start statement WHILE OP expr CP namespace_end attendnl", "simple_statement : FOR ignorenl namespace_start OP for_exprs CP statement namespace_end attendnl", "simple_statement : SWITCH ignorenl namespace_start OP expr CP case_block namespace_end attendnl", "simple_statement : union_or_enum SWITCH ignorenl namespace_start OP expr CP union_case_block namespace_end attendnl", "simple_statement : BREAK SEMI", "simple_statement : CONTINUE SEMI", "simple_statement : RETURNTOK opt_expr SEMI", "simple_statement : expr SEMI", "simple_statement : SEMI", "simple_statement : func_decl doc_string opt_func_body namespace_end", "simple_statement : opt_publish EXCEPTION ignorenl NAME namespace_start opt_argdecls namespace_end doc_string SEMI attendnl", "simple_statement : RAISE fullname OP opt_exprs CP SEMI", "simple_statement : opt_publish TYPEDEF ignorenl typenames SEMI attendnl", "simple_statement : opt_publish TYPEDEF ignorenl type typenames SEMI attendnl", "$$1 :", "simple_statement : publish_extend NAMESPACE ignorenl namespacename $$1 OC statements CC attendnl", "simple_statement : opt_publish IMPORT ignorenl fullnames SEMI attendnl", "simple_statement : try_statement attendnl", "simple_statement : TWIXT ignorenl namespace_start OP opt_expr SEMI opt_expr CP statement namespace_end attendnl", "for_exprs : opt_expr SEMI for_exprs", "for_exprs : opt_expr", "try_body_statement : simple_statement", "try_body_statement : OC statements CC", "try_statement : TRY ignorenl try_body_statement catches", "catches : catches catch", "catches :", "catch : CATCH fullname namespace_start args doc_string block namespace_end", "opt_func_body : func_body", "opt_func_body : SEMI", "$$2 :", "func_body : $$2 block_or_expr", "block_or_expr : block", "block_or_expr : attendnl ASSIGN simpleexpr SEMI", "union_or_enum : UNION", "union_or_enum : ENUM", "see_comment :", "doc_string : see_comment opt_comment", "opt_comment : COMMENT_CONST", "opt_comment :", "case_block : block_start cases block_end", "cases : case cases", "cases :", "case : CASE expr COLON statements", "case : DEFAULT COLON statements", "union_case_block : block_start union_cases block_end", "union_cases : union_case union_cases", "union_cases :", "union_case : CASE namespace_start NAME opt_name COLON statements namespace_end", "union_case : DEFAULT COLON statements", "opt_name : NAME", "opt_name :", "atoms : NAME COMMA atoms", "atoms : NAME", "typenames : typename COMMA typenames", "typenames : typename", "typename : TYPENAME", "typename : NAME", "initnames : name opt_init next_decl initnames", "initnames : name opt_init", "name : NAME", "next_decl : COMMA", "func_decl : func_name namespace_start opt_argdefines CP", "func_name : decl NAME OP", "func_name : decl FUNCTION NAME OP", "func_name : FUNCTION ignorenl NAME OP", "opt_init : ASSIGN simpleexpr", "opt_init : ASSIGN init", "opt_init :", "decl : publish opt_class opt_type opt_nl", "decl : class opt_type opt_nl", "decl : type opt_nl", "subscripts : opt_argdecls subscripts", "subscripts : OS opt_stars CS subscripts", "subscripts : OS dotdotdots CS subscripts", "subscripts : OS dims CS subscripts", "subscripts : OS type CS subscripts", "subscripts :", "type : subtype subscripts", "type : TIMES type", "type : STARSTAR type", "type : AND type", "type : LAND type", "type : type PLUS type", "subtype : basetype", "subtype : STRUCT OC struct_members CC", "subtype : UNION OC union_members CC", "subtype : ENUM OC atoms CC", "subtype : OP type CP", "subtype : fulltype", "opt_type : type", "opt_type :", "basetype : POLY", "basetype : INTEGER", "basetype : RATIONAL", "basetype : REAL", "basetype : STRING", "basetype : FILET", "basetype : MUTEX", "basetype : SEMAPHORE", "basetype : CONTINUATION", "basetype : THREAD", "basetype : VOID", "basetype : BOOL", "basetype : FOREIGN", "opt_stars : stars", "opt_stars :", "stars : stars COMMA TIMES", "stars : TIMES", "dotdotdots : dotdotdots COMMA DOTDOTDOT", "dotdotdots : DOTDOTDOT", "dims : simpleexpr COMMA dims", "dims : simpleexpr", "struct_members : opt_type atoms SEMI struct_members", "struct_members :", "union_members : opt_type atoms SEMI union_members", "union_members :", "opt_class : class", "opt_class :", "class : GLOBAL", "class : AUTO", "class : STATIC", "class : CONST", "opt_publish : publish", "opt_publish :", "publish : PUBLIC", "publish : PROTECTED", "publish_extend : opt_publish", "publish_extend : EXTEND", "opt_argdecls : OP argdecls CP", "opt_argdecls : OP CP", "argdecls : argdecl COMMA argdecls", "argdecls : argdecl opt_dotdotdot", "argdecl : type NAME", "argdecl : type", "args : OP opt_argdefines CP", "opt_argdefines : ignorenl argdefines", "opt_argdefines : ignorenl", "argdefines : argdefine COMMA argdefines", "argdefines : argdefine opt_dotdotdot", "argdefine : opt_type NAME", "argdefine : type", "opt_dotdotdot : DOTDOTDOT", "opt_dotdotdot :", "opt_expr : expr", "opt_expr :", "expr : comma_expr", "expr : decl initnames", "comma_expr : simpleexpr", "comma_expr : comma_expr COMMA simpleexpr", "opt_exprs : exprs", "opt_exprs :", "exprs : simpleexpr COMMA exprs", "exprs : simpleexpr", "opt_actuals : actuals", "opt_actuals :", "actuals : simpleexpr COMMA actuals", "actuals : simpleexpr opt_dotdotdot", "func_right : attendnl ASSIGN simpleexpr", "$$3 :", "func_right : $$3 block", "simpleexpr : simpleexpr assignop simpleexpr", "simpleexpr : opt_type FUNC namespace_start args doc_string func_right namespace_end", "simpleexpr : MOD integer", "simpleexpr : TIMES simpleexpr", "simpleexpr : STARSTAR simpleexpr", "simpleexpr : LAND simpleexpr", "simpleexpr : AND simpleexpr", "simpleexpr : MINUS simpleexpr", "simpleexpr : LNOT simpleexpr", "simpleexpr : BANG simpleexpr", "simpleexpr : simpleexpr BANG", "simpleexpr : INC simpleexpr", "simpleexpr : simpleexpr INC", "simpleexpr : DEC simpleexpr", "simpleexpr : simpleexpr DEC", "simpleexpr : FORK simpleexpr", "simpleexpr : simpleexpr PLUS simpleexpr", "simpleexpr : simpleexpr MINUS simpleexpr", "simpleexpr : simpleexpr TIMES simpleexpr", "simpleexpr : simpleexpr DIVIDE simpleexpr", "simpleexpr : simpleexpr DIV simpleexpr", "simpleexpr : simpleexpr MOD simpleexpr", "simpleexpr : simpleexpr STARSTAR simpleexpr", "simpleexpr : simpleexpr POW2", "simpleexpr : simpleexpr POW3", "simpleexpr : simpleexpr SHIFTL simpleexpr", "simpleexpr : simpleexpr SHIFTR simpleexpr", "simpleexpr : simpleexpr QUEST simpleexpr COLON simpleexpr", "simpleexpr : simpleexpr LXOR simpleexpr", "simpleexpr : simpleexpr LAND simpleexpr", "simpleexpr : simpleexpr LOR simpleexpr", "simpleexpr : simpleexpr AND simpleexpr", "simpleexpr : simpleexpr OR simpleexpr", "simpleexpr : simpleexpr EQ simpleexpr", "simpleexpr : simpleexpr NE simpleexpr", "simpleexpr : simpleexpr LT simpleexpr", "simpleexpr : simpleexpr GT simpleexpr", "simpleexpr : simpleexpr LE simpleexpr", "simpleexpr : simpleexpr GE simpleexpr", "simpleexpr : fullname", "simpleexpr : TEN_NUM", "simpleexpr : OCTAL_NUM", "simpleexpr : OCTAL0_NUM", "simpleexpr : BINARY_NUM", "simpleexpr : HEX_NUM", "simpleexpr : TEN_FLOAT", "simpleexpr : OCTAL_FLOAT", "simpleexpr : OCTAL0_FLOAT", "simpleexpr : BINARY_FLOAT", "simpleexpr : HEX_FLOAT", "simpleexpr : CHAR_CONST", "simpleexpr : STRING_CONST", "simpleexpr : VOIDVAL", "simpleexpr : BOOLVAL", "simpleexpr : OS CS", "simpleexpr : OP type CP namespace_start init namespace_end", "simpleexpr : OP OS stars CS CP namespace_start arrayinit namespace_end", "simpleexpr : OP OS dims CS CP namespace_start opt_arrayinit namespace_end", "simpleexpr : OP OS type CS CP namespace_start opt_hashinit namespace_end", "simpleexpr : type DOT NAME", "simpleexpr : OP type DOT NAME CP simpleexpr", "simpleexpr : DOLLAR opt_integer", "simpleexpr : DOT", "simpleexpr : OP expr CP", "simpleexpr : OP block CP", "simpleexpr : simpleexpr STAROS dims CS", "simpleexpr : simpleexpr OS dims CS", "simpleexpr : simpleexpr OP opt_actuals CP", "simpleexpr : ISTYPE OP simpleexpr COMMA type CP", "simpleexpr : HASMEMBER OP simpleexpr COMMA NAME CP", "simpleexpr : simpleexpr DOT NAME", "simpleexpr : simpleexpr ARROW NAME", "opt_integer : integer", "opt_integer :", "assignop : ASSIGNPLUS", "assignop : ASSIGNMINUS", "assignop : ASSIGNTIMES", "assignop : ASSIGNDIVIDE", "assignop : ASSIGNDIV", "assignop : ASSIGNMOD", "assignop : ASSIGNPOW", "assignop : ASSIGNSHIFTL", "assignop : ASSIGNSHIFTR", "assignop : ASSIGNLXOR", "assignop : ASSIGNLAND", "assignop : ASSIGNLOR", "assignop : ASSIGNOR", "assignop : ASSIGNAND", "assignop : ASSIGN", "integer : TEN_NUM", "integer : OCTAL_NUM", "integer : OCTAL0_NUM", "integer : BINARY_NUM", "integer : HEX_NUM", "opt_arrayinit : arrayinit", "opt_arrayinit : OC CC", "opt_arrayinit :", "arrayinit : OC arrayelts opt_comma opt_dotdotdot CC", "arrayinit : OC OS namespace_start compnames comparray CS comprehension namespace_end CC", "comprehension : ASSIGN arrayelt", "comprehension : block", "compnames : compname COMMA compnames", "compnames : compname", "compname : NAME", "comparray :", "arrayelts : arrayelts COMMA arrayelt", "arrayelts : arrayelt", "arrayelt : simpleexpr", "arrayelt : init", "opt_hashinit : hashinit", "opt_hashinit : OC CC", "opt_hashinit :", "hashinit : OC hashelts opt_comma CC", "hashelts : hashelts COMMA hashelt", "hashelts : hashelt", "hashelt : simpleexpr DARROW hashvalue", "hashelt : DARROW hashvalue", "hashvalue : simpleexpr", "hashvalue : init", "structinit : OC structelts opt_comma CC", "structelts : structelts COMMA structelt", "structelts : structelt", "structelt : NAME ASSIGN simpleexpr", "structelt : NAME ASSIGN init", "structelt : DOT NAME ASSIGN simpleexpr", "structelt : DOT NAME ASSIGN init", "init : arrayinit", "init : structinit", "init : hashinit", "init : OC CC", }; #endif int yydebug; int yynerrs; int yyerrflag; int yychar; YYSTYPE yyval; YYSTYPE yylval; /* define the initial stack-sizes */ #ifdef YYSTACKSIZE #undef YYMAXDEPTH #define YYMAXDEPTH YYSTACKSIZE #else #ifdef YYMAXDEPTH #define YYSTACKSIZE YYMAXDEPTH #else #define YYSTACKSIZE 10000 #define YYMAXDEPTH 10000 #endif #endif #define YYINITSTACKSIZE 200 typedef struct { unsigned stacksize; YYINT *s_base; YYINT *s_mark; YYINT *s_last; YYSTYPE *l_base; YYSTYPE *l_mark; } YYSTACKDATA; /* variables for the parser stack */ static YYSTACKDATA yystack; #line 1633 "gram.y" static void DeclListMark (void *object) { DeclListPtr dl = object; MemReference (dl->next); MemReference (dl->init); } DataType DeclListType = { DeclListMark, 0, "DeclListType" }; DeclListPtr NewDeclList (Atom name, ExprPtr init, DeclListPtr next) { ENTER (); DeclListPtr dl; dl = ALLOCATE (&DeclListType, sizeof (DeclList)); dl->next = next; dl->name = name; dl->symbol = 0; dl->init = init; RETURN (dl); } static void MemListMark (void *object) { MemListPtr ml = object; MemReference (ml->next); MemReference (ml->type); MemReference (ml->atoms); } DataType MemListType = { MemListMark, 0, "MemListType" }; MemListPtr NewMemList (AtomListPtr atoms, Type *type, MemListPtr next) { ENTER (); MemListPtr ml; ml = ALLOCATE (&MemListType, sizeof (MemList)); ml->next = next; ml->type = type; ml->atoms = atoms; RETURN (ml); } extern NamespacePtr CurrentNamespace; FramePtr CurrentFrame; Value lookupVar (char *ns, char *n) { ENTER (); Value v; SymbolPtr symbol; NamespacePtr namespace; Bool search; search = True; namespace = CurrentNamespace; if (ns) { symbol = NamespaceFindName (CurrentNamespace, AtomId (ns), True); if (symbol && symbol->symbol.class == class_namespace) namespace = symbol->namespace.namespace; else namespace = 0; } if (namespace) symbol = NamespaceFindName (namespace, AtomId (n), search); else symbol = 0; if (symbol && symbol->symbol.class == class_global) v = BoxValue (symbol->global.value, 0); else v = Void; RETURN (v); } void setVar (NamespacePtr namespace, char *n, Value v, Type *type) { ENTER (); Atom atom; SymbolPtr symbol; atom = AtomId (n); symbol = NamespaceFindName (namespace, atom, True); if (!symbol) symbol = NamespaceAddName (namespace, NewSymbolGlobal (atom, type), publish_private); if (symbol->symbol.class == class_global) BoxValueSet (symbol->global.value, 0, v); EXIT (); } void GetNamespace (NamespacePtr *scope, FramePtr *fp, CodePtr *cp) { *scope = CurrentNamespace; *fp = CurrentFrame; if (CurrentFrame) *cp = CurrentFrame->function->func.code; else *cp = 0; } ExprPtr BuildName (char *ns, char *n) { ENTER (); SymbolPtr symbol, ns_symbol = 0; Atom atom, ns_atom = 0; Bool search = True; NamespacePtr namespace = CurrentNamespace; ExprPtr e; Bool ns_privateFound = False; Bool privateFound = False; if (ns) { ns_atom = AtomId (ns); ns_symbol = NamespaceFindName (namespace, ns_atom, search); if (ns_symbol && ns_symbol->symbol.class == class_namespace) namespace = ns_symbol->namespace.namespace; else { if (!ns_symbol) ns_privateFound = NamespaceIsNamePrivate (namespace, ns_atom, search); namespace = 0; } search = False; } atom = AtomId (n); if (namespace) { symbol = NamespaceFindName (namespace, atom, search); if (!symbol) privateFound = NamespaceIsNamePrivate (namespace, atom, search); } else symbol = 0; e = NewExprAtom (atom, symbol, privateFound); if (ns_atom) e = NewExprTree (COLONCOLON, NewExprAtom (ns_atom, ns_symbol, ns_privateFound), e); RETURN (e); } static Value AtomString (Atom id) { ENTER (); RETURN (NewStrString (AtomName (id))); } ExprPtr BuildRawname (ExprPtr colonnames, Atom name) { ENTER (); int len; Value array; ExprPtr e; len = 1; for (e = colonnames; e; e = e->tree.left) len++; array = NewArray (False, False, typePrim[rep_string], 1, &len); len--; ArrayValueSet (&array->array, len, AtomString (name)); e = colonnames; while (--len >= 0) { ArrayValueSet (&array->array, len, AtomString (e->tree.right->atom.atom)); e = e->tree.left; } e = NewExprConst (POLY_CONST, array); RETURN (e); } ExprPtr BuildFullname (ExprPtr left, Atom atom) { ENTER (); NamespacePtr namespace; SymbolPtr symbol; Bool search; ExprPtr nameExpr; Bool privateFound = False; if (left) { if (left->base.tag == COLONCOLON) symbol = left->tree.right->atom.symbol; else symbol = left->atom.symbol; if (symbol && symbol->symbol.class == class_namespace) namespace = symbol->namespace.namespace; else namespace = 0; search = False; } else { namespace = CurrentNamespace; search = True; } if (namespace) { symbol = NamespaceFindName (namespace, atom, search); if (!symbol) privateFound = NamespaceIsNamePrivate (namespace, atom, search); } else symbol = 0; nameExpr = NewExprAtom (atom, symbol, privateFound); if (left) nameExpr = NewExprTree (COLONCOLON, left, nameExpr); RETURN (nameExpr); } ExprPtr BuildCall (char *scope, char *name, int nargs, ...) { ENTER (); va_list alist; ExprPtr args, *prev; ExprPtr f; ExprPtr e; va_start (alist, nargs); prev = &args; args = 0; while (nargs--) { *prev = NewExprTree (COMMA, va_arg (alist, ExprPtr), 0); prev = &(*prev)->tree.right; } va_end (alist); f = BuildName (scope, name); e = NewExprTree (OP, f, args); #ifdef DEBUG printExpr (stdout, e, -1, 0); printf ("\n"); #endif RETURN (e); } /* * Walk for() loop arguments and normalize the list */ static Expr * ParseCanonFor (Expr *expr) { if (!expr || !expr->tree.right) { ParseError ("Too few exprs in for()\n"); return 0; } if (!expr->tree.right->tree.right) { /* 2-argument for() */ expr = NewExprTree(FOR, 0, expr); } if (expr->tree.right->tree.right->tree.right) { ParseError ("Too many exprs in for()\n"); return 0; } return expr; } /* * Walk a type structure and resolve any type names */ static CanonTypeResult ParseCanonType (TypePtr type, Bool forwardAllowed) { ArgType *arg; int n; CanonTypeResult ret = CanonTypeDefined, t; Bool anyResolved; if (!type) { ParseError ("Type missing inside compiler"); return False; } switch (type->base.tag) { case type_prim: break; case type_name: if (!TypeNameType(type)) { if (!type->name.name) { ExprPtr e; e = type->name.expr; if (e->base.tag == COLONCOLON) e = e->tree.right; type->name.name = e->atom.symbol; if (!type->name.name) { ParseError ("No typedef \"%A\" in namespace", e->atom.atom); ret = CanonTypeUndefined; break; } } if (type->name.name->symbol.class != class_typedef) { ParseError ("Symbol \"%A\" not a typedef", type->name.name->symbol.name); ret = CanonTypeUndefined; } else if (!TypeNameType(type)) { if (!forwardAllowed) ParseError ("Typedef \"%A\" not defined yet", type->name.name->symbol.name); ret = CanonTypeForward; } else { ret = ParseCanonType (TypeNameType(type), forwardAllowed); } } break; case type_ref: ret = ParseCanonType (type->ref.ref, True); if (ret == CanonTypeForward) ret = CanonTypeDefined; break; case type_func: if (type->func.ret) ret = ParseCanonType (type->func.ret, forwardAllowed); for (arg = type->func.args; arg; arg = arg->next) { t = ParseCanonType (arg->type, forwardAllowed); if (t < ret) ret = t; } break; case type_array: ret = ParseCanonType (type->array.type, forwardAllowed); break; case type_hash: ret = ParseCanonType (type->hash.type, forwardAllowed); t = ParseCanonType (type->hash.keyType, forwardAllowed); if (t < ret) ret = t; break; case type_struct: for (n = 0; n < type->structs.structs->nelements; n++) { StructType *st = type->structs.structs; t = ParseCanonType (BoxTypesElements(st->types)[n], forwardAllowed); if (t < ret) ret = t; } break; case type_union: anyResolved = False; for (n = 0; n < type->structs.structs->nelements; n++) { StructType *st = type->structs.structs; t = ParseCanonType (BoxTypesElements(st->types)[n], True); if (t < ret) ret = t; if (t == CanonTypeDefined) anyResolved = True; } if (ret == CanonTypeForward) { if (anyResolved) ret = CanonTypeDefined; else if (!forwardAllowed) ParseError ("No member of '%T' defined yet", type); } break; case type_types: break; } return ret; } static SymbolPtr ParseNewSymbol (Publish publish, Class class, Type *type, Atom name) { ENTER (); SymbolPtr s = 0; if (class == class_undef) class = funcDepth ? class_auto : class_global; if (class == class_namespace || (class == class_typedef && type == 0) || ParseCanonType (type, False) == CanonTypeDefined) { switch (class) { case class_const: s = NewSymbolConst (name, type); break; case class_global: s = NewSymbolGlobal (name, type); break; case class_static: s = NewSymbolStatic (name, type); break; case class_arg: s = NewSymbolArg (name, type); break; case class_auto: s = NewSymbolAuto (name, type); break; case class_exception: s = NewSymbolException (name, type, Void); break; case class_typedef: /* * Special case for typedefs -- * allow forward declaration of untyped * typedef names, then hook the * new type to the old name */ if (type) { s = NamespaceFindName (CurrentNamespace, name, False); if (s && s->symbol.class == class_typedef && !s->symbol.type) { s->symbol.type = type; RETURN (s); } } s = NewSymbolType (name, type); break; case class_namespace: s = NewSymbolNamespace (name, NewNamespace (CurrentNamespace)); break; case class_undef: break; } if (s) NamespaceAddName (CurrentNamespace, s, publish); } RETURN (s); } int yywrap (void) { if (LexInteractive()) printf ("\n"); if (CurrentFrame) { do_Debug_done (); return 0; } return 1; } extern char *yytext; void ParseError (char *fmt, ...) { va_list args; if (LexFileName ()) FilePrintf (FileStderr, "%A:%d: ", LexFileName (), LexFileLine ()); va_start (args, fmt); FileVPrintf (FileStderr, fmt, args); FilePrintf (FileStderr, "\n"); va_end (args); } void yyerror (char *msg) { ignorenl = 0; ParseError ("%s before %S", msg, yytext); } #line 3024 "gram.c" #if YYDEBUG #include /* needed for printf */ #endif #include /* needed for malloc, etc */ #include /* needed for memset */ /* allocate initial stack or double stack size, up to YYMAXDEPTH */ static int yygrowstack(YYSTACKDATA *data) { int i; unsigned newsize; YYINT *newss; YYSTYPE *newvs; if ((newsize = data->stacksize) == 0) newsize = YYINITSTACKSIZE; else if (newsize >= YYMAXDEPTH) return YYENOMEM; else if ((newsize *= 2) > YYMAXDEPTH) newsize = YYMAXDEPTH; i = (int) (data->s_mark - data->s_base); newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss)); if (newss == 0) return YYENOMEM; data->s_base = newss; data->s_mark = newss + i; newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); if (newvs == 0) return YYENOMEM; data->l_base = newvs; data->l_mark = newvs + i; data->stacksize = newsize; data->s_last = data->s_base + newsize - 1; return 0; } #if YYPURE || defined(YY_NO_LEAKS) static void yyfreestack(YYSTACKDATA *data) { free(data->s_base); free(data->l_base); memset(data, 0, sizeof(*data)); } #else #define yyfreestack(data) /* nothing */ #endif #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab int YYPARSE_DECL() { int yym, yyn, yystate; #if YYDEBUG const char *yys; if ((yys = getenv("YYDEBUG")) != 0) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yynerrs = 0; yyerrflag = 0; yychar = YYEMPTY; yystate = 0; #if YYPURE memset(&yystack, 0, sizeof(yystack)); #endif if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; yystack.s_mark = yystack.s_base; yystack.l_mark = yystack.l_base; yystate = 0; *yystack.s_mark = 0; yyloop: if ((yyn = yydefred[yystate]) != 0) goto yyreduce; if (yychar < 0) { if ((yychar = YYLEX) < 0) yychar = YYEOF; #if YYDEBUG if (yydebug) { yys = yyname[YYTRANSLATE(yychar)]; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, shifting to state %d\n", YYPREFIX, yystate, yytable[yyn]); #endif if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) { goto yyoverflow; } yystate = yytable[yyn]; *++yystack.s_mark = yytable[yyn]; *++yystack.l_mark = yylval; yychar = YYEMPTY; if (yyerrflag > 0) --yyerrflag; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; YYERROR_CALL("syntax error"); goto yyerrlab; yyerrlab: ++yynerrs; yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, error recovery shifting\ to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); #endif if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) { goto yyoverflow; } yystate = yytable[yyn]; *++yystack.s_mark = yytable[yyn]; *++yystack.l_mark = yylval; goto yyloop; } else { #if YYDEBUG if (yydebug) printf("%sdebug: error recovery discarding state %d\n", YYPREFIX, *yystack.s_mark); #endif if (yystack.s_mark <= yystack.s_base) goto yyabort; --yystack.s_mark; --yystack.l_mark; } } } else { if (yychar == YYEOF) goto yyabort; #if YYDEBUG if (yydebug) { yys = yyname[YYTRANSLATE(yychar)]; printf("%sdebug: state %d, error recovery discards token %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif yychar = YYEMPTY; goto yyloop; } yyreduce: #if YYDEBUG if (yydebug) printf("%sdebug: state %d, reducing by rule %d (%s)\n", YYPREFIX, yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; if (yym) yyval = yystack.l_mark[1-yym]; else memset(&yyval, 0, sizeof yyval); switch (yyn) { case 5: #line 198 "gram.y" { yyerrok; } break; case 6: #line 200 "gram.y" { yyerrok; } break; case 7: #line 202 "gram.y" { yyerrok; } break; case 8: #line 210 "gram.y" { ignorenl++; } break; case 9: #line 213 "gram.y" { if (ignorenl > 0) ignorenl--; } break; case 10: #line 216 "gram.y" { ignorenl = 0; LexNamespace = 0; CurrentNamespace = TopNamespace; funcDepth = 0; notCommand = 0; lastThreadError = True; } break; case 11: #line 234 "gram.y" { notCommand = 1; } break; case 18: #line 249 "gram.y" { ENTER (); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; e = BuildCall ("Command", "display", 1,NewExprTree (EXPR, yystack.l_mark[-2].expr, 0)); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); EXIT (); } break; case 19: #line 265 "gram.y" { ENTER (); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; e = BuildCall("Command", "display_base", 2, NewExprTree (EXPR, yystack.l_mark[-4].expr, 0), yystack.l_mark[-2].expr); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); EXIT (); } break; case 20: #line 281 "gram.y" { ENTER (); NamespacePtr s; FramePtr f; CodePtr c; Value t; GetNamespace (&s, &f, &c); t = NewThread (f, CompileStat (yystack.l_mark[-2].expr, c)); ThreadsRun (t, 0); EXIT (); } break; case 21: #line 294 "gram.y" { ENTER(); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; CommandPtr cmd; cmd = CommandFind (CurrentCommands, yystack.l_mark[-4].atom); if (!cmd) ParseError ("Undefined command \"%s\"", AtomName (yystack.l_mark[-4].atom)); else { e = NewExprTree (OP, NewExprConst (POLY_CONST, cmd->func), yystack.l_mark[-3].expr); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); } EXIT (); } break; case 22: #line 318 "gram.y" { ENTER (); ExprPtr e; Value t; NamespacePtr s; FramePtr f; CodePtr c; CommandPtr cmd; cmd = CommandFind (CurrentCommands, yystack.l_mark[-4].atom); if (!cmd) ParseError ("Undefined command \"%s\"", AtomName (yystack.l_mark[-4].atom)); else { e = NewExprTree (OP, NewExprConst (POLY_CONST, cmd->func), yystack.l_mark[-3].expr); GetNamespace (&s, &f, &c); t = NewThread (f, CompileExpr (e, c)); ThreadsRun (t, 0); } EXIT (); } break; case 26: #line 347 "gram.y" { yyval.expr = 0; } break; case 27: #line 350 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 28: #line 352 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[0].expr, 0); } break; case 29: #line 355 "gram.y" { yyval.expr = BuildRawname (yystack.l_mark[-1].expr, yystack.l_mark[0].atom); } break; case 33: #line 362 "gram.y" { yyval.expr = NewExprTree (COLONCOLON, yystack.l_mark[-2].expr, NewExprAtom (yystack.l_mark[-1].atom, 0, False)); } break; case 34: #line 364 "gram.y" { yyval.expr = 0; } break; case 35: #line 367 "gram.y" { yyval.expr = BuildFullname (yystack.l_mark[-1].expr, yystack.l_mark[0].atom); LexNamespace = 0; } break; case 36: #line 372 "gram.y" { yyval.expr = BuildFullname (0, yystack.l_mark[0].atom); LexNamespace = 0; } break; case 37: #line 378 "gram.y" { yyval.expr = BuildFullname (yystack.l_mark[-1].expr, yystack.l_mark[0].atom); LexNamespace = 0; } break; case 38: #line 383 "gram.y" { yyval.expr = BuildFullname (0, yystack.l_mark[0].atom); LexNamespace = 0; } break; case 39: #line 389 "gram.y" { yyval.expr = yystack.l_mark[0].expr; } break; case 40: #line 393 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 41: #line 398 "gram.y" { ExprPtr e; SymbolPtr symbol; e = BuildFullname (yystack.l_mark[-2].expr, yystack.l_mark[-1].atom); if (e->base.tag == COLONCOLON) symbol = e->tree.right->atom.symbol; else symbol = e->atom.symbol; if (!symbol) { ParseError ("non-existant namespace \"%A\"", yystack.l_mark[-1].atom); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", yystack.l_mark[-1].atom); YYERROR; } LexNamespace = symbol->namespace.namespace; yyval.expr = e; } break; case 42: #line 421 "gram.y" { ExprPtr e; SymbolPtr symbol; e = BuildFullname (0, yystack.l_mark[-1].atom); if (e->base.tag == COLONCOLON) symbol = e->tree.right->atom.symbol; else symbol = e->atom.symbol; if (!symbol) { ParseError ("non-existant namespace \"%A\"", yystack.l_mark[-1].atom); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", yystack.l_mark[-1].atom); YYERROR; } LexNamespace = symbol->namespace.namespace; yyval.expr = e; } break; case 45: #line 451 "gram.y" { CurrentNamespace = NewNamespace (CurrentNamespace); } break; case 46: #line 454 "gram.y" { CurrentNamespace = CurrentNamespace->previous; } break; case 47: #line 457 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 50: #line 464 "gram.y" { yyval.expr = NewExprTree(OC, yystack.l_mark[-1].expr, yystack.l_mark[0].expr); } break; case 51: #line 466 "gram.y" { yyval.expr = NewExprTree(OC, 0, 0); } break; case 52: #line 469 "gram.y" { yyval.expr = NewExprTree(IF, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 53: #line 471 "gram.y" { yyval.expr = NewExprTree(ELSE, yystack.l_mark[-4].expr, NewExprTree(ELSE, yystack.l_mark[-2].expr, yystack.l_mark[0].expr)); } break; case 56: #line 478 "gram.y" { yyval.expr = yystack.l_mark[-2].expr; } break; case 57: #line 480 "gram.y" { yyval.expr = NewExprTree(WHILE, yystack.l_mark[-4].expr, yystack.l_mark[-2].expr); } break; case 58: #line 482 "gram.y" { yyval.expr = NewExprTree(DO, yystack.l_mark[-6].expr, yystack.l_mark[-3].expr); } break; case 59: #line 484 "gram.y" { Expr *expr = ParseCanonFor(yystack.l_mark[-4].expr); if (!expr) YYERROR; yyval.expr = NewExprTree(FOR, expr, yystack.l_mark[-2].expr); } break; case 60: #line 489 "gram.y" { yyval.expr = NewExprTree (SWITCH, yystack.l_mark[-4].expr, yystack.l_mark[-2].expr); } break; case 61: #line 491 "gram.y" { yyval.expr = NewExprTree (UNION, yystack.l_mark[-4].expr, yystack.l_mark[-2].expr); } break; case 62: #line 493 "gram.y" { yyval.expr = NewExprTree(BREAK, (Expr *) 0, (Expr *) 0); } break; case 63: #line 495 "gram.y" { yyval.expr = NewExprTree(CONTINUE, (Expr *) 0, (Expr *) 0); } break; case 64: #line 497 "gram.y" { yyval.expr = NewExprTree (RETURNTOK, (Expr *) 0, yystack.l_mark[-1].expr); } break; case 65: #line 499 "gram.y" { yyval.expr = NewExprTree(EXPR, yystack.l_mark[-1].expr, (Expr *) 0); } break; case 66: #line 501 "gram.y" { yyval.expr = NewExprTree(SEMI, (Expr *) 0, (Expr *) 0); } break; case 67: #line 503 "gram.y" { DeclList *decl = yystack.l_mark[-3].funcDecl.decl; SymbolPtr symbol = decl->symbol; Class class = yystack.l_mark[-3].funcDecl.type.class; Publish publish = yystack.l_mark[-3].funcDecl.type.publish; TypePtr type = yystack.l_mark[-3].funcDecl.type.type; TypePtr ret = type->func.ret; ArgType *argType = type->func.args; if (symbol) { if (yystack.l_mark[-1].expr) { symbol->symbol.forward = False; ParseCanonType (ret, False); decl->init = NewExprCode (NewFuncCode (ret, argType, yystack.l_mark[-1].expr, yystack.l_mark[-2].value), NewExprAtom (symbol->symbol.name, symbol, False)); } else symbol->symbol.forward = True; } yyval.expr = NewExprDecl (FUNC, decl, class, type, publish); } break; case 68: #line 530 "gram.y" { DeclListPtr decl; decl = NewDeclList (yystack.l_mark[-6].atom, 0, 0); decl->symbol = ParseNewSymbol (yystack.l_mark[-9].publish, class_exception, typePoly, yystack.l_mark[-6].atom); decl->symbol->exception.doc = yystack.l_mark[-2].value; yyval.expr = NewExprDecl (EXCEPTION, decl, class_exception, NewTypeFunc (typePoly, yystack.l_mark[-4].argType), yystack.l_mark[-9].publish); } break; case 69: #line 545 "gram.y" { yyval.expr = NewExprTree (RAISE, yystack.l_mark[-4].expr, yystack.l_mark[-2].expr); } break; case 70: #line 547 "gram.y" { DeclListPtr decl; for (decl = yystack.l_mark[-2].declList; decl; decl = decl->next) decl->symbol = ParseNewSymbol (yystack.l_mark[-5].publish, class_typedef, 0, decl->name); yyval.expr = NewExprTree (TYPEDEF, NewExprDecl (TYPEDEF, yystack.l_mark[-2].declList, class_typedef, 0, yystack.l_mark[-5].publish), 0); } break; case 71: #line 556 "gram.y" { DeclListPtr decl; for (decl = yystack.l_mark[-2].declList; decl; decl = decl->next) decl->symbol = ParseNewSymbol (yystack.l_mark[-6].publish, class_typedef, yystack.l_mark[-3].type, decl->name); yyval.expr = NewExprTree (TYPEDEF, NewExprDecl (TYPEDEF, yystack.l_mark[-2].declList, class_typedef, yystack.l_mark[-3].type, yystack.l_mark[-6].publish), 0); } break; case 72: #line 565 "gram.y" { SymbolPtr symbol; Publish publish = yystack.l_mark[-3].publish; /* * this is a hack - save the current namespace * on the parser stack to be restored after * the block is compiled. */ yystack.l_mark[-2].namespace = CurrentNamespace; if (publish == publish_extend) { symbol = NamespaceFindName (CurrentNamespace, yystack.l_mark[0].atom, True); if (!symbol) { ParseError ("non-existant namespace %A", yystack.l_mark[0].atom); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", yystack.l_mark[0].atom); YYERROR; } else CurrentNamespace = symbol->namespace.namespace; } else { symbol = ParseNewSymbol (yystack.l_mark[-3].publish, class_namespace, 0, yystack.l_mark[0].atom); CurrentNamespace = NewNamespace (CurrentNamespace); symbol->namespace.namespace = CurrentNamespace; } /* * Make all of the symbols visible while compiling within * the namespace */ if (CurrentNamespace != yystack.l_mark[-2].namespace) CurrentNamespace->publish = publish_public; } break; case 73: #line 606 "gram.y" { /* * close the namespace to non-public lookups */ if (CurrentNamespace != yystack.l_mark[-7].namespace) CurrentNamespace->publish = publish_private; /* * Restore to the namespace saved on * the parser stack */ CurrentNamespace = yystack.l_mark[-7].namespace; yyval.expr = NewExprTree (NAMESPACE, NewExprAtom (yystack.l_mark[-5].atom, 0, False), yystack.l_mark[-2].expr); } break; case 74: #line 620 "gram.y" { SymbolPtr symbol; ExprPtr p, e, n; p = yystack.l_mark[-2].expr; for (p = yystack.l_mark[-2].expr; p; p = n) { if (p->base.tag == COMMA) { e = p->tree.left; n = p->tree.right; } else { e = p; n = 0; } if (e->base.tag == COLONCOLON) e = e->tree.right; symbol = e->atom.symbol; if (!symbol) { ParseError ("non-existant namespace %A", e->atom.atom); YYERROR; } else if (symbol->symbol.class != class_namespace) { ParseError ("%A is not a namespace", e->atom.atom); YYERROR; } NamespaceImport (CurrentNamespace, symbol->namespace.namespace, yystack.l_mark[-5].publish); } yyval.expr = NewExprTree (IMPORT, yystack.l_mark[-2].expr, NewExprDecl (IMPORT, 0, class_undef, 0, yystack.l_mark[-5].publish)); } break; case 75: #line 660 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 76: #line 662 "gram.y" { yyval.expr = NewExprTree (TWIXT, NewExprTree (TWIXT, yystack.l_mark[-6].expr, yystack.l_mark[-4].expr), NewExprTree (TWIXT, yystack.l_mark[-2].expr, 0)); } break; case 77: #line 668 "gram.y" { yyval.expr = NewExprTree(SEMI, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 78: #line 670 "gram.y" { yyval.expr = NewExprTree(SEMI, yystack.l_mark[0].expr, 0); } break; case 80: #line 675 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 81: #line 678 "gram.y" { yyval.expr = NewExprTree (CATCH, yystack.l_mark[0].expr, yystack.l_mark[-1].expr); } break; case 82: #line 682 "gram.y" { yyval.expr = NewExprTree (CATCH, yystack.l_mark[-1].expr, yystack.l_mark[0].expr); } break; case 83: #line 684 "gram.y" { yyval.expr = 0; } break; case 84: #line 687 "gram.y" { yyval.expr = NewExprCode (NewFuncCode (typePrim[rep_void], yystack.l_mark[-3].argType, yystack.l_mark[-1].expr, yystack.l_mark[-2].value), yystack.l_mark[-5].expr); } break; case 86: #line 694 "gram.y" { yyval.expr = 0; } break; case 87: #line 696 "gram.y" { ++funcDepth; } break; case 88: #line 696 "gram.y" { --funcDepth; yyval.expr = yystack.l_mark[0].expr; } break; case 89: #line 699 "gram.y" { yyval.expr = yystack.l_mark[0].expr; } break; case 90: #line 701 "gram.y" { yyval.expr = NewExprTree (OC, NewExprTree (RETURNTOK, 0, yystack.l_mark[-1].expr), NewExprTree (OC, 0, 0)); } break; case 93: #line 711 "gram.y" { seeComment = 1; } break; case 94: #line 714 "gram.y" { seeComment = 0; yyval.value = yystack.l_mark[0].value; } break; case 96: #line 718 "gram.y" { yyval.value = Void; } break; case 97: #line 721 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 98: #line 724 "gram.y" { yyval.expr = NewExprTree (CASE, yystack.l_mark[-1].expr, yystack.l_mark[0].expr); } break; case 99: #line 726 "gram.y" { yyval.expr = 0; } break; case 100: #line 729 "gram.y" { yyval.expr = NewExprTree (CASE, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 101: #line 731 "gram.y" { yyval.expr = NewExprTree (CASE, 0, yystack.l_mark[0].expr); } break; case 102: #line 734 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 103: #line 737 "gram.y" { yyval.expr = NewExprTree (CASE, yystack.l_mark[-1].expr, yystack.l_mark[0].expr); } break; case 104: #line 739 "gram.y" { yyval.expr = 0; } break; case 105: #line 742 "gram.y" { SymbolPtr sym = yystack.l_mark[-3].symbol; Atom sym_atom = sym ? sym->symbol.name : 0; ExprPtr name = 0; if (sym) name = NewExprAtom (sym_atom, sym, False); yyval.expr = NewExprTree (CASE, NewExprTree (CASE, NewExprAtom (yystack.l_mark[-4].atom, 0, False), name), yystack.l_mark[-1].expr); } break; case 106: #line 757 "gram.y" { yyval.expr = NewExprTree (CASE, 0, yystack.l_mark[0].expr); } break; case 107: #line 760 "gram.y" { yyval.symbol = ParseNewSymbol (publish_private, class_undef, typePoly, yystack.l_mark[0].atom); } break; case 108: #line 767 "gram.y" { yyval.symbol = 0; } break; case 109: #line 773 "gram.y" { yyval.atomList = NewAtomList (yystack.l_mark[0].atomList, yystack.l_mark[-2].atom); } break; case 110: #line 775 "gram.y" { yyval.atomList = NewAtomList (0, yystack.l_mark[0].atom); } break; case 111: #line 778 "gram.y" { yyval.declList = NewDeclList (yystack.l_mark[-2].atom, 0, yystack.l_mark[0].declList); } break; case 112: #line 780 "gram.y" { yyval.declList = NewDeclList (yystack.l_mark[0].atom, 0, 0); } break; case 115: #line 794 "gram.y" { if (yystack.l_mark[-3].symbol) { yyval.declList = NewDeclList (yystack.l_mark[-3].symbol->symbol.name, yystack.l_mark[-2].expr, yystack.l_mark[0].declList); yyval.declList->symbol = yystack.l_mark[-3].symbol; } else yyval.declList = yystack.l_mark[0].declList; } break; case 116: #line 804 "gram.y" { if (yystack.l_mark[-1].symbol) { yyval.declList = NewDeclList (yystack.l_mark[-1].symbol->symbol.name, yystack.l_mark[0].expr, 0); yyval.declList->symbol = yystack.l_mark[-1].symbol; } else yystack.l_mark[-1].symbol = 0; } break; case 117: #line 815 "gram.y" { yyval.symbol = ParseNewSymbol (yystack.l_mark[-1].fulltype.publish, yystack.l_mark[-1].fulltype.class, yystack.l_mark[-1].fulltype.type, yystack.l_mark[0].atom); } break; case 118: #line 827 "gram.y" { yyval.fulltype = yystack.l_mark[-3].fulltype; } break; case 119: #line 833 "gram.y" { NamespacePtr save = CurrentNamespace; SymbolPtr symbol; Type *type = NewTypeFunc (yystack.l_mark[-3].funcDecl.type.type, yystack.l_mark[-1].argType); /* * namespace_start pushed a new namespace, make sure * this symbol is placed in the original namespace */ CurrentNamespace = save->previous; symbol = NamespaceFindName (CurrentNamespace, yystack.l_mark[-3].funcDecl.decl->name, True); if (symbol && symbol->symbol.forward) { if (!TypeIsSupertype (symbol->symbol.type, type)) { ParseError ("%A redefinition with different type", yystack.l_mark[-3].funcDecl.decl->name); symbol = 0; } } else { symbol = ParseNewSymbol (yystack.l_mark[-3].funcDecl.type.publish, yystack.l_mark[-3].funcDecl.type.class, type, yystack.l_mark[-3].funcDecl.decl->name); } CurrentNamespace = save; yyval.funcDecl = yystack.l_mark[-3].funcDecl; yyval.funcDecl.decl->symbol = symbol; yyval.funcDecl.type.type = type; } break; case 120: #line 866 "gram.y" { yyval.funcDecl.type = yystack.l_mark[-2].fulltype; yyval.funcDecl.decl = NewDeclList (yystack.l_mark[-1].atom, 0, 0); } break; case 121: #line 868 "gram.y" { yyval.funcDecl.type = yystack.l_mark[-3].fulltype; yyval.funcDecl.decl = NewDeclList (yystack.l_mark[-1].atom, 0, 0); } break; case 122: #line 870 "gram.y" { yyval.funcDecl.type.publish = publish_private; yyval.funcDecl.type.class = class_undef; yyval.funcDecl.type.type = typePoly; yyval.funcDecl.decl = NewDeclList (yystack.l_mark[-1].atom, 0, 0); } break; case 123: #line 878 "gram.y" { yyval.expr = yystack.l_mark[0].expr; } break; case 124: #line 880 "gram.y" { yyval.expr = yystack.l_mark[0].expr; } break; case 125: #line 882 "gram.y" { yyval.expr = 0; } break; case 126: #line 888 "gram.y" { yyval.fulltype.publish = yystack.l_mark[-3].publish; yyval.fulltype.class = yystack.l_mark[-2].class; yyval.fulltype.type = yystack.l_mark[-1].type; } break; case 127: #line 890 "gram.y" { yyval.fulltype.publish = publish_private; yyval.fulltype.class = yystack.l_mark[-2].class; yyval.fulltype.type = yystack.l_mark[-1].type; } break; case 128: #line 892 "gram.y" { yyval.fulltype.publish = publish_private; yyval.fulltype.class = class_undef; yyval.fulltype.type = yystack.l_mark[-1].type; } break; case 129: #line 898 "gram.y" { yyval.type = NewTypeFunc (yystack.l_mark[0].type, yystack.l_mark[-1].argType); } break; case 130: #line 900 "gram.y" { yyval.type = NewTypeArray (yystack.l_mark[0].type, yystack.l_mark[-2].expr, False); } break; case 131: #line 902 "gram.y" { yyval.type = NewTypeArray (yystack.l_mark[0].type, yystack.l_mark[-2].expr, True); } break; case 132: #line 904 "gram.y" { yyval.type = NewTypeArray (yystack.l_mark[0].type, yystack.l_mark[-2].expr, False); } break; case 133: #line 906 "gram.y" { yyval.type = NewTypeHash (yystack.l_mark[0].type, yystack.l_mark[-2].type); } break; case 134: #line 908 "gram.y" { yyval.type = 0; } break; case 135: #line 911 "gram.y" { Type *top = yystack.l_mark[0].type; Type *t, **bot = ⊤ /* * Walk down the type chain to hang the * base type off of the end. This * makes int[]() be an array of functions * rather than a function returning an array */ while ((t = *bot)) switch (t->base.tag) { case type_array: bot = &t->array.type; break; case type_hash: bot = &t->hash.type; break; case type_func: bot = &t->func.ret; break; default: assert(0); } *bot = yystack.l_mark[-1].type; yyval.type = top; } break; case 136: #line 939 "gram.y" { yyval.type = NewTypeRef (yystack.l_mark[0].type, True); } break; case 137: #line 941 "gram.y" { yyval.type = NewTypeRef (NewTypeRef (yystack.l_mark[0].type, True), True); } break; case 138: #line 943 "gram.y" { yyval.type = NewTypeRef (NewTypeRef (yystack.l_mark[0].type, False), False); } break; case 139: #line 945 "gram.y" { yyval.type = NewTypeRef (yystack.l_mark[0].type, False); } break; case 140: #line 947 "gram.y" { if (ParseCanonType (yystack.l_mark[-2].type, False) != CanonTypeDefined) YYERROR; if (ParseCanonType (yystack.l_mark[0].type, False) != CanonTypeDefined) YYERROR; yyval.type = NewTypePlus (yystack.l_mark[-2].type, yystack.l_mark[0].type); if (!yyval.type) YYERROR; } break; case 142: #line 959 "gram.y" { AtomListPtr al; StructType *st; MemListPtr ml; int nelements; nelements = 0; for (ml = yystack.l_mark[-1].memList; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) nelements++; } st = NewStructType (nelements); nelements = 0; for (ml = yystack.l_mark[-1].memList; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) { AddBoxType (&st->types, ml->type); StructTypeAtoms(st)[nelements] = al->atom; nelements++; } } yyval.type = NewTypeStruct (st); } break; case 143: #line 985 "gram.y" { AtomListPtr al; StructType *st; MemListPtr ml; int nelements; nelements = 0; for (ml = yystack.l_mark[-1].memList; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) nelements++; } st = NewStructType (nelements); nelements = 0; for (ml = yystack.l_mark[-1].memList; ml; ml = ml->next) { for (al = ml->atoms; al; al = al->next) { AddBoxType (&st->types, ml->type); StructTypeAtoms(st)[nelements] = al->atom; nelements++; } } yyval.type = NewTypeUnion (st, False); } break; case 144: #line 1011 "gram.y" { AtomListPtr al; StructType *st; int nelements; nelements = 0; for (al = yystack.l_mark[-1].atomList; al; al = al->next) nelements++; st = NewStructType (nelements); nelements = 0; for (al = yystack.l_mark[-1].atomList; al; al = al->next) { AddBoxType (&st->types, typePrim[rep_void]); StructTypeAtoms(st)[nelements] = al->atom; nelements++; } yyval.type = NewTypeUnion (st, True); } break; case 145: #line 1032 "gram.y" { yyval.type = yystack.l_mark[-1].type; } break; case 146: #line 1034 "gram.y" { yyval.type = NewTypeName (yystack.l_mark[0].expr, 0); } break; case 148: #line 1038 "gram.y" { yyval.type = typePoly; } break; case 163: #line 1056 "gram.y" { yyval.expr = 0; } break; case 164: #line 1059 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, yystack.l_mark[-2].expr); } break; case 165: #line 1061 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, 0); } break; case 166: #line 1064 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, yystack.l_mark[-2].expr); } break; case 167: #line 1066 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, 0); } break; case 168: #line 1069 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 169: #line 1071 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[0].expr, 0); } break; case 170: #line 1077 "gram.y" { yyval.memList = NewMemList (yystack.l_mark[-2].atomList, yystack.l_mark[-3].type, yystack.l_mark[0].memList); } break; case 171: #line 1079 "gram.y" { yyval.memList = 0; } break; case 172: #line 1082 "gram.y" { yyval.memList = NewMemList (yystack.l_mark[-2].atomList, yystack.l_mark[-3].type, yystack.l_mark[0].memList); } break; case 173: #line 1084 "gram.y" { yyval.memList = 0; } break; case 175: #line 1091 "gram.y" { yyval.class = class_undef; } break; case 181: #line 1100 "gram.y" { yyval.publish = publish_private; } break; case 186: #line 1114 "gram.y" { yyval.argType = yystack.l_mark[-1].argType; } break; case 187: #line 1116 "gram.y" { yyval.argType = 0; } break; case 188: #line 1119 "gram.y" { yyval.argType = NewArgType (yystack.l_mark[-2].argDecl.type, False, yystack.l_mark[-2].argDecl.name, 0, yystack.l_mark[0].argType); } break; case 189: #line 1121 "gram.y" { yyval.argType = NewArgType (yystack.l_mark[-1].argDecl.type, yystack.l_mark[0].bool, yystack.l_mark[-1].argDecl.name, 0, 0); } break; case 190: #line 1124 "gram.y" { ParseCanonType (yystack.l_mark[-1].type, False); yyval.argDecl.type = yystack.l_mark[-1].type; yyval.argDecl.name = yystack.l_mark[0].atom; } break; case 191: #line 1130 "gram.y" { ParseCanonType (yystack.l_mark[0].type, False); yyval.argDecl.type = yystack.l_mark[0].type; yyval.argDecl.name = 0; } break; case 192: #line 1141 "gram.y" { yyval.argType = yystack.l_mark[-1].argType; } break; case 193: #line 1144 "gram.y" { ArgType *args; Type *type; for (args = yystack.l_mark[0].argType; args; args = args->next) { type = args->type; if (ParseCanonType (type, False) != CanonTypeDefined) break; if (args->varargs) { type = NewTypeArray (type, NewExprTree (COMMA, NewExprConst (TEN_NUM, NewInt (0)), 0), False); } args->symbol = ParseNewSymbol (publish_private, class_arg, type, args->name); } yyval.argType = yystack.l_mark[0].argType; } break; case 194: #line 1169 "gram.y" { yyval.argType = 0; } break; case 195: #line 1172 "gram.y" { yyval.argType = NewArgType (yystack.l_mark[-2].argDecl.type, False, yystack.l_mark[-2].argDecl.name, 0, yystack.l_mark[0].argType); } break; case 196: #line 1174 "gram.y" { yyval.argType = NewArgType (yystack.l_mark[-1].argDecl.type, yystack.l_mark[0].bool, yystack.l_mark[-1].argDecl.name, 0, 0); } break; case 197: #line 1177 "gram.y" { yyval.argDecl.type = yystack.l_mark[-1].type; yyval.argDecl.name = yystack.l_mark[0].atom; } break; case 198: #line 1179 "gram.y" { yyval.argDecl.type = yystack.l_mark[0].type; yyval.argDecl.name = 0; } break; case 199: #line 1182 "gram.y" { yyval.bool = True; } break; case 200: #line 1184 "gram.y" { yyval.bool = False; } break; case 202: #line 1192 "gram.y" { yyval.expr = 0; } break; case 204: #line 1196 "gram.y" { DeclList *decl; for (decl = yystack.l_mark[0].declList; decl; decl = decl->next) { if (decl->init) { if (!decl->init->base.type) decl->init->base.type = yystack.l_mark[-1].fulltype.type; } } yyval.expr = NewExprDecl (VAR, yystack.l_mark[0].declList, yystack.l_mark[-1].fulltype.class, yystack.l_mark[-1].fulltype.type, yystack.l_mark[-1].fulltype.publish); } break; case 206: #line 1213 "gram.y" { yyval.expr = NewExprTree(COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 208: #line 1220 "gram.y" { yyval.expr = 0; } break; case 209: #line 1223 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 210: #line 1225 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[0].expr, 0); } break; case 212: #line 1229 "gram.y" { yyval.expr = 0; } break; case 213: #line 1232 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 214: #line 1234 "gram.y" { ExprPtr arg = yystack.l_mark[0].bool ? NewExprTree (DOTDOTDOT, yystack.l_mark[-1].expr, 0) : yystack.l_mark[-1].expr; yyval.expr = NewExprTree (COMMA, arg, 0); } break; case 215: #line 1240 "gram.y" { yyval.expr = NewExprTree (OC, NewExprTree (RETURNTOK, 0, yystack.l_mark[0].expr), NewExprTree (OC, 0, 0)); } break; case 216: #line 1245 "gram.y" { ++funcDepth; } break; case 217: #line 1245 "gram.y" { --funcDepth; yyval.expr = yystack.l_mark[0].expr; } break; case 218: #line 1251 "gram.y" { if (yystack.l_mark[-1].ints == ASSIGNPOW) yyval.expr = NewExprTree (ASSIGNPOW, BuildName ("Math", "assign_pow"), NewExprTree (ASSIGNPOW, yystack.l_mark[-2].expr, yystack.l_mark[0].expr)); else { ExprPtr left = yystack.l_mark[-2].expr; /* * Automatically declare names used in * simple assignements at the top level */ if (yystack.l_mark[-1].ints == ASSIGN && funcDepth == 0 && left->base.tag == NAME && !(left->atom.symbol)) { yystack.l_mark[-2].expr->atom.symbol = ParseNewSymbol (publish_private, class_undef, typePoly, yystack.l_mark[-2].expr->atom.atom); } yyval.expr = NewExprTree(yystack.l_mark[-1].ints, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } } break; case 219: #line 1277 "gram.y" { ParseCanonType (yystack.l_mark[-6].type, False); yyval.expr = NewExprCode (NewFuncCode (yystack.l_mark[-6].type, yystack.l_mark[-3].argType, yystack.l_mark[-1].expr, yystack.l_mark[-2].value), 0); } break; case 220: #line 1282 "gram.y" { Value t; t = do_Thread_id_to_thread (yystack.l_mark[0].value); if (t == Void) { ParseError ("No thread %v", yystack.l_mark[0].value); YYERROR; } else yyval.expr = NewExprConst(THREAD_CONST, t); } break; case 221: #line 1293 "gram.y" { yyval.expr = NewExprTree(STAR, yystack.l_mark[0].expr, (Expr *) 0); } break; case 222: #line 1295 "gram.y" { yyval.expr = NewExprTree(STAR, NewExprTree (STAR, yystack.l_mark[0].expr, 0), 0); } break; case 223: #line 1297 "gram.y" { yyval.expr = NewExprTree(AMPER, yystack.l_mark[0].expr, (Expr *) 0); } break; case 224: #line 1299 "gram.y" { yyval.expr = NewExprTree(AMPER, NewExprTree (AMPER, yystack.l_mark[0].expr, (Expr *) 0), (Expr *) 0); } break; case 225: #line 1303 "gram.y" { yyval.expr = NewExprTree(UMINUS, yystack.l_mark[0].expr, (Expr *) 0); } break; case 226: #line 1305 "gram.y" { yyval.expr = NewExprTree(LNOT, yystack.l_mark[0].expr, (Expr *) 0); } break; case 227: #line 1307 "gram.y" { yyval.expr = NewExprTree(BANG, yystack.l_mark[0].expr, (Expr *) 0); } break; case 228: #line 1309 "gram.y" { yyval.expr = NewExprTree(FACT, BuildName ("Math", "factorial"), yystack.l_mark[-1].expr); } break; case 229: #line 1315 "gram.y" { yyval.expr = NewExprTree(INC, yystack.l_mark[0].expr, (Expr *) 0); } break; case 230: #line 1317 "gram.y" { yyval.expr = NewExprTree(INC, (Expr *) 0, yystack.l_mark[-1].expr); } break; case 231: #line 1319 "gram.y" { yyval.expr = NewExprTree(DEC, yystack.l_mark[0].expr, (Expr *) 0); } break; case 232: #line 1321 "gram.y" { yyval.expr = NewExprTree(DEC, (Expr *) 0, yystack.l_mark[-1].expr); } break; case 233: #line 1323 "gram.y" { yyval.expr = NewExprTree (FORK, (Expr *) 0, yystack.l_mark[0].expr); } break; case 234: #line 1325 "gram.y" { yyval.expr = NewExprTree(PLUS, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 235: #line 1327 "gram.y" { yyval.expr = NewExprTree(MINUS, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 236: #line 1329 "gram.y" { yyval.expr = NewExprTree(TIMES, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 237: #line 1331 "gram.y" { yyval.expr = NewExprTree(DIVIDE, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 238: #line 1333 "gram.y" { yyval.expr = NewExprTree(DIV, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 239: #line 1335 "gram.y" { yyval.expr = NewExprTree(MOD, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 240: #line 1337 "gram.y" { yyval.expr = NewExprTree(POW, BuildName ("Math", "pow"), NewExprTree (POW, yystack.l_mark[-2].expr, yystack.l_mark[0].expr)); } break; case 241: #line 1343 "gram.y" { yyval.expr = NewExprTree (POW, BuildName("Math", "pow"), NewExprTree (POW, yystack.l_mark[-1].expr, NewExprConst (TEN_NUM, NewInt(2)))); } break; case 242: #line 1351 "gram.y" { yyval.expr = NewExprTree (POW, BuildName("Math", "pow"), NewExprTree (POW, yystack.l_mark[-1].expr, NewExprConst (TEN_NUM, NewInt(3)))); } break; case 243: #line 1359 "gram.y" { yyval.expr = NewExprTree(SHIFTL, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 244: #line 1361 "gram.y" { yyval.expr = NewExprTree(SHIFTR, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 245: #line 1363 "gram.y" { yyval.expr = NewExprTree(QUEST, yystack.l_mark[-4].expr, NewExprTree(COLON, yystack.l_mark[-2].expr, yystack.l_mark[0].expr)); } break; case 246: #line 1365 "gram.y" { yyval.expr = NewExprTree(LXOR, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 247: #line 1367 "gram.y" { yyval.expr = NewExprTree(LAND, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 248: #line 1369 "gram.y" { yyval.expr = NewExprTree(LOR, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 249: #line 1371 "gram.y" { yyval.expr = NewExprTree(AND, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 250: #line 1373 "gram.y" { yyval.expr = NewExprTree(OR, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 251: #line 1375 "gram.y" { yyval.expr = NewExprTree(EQ, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 252: #line 1377 "gram.y" { yyval.expr = NewExprTree(NE, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 253: #line 1379 "gram.y" { yyval.expr = NewExprTree(LT, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 254: #line 1381 "gram.y" { yyval.expr = NewExprTree(GT, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 255: #line 1383 "gram.y" { yyval.expr = NewExprTree(LE, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 256: #line 1385 "gram.y" { yyval.expr = NewExprTree(GE, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 258: #line 1388 "gram.y" { yyval.expr = NewExprConst(TEN_NUM, yystack.l_mark[0].value); } break; case 259: #line 1390 "gram.y" { yyval.expr = NewExprConst(OCTAL_NUM, yystack.l_mark[0].value); } break; case 260: #line 1392 "gram.y" { yyval.expr = NewExprConst(OCTAL0_NUM, yystack.l_mark[0].value); } break; case 261: #line 1394 "gram.y" { yyval.expr = NewExprConst(BINARY_NUM, yystack.l_mark[0].value); } break; case 262: #line 1396 "gram.y" { yyval.expr = NewExprConst(HEX_NUM, yystack.l_mark[0].value); } break; case 263: #line 1398 "gram.y" { yyval.expr = NewExprConst(TEN_FLOAT, yystack.l_mark[0].value); } break; case 264: #line 1400 "gram.y" { yyval.expr = NewExprConst(OCTAL_FLOAT, yystack.l_mark[0].value); } break; case 265: #line 1402 "gram.y" { yyval.expr = NewExprConst(OCTAL0_FLOAT, yystack.l_mark[0].value); } break; case 266: #line 1404 "gram.y" { yyval.expr = NewExprConst(BINARY_FLOAT, yystack.l_mark[0].value); } break; case 267: #line 1406 "gram.y" { yyval.expr = NewExprConst(HEX_FLOAT, yystack.l_mark[0].value); } break; case 268: #line 1408 "gram.y" { yyval.expr = NewExprConst(CHAR_CONST, yystack.l_mark[0].value); } break; case 269: #line 1410 "gram.y" { yyval.expr = NewExprConst(STRING_CONST, yystack.l_mark[0].value); } break; case 270: #line 1412 "gram.y" { yyval.expr = NewExprConst(VOIDVAL, yystack.l_mark[0].value); } break; case 271: #line 1414 "gram.y" { yyval.expr = NewExprConst(BOOLVAL, yystack.l_mark[0].value); } break; case 272: #line 1416 "gram.y" { yyval.expr = BuildFullname (0, AtomId ("[]")); } break; case 273: #line 1420 "gram.y" { ParseCanonType (yystack.l_mark[-4].type, False); if (yystack.l_mark[-1].expr) yystack.l_mark[-1].expr->base.type = yystack.l_mark[-4].type; yyval.expr = NewExprTree (NEW, yystack.l_mark[-1].expr, 0); yyval.expr->base.type = yystack.l_mark[-4].type; } break; case 274: #line 1428 "gram.y" { yystack.l_mark[-1].expr->base.type = NewTypeArray (typePoly, yystack.l_mark[-5].expr, True); ParseCanonType (yystack.l_mark[-1].expr->base.type, False); yyval.expr = NewExprTree (NEW, yystack.l_mark[-1].expr, 0); yyval.expr->base.type = yystack.l_mark[-1].expr->base.type; } break; case 275: #line 1435 "gram.y" { TypePtr t = NewTypeArray (typePoly, yystack.l_mark[-5].expr, False); ParseCanonType (t, False); yyval.expr = NewExprTree (NEW, yystack.l_mark[-1].expr, 0); if (yystack.l_mark[-1].expr) yystack.l_mark[-1].expr->base.type = t; yyval.expr->base.type = t; } break; case 276: #line 1444 "gram.y" { TypePtr t = NewTypeHash (typePoly, yystack.l_mark[-5].type); ParseCanonType (t, False); yyval.expr = NewExprTree (NEW, yystack.l_mark[-1].expr, 0); if (yystack.l_mark[-1].expr) yystack.l_mark[-1].expr->base.type = t; yyval.expr->base.type = t; } break; case 277: #line 1453 "gram.y" { ParseCanonType (yystack.l_mark[-2].type, False); yyval.expr = NewExprTree (UNION, NewExprAtom (yystack.l_mark[0].atom, 0, False), 0); yyval.expr->base.type = yystack.l_mark[-2].type; } break; case 278: #line 1459 "gram.y" { ParseCanonType (yystack.l_mark[-4].type, False); yyval.expr = NewExprTree (UNION, NewExprAtom (yystack.l_mark[-2].atom, 0, False), yystack.l_mark[0].expr); yyval.expr->base.type = yystack.l_mark[-4].type; } break; case 279: #line 1465 "gram.y" { yyval.expr = BuildCall ("History", "fetch", 1, NewExprConst (TEN_NUM, yystack.l_mark[0].value)); } break; case 280: #line 1467 "gram.y" { yyval.expr = NewExprTree (DOLLAR, 0, 0); } break; case 281: #line 1469 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 282: #line 1471 "gram.y" { yyval.expr = yystack.l_mark[-1].expr; } break; case 283: #line 1473 "gram.y" { yyval.expr = NewExprTree (OS, NewExprTree (STAR, yystack.l_mark[-3].expr, (Expr *) 0), yystack.l_mark[-1].expr); } break; case 284: #line 1475 "gram.y" { yyval.expr = NewExprTree(OS, yystack.l_mark[-3].expr, yystack.l_mark[-1].expr); } break; case 285: #line 1477 "gram.y" { yyval.expr = NewExprTree (OP, yystack.l_mark[-3].expr, yystack.l_mark[-1].expr); } break; case 286: #line 1479 "gram.y" { TypePtr type = yystack.l_mark[-1].type; ParseCanonType (type, False); yyval.expr = NewExprType (ISTYPE, yystack.l_mark[-3].expr, type); } break; case 287: #line 1485 "gram.y" { yyval.expr = NewExprTree (HASMEMBER, yystack.l_mark[-3].expr, NewExprAtom(yystack.l_mark[-1].atom, 0, False)); } break; case 288: #line 1487 "gram.y" { yyval.expr = NewExprTree(DOT, yystack.l_mark[-2].expr, NewExprAtom (yystack.l_mark[0].atom, 0, False)); } break; case 289: #line 1489 "gram.y" { yyval.expr = NewExprTree(ARROW, yystack.l_mark[-2].expr, NewExprAtom (yystack.l_mark[0].atom, 0, False)); } break; case 291: #line 1493 "gram.y" { yyval.value = Zero; } break; case 313: #line 1521 "gram.y" { yyval.expr = 0; } break; case 314: #line 1523 "gram.y" { yyval.expr = 0; } break; case 315: #line 1526 "gram.y" { ExprPtr elts = yystack.l_mark[-3].expr ? ExprRehang (yystack.l_mark[-3].expr, 0) : 0; if (yystack.l_mark[-1].bool) { ExprPtr i = elts; while (i->tree.right) i = i->tree.right; i->tree.right = NewExprTree (COMMA, NewExprTree (DOTDOTDOT, 0, 0), 0); } yyval.expr = NewExprTree (ARRAY, elts, 0); } break; case 316: #line 1540 "gram.y" { yyval.expr = NewExprTree (COMP, NewExprTree (COMP, yystack.l_mark[-5].expr, yystack.l_mark[-4].expr), yystack.l_mark[-2].expr); } break; case 317: #line 1545 "gram.y" { yyval.expr = yystack.l_mark[0].expr; } break; case 319: #line 1549 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 321: #line 1553 "gram.y" { SymbolPtr s; s = ParseNewSymbol (publish_private, class_arg, typePrim[rep_integer], yystack.l_mark[0].atom); yyval.expr = NewExprAtom (yystack.l_mark[0].atom, s, False); } break; case 322: #line 1561 "gram.y" { SymbolPtr s; Atom a = AtomId("[]"); s = ParseNewSymbol (publish_private, class_undef, typePoly, a); yyval.expr = NewExprAtom (a, s, False); } break; case 323: #line 1570 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 324: #line 1572 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, yystack.l_mark[0].expr); } break; case 328: #line 1583 "gram.y" { yyval.expr = 0; } break; case 329: #line 1585 "gram.y" { yyval.expr = 0; } break; case 330: #line 1588 "gram.y" { ExprPtr elts = yystack.l_mark[-2].expr ? ExprRehang (yystack.l_mark[-2].expr, 0) : 0; yyval.expr = NewExprTree (HASH, elts, 0); } break; case 331: #line 1594 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 332: #line 1596 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, yystack.l_mark[0].expr); } break; case 333: #line 1599 "gram.y" { yyval.expr = NewExprTree (DARROW, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 334: #line 1601 "gram.y" { yyval.expr = NewExprTree (DARROW, 0, yystack.l_mark[0].expr); } break; case 337: #line 1610 "gram.y" { yyval.expr = NewExprTree (STRUCT, ExprRehang (yystack.l_mark[-2].expr, 0), 0); } break; case 338: #line 1613 "gram.y" { yyval.expr = NewExprTree (COMMA, yystack.l_mark[-2].expr, yystack.l_mark[0].expr); } break; case 339: #line 1615 "gram.y" { yyval.expr = NewExprTree (COMMA, 0, yystack.l_mark[0].expr); } break; case 340: #line 1618 "gram.y" { yyval.expr = NewExprTree (ASSIGN, NewExprAtom (yystack.l_mark[-2].atom, 0, False), yystack.l_mark[0].expr); } break; case 341: #line 1620 "gram.y" { yyval.expr = NewExprTree (ASSIGN, NewExprAtom (yystack.l_mark[-2].atom, 0, False), yystack.l_mark[0].expr); } break; case 342: #line 1622 "gram.y" { yyval.expr = NewExprTree (ASSIGN, NewExprAtom (yystack.l_mark[-2].atom, 0, False), yystack.l_mark[0].expr); } break; case 343: #line 1624 "gram.y" { yyval.expr = NewExprTree (ASSIGN, NewExprAtom (yystack.l_mark[-2].atom, 0, False), yystack.l_mark[0].expr); } break; case 347: #line 1630 "gram.y" { yyval.expr = NewExprTree (ANONINIT, 0, 0); } break; #line 4895 "gram.c" } yystack.s_mark -= yym; yystate = *yystack.s_mark; yystack.l_mark -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state 0 to\ state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; *++yystack.s_mark = YYFINAL; *++yystack.l_mark = yyval; if (yychar < 0) { if ((yychar = YYLEX) < 0) yychar = YYEOF; #if YYDEBUG if (yydebug) { yys = yyname[YYTRANSLATE(yychar)]; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == YYEOF) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state %d \ to state %d\n", YYPREFIX, *yystack.s_mark, yystate); #endif if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) { goto yyoverflow; } *++yystack.s_mark = (YYINT) yystate; *++yystack.l_mark = yyval; goto yyloop; yyoverflow: YYERROR_CALL("yacc stack overflow"); yyabort: yyfreestack(&yystack); return (1); yyaccept: yyfreestack(&yystack); return (0); } nickle_2.81.orig/integer.c0000664000175000000620000002364513202412076014710 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * integer.c * * operations on integers */ #include "nickle.h" #define IMag(i) ((Natural *) ((long) ((i)->magn) & ~1)) #define ISign(i) ((Sign) ((long) ((i)->magn) & 1)) int IntegerToInt (Integer *i) { int result; result = NaturalToInt (IMag(i)); if (ISign(i) == Negative) result = -result; return result; } signed_digit IntegerToSignedDigit(Integer *i) { double_digit dd; signed_digit sd; dd = NaturalToDoubleDigit(IMag(i)); if (ISign(i) == Negative) sd = -(signed_digit) dd; else sd = (signed_digit) dd; return sd; } int IntegerFitsSignedDigit(Integer *i) { return NaturalLess(IMag(i), max_signed_digit_natural); } static Value IntegerPlus (Value av, Value bv, int expandOk) { ENTER (); Integer *a = &av->integer, *b = &bv->integer; Value ret; switch (catagorize_signs(ISign(a), ISign(b))) { case BothPositive: default: ret = NewInteger (Positive, NaturalPlus (IMag(a), IMag(b))); break; case FirstPositive: if (NaturalLess (IMag(a), IMag(b))) ret = NewInteger (Negative, NaturalMinus (IMag(b), IMag(a))); else ret = NewInteger (Positive, NaturalMinus (IMag(a), IMag(b))); break; case SecondPositive: if (NaturalLess (IMag(a), IMag(b))) ret = NewInteger (Positive, NaturalMinus (IMag(b), IMag(a))); else ret = NewInteger (Negative, NaturalMinus (IMag(a), IMag(b))); break; case BothNegative: ret = NewInteger (Negative, NaturalPlus (IMag(a), IMag(b))); break; } RETURN (ret); } static Value IntegerMinus (Value av, Value bv, int expandOk) { ENTER (); Integer *a = &av->integer, *b = &bv->integer; Value ret; switch (catagorize_signs(ISign(a), ISign(b))) { case BothPositive: default: if (NaturalLess (IMag(a), IMag(b))) ret = NewInteger (Negative, NaturalMinus (IMag(b), IMag(a))); else ret = NewInteger (Positive, NaturalMinus (IMag(a), IMag(b))); break; case FirstPositive: ret = NewInteger (Positive, NaturalPlus (IMag(a), IMag(b))); break; case SecondPositive: ret = NewInteger (Negative, NaturalPlus (IMag(a), IMag(b))); break; case BothNegative: if (NaturalLess (IMag(a), IMag(b))) ret = NewInteger (Positive, NaturalMinus (IMag(b), IMag(a))); else ret = NewInteger (Negative, NaturalMinus (IMag(a), IMag(b))); break; } RETURN (ret); } static Value IntegerTimes (Value av, Value bv, int expandOk) { ENTER (); Integer *a = &av->integer, *b = &bv->integer; Sign sign; sign = Positive; if (ISign(a) != ISign(b)) sign = Negative; RETURN (NewInteger (sign, NaturalTimes (IMag(a), IMag(b)))); } static Value IntegerDivide (Value av, Value bv, int expandOk) { ENTER (); Integer *a = &av->integer, *b = &bv->integer; Natural *rem; Sign sign; if (NaturalZero (IMag(b))) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } sign = Positive; if (ISign(a) != ISign(b)) sign = Negative; if (expandOk) RETURN (NewRational (sign, IMag(a), IMag(b))); else RETURN (NewInteger (sign, NaturalDivide (IMag(a), IMag(b), &rem))); } static Value IntegerDiv (Value av, Value bv, int expandOk) { ENTER (); Integer *a = &av->integer, *b = &bv->integer; Sign sign; Natural *quo, *rem; if (NaturalZero (IMag(b))) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } quo = NaturalDivide (IMag(a), IMag(b), &rem); sign = Positive; if (ISign (a) != ISign (b)) sign = Negative; if (ISign (a) == Negative && !NaturalZero (rem)) quo = NaturalPlus (quo, one_natural); RETURN (NewInteger (sign, quo)); } static Value IntegerMod (Value av, Value bv, int expandOk) { ENTER (); Integer *a = &av->integer, *b = &bv->integer; Natural *rem; if (NaturalZero (IMag(b))) { RaiseStandardException (exception_divide_by_zero, 2, av, bv); RETURN (Void); } (void) NaturalDivide (IMag(a), IMag(b), &rem); if (ISign(a) == Negative && !NaturalZero (rem)) rem = NaturalMinus (IMag(b), rem); RETURN (NewInteger (Positive, rem)); } static Value IntegerLess (Value av, Value bv, int expandOk) { Integer *a = &av->integer, *b = &bv->integer; Value ret; ret = FalseVal; switch (catagorize_signs (ISign(a), ISign(b))) { case BothPositive: if (NaturalLess (IMag(a), IMag(b))) ret = TrueVal; break; case FirstPositive: break; case SecondPositive: ret = TrueVal; break; case BothNegative: if (NaturalLess (IMag(b), IMag(a))) ret = TrueVal; break; } return ret; } static Value IntegerEqual (Value av, Value bv, int expandOk) { Integer *a = &av->integer, *b = &bv->integer; if (ISign(a) == ISign(b) && NaturalEqual (IMag(a), IMag(b))) return TrueVal; return FalseVal; } #if 0 #define DebugN(s,n) FilePrintf (FileStdout, "%s %N\n", s, n) #else #define DebugN(s,n) #endif static Value IntegerLand (Value av, Value bv, int expandOk) { ENTER (); Value ret; Integer *a = &av->integer, *b = &bv->integer; Natural *am = IMag(a), *bm = IMag(b), *m; DebugN("a", am); if (ISign(a) == Negative) { am = NaturalNegate (am, NaturalLength (bm)); DebugN ("-a", am); } DebugN("b", bm); if (ISign(b) == Negative) { bm = NaturalNegate (bm, NaturalLength (am)); DebugN("-b", bm); } m = NaturalLand (am, bm); DebugN("m", m); if (ISign(a) == Negative && ISign(b) == Negative) { m = NaturalNegate (m, 0); DebugN("-m", m); ret = NewInteger (Negative, m); } else ret = NewInteger (Positive, m); RETURN (ret); } static Value IntegerLor (Value av, Value bv, int expandOk) { ENTER (); Value ret; Integer *a = &av->integer, *b = &bv->integer; Natural *am = IMag(a), *bm = IMag(b), *m; DebugN("a", am); if (ISign(a) == Negative) { am = NaturalNegate (am, NaturalLength (bm)); DebugN ("-a", am); } DebugN("b", bm); if (ISign(b) == Negative) { bm = NaturalNegate (bm, NaturalLength (am)); DebugN("-b", bm); } m = NaturalLor (am, bm); DebugN("m", m); if (ISign(a) == Negative || ISign(b) == Negative) { m = NaturalNegate (m, 0); DebugN("-m", m); ret = NewInteger (Negative, m); } else ret = NewInteger (Positive, m); RETURN (ret); } static Value IntegerNegate (Value av, int expandOk) { Integer *a = &av->integer; return NewInteger (SignNegate (ISign(a)), IMag(a)); } static Value IntegerFloor (Value av, int expandOk) { return av; } static Value IntegerCeil (Value av, int expandOk) { return av; } static Value IntegerPromote (Value av, Value bv) { if (ValueIsInt(av)) av = NewIntInteger (ValueInt(av)); return av; } static Value IntegerReduce (Value av) { Integer *a = &av->integer; if (NaturalLess (IMag(a), max_int_natural)) av = NewInt (IntegerToInt (a)); return av; } static Bool IntegerPrint (Value f, Value iv, char format, int base, int width, int prec, int fill) { ENTER (); Integer *i = &iv->integer; char *result; int print_width; int fraction_width; if (base == 0) base = 10; result = NaturalSprint (0, IMag(i), base, &print_width); if (result) { if (ISign(i) == Negative) print_width++; fraction_width = 0; if (prec >= 0) { int avail_width; if (width > 0) avail_width = width; else avail_width = -width; fraction_width = prec + 1; if (avail_width > 0) { if (print_width + fraction_width > avail_width) { fraction_width = avail_width - print_width; if (fraction_width < 0) fraction_width = 0; } } } print_width += fraction_width; while (width > print_width) { FileOutchar (f, fill); width--; } if (ISign(i) == Negative) FileOutput (f, '-'); FilePuts (f, result); if (fraction_width) { FileOutput (f, '.'); --fraction_width; while (fraction_width) { FileOutput (f, '0'); --fraction_width; } } while (-width > print_width) { FileOutchar (f, fill); width++; } } EXIT (); return result != 0; } static HashValue IntegerHash (Value iv) { return NaturalHash (IntegerMag(iv)) ^ IntegerSign(iv); } static void IntegerMark (void *object) { Integer *integer = object; MemReference (IMag(integer)); } ValueRep IntegerRep = { { IntegerMark, 0, "IntegerRep" }, /* base */ rep_integer, /* tag */ { /* binary */ IntegerPlus, IntegerMinus, IntegerTimes, IntegerDivide, IntegerDiv, IntegerMod, IntegerLess, IntegerEqual, IntegerLand, IntegerLor, }, { /* unary */ IntegerNegate, IntegerFloor, IntegerCeil, }, IntegerPromote, IntegerReduce, IntegerPrint, 0, IntegerHash, }; #define INTEGER_CACHE_SIZE 8191 DataCachePtr integerCache; Value NewInteger (Sign sign, Natural *mag) { ENTER (); unsigned c = (PtrToUInt(mag) ^ (unsigned) sign) % INTEGER_CACHE_SIZE; Value *re = (Value *) DataCacheValues(integerCache) + c; Value ret = *re; if (ret && IntegerSign(ret) == sign && NaturalEqual (mag, IntegerMag(ret))) { RETURN (ret); } ret = ALLOCATE (&IntegerRep.data, sizeof (Integer)); ret->integer.magn = (Natural *) (((long) mag) | (long) sign); *re = ret; RETURN (ret); } Value NewIntInteger (int i) { ENTER (); Sign sign = Positive; unsigned long mag; if (i < 0) { sign = Negative; mag = -i; } else mag = i; RETURN (NewInteger (sign, NewNatural (mag))); } Value NewSignedDigitInteger (signed_digit d) { ENTER (); Sign sign = Positive; double_digit dd; if (d < 0) { sign = Negative; dd = -d; } else dd = d; RETURN (NewInteger (sign, NewDoubleDigitNatural (dd))); } int IntegerInit (void) { ENTER (); integerCache = NewDataCache (INTEGER_CACHE_SIZE); EXIT (); return 1; } nickle_2.81.orig/builtin-environ.c0000664000175000000620000000574210770315535016406 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * environ.c * * provide builtin functions for the Environ namespace */ #include #include #include #include "builtin.h" NamespacePtr EnvironNamespace; void import_Environ_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { { do_Environ_check, "check", "b", "s", "\n" " bool check (string name)\n" "\n" " Test whether 'name' is in the environment\n" }, { do_Environ_get, "get", "s", "s", "\n" " string get (string name)\n" "\n" " Return a value from the environment.\n" " raise invalid_argument if 'name' isn't in the environment.\n" }, { do_Environ_unset, "unset", "b", "s", "\n" " bool unset (string name)\n" "\n" " Remove 'name' from the environment.\n" " Returns 'true' if 'name' was in the environment.\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_Environ_set, "set", "b", "ss", "\n" " bool set (string name, string value)\n" "\n" " Places 'name' with 'value' in the environment.\n" " Returns false if it didn't work for some reason.\n" }, { 0 } }; EnvironNamespace = BuiltinNamespace (/*parent*/ 0, "Environ")->namespace.namespace; BuiltinFuncs1 (&EnvironNamespace, funcs_1); BuiltinFuncs2 (&EnvironNamespace, funcs_2); EXIT (); } Value do_Environ_get (Value av) { ENTER (); char *name = StrzPart (av, "invalid environment variable name"); char *c; if (!name) RETURN (Void); c = getenv (name); if (!c) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("name not available"), NewInt(0), av); RETURN (Void); } RETURN (NewStrString (c)); } Value do_Environ_check (Value av) { ENTER (); char *name = StrzPart (av, "invalid environment variable name"); if (!name) RETURN (Void); if (getenv (name)) RETURN (TrueVal); RETURN (FalseVal); } Value do_Environ_unset (Value av) { ENTER (); char *name = StrzPart (av, "invalid environment variable name"); if (!name) RETURN (Void); #if HAVE_UNSETENV if (getenv (name)) { unsetenv (name); RETURN (TrueVal); } #endif RETURN (FalseVal); } Value do_Environ_set (Value name, Value value) { ENTER (); char *n = StrzPart (name, "invalid environment variable name"); char *v = StrzPart (value, "invalid environment variable value"); if (!n || !v) RETURN (Void); #if HAVE_SETENV if (setenv (n, v, 1) >= 0) RETURN (TrueVal); #else #if HAVE_PUTENV { Value binding = Plus (name, Plus (NewStrString ("="), value)); char *b = StrzPart (binding, "invalid environment variable binding"); if (!b) RETURN (Void); if (putenv (b) >= 0) RETURN (TrueVal); } #endif #endif RETURN (FalseVal); } nickle_2.81.orig/frame.c0000664000175000000620000000206010414112462014327 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ #include "nickle.h" static void FrameMark (void *object) { Frame *frame = object; do { MemReference (frame->staticLink); MemReference (frame->function); MemReference (frame->frame); MemReference (frame->statics); MemReference (frame->saveObj); frame = frame->previous; } while (MemReferenceNoRecurse (frame) == 0); } DataType FrameType = { FrameMark, 0, "FrameType" }; FramePtr NewFrame (Value function, FramePtr previous, FramePtr staticLink, BoxTypesPtr dynamics, BoxPtr statics) { ENTER (); FramePtr frame; frame = ALLOCATE (&FrameType, sizeof (Frame)); frame->previous = previous; frame->staticLink = staticLink; frame->function = function; frame->savePc = 0; frame->saveObj = 0; frame->statics = statics; frame->frame = 0; if (dynamics) frame->frame = NewTypedBox (False, dynamics); RETURN (frame); } nickle_2.81.orig/builtin.c0000664000175000000620000002305413202404114014705 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * builtin.c * * initialize builtin functions */ #include "builtin.h" static const struct sbuiltin svars[] = { { "> ", "prompt" }, { "+ ", "prompt2" }, { "- ", "prompt3" }, { "%g", "format" }, #ifdef BUILD_VERSION { BUILD_VERSION, "version" }, #else { VERSION, "version" }, #endif #ifdef BUILD { BUILD, "build" }, #else { "?", "build" }, #endif { 0, 0 }, }; extern NamespacePtr CommandNamespace; extern Type *typeSockaddr; static const struct envbuiltin envvars[] = { #ifdef CENVIRON { "NICKLEPATH", NICKLEPATH, "nickle_path", &CommandNamespace }, #else { NICKLELIBDIR, "nickle_libdir", &CommandNamespace }, #endif { 0, 0 }, }; static const struct filebuiltin fvars[] = { { "stdin", &FileStdin }, { "stdout", &FileStdout }, { "stderr", &FileStderr }, { 0, 0 }, }; static const struct ibuiltin ivars[] = { { DEFAULT_FLOAT_PREC, "float_precision", &GlobalNamespace }, { 0, 0 }, }; static const struct ebuiltin excepts[] = { {"uninitialized_value", exception_uninitialized_value, "s", "\n" " uninitialized_value (string message)\n" "\n" " Attempting to fetch from uninitialized storage.\n" " 'message' indicates the error context.\n" }, {"invalid_argument", exception_invalid_argument, "sip", "\n" " invalid_argument (string message, int id, poly value)\n" "\n" " Function argument 'id' couldn't accept 'value'.\n" " 'message' indicates the error context.\n" }, {"readonly_box", exception_readonly_box, "sp", "\n" " readonly_box (string message, poly value)\n" "\n" " Attempting to store 'value' in const storage.\n" " 'message' indicates the error context.\n" }, {"invalid_array_bounds", exception_invalid_array_bounds, "spp", "\n" " invalid_array_bounds (string message, poly box, poly index)\n" "\n" " Attempt to index outside of array or do pointer arithmetic\n" " on a pointer not referencing an array.\n" " 'message' indicates the error context.\n" }, {"divide_by_zero", exception_divide_by_zero, "RR", "\n" " divide_by_zero (real num, real den)\n" "\n" " Division or modulus by zero.\n" }, {"invalid_struct_member", exception_invalid_struct_member,"ps", "\n" " invalid_struct_member (poly value, string member)\n" "\n" " 'member' is not in 'value'.\n" }, {"invalid_binop_values", exception_invalid_binop_values, "spp", " invalid_binop_values (string message, poly left, poly right)\n" "\n" " 'left' and 'right' aren't compatible with a binary operator.\n" " 'message' indicates which operator is problematic.\n" }, {"invalid_unop_value", exception_invalid_unop_value, "sp", "\n" " invalid_unop_value (string message, poly value)\n" "\n" " 'value' isn't compatible with a unary operator.\n" " 'message' indicates which operator is problematic.\n" }, {0, 0 }, }; SymbolPtr BuiltinAddName (NamespacePtr *namespacep, SymbolPtr symbol) { ENTER (); NamespacePtr namespace; if (namespacep) namespace = *namespacep; else namespace = GlobalNamespace; RETURN(NamespaceAddName (namespace, symbol, publish_public)); } SymbolPtr BuiltinSymbol (NamespacePtr *namespacep, char *string, Type *type) { ENTER (); RETURN (BuiltinAddName (namespacep, NewSymbolGlobal (AtomId (string), type))); } static Type *typeUserdef[100]; void BuiltinSetUserdefType (Type *type, int n) { typeUserdef[n] = type; } static char * BuiltinType (char *format, Type **type, Bool arg) { Type *t; Bool ref = False; Bool array = False; Bool hash = False; Bool resizable = False; Expr *dims = 0; Type *k; char f; int i; ref = False; if (*format == '*') { ref = True; format++; } if (*format == 'A') { array = True; format++; while (*format == '*' || *format == '.') { if (*format == '.') resizable = True; dims = NewExprComma (0, dims); format++; } } if (*format == 'H') { hash = True; format = BuiltinType (format + 1, &k, True); } switch (f = *format++) { case 'p': t = typePoly; break; case 'n': t = typePrim[rep_float]; break; case 'N': t = typePrim[rep_float]; break; case 'E': t = typeFileError; break; case 'R': t = typePrim[rep_float]; break; case 'r': t = typePrim[rep_rational]; break; case 'i': t = typePrim[rep_integer]; break; case 's': t = typePrim[rep_string]; break; case 'f': t = typePrim[rep_file]; break; case 't': t = typePrim[rep_thread]; break; case 'S': t = typePrim[rep_semaphore]; break; case 'c': t = typePrim[rep_continuation]; break; case 'b': t = typePrim[rep_bool]; break; case 'v': t = typePrim[rep_void]; break; case 'F': t = typePrim[rep_foreign]; break; case 'a': t = typeSockaddr; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i = (f - '0') * 10 + (*format++) - '0'; t = typeUserdef[i]; if (t) break; default: t = 0; i = write (2, "Invalid builtin argument type\n", 30); (void) i; break; } if (ref) t = NewTypeRef (t, arg ? False : True); if (array) t = NewTypeArray (t, dims, resizable); if (hash) t = NewTypeHash (t, k); *type = t; return format; } static ArgType * BuiltinArgType (char *format, int *argcp) { ENTER (); ArgType *args, *a, **last; int argc; Type *t; Bool varargs; args = 0; last = &args; argc = 0; while (*format) { varargs = False; if (*format == '.') { varargs = True; format++; } format = BuiltinType (format, &t, True); if (!varargs) argc++; a = NewArgType (t, varargs, 0, 0, 0); *last = a; last = &a->next; } *argcp = argc; RETURN(args); } SymbolPtr BuiltinNamespace (NamespacePtr *namespacep, char *string) { ENTER (); RETURN (BuiltinAddName (namespacep, NewSymbolNamespace (AtomId (string), NewNamespace (GlobalNamespace)))); } SymbolPtr BuiltinException (NamespacePtr *namespacep, char *string, Type *type, char *doc) { ENTER (); Value doc_value = doc ? NewStrString (doc) : Void; RETURN (BuiltinAddName (namespacep, NewSymbolException (AtomId (string), type, doc_value))); } void BuiltinAddException (NamespacePtr *namespacep, StandardException exception, char *name, char *format, char *doc) { ENTER (); SymbolPtr sym; ArgType *args; Type *type; int argc; args = BuiltinArgType (format, &argc); type = NewTypeFunc (typePoly, args); sym = BuiltinException (namespacep, name, type, doc); RegisterStandardException (exception, sym); EXIT (); } void BuiltinAddFunction (NamespacePtr *namespacep, char *name, char *ret_format, char *format, BuiltinFunc f, Bool jumping, char *doc) { ENTER (); Value func; SymbolPtr sym; int argc; ArgType *args; Type *ret; args = BuiltinArgType (format, &argc); BuiltinType (ret_format, &ret, False); sym = BuiltinSymbol (namespacep, name, NewTypeFunc (ret, args)); func = NewFunc (NewBuiltinCode (ret, args, argc, f, jumping, doc), 0); BoxValueSet (sym->global.value, 0, func); EXIT (); } void BuiltinInit (void) { ENTER (); const struct filebuiltin *f; const struct ebuiltin *e; SymbolPtr sym; const struct envbuiltin *env; #ifdef CENVIRON char *home; Value home_val; #endif /* Import standard namespaces (and their contents :) */ import_Toplevel_namespace(); import_Debug_namespace(); import_File_namespace(); import_Math_namespace(); #ifdef BSD_RANDOM import_BSDRandom_namespace(); #endif import_Semaphore_namespace(); import_String_namespace(); import_Thread_namespace(); import_Command_namespace(); #ifdef GCD_DEBUG import_Gcd_namespace(); #endif import_Environ_namespace(); import_Socket_namespace(); import_Foreign_namespace (); import_PID_namespace (); import_Date_namespace(); /* Import builtin strings with predefined values */ BuiltinStrings (svars); #ifdef CENVIRON /* Get the user's home directory in case it's referenced in the * environment */ home = getenv ("HOME"); if (!home) home = "/tmp"; if (home[0] == '/' && home[1] == '\0') home = ""; home_val = NewStrString (home); /* Import builtin strings from the environment */ for (env = envvars; env->name; env++) { char *v; Value val; sym = BuiltinSymbol (env->namespace, env->name, typePrim[rep_string]); v = getenv (env->var); if (!v) v = env->def; if (*v == '~') val = Plus (home_val, NewStrString (v + 1)); else val = NewStrString (v); BoxValueSet (sym->global.value, 0, val); } #else /* export builtin strings */ for (env = envvars; env->name; env++) { Value val; sym = BuiltinSymbol (env->namespace, env->name, typePrim[rep_string]); val = NewStrString (env->def); BoxValueSet (sym->global.value, 0, val); } #endif /* Import File objects with predefined values */ for (f = fvars; f->name; f++) { sym = BuiltinSymbol (f->namespace, f->name, typePrim[rep_file]); BoxValueSet (sym->global.value, 0, *f->value); } /* Import int objects with predefined values */ BuiltinIntegers (ivars); /* Import standard exceptions */ for (e = excepts; e->name; e++) BuiltinAddException (0, e->exception, e->name, e->args, e->doc); EXIT (); } nickle_2.81.orig/builtin-string.c0000664000175000000620000001024110770315535016222 0ustar keithpstaff/* $Header$ */ /* * Copyright © 1988-2004 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ /* * string.c * * provide builtin functions for the String namespace */ #include #include #include #include "builtin.h" NamespacePtr StringNamespace; void import_String_namespace() { ENTER (); static const struct fbuiltin_1 funcs_1[] = { { do_String_length, "length", "i", "s", "\n" " int length (string s)\n" "\n" " Return the number of characters in 's'.\n" }, { do_String_new, "new", "s", "p", "\n" " string new (int c)\n" " string new (int[*] a)\n" "\n" " With 'c', return a single character string containing it.\n" " With 'a', return a string constructed from the list of\n" " characters in 'a'.\n" }, { 0 } }; static const struct fbuiltin_2 funcs_2[] = { { do_String_index, "index", "i", "ss", "\n" " int index (string str, string substr)\n" "\n" " Return the index of the first location of 'substr'\n" " within 'str', -1 if not found.\n" }, { 0 } }; static const struct fbuiltin_3 funcs_3[] = { { do_String_substr, "substr", "s", "sii", "\n" " string substr (string str, int first, int len)\n" "\n" " Return a string containing characters in 'str' starting at\n" " 'first' for 'len' characters.\n" }, { 0 } }; StringNamespace = BuiltinNamespace (/*parent*/ 0, "String")->namespace.namespace; BuiltinFuncs1 (&StringNamespace, funcs_1); BuiltinFuncs2 (&StringNamespace, funcs_2); BuiltinFuncs3 (&StringNamespace, funcs_3); EXIT (); } Value do_String_length (Value av) { ENTER(); Value ret; ret = NewInt(StringLength(StringChars(&av->string), av->string.length)); RETURN (ret); } Value do_String_new (Value av) { ENTER (); Value ret; int len, i, size; char *s; if (ValueIsArray(av) && av->array.ndim == 1) { len = ArrayLimits(&av->array)[0]; size = 0; for (i = 0; i < len; i++) size += StringCharSize (IntPart (ArrayValue (&av->array, i), "new: array element not integer")); ret = NewString (size); s = StringChars (&ret->string); for (i = 0; i < len; i++) { s += StringPutChar (IntPart (ArrayValue (&av->array, i), "new: array element not integer"), s); } } else { int c = IntPart (av, "new: argument not integer"); size = StringCharSize (c); ret = NewString (size); s = StringChars (&ret->string); s += StringPutChar (c, s); } RETURN (ret); } Value do_String_index (Value av, Value bv) { ENTER(); char *a, *b, *p; long al; Value ret; int i; a = StringChars(&av->string); al = av->string.length; b = StringChars(&bv->string); p = strstr(a, b); if (!p) RETURN (NewInt(-1)); i = 0; while (a < p) { unsigned c; a = StringNextChar (a, &c, &al); i++; } ret = NewInt(i); RETURN (ret); } Value do_String_substr (Value av, Value bv, Value cv) { ENTER(); char *a, *rchars, *e; int b, c, al, size; Value ret; long alen = av->string.length; long elen; a = StringChars(&av->string); al = StringLength (a, alen); b = IntPart(bv, "substr: index not integer"); c = IntPart(cv, "substr: count not integer"); if (c < 0) { b += c; c = -c; } if (b < 0 || b > al) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("substr: index out of range"), NewInt (1), bv); RETURN (av); } if (b + c > al) { RaiseStandardException (exception_invalid_argument, 3, NewStrString ("substr: count out of range"), NewInt (2), cv); RETURN (av); } /* * Find start of substring */ while (b > 0) { unsigned ch; a = StringNextChar (a, &ch, &alen); b--; } /* * Find size of substring */ e = a; elen = alen; while (c > 0) { unsigned ch; e = StringNextChar (e, &ch, &elen); c--; } size = e - a; ret = NewString(size); rchars = StringChars(&ret->string); memcpy (rchars, a, size); RETURN (ret); }