#if 0
* Pass parameters into partial area (and result area if any)
* select correct body (if overloaded)
* calculate defaults
* finish setting up for C calling standard, and call function
  - pop parameter bitmap and extra information, leaving real parameters

Non-private idents are allocated in result area.
otherwise, if private param ident: allocate in parameter area.
??? how about layout of parameter area
Private idents in body are C locals (unless en-closed)
Each identifier has a unique location
(Even if multiple defining mentions)
It proc not a construtor, all idents are private
  
for each defining identifier:
typedef struct Field ParamId;
use struct Field ?
    Name name;
    ExType type;
    long location; /* either argument record offset or register number */
    flag ? must AllocVariable?
    multiply defining?

what about *~type: ??

struct Param {
    short flags;
    short offset;
    Name name;
    Func coercion;/struct Type *type;
    void *default; /* must be expression/function */
};

struct Any
PartialPrefix(partial, arg)
    struct Any partial; struct Any arg;
{
    if (toomanyargs) {
	return PrefixApply(PartialLastfix(partial), arg);
    }
    argDesc = ...
    if (!partial->onstack)
	partial = copytostack(partial);
    (* argDesc->coercion)((char*)partial + argDesc->offset, ?, arg);
    if (last_arg) apply_guard();
    return partial
}

struct Any
PartialLastfix(struct Any partial)
{
    if (too few args) {
	return copy_to_heap(partial);
    }
    arglist = alloca(partial->addr.size);
    bcopy(partial->argbuf, arglist, partial->arglen);
    add default parameters
    (* partial->code)();
    /* don't pop stack; leave job to unlink/PatchReturn */    
}
#endif

/* Copyright Per Bothner 1987. Read the file Q-INFO */
#ifndef PROCS_H
#define PROCS_H
/* assembler combinations */
#define WORDS(x,y)	(((x)<<16)|(0xFFFF&(y)))
#define _MOVEQ	0x72			/* moveq #"n-1",d1 */
#define _POPRET	0x205F			/* movel sp@+,a0 */
#define _LOAD	WORDS(0x43FA, -6)	/* lea pc@(-6),a1 */
#define _MOVARG	0x2F21			/* movl a1@-,sp@- */
#define _REPEAT	WORDS(0x51C9, -4)	/* dbf d1,.-4 */
#define _PSHJMP	WORDS(0x2F08, _JMP)	/* movl a0,sp@-; jmp "code" */
#define _MOVL 0x203C		/* movl #data,d0 */
#define _JMP 0x4EF9		/* jmp "code" */
#define _JSR 0x4EB9		/* jsr "proc" */
#define _LINK 0x4E56		/* link a6,#n */
#define _LINK0 WORDS(_LINK, 0)	/* link a6,#0 */
#define _ADD_SP_n 0x4FEF	/* lea sp("n"),sp */
#define _ADD_SP_4 0x588F	/* addql #4,sp */
#define _ADD_SP_8 0x508F	/* addql #8,sp */
#define _ADD_SP_L 0xDFFC	/* addl #"n",sp */
#define _ADD_SP_W 0xDEFC	/* addw #"n",sp */
#define _PUSH(mode, reg) (0x2F00+((mode)<<3)+(reg)) /* movl [mode,reg],sp@- */
#define _UNLK 0x4E5E		/* unlk */
#define _RTS 0x4E75		/* rts */
#define _RTD 0x4E74
#define Hi_(x) (((long)(x) >> 16) & 0xFFFF)
#define Lo_(x) ((unsigned short)(x))
#define _RETURN WORDS(_UNLK, _RTS)
/* the Proc type is defined in <types.h> */
#define _MakeProc(p, f, x)	\
	{(p)->_movl = _MOVL; (p)->data=(Object)(x);	\
	(p)->_jmp = _JMP; (p)->code = f;}
#define MakeProc(p, f, x)	\
	{p=(Proc*)SetPType(malloc(sizeof(Proc)),TProc);	\
	_MakeProc(p, f, x); }
extern long d0;
#define SetProcData(x) (d0=(long)(x))
#define GetProcData d0

typedef struct
  {
    unsigned char _moveq;	/* always = _MOVEQ */
    char nParams;	/* one less than number of params to add */
    unsigned short _popret;	/* always = _POPRET */
    unsigned long _load;	/* always = _LOAD */
    unsigned short _movarg;	/* always = _MOVARG */
    unsigned long _repeat;	/* always = _REPEAT */
    unsigned long _pshjmp;	/* always = _PSHJMP */
    Object (*code)();
  } Procn;

#define MakeProcn(p, f, n)	{	\
  (p)->_moveq=_MOVEQ; (p)->nParams=(n)-1; (p)->_popret=_POPRET;	\
  (p)->_load=_LOAD; (p)->_movarg=_MOVARG; (p)->_repeat=_REPEAT;	\
  (p)->_pshjmp=_PSHJMP; (p)->code=f;}

#if 0
struct TypeProc
  {
    struct Type t;
    char *paramName;
    Object paramType;
    Object resultType;
  };
#endif

#define _Ex_Magic (Object)0x78abcd

Object CallQProcTemp[3], _CallQProc();
#define _PutQArg_(i,x) CallQProcTemp[i]=(Object)(x)
#define CallQProc1(f, x1) \
 (_PutQArg_(0,x1), _CallQProc(f, 1, CallQProcTemp))
#define CallQProc2(f, x1, x2) \
 (_PutQArg_(0,x1),_PutQArg_(1,x2), _CallQProc(f, 2, CallQProcTemp))
#define CallQProc3(f, x1, x2, x3) \
 (_PutQArg_(0,x1),_PutQArg_(1,x2),_PutQArg_(2,x3),_CallQProc(f,3,CallQProcTemp))

#define RecordField Declaration
#endif PROCS_H
