Logo Search packages:      
Sourcecode: hat version File versions

hat-c.c

/* Primitive functions for writing the ART trace */

/* Control C interruption not yet implemented */

/* highest bit of fileoffset is used to mark those pointing to hidden nodes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <netinet/in.h>       /* for ntohl() macro */
#include "hat-c.h"


#if defined(DEBUG)
#define HIDE(x) x
#define CHECKCOUNTER(name) if (HatCounter != ftell(HatFile)) { fprintf(stderr,"wrong %s 0x%x 0x%x\n",name,HatCounter,ftell(HatFile)); exit(-1);}
#else
#define HIDE(x)
#define CHECKCOUNTER(name)
#endif

/* forward references */
static void initBuffers();
static FileOffset writeTag (int tag, int size);
static void writeByte (int byte);
static void writeFileOffset (FileOffset offset);
static void writeInt (int number);
static void writeFloat (float number);
static void writeDouble (double number);
static void updateFileOffset (FileOffset at, FileOffset entry); 
static int stringSize(char *s);
static void writeString(char *s);
static void dumpBuffers();

/* global variables */

#define HeaderSize (8 + 2*sizeof(FileOffset))
typedef char byte;

static FILE *HatFile, *HatOutput, *HatBridge;
static FileOffset HatCounter = HeaderSize;
static FileOffset LastExp = 0;
static bool traceOpen = False;
static bool atTraceEnd = True;
static bool controlC = False;
static FileOffset hiddenMask;
static FileOffset unevaluated;
static FileOffset entered;

/* helper functions */

/*
void
writeString(char *s)
{
  int length = strlen(s);
  if (length < 255)
    fputc(length,HatFile);
  else {
    fputc(255,HatFile);
    fputc((unsigned char) (length>>8),HatFile); 
    fputc((unsigned char) length,HatFile);
  }
  fprintf(HatFile,"%s",s);
}
*/

/* catching errors of the runtime system */

#if defined(__GLASGOW_HASKELL__)
void
OutOfHeapHook (unsigned long x, unsigned long y)
{ hat_ErrorExit("Run out of heap memory.", hat_topStack(), -1); }

void 
StackOverflowHook (long int x)
{ hat_ErrorExit("Run out of stack memory.", hat_topStack(), -1); }

void 
MallocFailHook (long int x)
{ hat_ErrorExit("Cannot allocate enough memory.", hat_topStack(), -1); }
#endif

#if defined(__NHC__) 
extern void (*haskellErrorHandler)(char *errorMsg);
#endif 

/* general functions */

void 
hat_Open(char *progname)
{
    unsigned p = 0;
    char filename[256];

    unevaluated = htonl(Unevaluated);
    entered = htonl(Entered);    
    
    hiddenMask = htonl(~(1<<31)); /* only 0 at highest bit */
    /* logical & with possibly hidden fileoffset yields fileoffset */

    strcpy(filename,progname);
    strcat(filename,".hat");        /* the .hat file holds the archive */
    HatFile = fopen(filename,"w");  /* of redex trails */
    p = ftell(HatFile);                 /* should be 0 */
    fprintf(HatFile,"Hat%s",VERSION);     /* initialise file */
    fputc(0,HatFile);
    fwrite(&p,sizeof(FileOffset),1,HatFile);
    fwrite(&p,sizeof(FileOffset),1,HatFile);

    initBuffers();

    strcpy(filename,progname);            /* the .output file is a copy of */
    strcat(filename,".hat.output"); /* stdout */
    HatOutput = fopen(filename,"w");
    strcpy(filename,progname);            /* the .bridge file links the output */
    strcat(filename,".hat.bridge"); /* to the archived trails */
    HatBridge = fopen(filename,"w");

    controlC = False;
    /* SIGQUIT here before, why? */
    signal(SIGQUIT, hat_Interrupt);    /* install handler for abortion? */
    signal(SIGABRT, hat_Interrupt);    /* install handler for abortion? */
    signal(SIGFPE, hat_ArithmeticError);
    signal(SIGINT, hat_Interrupt); /* install handler for Control-C */

#if defined(__NHC__) 
    haskellErrorHandler = hat_Error;
#endif 
    traceOpen = True;
}

void hat_Close(void)
{
  if (!traceOpen) 
    return;
  dumpBuffers();
  hat_dumpBuffer();
  fclose(HatFile);
  fclose(HatOutput);
  fclose(HatBridge);
  traceOpen = False;
}

