/********************************************************************************
*
* File: constant.cc
* Title: some constant OQL methods
* Programmer: Leonidas Fegaras, UTA
* Date: 4/26/97
*
********************************************************************************/


#include "external.h"
#include "evaluation.h"
#include "constant.h"


const Type int_type = variable("Short");
const Type bool_type = variable("bool");
const Type string_type = variable("String");


#define F(name,params,body)				\
	Object _ ## name ( list<Object>* args ) {	\
	   params;					\
	   return new object(body);			\
	};

#define Int(var)						\
	int var;						\
	if (args->hd->integerp())				\
	   var = args->hd->info.Integer;			\
	else if (args->hd->aggregationp())			\
	   var = args->hd->info.Aggregation.OID;		\
	else evaluation_error("Expected an integer",args->hd);	\
	args = args->tl;

#define Bool(var)						\
	if (!args->hd->boolp())					\
	   evaluation_error("Expected a boolean",args->hd);	\
	bool var = args->hd->info.Boolean;			\
	args = args->tl;

#define Str(var)						\
	if (!args->hd->stringp())				\
	   evaluation_error("Expected a string",args->hd);	\
	String var = args->hd->info.Estring;			\
	args = args->tl;



F(plus,Int(x) Int(y),x+y)
F(minus,Int(x) Int(y),x-y)
F(times,Int(x) Int(y),x*y)
F(and,Bool(x) Bool(y),x && y)
F(or,Bool(x) Bool(y),x || y)
F(not,Bool(x),!x)
F(eq,Int(x) Int(y),x==y)
F(neq,Int(x) Int(y),x!=y)
F(gt,Int(x) Int(y),x>y)
F(lt,Int(x) Int(y),x<y)
F(geq,Int(x) Int(y),x>=y)
F(leq,Int(x) Int(y),x<=y)
F(seq,Str(x) Str(y),x->eq(y))
F(sneq,Str(x) Str(y),!x->eq(y))
F(sgt,Str(x) Str(y),strcmp(x->value(),y->value())>0)
F(slt,Str(x) Str(y),strcmp(x->value(),y->value())<0)
F(sgeq,Str(x) Str(y),strcmp(x->value(),y->value())>=0)
F(sleq,Str(x) Str(y),strcmp(x->value(),y->value())<=0)


/*********************************************************************************/


#undef Int
#undef Bool
#undef Str
#define Int(var)	->extend(new string(#var),int_type)
#define Bool(var)	->extend(new string(#var),bool_type)
#define Str(var)	->extend(new string(#var),string_type)


#define T(name,params,out)									\
	->extend(new string(#name),new pair<Signature,Function>(new pair<binding<Type>*,Type>	\
	((new binding<Type>)params,out),&_ ## name))


Internals internal_methods = (new binding<Internal>)
	T(plus,Int(y) Int(x),int_type)
	T(minus,Int(y) Int(x),int_type)
	T(times,Int(y) Int(x),int_type)
	T(and,Bool(x) Bool(y),bool_type)
	T(or,Bool(x) Bool(y),bool_type)
	T(not,Bool(x),bool_type)
	T(eq,Int(y) Int(x),bool_type)
	T(neq,Int(y) Int(x),bool_type)
	T(gt,Int(y) Int(x),bool_type)
	T(lt,Int(y) Int(x),bool_type)
	T(geq,Int(y) Int(x),bool_type)
	T(leq,Int(y) Int(x),bool_type)
	T(seq,Str(y) Str(x),bool_type)
	T(sneq,Str(y) Str(x),bool_type)
	T(sgt,Str(y) Str(x),bool_type)
	T(slt,Str(y) Str(x),bool_type)
	T(sgeq,Str(y) Str(x),bool_type)
	T(sleq,Str(y) Str(x),bool_type)
;
