/*
 * PRED node program copyright (C) 2009 - 2013 H.Niwa
 */

/*
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#ifndef __PRED_H
#define __PRED_H

extern Node* FreePredNodes;

// Predication class
class Pred : public Node {
private:
	Node*	node;

public:
	Pred(Node* nd) { 
		k = PRED;
		node = nd;
	}
	virtual ~Pred() {};

	void init(Node* nd) { node = nd; }
	
	Node* Val()
	{
		return new Pred(node->Val());
	}

	// lisp functions
	Node* Car() { return node->Car(); }
	Node* Cdr() { return node->Cdr(); }
	int   Eq(Node* nd) 
	{
		if (nd->kind() != PRED) {
			return 0;
		}
		return node->Eq(((Pred*)nd)->node); 
	}
	int   Nul() { return node->Nul(); }

	Node* Dup() {
		if (dupp == NULL) 
			dupp = new Pred(node->Dup());
		return dupp; 
	}
	void  DuppClr() {
		dupp = NULL;
		node->DuppClr();
	}
	Node* Insert(Node* nd) { return node->Insert(nd); }
	void  Del() { node->Del(); }
	Node* Find(Node* nd) { return node->Find(nd); }

	// print nodes
	void printsub(FILE* fd);
	void printcdrsub(FILE* fd);

	void Set(Node* n1, Node* n2) { ((List*)node)->Set(n1, n2); }
	void SetCar(Node* n) { ((List*)node)->SetCar(n); }
	void SetCdr(Node* n) { ((List*)node)->SetCdr(n); }

	// GC
	void gcmark() { 
		if (ref) return;
		ref++; node->gcmark(); 
	}

	Node* Pred2List() {return node; };
	Node* Node() { return node; };
};


extern Node* MkPred(Node* n1);
extern Node* MkPred(Node* n1, Node* n2);
extern Node* MkPred(Node* n1, Node* n2, Node* n3, Node* n4);
extern Node* MkPred(Node* n1, Node* n2, Node* n3, Node* n4, Node* n5);
extern Node* MkPred(Node* n1, Node* n2, Node* n3, Node* n4, Node* n5, Node* n6);
extern Node* MkPred(Node* n1, Node* n2, Node* n3, Node* n4, Node* n5, Node* n6, Node* n7);




#endif // __PRED_H