void hat_ErrorClose(char* errmsg, FileOffset trace)
{
  FileOffset nt;

  if (!traceOpen) 
    return;

  nt = mkAbstract(errmsg);
  nt &= hiddenMask;
  trace &= hiddenMask;
  fseek(HatFile,8,SEEK_SET);
  fwrite(&trace, sizeof(FileOffset), 1, HatFile);
  fwrite(&nt, sizeof(FileOffset), 1, HatFile);

  hat_dumpStack();
  hat_Close();
}

void hat_Error(char* errmsg)
{
  hat_ErrorClose(errmsg,hat_topStack());
}

void
hat_ErrorExit(char* errmsg, FileOffset trace, int ecode)
{
  fflush(stdout);
  fprintf(stderr, "\nError: %s\n", errmsg);
  hat_ErrorClose(errmsg,trace);
  exit(ecode);    
}

void 
hat_Abort(char *msg)
{ hat_ErrorExit(msg, hat_topStack(), -1); }

void
hat_InterruptExit()
{
  FileOffset node = hat_topStack();

  fflush(stdout);
  fprintf(stderr, "Interrupted\n");

  fseek(HatFile,8,SEEK_SET);
  fwrite(&node, sizeof(FileOffset), 1, HatFile);
  fwrite(&entered, sizeof(FileOffset), 1, HatFile);

  hat_dumpStack();
  hat_Close();

  exit(-1); 
}

void 
hat_Interrupt(int sig)
{ controlC = True; }

void
hat_ArithmeticError(int sig)
{ hat_Abort("Arithmetic error."); }


void hat_OutputTrace(FileOffset trace, char *output)
{
  fprintf(HatOutput,"%s",output);  /* copy of output */
  trace &= hiddenMask;
  while (*output++) {
    fwrite(&trace, sizeof(FileOffset), 1, HatBridge);
                        /* link trace to output */
  }
}

bool
hat_Hidden(FileOffset node)
{
  return (!((node & hiddenMask) == node));
}

FileOffset
mkRoot()
{
  return (htonl(Root));
}


/* Write trace nodes */

FileOffset
mkModule(char *modname, char *srcfile, bool traced)
{
  FileOffset fo;

  fo = writeTag(Module | (traced?TracedModule:0)
               ,1+stringSize(modname)+stringSize(srcfile));
  writeString(modname);
  writeString(srcfile);
  HIDE(fprintf(stderr,"\tmkModule %s (%s) -> 0x%x\n",modname,srcfile,fo);)
  return fo;
}

FileOffset
mkSrcPos(FileOffset moduleTraceInfo,int pos)
{
  FileOffset fo;

  fo = writeTag(SrcPos,1+sizeof(FileOffset)+sizeof(int));
  writeFileOffset(moduleTraceInfo);
  writeInt(pos);
  HIDE(fprintf(stderr,"\tmkSrcPos -> 0x%x\n",fo);)
  return fo;
}


/* Exp nodes; if use is 0, then the variant without a use field is written */

