diff -rN old-lithium/li3_interp.h new-lithium/li3_interp.h
33c33,34
< #define LIMIT_PAIRS MAX_EXPLAIN*10      /* arbitrary, but limits computations */
---
> #define LIMIT_NODES MAX_EXPLAIN*10      /* arbitrary, but limits computations */
> #define LIMIT_CHARS 256
39a41,42
> typedef unsigned long addr;  // can hold a pointer
> 
41a45,46
> 	node hd;
> 	node tl;
43c48,49
< 	typedef node (*func_t)(node,machine,node);
---
> 	enum TYPE { NUMBER, CHAR, PAIR, PARTIAL, CFUNC };
> 	typedef node (* func_t )(node,machine,node);   // func_t points to C function
45,46d50
< 	unsigned short	value;
< 	enum { /*non-intlike:*/ PAIR, FUNC, /*intlike:*/ NUMBER, LETTER, SYMBOL } type : 3;
48,49d51
< 	node hd;
< 	node tl;
51c53,54
< 	char typeLetter() { return type==PAIR?'P':type==FUNC?'F':type==NUMBER?'N':type==LETTER?'L':type==SYMBOL?'S':     type==PAIR?'p': '?'; }
---
> 	inline	char	typeLetter();
> 	inline	Node::TYPE	getType();
53,64c56,60
< 	bool isNum() { return type==NUMBER; }
< 	bool isLet() { return type==LETTER; }
< 	bool isSym() { return type==SYMBOL; }
< 	bool isPair() { return type==PAIR; }
< 	bool isAtom() { return type!=PAIR; }
< 	bool isFunc() { return type==FUNC; }
< 	bool isIntLike() { return type >= NUMBER; }
< 	inline int integerize();
< 
< 	static void Initialize();
< 	static node Cons(node h, node t);
< 	static node NewFuncNode(func_t f, node t);
---
> 	inline	bool	isNumber();
> 	inline	bool	isChar();
> 	inline	bool	isPair();
> 	inline	bool	isCFunc();
> 	inline	bool	isPartial();
66c62,63
< 	node CallFuncNode(machine m, node arg);
---
> 	inline bool	isGlobalLetter();
> 	inline bool	isLambdaLetter();
68c65,76
< 	char* explain();  // caller must free
---
> 	inline	bool	isIntLike();
> 	inline	int	integerize();
> 	inline	int	letterNumber();
> 	inline	int	asciiValue();
> 
> 	static	void	Initialize();
> 	static	node	Cons(node h, node t);
> 	static	node	NewPartialNode(func_t f, node t);
> 
> 		node	CallPartialNode(machine m, node arg);
> 
> 	char*	explain();  // caller must free
75a84,85
> #define	FIRST_GLOBAL_LETTER ATOM('a')  /* a-m are globals; n-z are lambda */
> #define	LAST_GLOBAL_LETTER ATOM('m')  /* a-m are globals; n-z are lambda */
77c87,88
< #define	FIRST_NUMBER ATOM('0')
---
> #define	LAST_LAMBDA_LETTER ATOM('z')  /* a-m are globals; n-z are lambda */
> //#define	FIRST_NUMBER ATOM('0')
80,81c91
< extern Node Atoms[NUM_ATOMS];
< extern Node Pairs[LIMIT_PAIRS];
---
> extern Node Nodes[LIMIT_NODES];
84c94,110
< inline node ATOM(char c) { int x= 255&(int)c; assert( 0<=x && x<NUM_ATOMS ); return & Atoms[x]; } 
---
> #define CHARS_END (Nodes+LIMIT_CHARS)
> #define NODES_END (Nodes+LIMIT_NODES)
> 
> inline node ATOM(char c) { int x= 255&(int)c; assert(0<=x && x<NUM_ATOMS ); return & Nodes[x]; } 
> 
> inline bool Node::isNumber() {	return (1&(addr)this) != 0; }
> inline bool Node::isCFunc() {	return !(isNumber()) && (this<Nodes || NODES_END<=this); }
> 
> inline bool Node::isChar() {	return !(isNumber()) && Nodes<=this && this<CHARS_END; }
> inline bool Node::isPair() {	return !(isNumber()) && CHARS_END<=this && this<NODES_END && !hd->isCFunc(); }
> inline bool Node::isPartial() {	return !(isNumber()) && CHARS_END<=this && this<NODES_END &&  hd->isCFunc(); }
> 
> inline	Node::TYPE Node::getType() { return isNumber()? NUMBER: isChar()? CHAR: isPair()? PAIR: isPartial()? PARTIAL: isCFunc()? CFUNC: (assert(!"getType"), CFUNC ); }
> 
> inline	char Node::typeLetter() { return getType()==PAIR?'P':getType()==CFUNC?'Z':getType()==CHAR?'C':getType()==PARTIAL?'p': '?'; }
> 
> inline	bool	Node::isIntLike() { return isNumber() || isChar(); }
93c119
< int Node::integerize() {
---
> inline int Node::integerize() {
96c122,137
< 	return this->isIntLike()? ( NUM_ATOMS + (this - (Atoms+'0')) ) % NUM_ATOMS : 0;
---
> 	return isNumber()? ((int)this)>>1 : isChar()? (int)(this-Nodes) : (assert(!"integerize"),0);
> }
> inline bool Node::isGlobalLetter() {
> 	return ( FIRST_GLOBAL_LETTER<=this && this<=LAST_GLOBAL_LETTER);
> }
> inline bool Node::isLambdaLetter() {
> 	return ( FIRST_LAMBDA_LETTER<=this && this<=LAST_LAMBDA_LETTER);
> }
> 
> inline int Node::letterNumber() {
> 	assert( isGlobalLetter() || isLambdaLetter() );
> 	return this - FIRST_LETTER;
> }
> inline int Node::asciiValue() {
> 	assert( isChar() );
> 	return this - Nodes;
diff -rN old-lithium/lithium3.cc new-lithium/lithium3.cc
55,56c55,56
< Node Pairs[LIMIT_PAIRS];
< node NextPairPtr;
---
> Node Nodes[LIMIT_NODES];
> node NextNodePtr;
77c77
< 	Assert( Pairs<=NextPairPtr && NextPairPtr<=Pairs+LIMIT_PAIRS );
---
> 	Assert( Pairs<=NextNodePtr && NextNodePtr<=Pairs+LIMIT_NODES );
80,81c80,88
< 	if (p->isIntLike()) {
< 		Assert( Atoms<=p && p<=Atoms+NUM_ATOMS );
---
> 
> 	if ( (int)p & 1 ) return;
> 
> 	Assert( Nodes <= p ); 
> 	Assert( p < Nodes + LIMIT_NODES );
> 
> 	if (p->isChar()) {
> 		Assert( Nodes <= p ); 
> 		Assert( p < Nodes + LIMIT_CHARS );
83c90
< 		Assert( Pairs<=p && p<=Pairs+LIMIT_PAIRS );
---
> 		Assert( Pairs<=p && p<=Pairs+LIMIT_NODES );
86,87c93,94
< 	} else if (p->isFunc()) {
< 		Assert( Pairs<=p && p<=Pairs+LIMIT_PAIRS );
---
> 	} else if (p->isPartial()) {
> 		Assert( Pairs<=p && p<=Pairs+LIMIT_NODES );
114c121
< 	NextPairPtr= &Pairs[0];
---
> 	NextNodePtr= &Pairs[0];
117c124
< 	ICombinator= Node::NewFuncNode( & PrimativeI, Nil );
---
> 	ICombinator= Node::NewPartialNode( & PrimativeI, Nil );
123,124c130,131
< bool MorePairs() { return NextPairPtr < &Pairs[LIMIT_PAIRS]; }
< node NextPair() { return MorePairs() ? NextPairPtr++ : NULL; }
---
> bool MorePairs() { return NextNodePtr < &Pairs[LIMIT_NODES]; }
> node NextPair() { return MorePairs() ? NextNodePtr++ : NULL; }
133c140
< 		++freeTryCount; if (NextPairPtr - 1 == p) { --NextPairPtr; ++freeSuccessCount; } 
---
> 		++freeTryCount; if (NextNodePtr - 1 == p) { --NextNodePtr; ++freeSuccessCount; } 
220c227
< node Node::NewFuncNode(func_t f, node t)
---
> node Node::NewPartialNode(func_t f, node t)
226d232
< 	p->type= FUNC;
233c239
< node Node::CallFuncNode(machine m, node arg)
---
> node Node::CallPartialNode(machine m, node arg)
235c241
< 	Assert(this->isFunc());
---
> 	Assert(this->isPartial());
249d254
< 	p->type= PAIR;
261c266
< 			Assert( p->type == Node::PAIR );
---
> 			Assert( p->getType() == Node::PAIR );
265c270
< 			int n= LIMIT_PAIRS - 1; // -1 for ICombinator
---
> 			int n= LIMIT_NODES - LIMIT_CHARS - 1; // -1 for ICombinator
301c306
< 			Assert( ! Node::NewFuncNode(NULL,Nil)->isIntLike() );
---
> 			Assert( ! Node::NewPartialNode(NULL,Nil)->isIntLike() );
315c320
< 			Assert( Node::NewFuncNode(NULL,Nil)->integerize() == 0 );
---
> 			Assert( Node::NewPartialNode(NULL,Nil)->integerize() == 0 );
353c358
< 	return Node::NewFuncNode( & PartialCons, arg );
---
> 	return Node::NewPartialNode( & PartialCons, arg );
361c366
< 	return Node::NewFuncNode( & PartialReverseCons, arg );
---
> 	return Node::NewPartialNode( & PartialReverseCons, arg );
441c446
< 	return Node::NewFuncNode( & PartialMapCar, arg );
---
> 	return Node::NewPartialNode( & PartialMapCar, arg );
466c471
< 	return Node::NewFuncNode( & PartialS2, Node::Cons( self->tl, arg ) );
---
> 	return Node::NewPartialNode( & PartialS2, Node::Cons( self->tl, arg ) );
470c475
< 	return Node::NewFuncNode( & PartialS1, arg );
---
> 	return Node::NewPartialNode( & PartialS1, arg );
482c487
< 	return Node::NewFuncNode( & PartialPlus, arg );
---
> 	return Node::NewPartialNode( & PartialPlus, arg );
494c499
< 	return Node::NewFuncNode( & PartialMinus, arg );
---
> 	return Node::NewPartialNode( & PartialMinus, arg );
506c511
< 	return Node::NewFuncNode( & PartialMultiply, arg );
---
> 	return Node::NewPartialNode( & PartialMultiply, arg );
518c523
< 	return Node::NewFuncNode( & PartialBitOr, arg );
---
> 	return Node::NewPartialNode( & PartialBitOr, arg );
530c535
< 	return Node::NewFuncNode( & PartialBitAnd, arg );
---
> 	return Node::NewPartialNode( & PartialBitAnd, arg );
597c602
< 	return Node::NewFuncNode( &PrimativeI, Nil );
---
> 	return Node::NewPartialNode( &PrimativeI, Nil );
607c612
< 	return Node::NewFuncNode( &PartialK, arg );
---
> 	return Node::NewPartialNode( &PartialK, arg );
614c619
< 	return Node::NewFuncNode( &PrimativeI, Nil );
---
> 	return Node::NewPartialNode( &PrimativeI, Nil );
624c629
< 	return Node::NewFuncNode( &PartialV, arg );
---
> 	return Node::NewPartialNode( &PartialV, arg );
663c668
< 	Assert(v->isLet());
---
> 	Assert(v->isLambdaLetter());
690c695
<   Assert( p->type == Node::PAIR );
---
>   Assert( p->getType() == Node::PAIR );
700c705
<   switch(h->type) {
---
>   switch(h->getType()) {
710c715
< 		z= Node::NewFuncNode( &PrimativeK, Nil );
---
> 		z= Node::NewPartialNode( &PrimativeK, Nil );
713c718
< 		z= Node::NewFuncNode( &PrimativeJ, Nil );
---
> 		z= Node::NewPartialNode( &PrimativeJ, Nil );
721c726
<   case Node::LETTER:  // lambda or global
---
>   case Node::CHAR:  // lambda or global or symbol
724c729
< 	if (h < FIRST_LAMBDA_LETTER) {
---
> 	if ( h->isGlobalLetter() ) {
729,730c734,735
< 		if(trace) fprintf(stderr, "    Set Global #%d\n", h->value );
< 	} else {
---
> 		if(trace) fprintf(stderr, "    Set Global #%d\n", h-FIRST_LETTER );
> 	} else if ( h->isLambdaLetter() ) {
733,742c738,741
< 		z= Node::NewFuncNode( & LambdaFunc, p );
< 		if(trace) fprintf(stderr, "    Lambda #%d\n", h->value );
< 	}
< 
<     }
<     break;
< 
<   case Node::SYMBOL:  // primative
<     {
< 	if ( h == ATOM('\'') ) {  // Lisp QUOTE
---
> 		z= Node::NewPartialNode( & LambdaFunc, p );
> 		if(trace) fprintf(stderr, "    Lambda #%d\n", h-FIRST_LETTER );
> 	} else {
> 	    if ( h == ATOM('\'') ) {  // Lisp QUOTE
746c745
< 	} else if ( h == ATOM(';') ) {  // special INCREMENT
---
> 	    } else if ( h == ATOM(';') ) {  // special INCREMENT
753c752
< 				if(trace) fprintf(stderr, "    Special Incr Intlike: Global #%d := %d\n", t->value, z->value );
---
> 				if(trace) fprintf(stderr, "    Special Incr Intlike: Global #%d := %d\n", t->asciiValue(), z->asciiValue() );
755c754
< 				if(trace) fprintf(stderr, "    Special Incr: Global #%d :=\n", t->value );
---
> 				if(trace) fprintf(stderr, "    Special Incr: Global #%d :=\n", t->asciiValue() );
763c762
< 				if(trace) fprintf(stderr, "    Special Incr Intlike:   -> %d\n", z->value );
---
> 				if(trace) fprintf(stderr, "    Special Incr Intlike:   -> %d\n", z->asciiValue() );
768c767
< 	} else if ( h->hd ) {           // has primitive func
---
> 	    } else if ( h->hd ) {           // has primitive func
778c777
< 	} else {			// do no harm
---
> 	    } else {			// do no harm
782,783c781,783
< 	}
<     }
---
> 	    }
> 	} //fi
>     } //esac
793c793
< 	if (	a->isFunc() &&	(  (void*)a->hd == (void*)&PrimativeU
---
> 	if (	a->isPartial() &&	(  (void*)a->hd == (void*)&PrimativeU
811c811
<   case Node::FUNC:  //  ?
---
>   case Node::PARTIAL:  //  ?
844c844
< 			Assert( f->isFunc() );
---
> 			Assert( f->isPartial() );
848c848
< 			node z= f->CallFuncNode( &m, Atoms+'8' )->CallFuncNode( &m, Atoms+'9');
---
> 			node z= f->CallPartialNode( &m, Atoms+'8' )->CallPartialNode( &m, Atoms+'9');
856c856
< 			Assert( f->isFunc() );
---
> 			Assert( f->isPartial() );
860c860
< 			z= f->CallFuncNode( &m, Atoms+'8' )->CallFuncNode( &m, Atoms+'9');
---
> 			z= f->CallPartialNode( &m, Atoms+'8' )->CallPartialNode( &m, Atoms+'9');
874c874
< 			Assert( f->isFunc() );
---
> 			Assert( f->isPartial() );
878c878
< 			node z= f->CallFuncNode( &m, Atoms+'6' );
---
> 			node z= f->CallPartialNode( &m, Atoms+'6' );
896c896
< 			Assert( f->isFunc() );
---
> 			Assert( f->isPartial() );
900c900
< 			node z= f->CallFuncNode( &m, Atoms+'4' );
---
> 			node z= f->CallPartialNode( &m, Atoms+'4' );
927c927
<   switch(p->type) {
---
>   switch(p->getType()) {
930,931c930
<   case Node::SYMBOL:
<   case Node::FUNC:
---
>   case Node::PARTIAL:
935,936c934,939
<   case Node::LETTER:
< 	z= getVar(p);
---
>   case Node::CHAR:
> 	if ( p->isGlobalLetter() || p->isLambdaLetter() ) {
> 		z= getVar(p);
> 	} else {
> 		z= p;
> 	}
950,951c953,956
< 	if ( p->type == Node::LETTER ) fprintf(stderr, "Eval<%c>:  %s  -->  %s\n", p->typeLetter(), pp, zz ); 
< 	else fprintf(stderr, "Eval<%c>nop:  %s\n", p->typeLetter(), zz ); 
---
> 	if ( p->isGlobalLetter() || p->isLambdaLetter() ) 
> 		fprintf(stderr, "Eval<%c>:  %s  -->  %s\n", p->typeLetter(), pp, zz ); 
> 	else 
> 		fprintf(stderr, "Eval<%c>nop:  %s\n", p->typeLetter(), zz ); 
979,994c984
< 		node p= &Atoms[i];
< 		p->type= Node::SYMBOL;
< 		p->hd= 0;
< 		p->tl= 0;
< 
< 		if ('0'<=i && i<='9') p->type= NUMBER, p->value= i-'0';
< 		else if ('a'<=i && i<='z') p->type= LETTER, p->value= i-'a';
< 		else p->type= SYMBOL, p->value= i;
< 	}
< 	//memset( Pairs, 0, sizeof Pairs );
< 	if (0) for (int i=0; i<LIMIT_PAIRS; i++) {
< 		
< 		node p= &Pairs[i];
< 		p->type= Node::PAIR;
< 		p->hd= 0;
< 		p->tl= 0;
---
> 		memset( Nodes, 0, sizeof Nodes );
995a986
> 
1033,1044c1024
< 			for (int i=0; i<NUM_ATOMS; i++) {
< 				Assert( Atoms[i].type != Node::PAIR );
< 			}
< 			for (int i='0'; i<='9'; i++) {
< 				Assert( Atoms[i].type == Node::NUMBER );
< 				Assert( Atoms[i].value == i-'0' );
< 			}
< 			for (int i='a'; i<='z'; i++) {
< 				Assert( Atoms[i].type == Node::LETTER );
< 				Assert( Atoms[i].value == i-'a' );
< 			}
< 
---
> 			// hmmm
1185c1165
< 	} else if ( p->isFunc() ) {
---
> 	} else if ( p->isPartial() ) {
1385c1365
< 	Li3_EvalPairCount= NextPairPtr-Pairs;
---
> 	Li3_EvalPairCount= NextNodePtr-Nodes;

