blob: dc2648ab95e0cf6f964416236dbc51f98a8084c8 [file] [log] [blame]
/* node.h */
/*
Copyright (C) 2003 Unique Software Designs
This file is part of the program "lambda".
The program "lambda" 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 of the License, or
(at your option) any later version.
The program "lambda" 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 "lambda"; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
A copy of the GNU General Public License may also be found at:
http://www.gnu.org/copyleft/gpl.html
*/
class arg_node;
class exp_node;
class var_node;
class lam_node;
class app_node;
class alst_node;
class arglst_node;
class argrefs_node;
#ifndef Boolean
#define Boolean short
#define False 0
#define True 1
#endif
/////////////////////////////////////////////////////////////////////
class node {
public:
enum type { NTYPE, NODE, ARG, VAR, LAM, APP, ARGLST, STACKFRAME, ARGREFS };
enum { RECURSE_LVL=1, BETA_ETA_DONE=2, ETA_DONE=4 };
enum { DO_STEP=1, DO_APP_ORDER=2, DO_REDUCE_BODY=4,
DO_PRINT_SYM=8,DO_PRINT_BRIEF=16,
DO_TRACE=32, DO_EXTRACT_ETA=64,
DO_EXTRACT_APP=128,
DO_REDUCE_FULLY=256};
public:
node() { parent_v = 0;};
node(const node& from) { parent_v=from.parent_v; };
virtual node* clone() const= 0;
virtual ~node() {};
public:
virtual type op() const{ return NODE;};
virtual const char* name() const{ return 0;};
virtual exp_node* value() const{ return 0;};
virtual arg_node* arg() const{ return 0;};
virtual exp_node* body() const{ return 0;};
virtual exp_node* left() const{ return 0;};
virtual exp_node* right() const{ return 0;};
virtual alst_node* next() const{ return 0;};
virtual node* parent() const{ return parent_v; };
public:
virtual void set_parent(node* par){ parent_v = par;};
public:
static void reset();
public:
//virtual void rename() {};
virtual exp_node* reduce(
const alst_node* env,int inp,int* outp){
return 0;};
public:
virtual void print(const alst_node*env=0,int inp=0) const;
protected:
node* parent_v;
};
/////////////////////////////////////////////////////////////////////
class exp_node: public node
{
public:
virtual Boolean has_free(const arg_node*, const alst_node* env)const{ return False; };
virtual arglst_node* bind(const alst_node* env=0)const{return 0;};
virtual exp_node* reduce_vars(const alst_node* env,int inp,int* outp){
return this; };
virtual void rename(
arg_node* arg,const char* newname,alst_node* env=0){};
virtual void resolve_name_clash(
arg_node* outer_arg,alst_node* env=0){};
public:
virtual int operator == (const exp_node& cmp) const {return False;};
public:
virtual exp_node* export_body(){return 0;};
virtual exp_node* export_left(){return 0;};
virtual exp_node* export_right(){return 0;};
public:
virtual const alst_node* match(const alst_node* env=0) const;
virtual exp_node* extract_defs(const alst_node* env=0){return 0; };
void symbolic_print(const alst_node* env,int inp = 0) const;
public:
virtual exp_node* extract(const char* nm,int inp=0) const {return 0; };
};
/////////////////////////////////////////////////////////////////////
class alst_node: public node
{
public:
virtual ~alst_node(){};
virtual alst_node* add(
arg_node* anode,Boolean import=False){
return 0; };
virtual arg_node* find(arg_node* anode) {
return 0;};
virtual void list(){};
};
/////////////////////////////////////////////////////////////////////
class arg_node: public node
{
public:
arg_node(){ name_v = 0; value_v=0;};
arg_node(const char*nm,const exp_node* ex,
Boolean import=False);
arg_node(const arg_node& from);
virtual node* clone() const;
virtual ~arg_node();
public:
virtual arg_node& operator =(const arg_node& from);
public:
//Boolean free_in(exp_node* exp);
virtual void print(const alst_node*env=0, int inp=0) const;
public:
virtual type op() const{ return ARG;};
virtual const char* name() const{ return name_v;};
virtual exp_node* value() const{ return value_v;}; // VAR, LAM, or APP
//virtual arg_node* arg() const{ return 0;};
//virtual exp_node* body() const{ return 0;};
//virtual exp_node* left() const{ return 0;};
//virtual exp_node* right() const{ return 0;};
//virtual alst_node* next() const{ return 0;};
public:
//virtual exp_node* reduce(const alst_node* env,int inp,int* outp) { return 0;};
void import_value(exp_node** val);
int operator == (const arg_node& cmp) const;
int operator == (const char* cmp) const;
public:
void set_name(const char* nm)
{
if( name_v == nm ) return;
if( name_v ) delete [] name_v;
name_v = nm?new char[strlen(nm)+1]:0;
if( name_v && nm ) strcpy(name_v,nm);
};
void import_value(exp_node* nd)
{
if( value_v == nd ) return;
if( value_v ) delete value_v;
value_v = nd;
if( value_v ) value_v->set_parent(this);
};
private:
char* name_v;
exp_node* value_v;
};
/////////////////////////////////////////////////////////////////////
class var_node: public exp_node
{
public:
var_node(const char* nm=0);
var_node(const var_node& from);
virtual node* clone() const { return (node*)new var_node(*this); };
virtual ~var_node(){ if( name_v ) delete [] name_v;};
public:
virtual Boolean has_free(const arg_node* argr, const alst_node* env) const;
arglst_node* bind(const alst_node* env=0)const;
virtual void print(const alst_node*env=0,int inp=0) const;
public:
var_node& operator =(const var_node& from);
public:
virtual type op() const { return VAR;};
virtual const char* name() const{
return name_v;};
//virtual exp_node* value() const{return arg() ? arg()->value() : 0; }; // VAR, LAM, or APP
//virtual exp_node* value() const;
////virtual arg_node* arg() const{return ref_arg_v ? ref_arg_v : def_arg_v;};
//virtual exp_node* body() const{ return 0;};
//virtual exp_node* left() const{ return 0;};
//virtual exp_node* right() const{ return 0;};
//virtual alst_node* next() const{ return 0;};
public:
void set_name(const char* nm);
public:
virtual void rename(
arg_node* arg,const char* newname,alst_node*env=0);
virtual void resolve_name_clash(
arg_node* outer_arg,alst_node* env=0){};
virtual exp_node* reduce_value(
const alst_node* env, int inp, int* outp,
const alst_node** pnenv);
exp_node* reduce_number();
virtual exp_node* reduce(
const alst_node* env,int inp,int* outp);
virtual exp_node* reduce_vars(const alst_node* env,int inp,int* outp)
{
return reduce(env,inp,outp);
};
public:
////void reduce_arg();
////arg_node* ref_arg() { return ref_arg_v;};
public:
virtual int operator == (const exp_node& cmp) const;
public:
virtual exp_node* extract(const char* nm,int inp=0) const;
private:
////arg_node* def_arg_v;
////arg_node* ref_arg_v;
char* name_v;
};
/////////////////////////////////////////////////////////////////////
class lam_node: public exp_node
{
public:
lam_node(){ arg_v=0; body_v=0;};
lam_node(arg_node* arg, exp_node* bdy,
Boolean import=False);
lam_node(const lam_node& from);
virtual node* clone() const { return (node*)new lam_node(*this); };
virtual ~lam_node();
public:
virtual Boolean has_free(const arg_node* argr, const alst_node* env) const;
virtual arglst_node* bind(const alst_node* env=0)const{
//if( body_v ){body_v->set_parent(this);body_v->bind(env); };
return 0;
};
virtual void print(const alst_node*env=0,int inp=0) const;
public:
lam_node& operator =(const lam_node& from);
public:
virtual type op() const { return LAM;};
//virtual const char* name() const{ return 0;};
//virtual exp_node* value() const{ return value;}; // VAR, LAM, or APP
virtual arg_node* arg() const{ return arg_v;};
virtual exp_node* body() const{ return body_v;};
//virtual exp_node* left() const{ return 0;};
//virtual exp_node* right() const{ return 0;};
//virtual alst_node* next() const{ return 0;};
public:
virtual void rename(
arg_node* arg,const char* newname,alst_node* env=0);
virtual void resolve_name_clash(
arg_node* outer_arg,alst_node* env=0);
virtual exp_node* reduce(
const alst_node* env,int inp,int* outp);
virtual exp_node* eta_reduce(
const alst_node* env,int inp,int* outp);
virtual exp_node* reduce_vars(const alst_node* env,int inp,int* outp);
public:
void set_arg(arg_node* nd, Boolean import);
void set_body(exp_node* nd, Boolean import);
public:
virtual int operator == (const exp_node& cmp) const;
public:
virtual exp_node* export_body(){
exp_node* exp = body_v;
body_v = 0;
return exp;};
public:
virtual exp_node* extract_defs(const alst_node* env=0);
public:
virtual exp_node* extract(const char* nm,int inp=0) const;
private:
arg_node* arg_v;
exp_node* body_v;
};
/////////////////////////////////////////////////////////////////////
class app_node: public exp_node
{
public:
app_node(){ left_v=0; right_v=0;};
app_node( exp_node* lft, exp_node* rgt,
Boolean import = False);
app_node(const app_node& from);
virtual node* clone() const { return (node*)new app_node(*this); };
virtual ~app_node();
public:
virtual Boolean has_free(const arg_node* argr, const alst_node* env) const;
virtual arglst_node* bind(const alst_node* env=0)const{
////if( left_v ){left_v->set_parent(this);left_v->bind(env); }
////if( right_v ){right_v->set_parent(this);right_v->bind(env); };
return 0;
};
virtual void print(const alst_node*env=0,int inp=0) const;
public:
app_node& operator =(const app_node& from);
public:
virtual type op() const{ return APP;};
//virtual const char* name() const{ return 0;};
//virtual exp_node* value() const{ return value;}; // VAR, LAM, or APP
//virtual arg_node* arg() const{ return 0;};
//virtual exp_node* body() const{ return 0;};
virtual exp_node* left() const{ return left_v;};
virtual exp_node* right() const{ return right_v;};
//virtual alst_node* next() const{ return 0;};
public:
virtual void rename(
arg_node* arg,const char* newname,alst_node* env=0);
virtual void resolve_name_clash(
arg_node* outer_arg,alst_node* env=0);
virtual exp_node* reduce(
const alst_node* env,int inp,int* outp);
virtual exp_node* reduce_vars(const alst_node* env,int inp,int* outp);
public:
void set_left(exp_node* nd, Boolean import);
void set_right(exp_node* nd, Boolean import);
public:
virtual int operator == (const exp_node& cmp) const;
public:
virtual exp_node* export_left(){
exp_node* exp = left_v;
left_v = 0;
return exp;};
virtual exp_node* export_right(){
exp_node* exp = right_v;
right_v = 0;
return exp;};
public:
virtual exp_node* extract_defs(const alst_node* env=0);
public:
virtual exp_node* extract(const char* nm,int inp=0) const;
private:
exp_node* left_v;
exp_node* right_v;
};
/////////////////////////////////////////////////////////////////////
class arglst_node: public alst_node
{
public:
arglst_node(
arg_node* arg=0,arglst_node* next=0,
Boolean import=False);
arglst_node(const arglst_node& from);
virtual node* clone() const { return (node*)new arglst_node(*this); };
virtual ~arglst_node();
public:
virtual type op() const { return ARGLST;};
//virtual const char* name() const{ return 0;};
//virtual exp_node* value() const{ return value;}; // VAR, LAM, or APP
virtual arg_node* arg() const{ return arg_v;};
//virtual exp_node* body() const{ return 0;};
//virtual exp_node* left() const{ return 0;};
//virtual exp_node* right() const{ return 0;};
virtual alst_node* next() const{ return (alst_node*)next_v;};
public:
//virtual void rename() {};
//virtual exp_node* reduce(const alst_node* env,int inp,int* outp) { return 0;};
virtual alst_node* add(arg_node* anode,Boolean import=False);
virtual arg_node* find(arg_node* anode);
public:
void set_arg(arg_node* nd, Boolean import);
virtual void list();
protected:
arg_node* arg_v;
arglst_node* next_v;
};
/////////////////////////////////////////////////////////////////////
class stack_frame: public arglst_node
{
public:
virtual type op() const{ return STACKFRAME;};
stack_frame(arg_node* arg=0, const alst_node* next=0)
{ arg_v = arg; next_v = (arglst_node*)next; }
virtual ~stack_frame(){arg_v = 0;next_v = 0;};
};
extern const arglst_node* definition_env;