FileOffset
mkResApp1(FileOffset parent,FileOffset use,FileOffset fun
         ,FileOffset arg1)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (4*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if (use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fo);
  writeFileOffset(fun);
  writeByte(1);
  writeFileOffset(arg1);
  HIDE(fprintf(stderr,"\tmkResApp1 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fo,fun,arg1,fo);)
  return fo;
}

FileOffset
mkApp1(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (4*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(1);
  writeFileOffset(arg1);
  HIDE(fprintf(stderr,"\tmkApp1 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,fo);)
  return fo;
}

FileOffset
mkApp2(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (5*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(2);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  HIDE(fprintf(stderr,"\tmkApp2 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,fo);)
  return fo;
}

FileOffset
mkApp3(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (6*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(3);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  HIDE(fprintf(stderr,"\tmkApp3 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,fo);)
  return fo;
}

FileOffset
mkApp4(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (7*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(4);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  HIDE(fprintf(stderr,"\tmkApp4 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,fo);)
  return fo;
}

FileOffset
mkApp5(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (8*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(5);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  HIDE(fprintf(stderr,"\tmkApp5 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,fo);)
  return fo;
}

FileOffset
mkApp6(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (9*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(6);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  HIDE(fprintf(stderr,"\tmkApp6 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,fo);)
  return fo;
}

FileOffset
mkApp7(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (10*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(7);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  HIDE(fprintf(stderr,"\tmkApp7 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,fo);)
  return fo;
}

FileOffset
mkApp8(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (11*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(8);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  HIDE(fprintf(stderr,"\tmkApp8 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,fo);)
  return fo;
}

FileOffset
mkApp9(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (12*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(9);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  HIDE(fprintf(stderr,"\tmkApp9 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,fo);)
  return fo;
}

FileOffset
mkApp10(FileOffset parent,FileOffset use,FileOffset fun
       ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
       ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
       ,FileOffset arg9,FileOffset arg10)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (13*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(10);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  HIDE(fprintf(stderr,"\tmkApp10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,fo);)
  return fo;
}

FileOffset
mkApp11(FileOffset parent,FileOffset use,FileOffset fun
       ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
       ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
       ,FileOffset arg9,FileOffset arg10,FileOffset arg11)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (14*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(11);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  HIDE(fprintf(stderr,"\tmkApp11 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,fo);)
  return fo;
}

FileOffset
mkApp12(FileOffset parent,FileOffset use,FileOffset fun
       ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
       ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
       ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (15*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(12);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  HIDE(fprintf(stderr,"\tmkApp12 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,fo);)
  return fo;
}

FileOffset
mkApp13(FileOffset parent,FileOffset use,FileOffset fun
       ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
       ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
       ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12
       ,FileOffset arg13)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (16*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(13);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  writeFileOffset(arg13);
  HIDE(fprintf(stderr,"\tmkApp13 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,fo);)
  return fo;
}

FileOffset
mkApp14(FileOffset parent,FileOffset use,FileOffset fun
       ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
       ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
       ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12
       ,FileOffset arg13,FileOffset arg14)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (17*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(14);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  writeFileOffset(arg13);
  writeFileOffset(arg14);
  HIDE(fprintf(stderr,"\tmkApp14 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,fo);)
  return fo;
}

FileOffset
mkApp15(FileOffset parent,FileOffset use,FileOffset fun
       ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
       ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
       ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12
       ,FileOffset arg13,FileOffset arg14,FileOffset arg15)
{
  FileOffset fo;

  fo = writeTag(ExpApp | (use?HasSrcPos:0)
             ,2 + (18*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(fun);
  writeByte(15);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  writeFileOffset(arg13);
  writeFileOffset(arg14);
  writeFileOffset(arg15);
  HIDE(fprintf(stderr,"\tmkApp15 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,fo);)
  return fo;
}

FileOffset
mkValueApp1(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (3*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(1);
  writeFileOffset(arg1);
  HIDE(fprintf(stderr,"\tmkValueApp1 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,fo);)
  return fo;
}

FileOffset
mkValueApp2(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
            ,2 + (4*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(2);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  HIDE(fprintf(stderr,"\tmkValueApp2 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,fo);)
  return fo;
}

FileOffset
mkValueApp3(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (5*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(3);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  HIDE(fprintf(stderr,"\tmkValueApp3 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,fo);)
  return fo;
}

FileOffset
mkValueApp4(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (6*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(4);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  HIDE(fprintf(stderr,"\tmkValueApp4 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,fo);)
  return fo;
}

FileOffset
mkValueApp5(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5)
{
  FileOffset fo;
  
  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (7*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(5);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  HIDE(fprintf(stderr,"\tmkValueApp5 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,fo);)
  return fo;
}

FileOffset
mkValueApp6(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (8*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(6);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  HIDE(fprintf(stderr,"\tmkValueApp6 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,fo);)
  return fo;
}

FileOffset
mkValueApp7(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (9*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(7);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  HIDE(fprintf(stderr,"\tmkValueApp7 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,fo);)
  return fo;
}

FileOffset
mkValueApp8(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (10*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(8);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  HIDE(fprintf(stderr,"\tmkValueApp8 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,LastExp);)
  return fo;
}

FileOffset
mkValueApp9(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (11*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(9);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  HIDE(fprintf(stderr,"\tmkValueApp9 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,LastExp);)
  return fo;
}

FileOffset
mkValueApp10(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9,FileOffset arg10)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (12*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(10);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  HIDE(fprintf(stderr,"\tmkValueApp10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,LastExp);)
  return fo;
}

FileOffset
mkValueApp11(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9,FileOffset arg10,FileOffset arg11)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (13*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(11);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  HIDE(fprintf(stderr,"\tmkValueApp11 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,LastExp);)
  return fo;
}

FileOffset
mkValueApp12(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (14*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(12);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  HIDE(fprintf(stderr,"\tmkValueApp12 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,LastExp);)
  return fo;
}

FileOffset
mkValueApp13(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12
      ,FileOffset arg13)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (15*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(13);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  writeFileOffset(arg13);
  HIDE(fprintf(stderr,"\tmkValueApp13 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,LastExp);)
  return fo;
}

FileOffset
mkValueApp14(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12
      ,FileOffset arg13,FileOffset arg14)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (16*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(14);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  writeFileOffset(arg13);
  writeFileOffset(arg14);
  HIDE(fprintf(stderr,"\tmkValueApp14 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,LastExp);)
  return fo;
}

FileOffset
mkValueApp15(FileOffset parent,FileOffset use,FileOffset fun
      ,FileOffset arg1,FileOffset arg2,FileOffset arg3,FileOffset arg4
      ,FileOffset arg5,FileOffset arg6,FileOffset arg7,FileOffset arg8
      ,FileOffset arg9,FileOffset arg10,FileOffset arg11,FileOffset arg12
      ,FileOffset arg13,FileOffset arg14,FileOffset arg15)
{
  FileOffset fo;

  fo = writeTag(ExpValueApp | (use?HasSrcPos:0)
             ,2 + (17*sizeof(FileOffset)) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(fun);
  writeByte(15);
  writeFileOffset(arg1);
  writeFileOffset(arg2);
  writeFileOffset(arg3);
  writeFileOffset(arg4);
  writeFileOffset(arg5);
  writeFileOffset(arg6);
  writeFileOffset(arg7);
  writeFileOffset(arg8);
  writeFileOffset(arg9);
  writeFileOffset(arg10);
  writeFileOffset(arg11);
  writeFileOffset(arg12);
  writeFileOffset(arg13);
  writeFileOffset(arg14);
  writeFileOffset(arg15);
  HIDE(fprintf(stderr,"\tmkValueApp15 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,fun,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,LastExp);)
  return fo;
}

FileOffset
mkChar(FileOffset parent,FileOffset use,char c)
{
  FileOffset fo;

  fo = writeTag(ExpChar | (use?HasSrcPos:0)
             ,1 + sizeof(FileOffset) + sizeof(char)
                + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeByte(c);
  HIDE(fprintf(stderr,"\tmkChar 0x%x 0x%x %c -> 0x%x\n",parent,use,c,fo);)
  return fo;
}

FileOffset
mkInt(FileOffset parent,FileOffset use,int i)
{
  FileOffset fo;

  fo = writeTag(ExpInt | (use?HasSrcPos:0)
             ,1 + sizeof(FileOffset) + sizeof(int) 
                + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeInt(i);  
  HIDE(fprintf(stderr,"\tmkInt 0x%x 0x%x %d -> 0x%x\n",parent,use,i,fo);)
  return fo;
}

FileOffset
mkInteger(FileOffset parent,FileOffset use,char *i)
{
  FileOffset fo;

  fo = writeTag(ExpInteger | (use?HasSrcPos:0)
             ,1 + sizeof(FileOffset) + stringSize(i) 
            + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeString(i);
  HIDE(fprintf(stderr,"\tmkInteger 0x%x 0x%x %s -> 0x%x\n",parent,use,i,fo);)
  return fo;
}

FileOffset
mkRat(FileOffset parent,FileOffset use,int num,int denom)
{
  FileOffset fo;

  fo = writeTag(ExpRat | (use?HasSrcPos:0)
             ,1 + sizeof(FileOffset) + 2*sizeof(int) 
                + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeInt(num);
  writeInt(denom);
  HIDE(fprintf(stderr,"\tmkRat 0x%x 0x%x %d/%d -> 0x%x\n",parent,use,num,denom,fo);)
  return fo;
}

FileOffset
mkRational(FileOffset parent,FileOffset use
          ,char *num,char *denom)
{
  FileOffset fo;

  fo = writeTag(ExpRational | (use?HasSrcPos:0)
             ,1+ sizeof(FileOffset) + stringSize(num) + stringSize(denom)
                + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeString(num);
  writeString(denom);
  HIDE(fprintf(stderr,"\tmkRational 0x%x 0x%x %s/%s -> 0x%x\n",parent,use,num,denom,fo);)
  return fo;
}

FileOffset
mkFloat(FileOffset parent,FileOffset use,float f)
{
  FileOffset fo;

  fo = writeTag(ExpFloat | (use?HasSrcPos:0)
             ,1 + sizeof(FileOffset) + sizeof(float) 
            + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFloat(f);
  HIDE(fprintf(stderr,"\tmkFloat 0x%x 0x%x %f -> 0x%x\n",parent,use,f,fp);)
  return fo;
}

FileOffset
mkDouble(FileOffset parent,FileOffset use,double d)
{
  FileOffset fo;

  fo = writeTag(ExpDouble | (use?HasSrcPos:0)
             ,1 + sizeof(FileOffset) + sizeof(double) 
            + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeDouble(d);
  HIDE(fprintf(stderr,"\tmkDouble 0x%x 0x%x %f -> 0x%x\n",parent,use,d,fo);)
  return fo;
}

FileOffset
mkValueUse(FileOffset parent,FileOffset use,FileOffset value)
{
  FileOffset fo;

  fo = writeTag(ExpValueUse | (use?HasSrcPos:0)
             ,1 + 2*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(value);
  HIDE(fprintf(stderr,"\tmkValueUse 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,value,fo);)
  return fo;
}

FileOffset
mkConstUse(FileOffset parent,FileOffset use,FileOffset con)
{
  FileOffset fo;

  fo = writeTag(ExpConstUse | (use?HasSrcPos:0)
             , 1 + 2*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(con);
  HIDE(fprintf(stderr,"\tmkConstUse 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,con,fo);)
  return fo;
}

FileOffset
mkConstDef(FileOffset context,FileOffset var)
{
  FileOffset fo;

  fo = writeTag(ExpConstDef, 1 + 3*sizeof(FileOffset));
  writeFileOffset(context);
  writeFileOffset(unevaluated);
  writeFileOffset(var);
  HIDE(fprintf(stderr,"\tmkConstDef 0x%x 0x%x -> 0x%x\n",context,var,fo);)
  return fo;
}


FileOffset
mkGuard(FileOffset parent,FileOffset use,FileOffset cond)
{
  FileOffset fo;

  fo = writeTag(ExpGuard | (use?HasSrcPos:0)
             ,1 + 3*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(cond);  
  HIDE(fprintf(stderr,"\tmkGuard 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,unevaluated,cond,fo);)
  return fo;
}

FileOffset
mkCase(FileOffset parent,FileOffset use,FileOffset cond)
{
  FileOffset fo;

  fo = writeTag(ExpCase | (use?HasSrcPos:0)
             ,1 + 3*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(cond);  
  HIDE(fprintf(stderr,"\tmkCase 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,cond,fo);)
  return fo;
}

FileOffset
mkIf(FileOffset parent,FileOffset use,FileOffset cond)
{
  FileOffset fo;

  fo = writeTag(ExpIf | (use?HasSrcPos:0)
             ,1 + 3*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(cond);  
  HIDE(fprintf(stderr,"\tmkIf 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,cond,fo);)
  return fo;
}

FileOffset
mkFieldUpdate1(FileOffset parent,FileOffset use
              ,FileOffset arg,FileOffset binder1,FileOffset bindee1)
{
  FileOffset fo;

  fo = writeTag(ExpFieldUpdate | (use?HasSrcPos:0)
             ,2 + 5*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(arg);
  writeByte(1);
  writeFileOffset(binder1);
  writeFileOffset(bindee1);
  HIDE(fprintf(stderr,"\tmkFieldUpdate1 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,arg,binder1,bindee1,fo);)
  return fo;
}


FileOffset
mkFieldUpdate2(FileOffset parent,FileOffset use
              ,FileOffset arg,FileOffset binder1,FileOffset bindee1
              ,FileOffset binder2,FileOffset bindee2)
{
  FileOffset fo;

  fo = writeTag(ExpFieldUpdate | (use?HasSrcPos:0)
             ,2 + 7*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(arg);
  writeByte(2);
  writeFileOffset(binder1);
  writeFileOffset(bindee1);
  writeFileOffset(binder2);
  writeFileOffset(bindee2);
  HIDE(fprintf(stderr,"\tmkFieldUpdate2 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,arg,binder1,bindee1,binder2,bindee2,fo);)
  return fo;
}

FileOffset
mkFieldUpdate3(FileOffset parent,FileOffset use
              ,FileOffset arg,FileOffset binder1,FileOffset bindee1
              ,FileOffset binder2,FileOffset bindee2
              ,FileOffset binder3,FileOffset bindee3)
{
  FileOffset fo;

  fo = writeTag(ExpFieldUpdate | (use?HasSrcPos:0)
             ,2 + 9*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  writeFileOffset(arg);
  writeByte(3);
  writeFileOffset(binder1);
  writeFileOffset(bindee1);
  writeFileOffset(binder2);
  writeFileOffset(bindee2);
  writeFileOffset(binder3);
  writeFileOffset(bindee3);
  HIDE(fprintf(stderr,"\tmkFieldUpdate3 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,Unevaluated,arg,binder1,bindee1,binder2,bindee2,binder3,bindee3,fo);)
  return fo;
}

FileOffset
mkProjection(FileOffset parent,FileOffset use,FileOffset exp)
{
  FileOffset fo;

  fo = writeTag(ExpProjection | (use?HasSrcPos:0)
             ,1 + 2*sizeof(FileOffset) + (use?sizeof(FileOffset):0));
  if(use)
    writeFileOffset(use);
  writeFileOffset(parent);
  writeFileOffset(exp);
  HIDE(fprintf(stderr,"\tmkProjection 0x%x 0x%x 0x%x -> 0x%x\n",parent,use,exp,fo);)
  return fo;
}

FileOffset
mkHidden(FileOffset parent)
{
  FileOffset fo;

  fo = writeTag(ExpHidden,1 + 2*sizeof(FileOffset));
  writeFileOffset(parent);
  writeFileOffset(unevaluated);
  HIDE(fprintf(stderr,"\tmkHidden 0x%x 0x%x -> 0x%x\n",parent,Unevaluated,fo);)
  return (fo|~hiddenMask);
}

FileOffset
mkForward(FileOffset result)
{
  FileOffset fo;

  fo = writeTag(ExpForward,1 + sizeof(FileOffset));
  writeFileOffset(result);
  HIDE(fprintf(stderr,"\tmkForward 0x%x -> 0x%x\n",Unevaluated,fo);)
  return fo;
}

FileOffset
mkDoStmt(FileOffset stmt)
{
  FileOffset fo;

  fo = writeTag(ExpDoStmt, 1 + sizeof(FileOffset));
  writeFileOffset(stmt);
  HIDE(fprintf(stderr,"\tmkDoStmt 0x%x -> 0x%x\n",stmt,fo);)
  return fo;
}

/* Atom */

FileOffset
mkLambda()
{   return (htonl(Lambda)); }

FileOffset
mkVariable(FileOffset module,int pos,int fixity,int arity,char *name
        ,bool local)
{
  FileOffset fo;

  fo = writeTag(AtomVariable | (local?LocalDef:0)
               ,1+sizeof(FileOffset)+sizeof(int)+2*sizeof(byte)
                +stringSize(name));
  writeFileOffset(module);
  writeInt(pos);
  writeByte(fixity);
  writeByte(arity);
  writeString(name);
  HIDE(fprintf(stderr,"\tmkVariable 0x%x %d %d %d %s %d -> 0x%x\n",module,pos,fixity,arity,name,local,fo);)
  return fo;
}

FileOffset
mkConstructor(FileOffset module,int pos,int fixity,int arity,char *name)
{
  FileOffset fo;

  fo = writeTag(AtomConstructor
               ,1+sizeof(FileOffset)+sizeof(int)+2*sizeof(byte)
                +stringSize(name));
  writeFileOffset(module);
  writeInt(pos);
  writeByte(fixity);
  writeByte(arity);
  writeString(name);
  HIDE(fprintf(stderr,"\tmkConstructor 0x%x %d %d %d %s %d -> 0x%x\n",module,pos,fixity,arity,name,fo);)
  return fo;
}

FileOffset
mkConstructorWFields(FileOffset module,int pos,int fixity,int arity,char *name
                  ,FileOffset labels[])
{
  int i;
  FileOffset fo;

  fo = writeTag(AtomConstructor|HasFields
             ,1+(1+arity)*sizeof(FileOffset)+sizeof(int)+2*sizeof(byte)
                +stringSize(name));
  writeFileOffset(module);
  writeInt(pos);
  writeByte(fixity);
  writeByte(arity);
  writeString(name);
  for (i=0;i<arity;i++) 
    writeFileOffset(labels[i]);
  HIDE(fprintf(stderr,"\tmkConstructorWFields 0x%x %d %d %d %s -> 0x%x\n",module,pos,fixity,arity,name,fo);)
  return fo;
}


FileOffset
mkAbstract(char *description)
{
  FileOffset fo;

  fo = writeTag(AtomAbstract, 1+stringSize(description));
  writeString(description);
  HIDE(fprintf(stderr,"\tmkAbstract %s -> 0x%x\n",description,fo);)
  return fo;
}

/* Update node that it was entered */

void entResult(FileOffset node,FileOffset use)
{
  LastExp = node;
  node &= hiddenMask;
  HIDE(fprintf(stderr,"\tentResult 0x%x 0x%x 0x%x\n",node,use,ntohl(node)+1+sizeof(FileOffset)+(use?sizeof(FileOffset):0));)
  hat_enter(ntohl(node),1+sizeof(FileOffset)+(use?sizeof(FileOffset):0),
          entered);
  if (controlC) 
    hat_InterruptExit();
}

void entForward(FileOffset node,FileOffset hidden)
{
  hat_enter(ntohl(node),1,hidden);
  if (controlC) 
    hat_InterruptExit();
}

/* Update node with result */

void resResult(FileOffset node,FileOffset result,FileOffset use)
{
  LastExp = node;
  node &= hiddenMask;
  result &= hiddenMask;
  hat_reduce(ntohl(node),1+sizeof(FileOffset)+(use?sizeof(FileOffset):0),
           result);
}

void resForward(FileOffset node,FileOffset result)
{
  result &= hiddenMask;
  hat_reduce(ntohl(node),1,result);
}

/* Data structures and functions for various buffers.
 * All sequential writes are buffered in buffers, which consists of
 * WriteBufferNo buffers of size WriteBufferSize.
 * If updates effect data still in buffers, they are
 * made there (the majority, this it the purpose buffers);
 * the remaining ones are buffered in buffer of size BufferSize.
 * Information about entered redexes is put on the stack `stack',
 * which can grow and shrink in units of StackpartSize. Only when
 * stack elements are popped, updates are made.
 * The stack both avoids updates and enables locating an error position.
 *
 * Most FileOffsets are stored in network byte order, but some in host
 * byte order.
 */

/* Put enter updates on a stack. A reduce update pops an enter update from
 * the stack. To reduce number of seeks the reduce updates are buffered.
 * The stack is unbounded, it grows in parallel with the runtime stack.
 * An exception releases large parts of the stack. Notice this situation
 * by always comparing the at-positions of the reduce update with the
 * at-position of enter updates on the stack.
 * The stack is only written to the trace if the computation is aborted.
 */

typedef struct update {
  FileOffset at;
  FileOffset new;
} Update;

typedef struct entry {
  FileOffset at;
  FileOffset offset;
  FileOffset parent; /* or entered for anything but Forward */
} Entry;

#define StackpartSize 8000

typedef struct stackpart {
  struct stackpart *previous;
  Entry entry[StackpartSize];
} Stackpart;

static Stackpart *stack = NULL ;
static int stacktop = StackpartSize; 
  /* next free entry, initialisation important */


void hat_pushStack(FileOffset at, FileOffset offset, FileOffset new)
{
  if (stacktop >= StackpartSize) {
    Stackpart *newStackpart;
    newStackpart = malloc(sizeof(Stackpart));
    if (newStackpart == NULL) {
      fprintf(stderr,"No space for Hat stack.");
      exit (-1);
    }
    (*newStackpart).previous = stack;
    stack = newStackpart;
    stacktop = 0;
  }
  (*stack).entry[stacktop].at = at;
  (*stack).entry[stacktop].offset = offset;
  (*stack).entry[stacktop].parent = new;
  ++stacktop;
}

/* Returns at-position from top of stack; 
 * if top of stack is a Forward, then returns its parent;
 * result in network byte order; assumes stack != NULL; stack unchanged 
 */
FileOffset hat_topStack()
{
  int curStacktop = stacktop;
  Stackpart *curStack = stack;

  --curStacktop;
  if (curStacktop < 0) {
    curStack = (*curStack).previous; 
    curStacktop = StackpartSize-1;
    if (curStack == NULL) 
      return 0;
  }
  if ((*curStack).entry[curStacktop].offset == 1) /* is Forward */
    return (((*curStack).entry[curStacktop].parent)&hiddenMask);
  else
    return (htonl ((*curStack).entry[curStacktop].at));
}

/* returns at-position in host byte order; assumes stack != NULL */
FileOffset hat_popStack()
{
  if (stacktop == 0) {
    Stackpart *oldstack;
    oldstack = stack;
    stack = (*oldstack).previous;
    free(oldstack);
    stacktop = StackpartSize;
    if (stack == NULL) {
      fprintf(stderr,"Pop empty Hat stack.");
      exit (-1);
    }
  }
   --stacktop;
  return ((*stack).entry[stacktop].at);
}


/* writes top of stack to trace until at position equal given one */
void hat_writeStackUntil(FileOffset at)
{
  while (True) {
    FileOffset thisAt = hat_popStack();
    if (thisAt == at) 
      break;
    updateFileOffset(thisAt+(*stack).entry[stacktop].offset
                    ,((*stack).entry[stacktop].parent)&hiddenMask);
  }
}

/* Afterwards stack is unusable and even memory is not freed. */
void hat_dumpStack() {
  int i;

  while (stack != NULL) {
    for (i=0;i<stacktop;i++) {
      updateFileOffset((*stack).entry[i].at+(*stack).entry[i].offset
                      ,((*stack).entry[i].parent)&hiddenMask);
    }
    stacktop = StackpartSize;
    stack = (*stack).previous;
  }
}

/* Buffer for deferred updates */

#define BufferSize 4000
static Update buffer[BufferSize];
static int buffertop = 0;  /* next free one */

void hat_putInBuffer(FileOffset at, FileOffset new) {
  if (buffertop >= BufferSize) 
    hat_dumpBuffer();
  buffer[buffertop].at = at;
  buffer[buffertop].new = new;
  ++buffertop;
}

void hat_dumpBuffer() {
  int i;

  for (i=0;i<buffertop;i++) {
    fseek(HatFile,buffer[i].at,SEEK_SET);
    fwrite(&(buffer[i].new),sizeof(FileOffset),1,HatFile);
  }
  buffertop = 0;

  fseek(HatFile,0,SEEK_END);
}

void hat_enter(FileOffset at, FileOffset offset, FileOffset entry)
{
  hat_pushStack(at,offset,entry);
}

void hat_reduce(FileOffset at, FileOffset offset, FileOffset entry)
{
  hat_writeStackUntil(at);
  updateFileOffset(at+offset,entry);
}


/* Buffering scheme for sequential writing with updates */

#define WriteBufferNo 4  /* minimum: 1 */
#define WriteBufferSize 20000  /* minimum: size of largest node */

typedef struct writeBuffer {
  FileOffset begin;  /* in host byte order */
  int pos;
  byte content[WriteBufferSize];
} WriteBuffer;

WriteBuffer buffers[WriteBufferNo];
WriteBuffer *currentWriteBuffer = buffers;
int currentWriteBufferNo = 0;

static void 
initBuffers() 
{
  int i;

  for (i=0;i<WriteBufferNo;i++) {
    buffers[i].begin = 0;
    buffers[i].pos = 0;
  }
  currentWriteBuffer->begin = HeaderSize;
}

/* returns offset of newly started node in network byte order */
static FileOffset 
writeTag (int tag, int size) 
{
  FileOffset currentOffset;

  if (currentWriteBuffer->pos + size > WriteBufferSize) {
    currentOffset = currentWriteBuffer->begin + currentWriteBuffer->pos;
    currentWriteBufferNo = (currentWriteBufferNo+1) % WriteBufferNo;
    currentWriteBuffer = &(buffers[currentWriteBufferNo]);
    fwrite(currentWriteBuffer->content,sizeof(byte),currentWriteBuffer->pos
          ,HatFile);
    currentWriteBuffer->begin = currentOffset;
    currentWriteBuffer->pos = 0;
  }
  currentWriteBuffer->content[currentWriteBuffer->pos++] = tag;
  return (htonl(currentWriteBuffer->begin + currentWriteBuffer->pos - 1));
}

static void 
writeByte (int byte)
{
  currentWriteBuffer->content[currentWriteBuffer->pos++] = byte;
}

static void 
writeFileOffset (FileOffset offset) 
{
  offset &= hiddenMask;
  memcpy(&(currentWriteBuffer->content[currentWriteBuffer->pos])
        ,&offset,sizeof(FileOffset));
  currentWriteBuffer->pos += sizeof(FileOffset);
}

static void 
writeInt (int number) 
{
  number = htonl(number);
  memcpy(&(currentWriteBuffer->content[currentWriteBuffer->pos])
        ,&number,sizeof(int));
  currentWriteBuffer->pos += sizeof(int);
}

static void 
writeFloat (float number) 
{
  memcpy(&(currentWriteBuffer->content[currentWriteBuffer->pos])
        ,&number,sizeof(float));
  currentWriteBuffer->pos += sizeof(float);
}

static void 
writeDouble (double number) 
{
  memcpy(&(currentWriteBuffer->content[currentWriteBuffer->pos])
        ,&number,sizeof(double));
  currentWriteBuffer->pos += sizeof(double);
}

static void 
updateFileOffset (FileOffset at, FileOffset entry) 
{
  int i;

  if (buffers[(currentWriteBufferNo+1) % WriteBufferNo].begin > at) {
    hat_putInBuffer(at,entry);
  } else {
    for (i=0;i<WriteBufferNo;i++) {
      if (at >= buffers[i].begin && at < buffers[i].begin + buffers[i].pos) {
        memcpy(&(buffers[i].content[at - buffers[i].begin])
              ,&entry,sizeof(FileOffset));
        break;
      }
    } 
  }
}

static int
stringSize(char *s)
{
  int length = strlen(s);
  if (length < 255)
    return (length+1);
  else
    return (length+3);
}

static void
writeString(char *s)
{
  int length = strlen(s);
  if (length < 255)
    writeByte(length);
  else {
    writeByte(255);
    writeByte(length>>8); /* high byte first */
    writeByte(length);
  }
  memcpy(&(currentWriteBuffer->content[currentWriteBuffer->pos]),s,length);
  currentWriteBuffer->pos += length;
}

static void
dumpBuffers()
{
  int i;
  fseek(HatFile,0,SEEK_END);
  for (i=0;i<WriteBufferNo;i++) {
    currentWriteBufferNo = (currentWriteBufferNo + 1) % WriteBufferNo;
    fwrite(buffers[currentWriteBufferNo].content,sizeof(byte)
          ,buffers[currentWriteBufferNo].pos,HatFile);
  }
}


Generated by  Doxygen 1.6.0   Back to index