#include "types.h"
#include "typetabs.h"
#include "expression.h"
/*#include "methods.h"*/
#include "gfunc.h"
/*#include "writefile.h"*/
#include "gennum.h"
#include "genmap.h"
#include <symbol.h>

#define Constant_Field 1
#define Method_Field 2
#define Pointer_Field 3
#define Struct_Field 4
#define Include_Field 5
#define Bit_Field 6

typedef struct _HandlerDesc_ Continuation;

#ifndef __GNUC__
extern struct Any MAKE_ANY();
#else
#define MAKE_ANY(addr,type) ((struct Any){type, addr})
#endif
#ifdef CPLUS
#define UNSPEC_ARGS ...
#define EXTERNC extern "C"
#else
#define UNSPEC_ARGS
#define EXTERNC extern
#endif
/* #define DefaultPrefix PostfixApply */
/*extern struct Any DefaultPrefix(struct Any, struct Any);*/
extern struct Any Default_prefix_method(), Default_index_method(),
  Default_plus_method(),Default_intplus_method(),Default_fixnumplus_method();
extern struct Any Default_length_method(), Default_unify_method(),
  Default_postfix_method(), Default_hashValue_method(),
  Default_lookup_method(), Default_filler10_method(),
  Default_filler11_method();
extern int Default_compare_method();
extern struct Any DefaultPostfix(struct Any, struct Any);
extern struct Any DefaultNamefix(struct Any, Name, struct Any);
extern struct Any DefaultLastfix(struct Any);
extern struct Any PrefixApply(struct Any, struct Any);
extern struct Any PostfixApply(struct Any, struct Any);
extern struct Any LastfixApply(struct Any);
extern struct Any ApplyPlus(), ListToMultiple(struct Any),
  ListConcat(struct Any, struct Any), SetSort(struct Any);
extern Object Apply(), _Apply(), ApplyLastfix(), ObEqu(), MakeInverse();
extern void *StdAllocOb();
extern Name s_;
#define ALLOC_NEW_VAR() (Object)AllocVariable(s_)
#define CALL0(f) (f)()
#define CALL1(f, x1) (f)(x1)
#define CALL2(f, x1, x2) ({ Object __SAVE_1 = x1; (f)(__SAVE_1, x2); })
#define CALL3(f, x1, x2, x3) ({ Object __SAVE_1 = x1, __SAVE_2 = x2; (f)(__SAVE_1, __SAVE_2, x3); })
#define CALL0F(f) ({ extern Object f(); f();})
#define CALL1F(f, x1) ({ extern Object f(); f(x1);})
#define CALL2F(f, x1, x2) ({ extern Object f(); Object __SAVE_1 = x1; f(__SAVE_1, x2); })
#define CALL3F(f, x1, x2, x3) ({ extern Object f(); Object __SAVE_1 = x1, __SAVE_2 = x2; f(__SAVE_1, __SAVE_2, x3); })
#define CALL0A(f) ({ extern struct Any f(); f();})
#define CALL1A(f, x1) ({ extern struct Any f(); f(x1);})
#define CALL2A(f, x1, x2) ({ extern struct Any f(); struct Any __SAVE_1 = x1; f(__SAVE_1, x2); })
#define CALL3A(f, x1, x2, x3) ({ extern struct Any f(); struct Any __SAVE_1 = x1, __SAVE_2 = x2; f(__SAVE_1, __SAVE_2, x3); })
/*#define APPLY(func, arg) CALL2A(PrefixApply, func, arg)*/
#define APPLY_POSTFIX(arg, func) CALL2A(PostfixApply, arg, func)
#define APPLY_LASTFIX(arg) CALL1A(LastfixApply, arg)
#define OBEQU(x, y) CALL2(ObEqu, x, y)
#define GARRAYTAKE(x1, x2) CALL2A(GArrayTake, x1, x2)
extern struct Any MAKE_GARRAY(struct Any);
#define MAKE_INVERSE(arg, fun) CALL2(MakeInverse, arg, func)

#include <ifthenelse.h>

#define REF(name) ({ extern ObUnion TMP asm(#name); &TMP; })
#define EXT(name) ({ extern ObUnion name; &name; })
#define EXT_DEF(name) extern ObUnion name[1];
#define EXT_ALIAS(name, lname) extern ObUnion lname[1] asm(#name);
#define SYM(name) &_SYM_##name##_
#define SYM0(sym) extern struct Symbol _SYM_##sym##_;
#define SYM1(string, label) /* nothing */
#define SYM_DEF(sym) SYM_EXT(SYM(sym))
#define SYM_ALIAS(name, lname) EXT_ALIAS(name, lname)
#define MOD_INIT(name) extern void INIT() asm(#name "$_INIT_");
#define IS_PRIVATE IsPublic
#define FIELD_0(first) {0, 0, Include_Field, 0, 0, {(void*)(first<<16)}},
#define A_Method_FIELD(name, f) \
  {name, IS_PRIVATE, Method_Field, 0, {(void*)f}},
#define A_Constant_FIELD(name, ob) \
  {name, IS_PRIVATE, Constant_Field, 0, {ob}},
#define Unsigned_Bit_FIELD(name, offset, size)\
  {name, IS_PRIVATE, Bit_Field, offset, {(void*)((size)<<16)}},
#define Signed_Bit_FIELD(name, offset, size) \
  {name, IS_PRIVATE, Bit_Field, offset, {(void*)(((size)<<16) + 0x100)}},
#define A_Pointer_FIELD(name, offset, type) \
  {name, type, {(void*)(offset)}, IS_PRIVATE, IsField, 0, Pointer_Field, 0},
#define A_Struct_FIELD(name, offset, type) \
  {name, type, {(void*)(offset)}, IS_PRIVATE, IsField, 0, Struct_Field, 0},
#define EndFieldList() {NULL, NULL, {(void*)0}, IsLastField}
#define MOD_MACROS(symbol) /* */
#define FixIntConst(n) LongToAny(n)
#define SMALL_INT(i) &SmallIntTable[i-LeastSmallInt]
extern struct ClassDesc _Function_[1];
#define FunctionClassDesc _Function_[1]
extern void RegisterModule(Object self, const StringC* name);
struct DefineConstant {
    DefineConstant(Symbol *sym, Root *value) { sym->set_value(value); }
};
extern Root *CallEvaluated(Root *self, Root **lArgs, Root **rArgs,
			   Root **nArgs, Symbol**names,
			   int lCount, int rCount, int nCount);
extern Root *MakeTuple(Root *val);
