[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\DbgMount-Sup1-Sup1Distro-Home.html
// Date: unknown-date
// Language: HolyC

#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
public I64 Mount(Bool repartition=FALSE)
{
  I64 cnt,res=0,num_hints,drv_let,type,unit,prt_num;
  U8 blks_buf[STR_LEN],addr_buf[STR_LEN],base0_buf[STR_LEN],base1_buf[STR_LEN],
        *filename=NULL,*filename2=NULL;
  CATARep *head=NULL,*tmpha;
  Bool whole_drv;
  CBlkDev *bd;
  do {
    cnt=0;
    DrvRep;
    "\n****** Mount Drives ******\n"
          "A-B are RAM drives.\n"
          "C-L are ATA hard drives.\n"
          "M-P are ISO file read drives.\n"
          "Q-S are ISO file write drives.\n"
          "T-Z are ATAPI CD/DVD drives.\n"
          "\nDrive Letter (<ENTER> to exit):";
    drv_let=Let2Let(GetChar);
    '\n';
    if (type=Let2BlkDevType(drv_let)) {
      whole_drv=FALSE;
      unit=0;
      prt_num=I64_MIN;
      switch (type) {
        case BDT_RAM:
          "Addr of RAM disk (<ENTER> to MAlloc):";
          GetS(addr_buf,STR_LEN);
        case BDT_ISO_FILE_WRITE:
          "Blks of 512 bytes:";
          GetS(blks_buf,STR_LEN);
          break;
        case BDT_ISO_FILE_READ:
          filename=GetStr("File Name:");
          break;
        case BDT_ATA:
          prt_num=GetI64("Partition Num (Default=All):",prt_num);
        case BDT_ATAPI:
          num_hints=ATARep(,,&head);
          do {
            if (num_hints)
              "Enter dev number or\nport with 0x prefix.\n"
                    "I/O Port Base0:\n";
            else
              "Include 0x prefix.\nI/O Port Base0:\n";
            GetS(base0_buf,STR_LEN);
          } while (!Str2I64(base0_buf));
          if (1<=Str2I64(base0_buf)<=num_hints) {
            tmpha=ATARepFind(head,Str2I64(base0_buf));
            StrPrint(base0_buf,"0x%X",tmpha->base0);
            StrPrint(base1_buf,"0x%X",tmpha->base1);
            unit=tmpha->unit;
          } else if (type!=BDT_ATAPI || *base0_buf) {
            if (type==BDT_ATAPI)
              StrCpy(base1_buf,"0");
            else
              do {
                "I/O Port Base1:\n";
                GetS(base1_buf,STR_LEN);
              } while (!Str2I64(base1_buf));
            do {
              "\t0=Master\n\t1=Slave\nUnit:";
              unit=GetChar-'0';
            } while (!(0<=unit<=1));
            '\n';
          }
          LinkedLstDel(head);
          break;
      }
      bd=BlkDevNextFreeSlot(drv_let,type);
      bd->unit=unit;
      switch (type) {
        case BDT_RAM:
          if (!*addr_buf)
            bd->RAM_dsk=0;
          else
            bd->RAM_dsk=Str2I64(addr_buf);
        case BDT_ISO_FILE_WRITE:
          if (!*blks_buf)
            bd->max_blk=-1;
          else
            bd->max_blk=Str2I64(blks_buf)-1;
          bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
          break;
        case BDT_ISO_FILE_READ:
          filename2=FileNameAbs(filename);
          bd->file_dsk_name=AStrNew(filename2);
          bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
          break;
        case BDT_ATA:
        case BDT_ATAPI:
          bd->base0=Str2I64(base0_buf);
          bd->base1=Str2I64(base1_buf);
          if (type==BDT_ATA && repartition) {
            "\nReformat WHOLE drive!";
            whole_drv=YorN;
          }
          break;
      }
      if ((cnt=BlkDevAdd(bd,prt_num,whole_drv,TRUE)) && whole_drv)
        ExePrint("DskPrt('%C');\n",drv_let);
    }
    res+=cnt;
  } while (cnt);
  Free(filename);
  Free(filename2);
  return res;
}


// Source: D:\TempleOS-Projects\html\DocGet-DolDoc-Adam.html
// Date: unknown-date
// Language: HolyC

#help_index "DolDoc"

U0 EdUndoFilter(CDoc *doc)
{
  Bool unlock=DocLock(doc);
  CDocEntry *doc_ce=doc->head.next;
  while (doc_ce!=doc) {
    doc_ce->de_flags&=~DOCEF_FILTER_SKIP;
    doc_ce=doc_ce->next;
  }
  doc->find_replace->filter_lines=0;
  if (unlock)
    DocUnlock(doc);
}

public I64 DocGetKey(I64 *_sc=NULL)
{//Called by View. You probably don't need this.
  I64 ch,sc;
  Bool cont,old_key_desc;
  do {
    old_key_desc=LBtr(&Fs->win_inhibit,WIf_SELF_KEY_DESC);
    do ch=GetKey(&sc,TRUE);
    while (sc&SCF_KEY_DESC);
    LBEqu(&Fs->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);

    DocRecalc(DocPut);
    cont=FALSE;
    if ((ch==CH_ESC || ch==CH_SHIFT_ESC) && //Check for exit filter mode
          DocPut && DocPut->find_replace->filter_lines) {
      EdUndoFilter(DocPut);
      cont=TRUE;
    }
  } while (cont);
  if (_sc) *_sc=sc;
  return ch;
}

#help_index "DolDoc/Input;StdIn/DolDoc"
public U8 *DocScanLine(CDoc *doc,CDocEntry *doc_e,
        I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
{//Start at entry in doc,make and return one line as str.
  CDocEntry *doc_e2=doc_e;
  Bool unlock=DocLock(doc);
  U8 *dst,*src,*start,*res;
  I64 i=0;
  if (cur_col)
    *cur_col=-1;
  while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
    if (doc_e2->de_flags&DOCEF_TAG && doc_e2->tag) {
      src=doc_e2->tag;
      i+=StrLen(src);
    } else if (doc_e2->type_u8==DOCT_TAB)
      i++;
    else if (doc_e2->type_u8==DOCT_SHIFTED_X ||
          doc_e2->type_u8==DOCT_SHIFTED_Y) {
      if (doc_e2->attr<0)
        i++;
      i+=6; //$SY,3$
    }
    doc_e2=doc_e2->next;
  }
  res=MAlloc(i+1);
  dst=res;
  while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
    start=dst;
    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
      src=doc_e->tag;
      while (*src)
        *dst++=*src++;
    } else if (doc_e->type_u8==DOCT_TAB)
      *dst++='\t';
    else if (doc_e->type_u8==DOCT_SHIFTED_Y) {
      *dst(U32 *)++='$SY,';
      if (doc_e->attr<0)
        *dst++='-';
      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
      *dst++='$';
    } else if (doc_e->type_u8==DOCT_SHIFTED_X) {
      *dst(U32 *)++='$SX,';
      if (doc_e->attr<0)
        *dst++='-';
      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
      *dst++='$';
    }
    if (doc_e==doc->cur_entry && cur_col)
      *cur_col=start-res+doc->cur_col;
    doc_e=doc_e->next;
  }
  if (_do_e_end) *_do_e_end=doc_e;
  *dst=0;
  if (doc_e==doc->cur_entry && cur_col && !doc->cur_col)
    *cur_col=dst-res;
  if (unlock)
    DocUnlock(doc);
  return res;
}

U8 *DocGetStr2(I64 flags=0)
{//Flags
  CDoc *doc;
  CDocEntry *doc_e,*doc_e_end;
  U8 *st,*st2,*res;
  I64 ch,sc;
  "$PT$";
  do {
    ch=DocGetKey(&sc);
    if (ch==CH_ESC) {
      if (doc=DocPut) {
        DocLock(doc);
        if (doc->doc_signature==DOC_SIGNATURE_VAL && doc->cur_entry!=doc) {
          doc_e=DocEntryCopy(doc,doc->cur_entry);
          DocBottom(doc);
          DocEntryRun(doc,doc_e,TRUE);
          DocEntryDel(doc,doc_e);
        }
        DocUnlock(doc);
      }
      if (flags&GSF_WITH_NEW_LINE)
        break;
    } if (ch==CH_SHIFT_ESC) {
      if (flags&GSF_SHIFT_ESC_EXIT)
        Exit;
      else {
        res=StrNew("");
        goto gs_done;
      }
    }
//<CTRL-SHIFT-ENTER> is a blank line without entry
  } while (flags&GSF_WITH_NEW_LINE || ch!='\n' ||
        sc&SCF_CTRL && sc&SCF_SHIFT);

  doc=DocPut;
  DocLock(doc);
  if (flags&GSF_WITH_NEW_LINE) {
    doc_e=doc->cur_entry;
    do doc_e=doc_e->last;
    while (doc_e!=doc && doc_e->type_u8!=DOCT_PMT);
    doc_e=doc_e->next;
    if (res=DocScanLine(doc,doc_e,NULL,&doc_e_end)) {
      while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
        st2=MStrPrint("%s\n",res);
        Free(res);
        res=st2;
        if (st=DocScanLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
          st2=MStrPrint("%s%s",res,st);
          Free(st);
          Free(res);
          res=st2;
        }
      }
    }
  } else {
    doc_e=doc->cur_entry;
    do doc_e=doc_e->last;
    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
          doc_e->type_u8!=DOCT_PMT);
    if (doc_e!=doc && doc_e->type_u8!=DOCT_PMT) {
      do doc_e=doc_e->last;
      while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
            doc_e->type_u8!=DOCT_PMT);
    }
    doc_e=doc_e->next;
    res=DocScanLine(doc,doc_e,NULL);
  }
  DocUnlock(doc);
gs_done:
  "$PT$$FG$$BG$";
  return res;
}

#help_index "Keyboard Devices;Char/Input;StdIn"
public I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX)
{//Prompt user for I64 expression.
  Bool okay;
  U8 *st;
  I64 res;
  while (TRUE) {
    if (msg)
      "" msg,dft;
    st=GetStr;
    if (!*st) {
      Free(st);
      return dft;
    }
    try {
      res=ExePrint2("ToI64(%s);",st);
      okay=TRUE;
    } catch {
      Fs->catch_except=TRUE;
      okay=FALSE;
    }
    Free(st);
    if (okay && lo<=res<=hi)
      return res;
  }
}

public F64 GetF64(U8 *msg=NULL,F64 dft=0,F64 lo=F64_MIN,F64 hi=F64_MAX)
{//Prompt user for F64 expression.
  Bool okay;
  U8 *st;
  F64 res;
  while (TRUE) {
    if (msg)
      "" msg,dft;
    st=GetStr;
    if (!*st) {
      Free(st);
      return dft;
    }
    try {
      res=ExePrint2("ToF64(%s);",st)(F64);
      okay=TRUE;
    } catch {
      Fs->catch_except=TRUE;
      okay=FALSE;
    }
    Free(st);
    if (okay && lo<=res<=hi)
      return res;
  }
}

public CDate GetDate(U8 *msg=NULL,CDate dft=I64_MIN,
        CDate lo=I64_MIN,CDate hi=I64_MAX)
{//Prompt user for date expression. (Use Now() if you want current time.)
  U8 *st;
  CDate res;
  if (dft==I64_MIN) dft=Now;
  while (TRUE) {
    if (msg)
      "" msg,dft,dft;
    st=GetStr;
    if (!*st) {
      Free(st);
      return dft;
    }
    res=Str2Date(st);
    Free(st);
    if (res>=lo && res<=hi)
      return res;
  }
}

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\DocGet-DolDoc-Adam.html
// Date: unknown-date
// Language: HolyC

#help_index "DolDoc"

U0 EdUndoFilter(CDoc *doc)
{
  Bool unlock=DocLock(doc);
  CDocEntry *doc_ce=doc->head.next;
  while (doc_ce!=doc) {
    doc_ce->de_flags&=~DOCEF_FILTER_SKIP;
    doc_ce=doc_ce->next;
  }
  doc->find_replace->filter_lines=0;
  if (unlock)
    DocUnlock(doc);
}

public I64 DocGetKey(I64 *_sc=NULL)
{//Called by View. You probably don't need this.
  I64 ch,sc;
  Bool cont,old_key_desc;
  do {
    old_key_desc=LBtr(&Fs->win_inhibit,WIf_SELF_KEY_DESC);
    do ch=GetKey(&sc,TRUE);
    while (sc&SCF_KEY_DESC);
    LBEqu(&Fs->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);

    DocRecalc(DocPut);
    cont=FALSE;
    if ((ch==CH_ESC || ch==CH_SHIFT_ESC) && //Check for exit filter mode
          DocPut && DocPut->find_replace->filter_lines) {
      EdUndoFilter(DocPut);
      cont=TRUE;
    }
  } while (cont);
  if (_sc) *_sc=sc;
  return ch;
}

#help_index "DolDoc/Input;StdIn/DolDoc"
public U8 *DocScanLine(CDoc *doc,CDocEntry *doc_e,
        I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
{//Start at entry in doc,make and return one line as str.
  CDocEntry *doc_e2=doc_e;
  Bool unlock=DocLock(doc);
  U8 *dst,*src,*start,*res;
  I64 i=0;
  if (cur_col)
    *cur_col=-1;
  while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
    if (doc_e2->de_flags&DOCEF_TAG && doc_e2->tag) {
      src=doc_e2->tag;
      i+=StrLen(src);
    } else if (doc_e2->type_u8==DOCT_TAB)
      i++;
    else if (doc_e2->type_u8==DOCT_SHIFTED_X ||
          doc_e2->type_u8==DOCT_SHIFTED_Y) {
      if (doc_e2->attr<0)
        i++;
      i+=6; //$SY,3$
    }
    doc_e2=doc_e2->next;
  }
  res=MAlloc(i+1);
  dst=res;
  while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
    start=dst;
    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
      src=doc_e->tag;
      while (*src)
        *dst++=*src++;
    } else if (doc_e->type_u8==DOCT_TAB)
      *dst++='\t';
    else if (doc_e->type_u8==DOCT_SHIFTED_Y) {
      *dst(U32 *)++='$SY,';
      if (doc_e->attr<0)
        *dst++='-';
      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
      *dst++='$';
    } else if (doc_e->type_u8==DOCT_SHIFTED_X) {
      *dst(U32 *)++='$SX,';
      if (doc_e->attr<0)
        *dst++='-';
      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
      *dst++='$';
    }
    if (doc_e==doc->cur_entry && cur_col)
      *cur_col=start-res+doc->cur_col;
    doc_e=doc_e->next;
  }
  if (_do_e_end) *_do_e_end=doc_e;
  *dst=0;
  if (doc_e==doc->cur_entry && cur_col && !doc->cur_col)
    *cur_col=dst-res;
  if (unlock)
    DocUnlock(doc);
  return res;
}

U8 *DocGetStr2(I64 flags=0)
{//Flags
  CDoc *doc;
  CDocEntry *doc_e,*doc_e_end;
  U8 *st,*st2,*res;
  I64 ch,sc;
  "$PT$";
  do {
    ch=DocGetKey(&sc);
    if (ch==CH_ESC) {
      if (doc=DocPut) {
        DocLock(doc);
        if (doc->doc_signature==DOC_SIGNATURE_VAL && doc->cur_entry!=doc) {
          doc_e=DocEntryCopy(doc,doc->cur_entry);
          DocBottom(doc);
          DocEntryRun(doc,doc_e,TRUE);
          DocEntryDel(doc,doc_e);
        }
        DocUnlock(doc);
      }
      if (flags&GSF_WITH_NEW_LINE)
        break;
    } if (ch==CH_SHIFT_ESC) {
      if (flags&GSF_SHIFT_ESC_EXIT)
        Exit;
      else {
        res=StrNew("");
        goto gs_done;
      }
    }
//<CTRL-SHIFT-ENTER> is a blank line without entry
  } while (flags&GSF_WITH_NEW_LINE || ch!='\n' ||
        sc&SCF_CTRL && sc&SCF_SHIFT);

  doc=DocPut;
  DocLock(doc);
  if (flags&GSF_WITH_NEW_LINE) {
    doc_e=doc->cur_entry;
    do doc_e=doc_e->last;
    while (doc_e!=doc && doc_e->type_u8!=DOCT_PMT);
    doc_e=doc_e->next;
    if (res=DocScanLine(doc,doc_e,NULL,&doc_e_end)) {
      while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
        st2=MStrPrint("%s\n",res);
        Free(res);
        res=st2;
        if (st=DocScanLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
          st2=MStrPrint("%s%s",res,st);
          Free(st);
          Free(res);
          res=st2;
        }
      }
    }
  } else {
    doc_e=doc->cur_entry;
    do doc_e=doc_e->last;
    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
          doc_e->type_u8!=DOCT_PMT);
    if (doc_e!=doc && doc_e->type_u8!=DOCT_PMT) {
      do doc_e=doc_e->last;
      while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
            doc_e->type_u8!=DOCT_PMT);
    }
    doc_e=doc_e->next;
    res=DocScanLine(doc,doc_e,NULL);
  }
  DocUnlock(doc);
gs_done:
  "$PT$$FG$$BG$";
  return res;
}

#help_index "Keyboard Devices;Char/Input;StdIn"
public I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX)
{//Prompt user for I64 expression.
  Bool okay;
  U8 *st;
  I64 res;
  while (TRUE) {
    if (msg)
      "" msg,dft;
    st=GetStr;
    if (!*st) {
      Free(st);
      return dft;
    }
    try {
      res=ExePrint2("ToI64(%s);",st);
      okay=TRUE;
    } catch {
      Fs->catch_except=TRUE;
      okay=FALSE;
    }
    Free(st);
    if (okay && lo<=res<=hi)
      return res;
  }
}

public F64 GetF64(U8 *msg=NULL,F64 dft=0,F64 lo=F64_MIN,F64 hi=F64_MAX)
{//Prompt user for F64 expression.
  Bool okay;
  U8 *st;
  F64 res;
  while (TRUE) {
    if (msg)
      "" msg,dft;
    st=GetStr;
    if (!*st) {
      Free(st);
      return dft;
    }
    try {
      res=ExePrint2("ToF64(%s);",st)(F64);
      okay=TRUE;
    } catch {
      Fs->catch_except=TRUE;
      okay=FALSE;
    }
    Free(st);
    if (okay && lo<=res<=hi)
      return res;
  }
}

public CDate GetDate(U8 *msg=NULL,CDate dft=I64_MIN,
        CDate lo=I64_MIN,CDate hi=I64_MAX)
{//Prompt user for date expression. (Use Now() if you want current time.)
  U8 *st;
  CDate res;
  if (dft==I64_MIN) dft=Now;
  while (TRUE) {
    if (msg)
      "" msg,dft,dft;
    st=GetStr;
    if (!*st) {
      Free(st);
      return dft;
    }
    res=Str2Date(st);
    Free(st);
    if (res>=lo && res<=hi)
      return res;
  }
}


// Source: D:\TempleOS-Projects\html\Flappy-Sup1-Sup1Games-Home.html
// Date: unknown-date
// Language: HolyC

<1>/* Graphics Not Rendered in HTML */

        <2>/* Graphics Not Rendered in HTML */

        <3>/* Graphics Not Rendered in HTML */

#define BIRD_X 100
F64 dy,y,scroll_x;
Bool game_over;

#define PIPES_NUM       16
#define GAP             100

class Pipe
{
  I64 x,y;
} pipes[PIPES_NUM];

U0 DrawIt(CTask *task, CDC *dc)
{
  I64 i;
  Pipe *p;
  for (i=0;i<PIPES_NUM;i++) {
    p=&pipes[i];
    Sprite3(dc,p->x-scroll_x,p->y+task->pix_height>>1+GAP>>1,0,<3>);
    Sprite3(dc,p->x-scroll_x,p->y+task->pix_height>>1-GAP>>1,0,<2>);
  }

  dc->collision_cnt=0;
  dc->color=ROP_COLLISION;
  dc->bkcolor=WHITE;
  Sprite3ZB(dc,BIRD_X,y,0,<1>,-0.2*dy);
  if (dc->collision_cnt)
    game_over=TRUE;

  dc->color=ROP_EQU;
  Sprite3ZB(dc,BIRD_X,y,0,<1>,-0.2*dy);
}

U0 Init()
{
  I64 i;
  Pipe *p;
  for (i=0;i<PIPES_NUM;i++) {
    p=&pipes[i];
    p->x=i*125+200;
    p->y=80*Sin(i);
  }
  scroll_x=0;
  y=Fs->pix_height>>1;
  dy=0;
  game_over=FALSE;
}

U0 AnimateTask(I64)
{
  while (TRUE) {
    if (!game_over) {
      scroll_x++;
      y=y-dy+1;
      dy*=0.5;
    }
    Sleep(25);
  }
}

U0 Flappy()
{
  SettingsPush; //See SettingsPush
  AutoComplete;
  WinBorder;
  WinMax;
  DocClear;
  Refresh(2);
  Init;
  Fs->draw_it=&DrawIt;
  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
  try {
    while (TRUE) {
      switch (GetChar(,FALSE)) {
        case CH_ESC:
        case CH_SHIFT_ESC:
          goto fp_done;
        case '\n':
          Init;
          break;
        case CH_SPACE:
          Noise(20,74,86);
          dy+=20;
          break;
      }
    }
fp_done:
  } catch
    PutExcept;
  SettingsPop;
}

Flappy;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\Flappy-Sup1-Sup1Games-Home.html
// Date: unknown-date
// Language: HolyC

<1>/* Graphics Not Rendered in HTML */

        <2>/* Graphics Not Rendered in HTML */

        <3>/* Graphics Not Rendered in HTML */

#define BIRD_X 100
F64 dy,y,scroll_x;
Bool game_over;

#define PIPES_NUM       16
#define GAP             100

class Pipe
{
  I64 x,y;
} pipes[PIPES_NUM];

U0 DrawIt(CTask *task, CDC *dc)
{
  I64 i;
  Pipe *p;
  for (i=0;i<PIPES_NUM;i++) {
    p=&pipes[i];
    Sprite3(dc,p->x-scroll_x,p->y+task->pix_height>>1+GAP>>1,0,<3>);
    Sprite3(dc,p->x-scroll_x,p->y+task->pix_height>>1-GAP>>1,0,<2>);
  }

  dc->collision_cnt=0;
  dc->color=ROP_COLLISION;
  dc->bkcolor=WHITE;
  Sprite3ZB(dc,BIRD_X,y,0,<1>,-0.2*dy);
  if (dc->collision_cnt)
    game_over=TRUE;

  dc->color=ROP_EQU;
  Sprite3ZB(dc,BIRD_X,y,0,<1>,-0.2*dy);
}

U0 Init()
{
  I64 i;
  Pipe *p;
  for (i=0;i<PIPES_NUM;i++) {
    p=&pipes[i];
    p->x=i*125+200;
    p->y=80*Sin(i);
  }
  scroll_x=0;
  y=Fs->pix_height>>1;
  dy=0;
  game_over=FALSE;
}

U0 AnimateTask(I64)
{
  while (TRUE) {
    if (!game_over) {
      scroll_x++;
      y=y-dy+1;
      dy*=0.5;
    }
    Sleep(25);
  }
}

U0 Flappy()
{
  SettingsPush; //See SettingsPush
  AutoComplete;
  WinBorder;
  WinMax;
  DocClear;
  Refresh(2);
  Init;
  Fs->draw_it=&DrawIt;
  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
  try {
    while (TRUE) {
      switch (GetChar(,FALSE)) {
        case CH_ESC:
        case CH_SHIFT_ESC:
          goto fp_done;
        case '\n':
          Init;
          break;
        case CH_SPACE:
          Noise(20,74,86);
          dy+=20;
          break;
      }
    }
fp_done:
  } catch
    PutExcept;
  SettingsPop;
}

Flappy;


// Source: D:\TempleOS-Projects\html\GuideLines-Doc.html
// Date: unknown-date
// Language: HolyC

Directory Structure

/Home All your user data should be placed in here to ease backing-up your data.
When you install an application it will create a subdirectory of your /Home
directory for storage.

/Apps Applications are placed in subdirectories of /Apps.  Applications should
have a file called Install.HC.Z which will install the app, possibly making
files or directories in /Home.  The file, Load.HC.Z will load the application
into mem.  The file, Run.HC.Z, will usually load and execute the app.  To add an
app to your PersonalMenu, use <CTRL-l>, insert a macro with the PopUp option
checked and invoke the Run.HC.Z file.

/Demo Here you can find lots of sample code to do various things.

/Doc Here you can find documentation.

/Kernel The core of the operating system is found here.  Since priviledge levels
are not used, calling it a kernel is deceptive.  It is AOT compiled by
BootHDIns().  It is loaded by the boot loader and must fit in 640K.

/Compiler The compiler module src code is found here.  The compiler is AOT
compiled to produce a binary file which is loaded at boot.  It, too, is AOT
compiled by BootHDIns().

/Adam The non-kernel part of the operating system is found here.  It is JIT
compiled during boot.  The Adam Task is the father of all tasks, like Adam and
Eve.

/0000Boot Boot files go here.  Stage 2 of the TempleOS hard drive master boot
loader, the old hard drive master boot record which is just blk#0, and the
CD/DVD 0000Kernel.BIN.C file go here.  ASCII 0000 is near the top,
alphabetically, in case you use MagicISO.

                                 ::/Home Files

The home dir is specified with '~'.  The home dir is ::/Home unless you change
it with HomeSet() or compile the kernel with a cfg option.  An empty /Home dir
should be valid because it will get default files from the root dir.

~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in
the upper left border area of a window.

~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key.

~/MakeHome.HC a file compiled by the Adam Task during StartOS.

~/Home* Copy Home* files from the root into ~ and customize them.  These files
are invoked when the Adam Task starts-up.

~/Once.HC a file invoked at the start-up of the first user.  Customize this!

~/Registry.HC can be edited by hand or deleted to reset to defaults.  Takes
affect next boot.

                              Application Policies

* Place applications in their own /Apps subdirectory.

* Make a file called Load.HC.Z to load the application.

* Make a file called Run.HC.Z to load and run the application, preferable by #in
cludeing the Load.HC.Z file.

* Place user data in a subdirectory of /Home, preferably naming the subdirectory
the same as the /Apps subdirectory.  Or, place data in the Registry.HC.Z file.
See ::/Demo/RegistryDemo.HC.

* If the app needs files in the /Home directory, make an /Apps file called Insta
ll.HC.Z or Install.IN.Z to create the /Home subdirectory.

                             Programming Guidelines

* Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode.  The
stk does not grow, so alloc enough when the task (process) is Spawned and use
the heap for most things.  (The heap refers to MAlloc() and Free().)

* You can Free(NULL).

* See Naming Convention and Abbreviations.

* There are two modes of compiling, AOT Compile Mode and JIT Compile Mode.
Compilation is done in both -- neither is "interpreted".  Use JIT Mode.

* HolyC

* Use I64 instead of smaller int sizes because the compiler converts everything
to 64-bit.  Don't use unsigned unless it actually breaks.  A policy of signed
keeps it simple so you don't have to agonize over choices.

     U32 DistDist(U16 x1, U16 y1, U16 x2, U16 y2)
     {//This requires zero-extend when fetching args.
       return SqrI64(x1-x2)+SqrI64(y1-y2);
     }

     I64 DistDist(I64 x1, I64 y1, I64 x2, I64 y2)
     {
       return SqrI64(x1-x2)+SqrI64(y1-y2);
     }

* In-order, short circuit logic is assumed.

* Avoid boolean expression assignments.  Boolean assignments don't have short
circuit logic and are not compiled efficiently.  The Bool type is just an alias
for a 1 byte signed int -- nothing forces it to 1 or 0.  There is a ToBool()
function that will for to 1 ot 0, however.

* Glbl vars in AOT BIN modules are initialized to zero.  They occupy space in
BIN files.

* Bracketing code with PUSHFD CLI and POPFD will protect against simultaneous
accesses from tasks on one core.  To protect against multiple cores, you need a
locked semaphore.  I think semiphores need to be in their own cache line, but
I'm not sure.  I use lock bits in a lot of places not aligned.

* SysDbg() and IsSysDbg() are really handy when working on the compiler or
kernel.  It's just a bit you can set and test.

* I don't use U0 * because the size is zero for ptr arithmetic.

* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run
Spaces-to-Tabs on source code.

* Do not use #if or #ifdef

                                Hash Sym Tables

* See ::/Adam/AHash.HC for examples of how the hash tables are set-up.
Basically, syms are placed into hash tables and child process hash tables are
chained to parents.  This provides scopes for vars and functions.

* adam_task->hash_table holds the HolyC syms loaded in on start-up.

* Fs->hash_table holds user HolyC syms and if a sym is not found, it checks
parents.  When a duplicate sym is added to the table, it overshadows the prev
sym.  When developing software, typically you include the file at the cmd
prompt, make changes and reinclude it.  Old syms are overshadowed but they are
still there.  Periodically, kill the TASK and start fresh when mem is low.  If
you wish your applications to free themselves instead of staying in mem, spawn
or PopUp() a task to run the application and kill it when it's done.

* To display the contents of a hash table, use the Who() routine or the
varients.  HashDepthRep() gives a histogram  of how long the chains are, in case
you wish to make hash table sizes bigger.

                               Assembly Language

See ::/Doc/Asm.DD.

* FS must always point to the cur CTask.

* GS must always point to the cur CCPU.

* Don't change the segment regs unless interrupts are off.  It's hard to do,
anyway.  SET_FS_BASE and SET_GS_BASE.

* When interacting with HolyC compiled code, preserve RBP, RSI, RDI, R10-R15
because the compiler uses these for reg vars.  You are free to clobber RAX, RBX,
RCX, RDX, R8 and R9.  See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS

* I recommend using the standard stk frame for functions because Caller() is
used to display the call stk, such as for the wallpaper.
        PUSH    RBP
        MOV     RBP,RSP
        SUB     RSP,nnnn
...
        LEAVE
        RET

* The args are removed from the stack with RET1 stmts.

        RET1    16      //remove two args

* No args are passed in regs.

* RAX holds function return values, of course.

* "MagicISO" is a trademark owned by MagicISO Corp.

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\GuideLines-Doc.html
// Date: unknown-date
// Language: HolyC

Directory Structure

/Home All your user data should be placed in here to ease backing-up your data.
When you install an application it will create a subdirectory of your /Home
directory for storage.

/Apps Applications are placed in subdirectories of /Apps.  Applications should
have a file called Install.HC.Z which will install the app, possibly making
files or directories in /Home.  The file, Load.HC.Z will load the application
into mem.  The file, Run.HC.Z, will usually load and execute the app.  To add an
app to your PersonalMenu, use <CTRL-l>, insert a macro with the PopUp option
checked and invoke the Run.HC.Z file.

/Demo Here you can find lots of sample code to do various things.

/Doc Here you can find documentation.

/Kernel The core of the operating system is found here.  Since priviledge levels
are not used, calling it a kernel is deceptive.  It is AOT compiled by
BootHDIns().  It is loaded by the boot loader and must fit in 640K.

/Compiler The compiler module src code is found here.  The compiler is AOT
compiled to produce a binary file which is loaded at boot.  It, too, is AOT
compiled by BootHDIns().

/Adam The non-kernel part of the operating system is found here.  It is JIT
compiled during boot.  The Adam Task is the father of all tasks, like Adam and
Eve.

/0000Boot Boot files go here.  Stage 2 of the TempleOS hard drive master boot
loader, the old hard drive master boot record which is just blk#0, and the
CD/DVD 0000Kernel.BIN.C file go here.  ASCII 0000 is near the top,
alphabetically, in case you use MagicISO.

                                 ::/Home Files

The home dir is specified with '~'.  The home dir is ::/Home unless you change
it with HomeSet() or compile the kernel with a cfg option.  An empty /Home dir
should be valid because it will get default files from the root dir.

~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in
the upper left border area of a window.

~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key.

~/MakeHome.HC a file compiled by the Adam Task during StartOS.

~/Home* Copy Home* files from the root into ~ and customize them.  These files
are invoked when the Adam Task starts-up.

~/Once.HC a file invoked at the start-up of the first user.  Customize this!

~/Registry.HC can be edited by hand or deleted to reset to defaults.  Takes
affect next boot.

                              Application Policies

* Place applications in their own /Apps subdirectory.

* Make a file called Load.HC.Z to load the application.

* Make a file called Run.HC.Z to load and run the application, preferable by #in
cludeing the Load.HC.Z file.

* Place user data in a subdirectory of /Home, preferably naming the subdirectory
the same as the /Apps subdirectory.  Or, place data in the Registry.HC.Z file.
See ::/Demo/RegistryDemo.HC.

* If the app needs files in the /Home directory, make an /Apps file called Insta
ll.HC.Z or Install.IN.Z to create the /Home subdirectory.

                             Programming Guidelines

* Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode.  The
stk does not grow, so alloc enough when the task (process) is Spawned and use
the heap for most things.  (The heap refers to MAlloc() and Free().)

* You can Free(NULL).

* See Naming Convention and Abbreviations.

* There are two modes of compiling, AOT Compile Mode and JIT Compile Mode.
Compilation is done in both -- neither is "interpreted".  Use JIT Mode.

* HolyC

* Use I64 instead of smaller int sizes because the compiler converts everything
to 64-bit.  Don't use unsigned unless it actually breaks.  A policy of signed
keeps it simple so you don't have to agonize over choices.

     U32 DistDist(U16 x1, U16 y1, U16 x2, U16 y2)
     {//This requires zero-extend when fetching args.
       return SqrI64(x1-x2)+SqrI64(y1-y2);
     }

     I64 DistDist(I64 x1, I64 y1, I64 x2, I64 y2)
     {
       return SqrI64(x1-x2)+SqrI64(y1-y2);
     }

* In-order, short circuit logic is assumed.

* Avoid boolean expression assignments.  Boolean assignments don't have short
circuit logic and are not compiled efficiently.  The Bool type is just an alias
for a 1 byte signed int -- nothing forces it to 1 or 0.  There is a ToBool()
function that will for to 1 ot 0, however.

* Glbl vars in AOT BIN modules are initialized to zero.  They occupy space in
BIN files.

* Bracketing code with PUSHFD CLI and POPFD will protect against simultaneous
accesses from tasks on one core.  To protect against multiple cores, you need a
locked semaphore.  I think semiphores need to be in their own cache line, but
I'm not sure.  I use lock bits in a lot of places not aligned.

* SysDbg() and IsSysDbg() are really handy when working on the compiler or
kernel.  It's just a bit you can set and test.

* I don't use U0 * because the size is zero for ptr arithmetic.

* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run
Spaces-to-Tabs on source code.

* Do not use #if or #ifdef

                                Hash Sym Tables

* See ::/Adam/AHash.HC for examples of how the hash tables are set-up.
Basically, syms are placed into hash tables and child process hash tables are
chained to parents.  This provides scopes for vars and functions.

* adam_task->hash_table holds the HolyC syms loaded in on start-up.

* Fs->hash_table holds user HolyC syms and if a sym is not found, it checks
parents.  When a duplicate sym is added to the table, it overshadows the prev
sym.  When developing software, typically you include the file at the cmd
prompt, make changes and reinclude it.  Old syms are overshadowed but they are
still there.  Periodically, kill the TASK and start fresh when mem is low.  If
you wish your applications to free themselves instead of staying in mem, spawn
or PopUp() a task to run the application and kill it when it's done.

* To display the contents of a hash table, use the Who() routine or the
varients.  HashDepthRep() gives a histogram  of how long the chains are, in case
you wish to make hash table sizes bigger.

                               Assembly Language

See ::/Doc/Asm.DD.

* FS must always point to the cur CTask.

* GS must always point to the cur CCPU.

* Don't change the segment regs unless interrupts are off.  It's hard to do,
anyway.  SET_FS_BASE and SET_GS_BASE.

* When interacting with HolyC compiled code, preserve RBP, RSI, RDI, R10-R15
because the compiler uses these for reg vars.  You are free to clobber RAX, RBX,
RCX, RDX, R8 and R9.  See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS

* I recommend using the standard stk frame for functions because Caller() is
used to display the call stk, such as for the wallpaper.
        PUSH    RBP
        MOV     RBP,RSP
        SUB     RSP,nnnn
...
        LEAVE
        RET

* The args are removed from the stack with RET1 stmts.

        RET1    16      //remove two args

* No args are passed in regs.

* RAX holds function return values, of course.

* "MagicISO" is a trademark owned by MagicISO Corp.


// Source: D:\TempleOS-Projects\html\TourB-Tour-Misc.html
// Date: unknown-date
// Language: HolyC

TourPut(
"All text widgets work everywhere.  The $GREEN$Type()$FG$ command is like "
"the DOS command of the same name or the UNIX, $GREEN$cat$FG$ command.  "
"We will, now, send your menu document to the command line.  It uses the "
"same document format and the icons are even active!!\n\n"
"Press $GREEN$<ENTER>$FG$.\n");

//Puts the cursor at the bottom.
Msg(MSG_KEY_DOWN,0,SC_CURSOR_DOWN|SCF_CTRL);
"\n";

"Type(\"~/PersonalMenu.DD\");";
InGetStr("\n");

Sleep(1500);
InPrint(250,"Dir;\n");

Sleep(1500);
TourPut(
"$GREEN$Type()$FG$ can also be used on $GREEN$.BMP$FG$ or $GREEN$.GR$FG$ "
"files!",TRUE);

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\TourB-Tour-Misc.html
// Date: unknown-date
// Language: HolyC

TourPut(
"All text widgets work everywhere.  The $GREEN$Type()$FG$ command is like "
"the DOS command of the same name or the UNIX, $GREEN$cat$FG$ command.  "
"We will, now, send your menu document to the command line.  It uses the "
"same document format and the icons are even active!!\n\n"
"Press $GREEN$<ENTER>$FG$.\n");

//Puts the cursor at the bottom.
Msg(MSG_KEY_DOWN,0,SC_CURSOR_DOWN|SCF_CTRL);
"\n";

"Type(\"~/PersonalMenu.DD\");";
InGetStr("\n");

Sleep(1500);
InPrint(250,"Dir;\n");

Sleep(1500);
TourPut(
"$GREEN$Type()$FG$ can also be used on $GREEN$.BMP$FG$ or $GREEN$.GR$FG$ "
"files!",TRUE);


// Source: D:\TempleOS-Projects\html\Slider-Graphics-Demo.html
// Date: unknown-date
// Language: HolyC

/*This was done with <CTRL-SHIFT-L> template code.
It's conceptually easy to do a ctrl,
but tedious.  You have complete freedom.

See CCtrl.
*/

//Start of autocreated Code
#define SLIDER_RANGE   30
#define SLIDER_SPACING 20
#define SLIDER_BORDER  2

class CSliderState
{
  I64 left_pos;
  I64 right_pos;
} sld;

U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
{
  CSliderState *s=c->state;

  dc->color=LTRED;
  GrRect(dc, c->left,c->top,SLIDER_SPACING*3+2,SLIDER_SPACING*2+SLIDER_RANGE);
  dc->color=BLUE;
  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
        SLIDER_SPACING*3+2-2*SLIDER_BORDER,
        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
  dc->color=BLACK;
  GrLine(dc,c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING,
        c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
  dc->color=LTRED;
  GrPrint(dc,c->left+1*SLIDER_SPACING+0-FONT_WIDTH/2,
        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
        "%d",s->left_pos*10/SLIDER_RANGE);
  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
        "%d",s->right_pos*10/SLIDER_RANGE);
  GrRect(dc,c->left+1*SLIDER_SPACING+0-3,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-2,7,5);
  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-2,7,5);
  dc->color=YELLOW;
  GrRect(dc,c->left+1*SLIDER_SPACING+0-2,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-1,5,3);
  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-1,5,3);
}

U0 UpdateDerivedCtrlSlider(CCtrl *c)
{
  CSliderState *s=c->state;
  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
  c->right=c->left+3*SLIDER_SPACING+2;
  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
  s->left_pos=ClampI64(s->left_pos,0,SLIDER_RANGE-1);
  s->right_pos=ClampI64(s->right_pos,0,SLIDER_RANGE-1);
}

U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
{
  CSliderState *s=c->state;
  if (x<c->left+1*SLIDER_SPACING+0+SLIDER_SPACING/2)
    s->left_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
  else
    s->right_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
  if (c->update_derived_vals)
    (*c->update_derived_vals)(c);
}

CCtrl *SliderNew()
{
  CCtrl *c=CAlloc(sizeof(CCtrl));
  c->win_task=Fs;
  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
  c->type=CTRLT_GENERIC;
  c->state=&sld;
  MemSet(&sld,0,sizeof(CSliderState));
  c->draw_it=&DrawCtrlSlider;
  c->left_click=&LeftClickSlider;
  c->update_derived_vals=&UpdateDerivedCtrlSlider;
  QueIns(c,Fs->last_ctrl);
  TaskDerivedValsUpdate;
  return c;
}

U0 SliderDel(CCtrl *c)
{
  QueRem(c);
  Free(c);
}

//End of autocreated Code

U0 Main()
{
  "This is to demo ctrls.\n";
  CCtrl *c=SliderNew;
  PressAKey;
  "Left: %d  Right: %d\n",
        sld.left_pos*10/SLIDER_RANGE,
        sld.right_pos*10/SLIDER_RANGE;
  SliderDel(c);
  DocBottom;
}

Main;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\Slider-Graphics-Demo.html
// Date: unknown-date
// Language: HolyC

/*This was done with <CTRL-SHIFT-L> template code.
It's conceptually easy to do a ctrl,
but tedious.  You have complete freedom.

See CCtrl.
*/

//Start of autocreated Code
#define SLIDER_RANGE   30
#define SLIDER_SPACING 20
#define SLIDER_BORDER  2

class CSliderState
{
  I64 left_pos;
  I64 right_pos;
} sld;

U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
{
  CSliderState *s=c->state;

  dc->color=LTRED;
  GrRect(dc, c->left,c->top,SLIDER_SPACING*3+2,SLIDER_SPACING*2+SLIDER_RANGE);
  dc->color=BLUE;
  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
        SLIDER_SPACING*3+2-2*SLIDER_BORDER,
        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
  dc->color=BLACK;
  GrLine(dc,c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING,
        c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
  dc->color=LTRED;
  GrPrint(dc,c->left+1*SLIDER_SPACING+0-FONT_WIDTH/2,
        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
        "%d",s->left_pos*10/SLIDER_RANGE);
  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
        "%d",s->right_pos*10/SLIDER_RANGE);
  GrRect(dc,c->left+1*SLIDER_SPACING+0-3,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-2,7,5);
  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-2,7,5);
  dc->color=YELLOW;
  GrRect(dc,c->left+1*SLIDER_SPACING+0-2,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-1,5,3);
  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-1,5,3);
}

U0 UpdateDerivedCtrlSlider(CCtrl *c)
{
  CSliderState *s=c->state;
  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
  c->right=c->left+3*SLIDER_SPACING+2;
  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
  s->left_pos=ClampI64(s->left_pos,0,SLIDER_RANGE-1);
  s->right_pos=ClampI64(s->right_pos,0,SLIDER_RANGE-1);
}

U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
{
  CSliderState *s=c->state;
  if (x<c->left+1*SLIDER_SPACING+0+SLIDER_SPACING/2)
    s->left_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
  else
    s->right_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
  if (c->update_derived_vals)
    (*c->update_derived_vals)(c);
}

CCtrl *SliderNew()
{
  CCtrl *c=CAlloc(sizeof(CCtrl));
  c->win_task=Fs;
  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
  c->type=CTRLT_GENERIC;
  c->state=&sld;
  MemSet(&sld,0,sizeof(CSliderState));
  c->draw_it=&DrawCtrlSlider;
  c->left_click=&LeftClickSlider;
  c->update_derived_vals=&UpdateDerivedCtrlSlider;
  QueIns(c,Fs->last_ctrl);
  TaskDerivedValsUpdate;
  return c;
}

U0 SliderDel(CCtrl *c)
{
  QueRem(c);
  Free(c);
}

//End of autocreated Code

U0 Main()
{
  "This is to demo ctrls.\n";
  CCtrl *c=SliderNew;
  PressAKey;
  "Left: %d  Right: %d\n",
        sld.left_pos*10/SLIDER_RANGE,
        sld.right_pos*10/SLIDER_RANGE;
  SliderDel(c);
  DocBottom;
}

Main;


// Source: D:\TempleOS-Projects\html\Run-GrModels-Apps.html
// Date: unknown-date
// Language: HolyC

Cd(__DIR__);;
#include "Load"
Models;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\Run-GrModels-Apps.html
// Date: unknown-date
// Language: HolyC

Cd(__DIR__);;
#include "Load"
Models;


// Source: D:\TempleOS-Projects\html\Whap-Games-Demo.html
// Date: unknown-date
// Language: HolyC

#define BALLS_NUM       7
#define SPRINGS_NUM     3

#define STRETCH         500.0
#define GRAVITY         50.0 //not really gravity
#define BALL_RADIUS     5
#define BASE_SIZE       10

CMass balls[BALLS_NUM];
CSpring springs[SPRINGS_NUM];
F64 collision_t;

U0 DrawIt(CTask *task,CDC *dc)
{
  I64 i,
        cx=task->pix_width>>1,
        cy=task->pix_height>>1;
  Bool snd_on=FALSE;
  dc->color=BLACK;
  GrPrint(dc,0,0,"Protect your base.");
  GrRect(dc,cx-BASE_SIZE,cy-BASE_SIZE,BASE_SIZE*2,BASE_SIZE*2);
  dc->color=CYAN;
  GrRect(dc,cx-BASE_SIZE+2,cy-BASE_SIZE+2,BASE_SIZE*2-4,BASE_SIZE*2-4);
  dc->color=YELLOW;
  GrLine(dc,balls[0].x,balls[0].y,
        ms.pos.x-task->pix_left-task->scroll_x,
        ms.pos.y-task->pix_top-task->scroll_y);
  for (i=0;i<SPRINGS_NUM;i++)
    GrLine(dc,springs[i].end1->x,springs[i].end1->y,
          springs[i].end2->x,springs[i].end2->y);

  dc->color=LTCYAN;
  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
  GrFloodFill(dc,balls[0].x,balls[0].y,TRUE);
  dc->color=BLACK;
  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);

  for (i=1;i<BALLS_NUM;i++) {
    dc->color=LTPURPLE;
    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
    GrFloodFill(dc,balls[i].x,balls[i].y,TRUE);
    if (cx-BASE_SIZE-BALL_RADIUS<=balls[i].x<=cx+BASE_SIZE+BALL_RADIUS &&
          cy-BASE_SIZE-BALL_RADIUS<=balls[i].y<=cy+BASE_SIZE+BALL_RADIUS)
      snd_on=TRUE;
    dc->color=BLACK;
    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
  }
  if (snd_on)
    Snd(74);
  else
    Snd;
}

U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *,COrder2D3 *)
{
  I64 i,j;
  F64 d,dd;
  CD3 p,p2;
  CTask *task=ode->win_task;

  D3SubEqu(D3Equ(&p2,
        ms.pos.x-task->pix_left-task->scroll_x,
        ms.pos.y-task->pix_top-task->scroll_y,0),
        &balls[0].state->x);
  D3AddEqu(&balls[0].DstateDt->DxDt,D3MulEqu(&p2,STRETCH));

  D3Equ(&p2,task->pix_width>>1,task->pix_height>>1,0);
  for (i=1;i<BALLS_NUM;i++) {
    D3Sub(&p,&p2,&balls[i].state->x);
    if (d=D3Norm(&p)) {
//Gravity would be /(d*d*d), but that's too exponential.
      D3MulEqu(&p,GRAVITY/d);
      D3AddEqu(&balls[i].DstateDt->DxDt,&p);
    }
  }

  for (i=0;i<BALLS_NUM;i++)
    for (j=i+1;j<BALLS_NUM;j++) {
      D3Sub(&p,&balls[j].state->x,&balls[i].state->x);
      dd=D3NormSqr(&p);
      if (dd<=(2*BALL_RADIUS)*(2*BALL_RADIUS)) {
        if (t-collision_t>0.05) {
          Noise(50,102,105);
          collision_t=t;
        }
        d=Sqrt(dd)+0.0001;
        dd=10.0*Sqr(Sqr((2*BALL_RADIUS)*(2*BALL_RADIUS)-dd));
        D3MulEqu(&p,dd/d);
        D3AddEqu(&balls[j].DstateDt->DxDt,&p);
        D3SubEqu(&balls[i].DstateDt->DxDt,&p);
      }
    }

  d=balls[0].state->x;
  if (d-BALL_RADIUS<0)
    balls[0].DstateDt->DxDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
  if (d+BALL_RADIUS>task->pix_width)
    balls[0].DstateDt->DxDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_width)));

  d=balls[0].state->y;
  if (d-BALL_RADIUS<0)
    balls[0].DstateDt->DyDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
  if (d+BALL_RADIUS>task->pix_height)
    balls[0].DstateDt->DyDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_height)));
}

U0 Whap()
{
  I64 i;
  CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);

  SettingsPush; //See SettingsPush
  AutoComplete;
  WinBorder;
  WinMax;

  MenuPush(
        "File {"
        "  Abort(,CH_SHIFT_ESC);"
        "  Exit(,CH_ESC);"
        "}"
        );
  ode->derive=&MyDerivative;
  ode->drag_v2=0.002;
  ode->drag_v3=0.00001;
  ode->acceleration_limit=5e3;
  MemSet(balls,0,BALLS_NUM*sizeof(CMass));
  D3Equ(&balls[0].x,100,100,0);
  for (i=1;i<BALLS_NUM;i++)
    D3Equ(&balls[i].x,
          RandI16%500+Fs->pix_width>>1,RandI16%500+Fs->pix_height>>1,0);
  balls[0].x=ms.pos.x-Fs->pix_left-Fs->scroll_x;
  balls[0].y=ms.pos.y-Fs->pix_top-Fs->scroll_y;
  for (i=0;i<BALLS_NUM;i++) {
    balls[i].mass=1.0;
    balls[i].drag_profile_factor=1.0;
    QueIns(&balls[i],ode->last_mass);
  }
  balls[2].x=balls[1].x+15;
  balls[2].y=balls[1].y;
  balls[3].x=balls[1].x;
  balls[3].y=balls[1].y+15;
  MemSet(springs,0,SPRINGS_NUM*sizeof(CSpring));
  springs[0].end1=&balls[1];
  springs[0].end2=&balls[2];
  springs[0].rest_len=15;
  springs[0].const=10000;
  QueIns(&springs[0],ode->last_spring);
  springs[1].end1=&balls[1];
  springs[1].end2=&balls[3];
  springs[1].rest_len=15;
  springs[1].const=10000;
  QueIns(&springs[1],ode->last_spring);
  springs[2].end1=&balls[2];
  springs[2].end2=&balls[3];
  springs[2].rest_len=sqrt2*15;
  springs[2].const=10000;
  QueIns(&springs[2],ode->last_spring);

  collision_t=0;
  QueIns(ode,Fs->last_ode);

  DocCursor;
  DocClear;
  Fs->draw_it=&DrawIt;
  GetChar;
  SettingsPop;
  QueRem(ode);
  ODEDel(ode);
  MenuPop;
}

Whap;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\Whap-Games-Demo.html
// Date: unknown-date
// Language: HolyC

#define BALLS_NUM       7
#define SPRINGS_NUM     3

#define STRETCH         500.0
#define GRAVITY         50.0 //not really gravity
#define BALL_RADIUS     5
#define BASE_SIZE       10

CMass balls[BALLS_NUM];
CSpring springs[SPRINGS_NUM];
F64 collision_t;

U0 DrawIt(CTask *task,CDC *dc)
{
  I64 i,
        cx=task->pix_width>>1,
        cy=task->pix_height>>1;
  Bool snd_on=FALSE;
  dc->color=BLACK;
  GrPrint(dc,0,0,"Protect your base.");
  GrRect(dc,cx-BASE_SIZE,cy-BASE_SIZE,BASE_SIZE*2,BASE_SIZE*2);
  dc->color=CYAN;
  GrRect(dc,cx-BASE_SIZE+2,cy-BASE_SIZE+2,BASE_SIZE*2-4,BASE_SIZE*2-4);
  dc->color=YELLOW;
  GrLine(dc,balls[0].x,balls[0].y,
        ms.pos.x-task->pix_left-task->scroll_x,
        ms.pos.y-task->pix_top-task->scroll_y);
  for (i=0;i<SPRINGS_NUM;i++)
    GrLine(dc,springs[i].end1->x,springs[i].end1->y,
          springs[i].end2->x,springs[i].end2->y);

  dc->color=LTCYAN;
  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
  GrFloodFill(dc,balls[0].x,balls[0].y,TRUE);
  dc->color=BLACK;
  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);

  for (i=1;i<BALLS_NUM;i++) {
    dc->color=LTPURPLE;
    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
    GrFloodFill(dc,balls[i].x,balls[i].y,TRUE);
    if (cx-BASE_SIZE-BALL_RADIUS<=balls[i].x<=cx+BASE_SIZE+BALL_RADIUS &&
          cy-BASE_SIZE-BALL_RADIUS<=balls[i].y<=cy+BASE_SIZE+BALL_RADIUS)
      snd_on=TRUE;
    dc->color=BLACK;
    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
  }
  if (snd_on)
    Snd(74);
  else
    Snd;
}

U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *,COrder2D3 *)
{
  I64 i,j;
  F64 d,dd;
  CD3 p,p2;
  CTask *task=ode->win_task;

  D3SubEqu(D3Equ(&p2,
        ms.pos.x-task->pix_left-task->scroll_x,
        ms.pos.y-task->pix_top-task->scroll_y,0),
        &balls[0].state->x);
  D3AddEqu(&balls[0].DstateDt->DxDt,D3MulEqu(&p2,STRETCH));

  D3Equ(&p2,task->pix_width>>1,task->pix_height>>1,0);
  for (i=1;i<BALLS_NUM;i++) {
    D3Sub(&p,&p2,&balls[i].state->x);
    if (d=D3Norm(&p)) {
//Gravity would be /(d*d*d), but that's too exponential.
      D3MulEqu(&p,GRAVITY/d);
      D3AddEqu(&balls[i].DstateDt->DxDt,&p);
    }
  }

  for (i=0;i<BALLS_NUM;i++)
    for (j=i+1;j<BALLS_NUM;j++) {
      D3Sub(&p,&balls[j].state->x,&balls[i].state->x);
      dd=D3NormSqr(&p);
      if (dd<=(2*BALL_RADIUS)*(2*BALL_RADIUS)) {
        if (t-collision_t>0.05) {
          Noise(50,102,105);
          collision_t=t;
        }
        d=Sqrt(dd)+0.0001;
        dd=10.0*Sqr(Sqr((2*BALL_RADIUS)*(2*BALL_RADIUS)-dd));
        D3MulEqu(&p,dd/d);
        D3AddEqu(&balls[j].DstateDt->DxDt,&p);
        D3SubEqu(&balls[i].DstateDt->DxDt,&p);
      }
    }

  d=balls[0].state->x;
  if (d-BALL_RADIUS<0)
    balls[0].DstateDt->DxDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
  if (d+BALL_RADIUS>task->pix_width)
    balls[0].DstateDt->DxDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_width)));

  d=balls[0].state->y;
  if (d-BALL_RADIUS<0)
    balls[0].DstateDt->DyDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
  if (d+BALL_RADIUS>task->pix_height)
    balls[0].DstateDt->DyDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_height)));
}

U0 Whap()
{
  I64 i;
  CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);

  SettingsPush; //See SettingsPush
  AutoComplete;
  WinBorder;
  WinMax;

  MenuPush(
        "File {"
        "  Abort(,CH_SHIFT_ESC);"
        "  Exit(,CH_ESC);"
        "}"
        );
  ode->derive=&MyDerivative;
  ode->drag_v2=0.002;
  ode->drag_v3=0.00001;
  ode->acceleration_limit=5e3;
  MemSet(balls,0,BALLS_NUM*sizeof(CMass));
  D3Equ(&balls[0].x,100,100,0);
  for (i=1;i<BALLS_NUM;i++)
    D3Equ(&balls[i].x,
          RandI16%500+Fs->pix_width>>1,RandI16%500+Fs->pix_height>>1,0);
  balls[0].x=ms.pos.x-Fs->pix_left-Fs->scroll_x;
  balls[0].y=ms.pos.y-Fs->pix_top-Fs->scroll_y;
  for (i=0;i<BALLS_NUM;i++) {
    balls[i].mass=1.0;
    balls[i].drag_profile_factor=1.0;
    QueIns(&balls[i],ode->last_mass);
  }
  balls[2].x=balls[1].x+15;
  balls[2].y=balls[1].y;
  balls[3].x=balls[1].x;
  balls[3].y=balls[1].y+15;
  MemSet(springs,0,SPRINGS_NUM*sizeof(CSpring));
  springs[0].end1=&balls[1];
  springs[0].end2=&balls[2];
  springs[0].rest_len=15;
  springs[0].const=10000;
  QueIns(&springs[0],ode->last_spring);
  springs[1].end1=&balls[1];
  springs[1].end2=&balls[3];
  springs[1].rest_len=15;
  springs[1].const=10000;
  QueIns(&springs[1],ode->last_spring);
  springs[2].end1=&balls[2];
  springs[2].end2=&balls[3];
  springs[2].rest_len=sqrt2*15;
  springs[2].const=10000;
  QueIns(&springs[2],ode->last_spring);

  collision_t=0;
  QueIns(ode,Fs->last_ode);

  DocCursor;
  DocClear;
  Fs->draw_it=&DrawIt;
  GetChar;
  SettingsPop;
  QueRem(ode);
  ODEDel(ode);
  MenuPop;
}

Whap;


// Source: D:\TempleOS-Projects\html\AHash-Adam.html
// Date: unknown-date
// Language: HolyC

#help_index "Info;Hash/System;Cmd Line (Typically)"
class CWho
{
  CHashGeneric *h;
  U8 *idx;
};

I64 HashEntriesCompare(CWho *h1,CWho *h2)
{
  I64 i1,i2;
  if (i1=StrCmp(h1->h->str,h2->h->str))
    return i1;
  i1=HashTypeNum(h1->h);
  i2=HashTypeNum(h2->h);
  return i1-i2;
}

I64 HashEntriesCompare2(CWho *h1,CWho *h2)
{
  CHashFun *tmpf1=h1->h,*tmpf2=h2->h;
  I64 i1=HashVal(tmpf1),i2=HashVal(tmpf2);
  if (i1==i2) {
    i1=HashTypeNum(tmpf1);
    i2=HashTypeNum(tmpf2);
    if (i1==i2)
      return StrCmp(tmpf1->str,tmpf2->str);
  }
  return i1-i2;
}

I64 HelpIndexCnt(U8 *ptr,U8 *idx)
{
  I64 cnt=0,ch,idx_len=StrLen(idx);
  while (*ptr) {
    if (!StrNCmp(ptr,idx,idx_len))
      cnt++;
    while (ch=*ptr++)
      if (ch==';')
        break;
    if (!ch)
      ptr--;
  }
  return cnt;
}

U8 *HelpIndexStr(U8 **_ptr,U8 *idx)
{
  U8 *ptr=*_ptr,*ptr2,*res;
  I64 ch,idx_len=StrLen(idx);
  while (*ptr) {
    ptr2=ptr;
    while (ch=*ptr++)
      if (ch==';')
        break;
    if (!ch)
      ptr--;
    *_ptr=ptr;
    if (!StrNCmp(ptr2,idx,idx_len)) {
      if (ch==';')
        ptr--;
      *ptr=0;
      res=StrNew(ptr2);
      *ptr=ch;
      return res;
    }
  }
  return NULL;
}

U8 *HelpComment(CTask *task,CHash *tmph,U8 *_src_link)
{
  CDoc *doc;
  CDocEntry *doc_e;
  U8 *res=NULL,*ptr,*ptr2,*src_link=StrNew(_src_link);

  if (*src_link=='F' && src_link[2]==':')
    *src_link='P';
  XTalkWait(task,"Ed(0x%X,DOF_DONT_WINMGR_SYNC|DOF_DONT_SHOW);\n",src_link);
  Free(src_link);

  doc=DocPut(task);
  doc_e=doc->cur_entry;
  if (tmph->type&HTT_FUN) {
    if (Bt(&tmph(CHashFun *)->flags,Ff__EXTERN) ||
          Bt(&tmph(CHashFun *)->flags,Ff_INTERNAL))
      while (doc_e!=doc &&
            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,';')))
        doc_e=doc_e->next;
    else
      while (doc_e!=doc &&
            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,'{')))
        doc_e=doc_e->next;
  }
  if (doc_e!=doc) {
    if (doc_e->de_flags&DOCEF_TAG) {
      ptr=doc_e->tag;
      if (ptr2=StrMatch("//",ptr))
        ptr=ptr2+2;
      else if (ptr2=StrMatch("/*",ptr))
        ptr=ptr2+2;
      else if (!StrNCmp(ptr,"public",6))
        ptr+=6;
      while (*ptr==CH_SPACE)
        ptr++;
      res=StrNew(ptr);
      doc_e=doc_e->next;
    }
    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
      if (doc_e->type_u8==DOCT_TAB) {
        ptr=MStrPrint("%s ",res);
        Free(res);
        res=ptr;
      } else if (doc_e->de_flags&DOCEF_TAG) {
        ptr=MStrPrint("%s%s",res,doc_e->tag);
        Free(res);
        res=ptr;
      }
      doc_e=doc_e->next;
    }
  }
  XTalkWait(task,"%c",CH_SHIFT_ESC);
  if (res) {
    ptr=MStrUtil(res,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE);
    Free(res);
    res=ptr;
  }
  return res;
}

I64 HashEntriesCompare3(CWho *h1,CWho *h2)
{
  I64 i,i1=0,i2=0;
  i=StrCmp(h1->idx,h2->idx);
  if (i)
    return i;
  else {
    if (h1->h->type&HTT_HELP_FILE)
      i1=1;
    if (h2->h->type&HTT_HELP_FILE)
      i2=1;
    i=i2-i1;
    if (i)
      return i;
    else
      return StrCmp(h1->h->str,h2->h->str);
  }
}

public U0 Who(U8 *fu_flags=NULL,CHashTable *h=NULL,
U8 *idx=NULL,CDoc *doc=NULL)
{//Dump hash symbol table.
// "+p" for only public symbols
  // "+m" to order by number (normally alphabetical)
  // "-r" just local hash table
  CHashTable *table;
  CHashSrcSym *tmph;
  CHashGeneric *ptr;
  CWho *lst;
  I64 cnt,i,j,k,f=0;
  U8 buf[512],*last_idx=StrNew(""),*cur_idx,*comment;
  Bool recurse,publics,map;
  CTask *task;

  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r");
  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
  if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP))
    throw('FUF');
  recurse=Bt(&f,FUf_RECURSE);
  publics=Bt(&f,FUf_PUBLIC);
  map    =Bt(&f,FUf_MAP);

  if (!h) h=Fs->hash_table;

  if (idx) {
    task=User;
    TaskWait(task);
    LBtr(&task->display_flags,DISPLAYf_SHOW);
  } else
    task=NULL;

  cnt=0;
  table=h;
  while (table) {
    for (i=0;i<=table->mask;i++) {
      tmph=table->body[i];
      while (tmph) {
        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
              (tmph->type & HTF_PUBLIC || !publics)) {
          if (!idx)
            cnt++;
          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx))
            cnt+=HelpIndexCnt(cur_idx,idx);
        }
        tmph=tmph->next;
      }
    }
    if (recurse)
      table=table->next;
    else
      break;
  }
  if (!cnt) goto wh_done;

  lst=CAlloc(cnt*sizeof(CWho));
  j=0;
  table=h;
  while (table) {
    for (i=0;i<=table->mask;i++) {
      tmph=table->body[i];
      while (tmph) {
        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
              (tmph->type & HTF_PUBLIC || !publics))
          if (!idx)
            lst[j++].h=tmph;
          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx) &&
                (k=HelpIndexCnt(cur_idx,idx)))
            while (k--) {
              lst[j].idx=HelpIndexStr(&cur_idx,idx);
              lst[j++].h=tmph;
            }
        tmph=tmph->next;
      }
    }
    if (recurse)
      table=table->next;
    else
      break;
  }

  if (map)
    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2);
  else if (idx)
    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3);
  else
    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare);

  if (idx) {
    progress1_max=cnt;
    progress1=0;
  }
  for (i=0;i<cnt;i++) {
    comment=NULL;
    ptr=lst[i].h;
    if (idx)
      if (cur_idx=lst[i].idx) {
        if (StrCmp(cur_idx,last_idx)) {
          Free(last_idx);
          last_idx=StrNew(cur_idx);
          if (i)
            DocPrint(doc,"\n\n");
          DocPrint(doc,"$WW,0$$PURPLE$$TX+CX,\"%$Q\"$$FG$\n",cur_idx);
        }
      }

    if (idx && ptr->type & HTT_HELP_FILE) {
      DocPrint(doc,"$WW,1$");
      DocType(doc,ptr->str);
      DocPrint(doc,"$WW,0$");
    } else {
      if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) {
        DocPrint(doc,"$LK,\"%-20s\",A=\"%s\"$",
              ptr->str,ptr(CHashSrcSym *)->src_link);
        if (idx)

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\AHash-Adam.html
// Date: unknown-date
// Language: HolyC

#help_index "Info;Hash/System;Cmd Line (Typically)"
class CWho
{
  CHashGeneric *h;
  U8 *idx;
};

I64 HashEntriesCompare(CWho *h1,CWho *h2)
{
  I64 i1,i2;
  if (i1=StrCmp(h1->h->str,h2->h->str))
    return i1;
  i1=HashTypeNum(h1->h);
  i2=HashTypeNum(h2->h);
  return i1-i2;
}

I64 HashEntriesCompare2(CWho *h1,CWho *h2)
{
  CHashFun *tmpf1=h1->h,*tmpf2=h2->h;
  I64 i1=HashVal(tmpf1),i2=HashVal(tmpf2);
  if (i1==i2) {
    i1=HashTypeNum(tmpf1);
    i2=HashTypeNum(tmpf2);
    if (i1==i2)
      return StrCmp(tmpf1->str,tmpf2->str);
  }
  return i1-i2;
}

I64 HelpIndexCnt(U8 *ptr,U8 *idx)
{
  I64 cnt=0,ch,idx_len=StrLen(idx);
  while (*ptr) {
    if (!StrNCmp(ptr,idx,idx_len))
      cnt++;
    while (ch=*ptr++)
      if (ch==';')
        break;
    if (!ch)
      ptr--;
  }
  return cnt;
}

U8 *HelpIndexStr(U8 **_ptr,U8 *idx)
{
  U8 *ptr=*_ptr,*ptr2,*res;
  I64 ch,idx_len=StrLen(idx);
  while (*ptr) {
    ptr2=ptr;
    while (ch=*ptr++)
      if (ch==';')
        break;
    if (!ch)
      ptr--;
    *_ptr=ptr;
    if (!StrNCmp(ptr2,idx,idx_len)) {
      if (ch==';')
        ptr--;
      *ptr=0;
      res=StrNew(ptr2);
      *ptr=ch;
      return res;
    }
  }
  return NULL;
}

U8 *HelpComment(CTask *task,CHash *tmph,U8 *_src_link)
{
  CDoc *doc;
  CDocEntry *doc_e;
  U8 *res=NULL,*ptr,*ptr2,*src_link=StrNew(_src_link);

  if (*src_link=='F' && src_link[2]==':')
    *src_link='P';
  XTalkWait(task,"Ed(0x%X,DOF_DONT_WINMGR_SYNC|DOF_DONT_SHOW);\n",src_link);
  Free(src_link);

  doc=DocPut(task);
  doc_e=doc->cur_entry;
  if (tmph->type&HTT_FUN) {
    if (Bt(&tmph(CHashFun *)->flags,Ff__EXTERN) ||
          Bt(&tmph(CHashFun *)->flags,Ff_INTERNAL))
      while (doc_e!=doc &&
            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,';')))
        doc_e=doc_e->next;
    else
      while (doc_e!=doc &&
            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,'{')))
        doc_e=doc_e->next;
  }
  if (doc_e!=doc) {
    if (doc_e->de_flags&DOCEF_TAG) {
      ptr=doc_e->tag;
      if (ptr2=StrMatch("//",ptr))
        ptr=ptr2+2;
      else if (ptr2=StrMatch("/*",ptr))
        ptr=ptr2+2;
      else if (!StrNCmp(ptr,"public",6))
        ptr+=6;
      while (*ptr==CH_SPACE)
        ptr++;
      res=StrNew(ptr);
      doc_e=doc_e->next;
    }
    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
      if (doc_e->type_u8==DOCT_TAB) {
        ptr=MStrPrint("%s ",res);
        Free(res);
        res=ptr;
      } else if (doc_e->de_flags&DOCEF_TAG) {
        ptr=MStrPrint("%s%s",res,doc_e->tag);
        Free(res);
        res=ptr;
      }
      doc_e=doc_e->next;
    }
  }
  XTalkWait(task,"%c",CH_SHIFT_ESC);
  if (res) {
    ptr=MStrUtil(res,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE);
    Free(res);
    res=ptr;
  }
  return res;
}

I64 HashEntriesCompare3(CWho *h1,CWho *h2)
{
  I64 i,i1=0,i2=0;
  i=StrCmp(h1->idx,h2->idx);
  if (i)
    return i;
  else {
    if (h1->h->type&HTT_HELP_FILE)
      i1=1;
    if (h2->h->type&HTT_HELP_FILE)
      i2=1;
    i=i2-i1;
    if (i)
      return i;
    else
      return StrCmp(h1->h->str,h2->h->str);
  }
}

public U0 Who(U8 *fu_flags=NULL,CHashTable *h=NULL,
U8 *idx=NULL,CDoc *doc=NULL)
{//Dump hash symbol table.
// "+p" for only public symbols
  // "+m" to order by number (normally alphabetical)
  // "-r" just local hash table
  CHashTable *table;
  CHashSrcSym *tmph;
  CHashGeneric *ptr;
  CWho *lst;
  I64 cnt,i,j,k,f=0;
  U8 buf[512],*last_idx=StrNew(""),*cur_idx,*comment;
  Bool recurse,publics,map;
  CTask *task;

  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r");
  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
  if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP))
    throw('FUF');
  recurse=Bt(&f,FUf_RECURSE);
  publics=Bt(&f,FUf_PUBLIC);
  map    =Bt(&f,FUf_MAP);

  if (!h) h=Fs->hash_table;

  if (idx) {
    task=User;
    TaskWait(task);
    LBtr(&task->display_flags,DISPLAYf_SHOW);
  } else
    task=NULL;

  cnt=0;
  table=h;
  while (table) {
    for (i=0;i<=table->mask;i++) {
      tmph=table->body[i];
      while (tmph) {
        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
              (tmph->type & HTF_PUBLIC || !publics)) {
          if (!idx)
            cnt++;
          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx))
            cnt+=HelpIndexCnt(cur_idx,idx);
        }
        tmph=tmph->next;
      }
    }
    if (recurse)
      table=table->next;
    else
      break;
  }
  if (!cnt) goto wh_done;

  lst=CAlloc(cnt*sizeof(CWho));
  j=0;
  table=h;
  while (table) {
    for (i=0;i<=table->mask;i++) {
      tmph=table->body[i];
      while (tmph) {
        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
              (tmph->type & HTF_PUBLIC || !publics))
          if (!idx)
            lst[j++].h=tmph;
          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx) &&
                (k=HelpIndexCnt(cur_idx,idx)))
            while (k--) {
              lst[j].idx=HelpIndexStr(&cur_idx,idx);
              lst[j++].h=tmph;
            }
        tmph=tmph->next;
      }
    }
    if (recurse)
      table=table->next;
    else
      break;
  }

  if (map)
    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2);
  else if (idx)
    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3);
  else
    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare);

  if (idx) {
    progress1_max=cnt;
    progress1=0;
  }
  for (i=0;i<cnt;i++) {
    comment=NULL;
    ptr=lst[i].h;
    if (idx)
      if (cur_idx=lst[i].idx) {
        if (StrCmp(cur_idx,last_idx)) {
          Free(last_idx);
          last_idx=StrNew(cur_idx);
          if (i)
            DocPrint(doc,"\n\n");
          DocPrint(doc,"$WW,0$$PURPLE$$TX+CX,\"%$Q\"$$FG$\n",cur_idx);
        }
      }

    if (idx && ptr->type & HTT_HELP_FILE) {
      DocPrint(doc,"$WW,1$");
      DocType(doc,ptr->str);
      DocPrint(doc,"$WW,0$");
    } else {
      if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) {
        DocPrint(doc,"$LK,\"%-20s\",A=\"%s\"$",
              ptr->str,ptr(CHashSrcSym *)->src_link);
        if (idx)


// Source: D:\TempleOS-Projects\html\Help-Psalmody-Apps.html
// Date: unknown-date
// Language: HolyC

Psalmody Help

* The keyboard can be used as an organ by typing letter keys or clicking the
mouse on the keyboard diagram.  You can "record" notes by pressing the red bttn
and typing letters.  They will appear on the musical staff.  You can edit and
save them.

* The clip can be used to cut and paste.

* Psalmody uses HolyC files as the song format!  See
::/Apps/Psalmody/Examples/prosper.HC.  The Psalmody program does not fully parse
the songs when loading them back in, so changes made outside Psalmody will be
lost, like if you add graphics.

* The first line of the HolyC song files is a comment with a category recognized
by JukeBox().  The categories are "no nothing", "has words", "has graphics", or
"special".  The third character in the song comment is a digit rating number,
shown in JukeBox().  You can set the song rating in JukeBox() by pressing 0-9.
You can request your reward from God by pressing r.  You can press <DEL> to
delete songs.

* You can take the Play() stmts out of a song file and place them in your
programs.  You can also add a song to a document with <CTRL-l>, but you should
do it after pressing <CTRL-t> because the clip-insert in <CTRL-l> is screwy.
See this <Song> after pressing <CTRL-t>, now.

* You can call JukeBox("~/Psalmody"); to play your songs.

* To create a .SND file which can be exported and played under Windows, set the
Bool snd.record to TRUE, play music, and set it to FALSE.  Then, call
SndFileCreate().  You might wish to make a <CTRL-ALT-key> to toggle this system
level recording feat.  See Snd().  Add this code to your ~/HomeKeyPlugIns.HC
file.

U0 CtrlAltR(I64)
{
  snd.record=!snd.record;
}
CtrlAltCBSet('R',&CtrlAltR,"Cmd /Toggle snd.record");

* When calling SndFileCreate() you can set a waveform.  The PC speaker is
WF_SQUARE.  You can sel reverb and averaging, also.

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\Help-Psalmody-Apps.html
// Date: unknown-date
// Language: HolyC

Psalmody Help

* The keyboard can be used as an organ by typing letter keys or clicking the
mouse on the keyboard diagram.  You can "record" notes by pressing the red bttn
and typing letters.  They will appear on the musical staff.  You can edit and
save them.

* The clip can be used to cut and paste.

* Psalmody uses HolyC files as the song format!  See
::/Apps/Psalmody/Examples/prosper.HC.  The Psalmody program does not fully parse
the songs when loading them back in, so changes made outside Psalmody will be
lost, like if you add graphics.

* The first line of the HolyC song files is a comment with a category recognized
by JukeBox().  The categories are "no nothing", "has words", "has graphics", or
"special".  The third character in the song comment is a digit rating number,
shown in JukeBox().  You can set the song rating in JukeBox() by pressing 0-9.
You can request your reward from God by pressing r.  You can press <DEL> to
delete songs.

* You can take the Play() stmts out of a song file and place them in your
programs.  You can also add a song to a document with <CTRL-l>, but you should
do it after pressing <CTRL-t> because the clip-insert in <CTRL-l> is screwy.
See this <Song> after pressing <CTRL-t>, now.

* You can call JukeBox("~/Psalmody"); to play your songs.

* To create a .SND file which can be exported and played under Windows, set the
Bool snd.record to TRUE, play music, and set it to FALSE.  Then, call
SndFileCreate().  You might wish to make a <CTRL-ALT-key> to toggle this system
level recording feat.  See Snd().  Add this code to your ~/HomeKeyPlugIns.HC
file.

U0 CtrlAltR(I64)
{
  snd.record=!snd.record;
}
CtrlAltCBSet('R',&CtrlAltR,"Cmd /Toggle snd.record");

* When calling SndFileCreate() you can set a waveform.  The PC speaker is
WF_SQUARE.  You can sel reverb and averaging, also.


// Source: D:\TempleOS-Projects\html\ParenWarn-Demo.html
// Date: unknown-date
// Language: HolyC

Option(OPTf_WARN_PAREN,ON);

F64 d,d1=1,d2=1;

d1=(d2=3.0);

d1=(d2+3.0);

d=(d1+d2)+(d1+d2);

d=(2`3)`2;

d=2`(3`2);

d=-d1`(d+d2);

Option(OPTf_WARN_PAREN,OFF);

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\ParenWarn-Demo.html
// Date: unknown-date
// Language: HolyC

Option(OPTf_WARN_PAREN,ON);

F64 d,d1=1,d2=1;

d1=(d2=3.0);

d1=(d2+3.0);

d=(d1+d2)+(d1+d2);

d=(2`3)`2;

d=2`(3`2);

d=-d1`(d+d2);

Option(OPTf_WARN_PAREN,OFF);


// Source: D:\TempleOS-Projects\html\GrInitA-Gr-Adam.html
// Date: unknown-date
// Language: HolyC

#help_index "Graphics"

U0 GrInit1()
{
  DefineLstLoad("ST_SPRITE_ELEM_TYPES",
        "End\0Color\0Dither Color\0"
        "Thick\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
        "Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0"
        "BSpline3\0BSpline3 Closed\0"
        "Flood Fill\0Flood Fill Not Color\0BitMap\0Mesh\0Shiftable Mesh\0"
        "Arrow\0Text\0Text Box\0Text Diamond\0");
  DefineLstLoad("ST_SPRITE_ELEM_CODES",
        "End\0Color\0Color\0"
        "Thick\0PlanarSymmetry\0Transform\0Transform\0Shift\0"
        "Pt\0PolyPt\0Line\0PolyLine\0Rect\0Rect\0"
        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2\0BSpline3\0BSpline3\0"
        "FloodFill\0FloodFill\0BitMap\0Mesh\0Mesh\0"
        "Arrow\0Text\0TextBox\0TextDiamond\0");
}
GrInit1;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\GrInitA-Gr-Adam.html
// Date: unknown-date
// Language: HolyC

#help_index "Graphics"

U0 GrInit1()
{
  DefineLstLoad("ST_SPRITE_ELEM_TYPES",
        "End\0Color\0Dither Color\0"
        "Thick\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
        "Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0"
        "BSpline3\0BSpline3 Closed\0"
        "Flood Fill\0Flood Fill Not Color\0BitMap\0Mesh\0Shiftable Mesh\0"
        "Arrow\0Text\0Text Box\0Text Diamond\0");
  DefineLstLoad("ST_SPRITE_ELEM_CODES",
        "End\0Color\0Color\0"
        "Thick\0PlanarSymmetry\0Transform\0Transform\0Shift\0"
        "Pt\0PolyPt\0Line\0PolyLine\0Rect\0Rect\0"
        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2\0BSpline3\0BSpline3\0"
        "FloodFill\0FloodFill\0BitMap\0Mesh\0Mesh\0"
        "Arrow\0Text\0TextBox\0TextDiamond\0");
}
GrInit1;


// Source: D:\TempleOS-Projects\html\Stadium-Games-Stadium-Demo.html
// Date: unknown-date
// Language: HolyC

/*This shows how you can make a
background very easily.
*/

<1>/* Graphics Not Rendered in HTML */

<2>/* Graphics Not Rendered in HTML */

CDC *background;

#define BALL_TIME       0.2
#define FANS_NUM 10
I64 x[FANS_NUM],y[FANS_NUM];
Bool hit[FANS_NUM];
F64 theta[FANS_NUM],ball_t;
I64 target_x,target_y,pitcher_x,pitcher_y;

U0 DrawIt(CTask *,CDC *dc)
{
  I64 i,*r;
  F64 xx,yy,t0;
  background->flags|=DCF_NO_TRANSPARENTS;
  GrBlot(dc,0,0,background);
  for (i=0;i<FANS_NUM;i++)
    Sprite3ZB(dc,x[i],y[i],0,<fan>,theta[i]);
  if (ball_t) {
    t0=(tS-ball_t)/BALL_TIME;
    if (t0>1.0)
      ball_t=0;
    else {
      xx=t0*target_x+(1.0-t0)*pitcher_x;
      yy=t0*target_y+(1.0-t0)*pitcher_y;
      xx/=1.5-t0;
      yy/=1.5-t0;
      r=Mat4x4New(dc->r,dc->mem_task);
      Mat4x4Scale(r,1.5-t0);
      Free(dc->r);
      DCMat4x4Set(dc,r);
      dc->flags|=DCF_TRANSFORMATION;
      Sprite3ZB(dc,xx,yy,0,<ball>,t0);
    }
  }
  dc->color=RED;
  GrPrint(dc,FONT_WIDTH,FONT_HEIGHT,"Peg the Fans");
}

U0 AnimateTask(I64)
{
  I64 i;
  F64 xx,yy,t0;
  while (TRUE) {
    if (ball_t) {
      t0=(tS-ball_t)/BALL_TIME;
      xx=t0*target_x+(1.0-t0)*pitcher_x;
      yy=t0*target_y+(1.0-t0)*pitcher_y;
    }
    for (i=0;i<FANS_NUM;i++) {
      if (ball_t)
        if (Sqr(x[i]-xx)+Sqr(y[i]-yy)<200) {
          hit[i]=TRUE;
          theta[i]=-pi/2;
        }
      if (!hit[i]) {
        x[i]+=SignI64(RandI16);
        y[i]+=SignI64(RandI16);
        theta[i]+=Sign(RandI16)/25.0;
        if (!(0<=x[i]<GR_WIDTH)) x[i]=GR_WIDTH/2;
        if (!(10<=y[i]<100)) y[i]=50;
        if (!(-0.75<=theta[i]<0.75)) theta[i]=0;
      }
    }
    Sleep(10);
  }
}

U0 Init()
{
  I64 i;
  for (i=0;i<FANS_NUM;i++) {
    x[i]=RandU16%GR_WIDTH;
    y[i]=50;
    theta[i]=0;
    hit[i]=FALSE;
  }
}

U0 Stadium()
{
  I64 msg_code,arg1,arg2,ch=0;

  SettingsPush; //See SettingsPush
  Cd(__DIR__);
  Fs->win_inhibit|=WIG_DBL_CLICK;

  MenuPush(
        "File {"
        "  Abort(,CH_SHIFT_ESC);"
        "  Exit(,CH_ESC);"
        "}"
        "Play {"
        "  Restart(,'\n');"
        "}"
        );
  AutoComplete;
  WinBorder;
  WinMax;
  DocCursor;
  DocClear;
  Init;
  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);

  background=GRRead("StadiumBG");
  Fs->draw_it=&DrawIt;
  do {
    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
    if (msg_code==MSG_KEY_DOWN) {
      ch=arg1;
      if (ch=='\n')
        Init;
    } else {
      target_x=arg1; target_y=arg2;
      pitcher_x=GR_WIDTH/2; pitcher_y=GR_HEIGHT;
      ball_t=tS;
    }
  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
  GetMsg(,,1<<MSG_KEY_UP);

  DCDel(background);
  SettingsPop;
  MenuPop;
}

Stadium;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\Stadium-Games-Stadium-Demo.html
// Date: unknown-date
// Language: HolyC

/*This shows how you can make a
background very easily.
*/

<1>/* Graphics Not Rendered in HTML */

<2>/* Graphics Not Rendered in HTML */

CDC *background;

#define BALL_TIME       0.2
#define FANS_NUM 10
I64 x[FANS_NUM],y[FANS_NUM];
Bool hit[FANS_NUM];
F64 theta[FANS_NUM],ball_t;
I64 target_x,target_y,pitcher_x,pitcher_y;

U0 DrawIt(CTask *,CDC *dc)
{
  I64 i,*r;
  F64 xx,yy,t0;
  background->flags|=DCF_NO_TRANSPARENTS;
  GrBlot(dc,0,0,background);
  for (i=0;i<FANS_NUM;i++)
    Sprite3ZB(dc,x[i],y[i],0,<fan>,theta[i]);
  if (ball_t) {
    t0=(tS-ball_t)/BALL_TIME;
    if (t0>1.0)
      ball_t=0;
    else {
      xx=t0*target_x+(1.0-t0)*pitcher_x;
      yy=t0*target_y+(1.0-t0)*pitcher_y;
      xx/=1.5-t0;
      yy/=1.5-t0;
      r=Mat4x4New(dc->r,dc->mem_task);
      Mat4x4Scale(r,1.5-t0);
      Free(dc->r);
      DCMat4x4Set(dc,r);
      dc->flags|=DCF_TRANSFORMATION;
      Sprite3ZB(dc,xx,yy,0,<ball>,t0);
    }
  }
  dc->color=RED;
  GrPrint(dc,FONT_WIDTH,FONT_HEIGHT,"Peg the Fans");
}

U0 AnimateTask(I64)
{
  I64 i;
  F64 xx,yy,t0;
  while (TRUE) {
    if (ball_t) {
      t0=(tS-ball_t)/BALL_TIME;
      xx=t0*target_x+(1.0-t0)*pitcher_x;
      yy=t0*target_y+(1.0-t0)*pitcher_y;
    }
    for (i=0;i<FANS_NUM;i++) {
      if (ball_t)
        if (Sqr(x[i]-xx)+Sqr(y[i]-yy)<200) {
          hit[i]=TRUE;
          theta[i]=-pi/2;
        }
      if (!hit[i]) {
        x[i]+=SignI64(RandI16);
        y[i]+=SignI64(RandI16);
        theta[i]+=Sign(RandI16)/25.0;
        if (!(0<=x[i]<GR_WIDTH)) x[i]=GR_WIDTH/2;
        if (!(10<=y[i]<100)) y[i]=50;
        if (!(-0.75<=theta[i]<0.75)) theta[i]=0;
      }
    }
    Sleep(10);
  }
}

U0 Init()
{
  I64 i;
  for (i=0;i<FANS_NUM;i++) {
    x[i]=RandU16%GR_WIDTH;
    y[i]=50;
    theta[i]=0;
    hit[i]=FALSE;
  }
}

U0 Stadium()
{
  I64 msg_code,arg1,arg2,ch=0;

  SettingsPush; //See SettingsPush
  Cd(__DIR__);
  Fs->win_inhibit|=WIG_DBL_CLICK;

  MenuPush(
        "File {"
        "  Abort(,CH_SHIFT_ESC);"
        "  Exit(,CH_ESC);"
        "}"
        "Play {"
        "  Restart(,'\n');"
        "}"
        );
  AutoComplete;
  WinBorder;
  WinMax;
  DocCursor;
  DocClear;
  Init;
  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);

  background=GRRead("StadiumBG");
  Fs->draw_it=&DrawIt;
  do {
    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
    if (msg_code==MSG_KEY_DOWN) {
      ch=arg1;
      if (ch=='\n')
        Init;
    } else {
      target_x=arg1; target_y=arg2;
      pitcher_x=GR_WIDTH/2; pitcher_y=GR_HEIGHT;
      ball_t=tS;
    }
  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
  GetMsg(,,1<<MSG_KEY_UP);

  DCDel(background);
  SettingsPop;
  MenuPop;
}

Stadium;


// Source: D:\TempleOS-Projects\html\MPRadix-MultiCore-Demo.html
// Date: unknown-date
// Language: HolyC

/*
On an 8-core machine, this takes the top 3-bits
of random numbers and distributes them to the 8 cores
for sorting.  Then, it merge sorts them.
*/

#define NUM     1000000

I64 my_mp_cnt=1<<Bsr(mp_cnt);//Power of 2

I32 *arg1,*arg2;
I32 *b[my_mp_cnt],bn[my_mp_cnt];
I64 mp_not_done_flags;

I64 Compare(I32 *e1,I32 *e2)
{
  return *e1-*e2;
}

U0 QSortU32(I32 *base,I64 num)
{//By customizing, we dramatically improve it!
//Cut and paste from QSortI64().
  I64 i;
  I32 *less,*greater,pivot;
  if (num>1) {
    do {
      less=base;
      greater=base+num;
      pivot=base[num/2];
      while (less<greater) {
        if (*less<=pivot)
          less++;
        else {
          greater--;
          SwapU32(less,greater);
        }
      }
      i=less-base;
      if (i==num) {//All less or equ to pivot

        //Point greater to first less
        do greater--;
        while (--i && *greater==pivot);

        if (i) {
          less=base+num/2; //Pivot was not moved, point to it
          if (less<greater)
            SwapU32(less,greater);
          num=i;
        } else //All equ
          break;
      } else if (i<num/2) {
        QSortU32(base,i);
        num-=i;
        base=greater;
      } else {
        QSortU32(greater,num-i);
        num=i;
      }
    } while (num>1);
  }
}

U0 MPSort(I64 dummy=0)
{
  no_warn dummy;
  QSortU32(b[Gs->num],bn[Gs->num]);
  LBtr(&mp_not_done_flags,Gs->num);
}

U0 MPRadixSortDemo(I64 dummy=0)
{
  no_warn dummy;
  I64 i,j,k1,k2;
  F64 t0;
  arg1=MAlloc(NUM*sizeof(I32));
  for (i=0;i<NUM;i++)
    arg1[i]=RandI32;

  arg2=MAlloc(NUM*sizeof(I32));

  "$GREEN$QSort$FG$\n";
  t0=tS;
  MemCpy(arg2,arg1,sizeof(I32)*NUM);
  QSort(arg2,NUM,sizeof(I32),&Compare);
  "Time:%9.6f\n",tS-t0;
  D(arg2+NUM/4);

  "$GREEN$QSortU32$FG$\n";
  t0=tS;
  MemCpy(arg2,arg1,sizeof(I32)*NUM);
  QSortU32(arg2,NUM);
  "Time:%9.6f\n",tS-t0;
  D(arg2+NUM/4);

  for (i=0;i<my_mp_cnt;i++) {
//We must do full size, just in case.
    //There will be uneven split between cores
    //depending on the distribution of rand numbers.
    b[i]=MAlloc(NUM*sizeof(I32));
    bn[i]=0;
  }

  if (my_mp_cnt<2) throw('MultCore');

  "$GREEN$MP Radix QSortU32$FG$\n";
  t0=tS;
  k1=32-Bsr(my_mp_cnt);
  k2=my_mp_cnt/2;
  for (i=0;i<NUM;i++) {
    j=arg1[i]>>k1+k2; //This is a preliminary radix sort.
    b[j][bn[j]++]=arg1[i];
  }
  mp_not_done_flags=1<<my_mp_cnt-1;
  for (i=0;i<my_mp_cnt;i++)
    Spawn(&MPSort,NULL,NULL,i);
  while (mp_not_done_flags)
    Yield;
  j=0;
  for (i=0;i<my_mp_cnt;i++) {
    MemCpy(&arg2[j],b[i],bn[i]*sizeof(I32));
    j+=bn[i];
  }
  "Time:%9.6f\n",tS-t0;
  D(arg2+NUM/4);

  Free(arg1);
  Free(arg2);
  for (i=0;i<my_mp_cnt;i++)
    Free(b[i]);
}

MPRadixSortDemo;

/* Results on 8 Cores 3.397GHz Core i7:
QSort
Time: 0.759998
QSortU32
Time: 0.093684
MP Radix QSortU32
Time: 0.045450
*/

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\MPRadix-MultiCore-Demo.html
// Date: unknown-date
// Language: HolyC

/*
On an 8-core machine, this takes the top 3-bits
of random numbers and distributes them to the 8 cores
for sorting.  Then, it merge sorts them.
*/

#define NUM     1000000

I64 my_mp_cnt=1<<Bsr(mp_cnt);//Power of 2

I32 *arg1,*arg2;
I32 *b[my_mp_cnt],bn[my_mp_cnt];
I64 mp_not_done_flags;

I64 Compare(I32 *e1,I32 *e2)
{
  return *e1-*e2;
}

U0 QSortU32(I32 *base,I64 num)
{//By customizing, we dramatically improve it!
//Cut and paste from QSortI64().
  I64 i;
  I32 *less,*greater,pivot;
  if (num>1) {
    do {
      less=base;
      greater=base+num;
      pivot=base[num/2];
      while (less<greater) {
        if (*less<=pivot)
          less++;
        else {
          greater--;
          SwapU32(less,greater);
        }
      }
      i=less-base;
      if (i==num) {//All less or equ to pivot

        //Point greater to first less
        do greater--;
        while (--i && *greater==pivot);

        if (i) {
          less=base+num/2; //Pivot was not moved, point to it
          if (less<greater)
            SwapU32(less,greater);
          num=i;
        } else //All equ
          break;
      } else if (i<num/2) {
        QSortU32(base,i);
        num-=i;
        base=greater;
      } else {
        QSortU32(greater,num-i);
        num=i;
      }
    } while (num>1);
  }
}

U0 MPSort(I64 dummy=0)
{
  no_warn dummy;
  QSortU32(b[Gs->num],bn[Gs->num]);
  LBtr(&mp_not_done_flags,Gs->num);
}

U0 MPRadixSortDemo(I64 dummy=0)
{
  no_warn dummy;
  I64 i,j,k1,k2;
  F64 t0;
  arg1=MAlloc(NUM*sizeof(I32));
  for (i=0;i<NUM;i++)
    arg1[i]=RandI32;

  arg2=MAlloc(NUM*sizeof(I32));

  "$GREEN$QSort$FG$\n";
  t0=tS;
  MemCpy(arg2,arg1,sizeof(I32)*NUM);
  QSort(arg2,NUM,sizeof(I32),&Compare);
  "Time:%9.6f\n",tS-t0;
  D(arg2+NUM/4);

  "$GREEN$QSortU32$FG$\n";
  t0=tS;
  MemCpy(arg2,arg1,sizeof(I32)*NUM);
  QSortU32(arg2,NUM);
  "Time:%9.6f\n",tS-t0;
  D(arg2+NUM/4);

  for (i=0;i<my_mp_cnt;i++) {
//We must do full size, just in case.
    //There will be uneven split between cores
    //depending on the distribution of rand numbers.
    b[i]=MAlloc(NUM*sizeof(I32));
    bn[i]=0;
  }

  if (my_mp_cnt<2) throw('MultCore');

  "$GREEN$MP Radix QSortU32$FG$\n";
  t0=tS;
  k1=32-Bsr(my_mp_cnt);
  k2=my_mp_cnt/2;
  for (i=0;i<NUM;i++) {
    j=arg1[i]>>k1+k2; //This is a preliminary radix sort.
    b[j][bn[j]++]=arg1[i];
  }
  mp_not_done_flags=1<<my_mp_cnt-1;
  for (i=0;i<my_mp_cnt;i++)
    Spawn(&MPSort,NULL,NULL,i);
  while (mp_not_done_flags)
    Yield;
  j=0;
  for (i=0;i<my_mp_cnt;i++) {
    MemCpy(&arg2[j],b[i],bn[i]*sizeof(I32));
    j+=bn[i];
  }
  "Time:%9.6f\n",tS-t0;
  D(arg2+NUM/4);

  Free(arg1);
  Free(arg2);
  for (i=0;i<my_mp_cnt;i++)
    Free(b[i]);
}

MPRadixSortDemo;

/* Results on 8 Cores 3.397GHz Core i7:
QSort
Time: 0.759998
QSortU32
Time: 0.093684
MP Radix QSortU32
Time: 0.045450
*/


// Source: D:\TempleOS-Projects\html\MiniCompiler-Lectures-Demo.html
// Date: unknown-date
// Language: HolyC

/*
-] Main Compiler
  The mini compiler is like the main compiler, except the main compiler's
  lexical analyser removes comments and does preprocessing.  Lex(),Echo(ON).

  The main compiler generates Intermediate Code at the parser stage.  See
  PrsExpression(), PrsStmt().

  The main compiler optimizes   See Intermediate Code Attributes,
  Combining Consts, Choosing Reg Vars.  Use PassTrace() to see the optimization
  stages.

  The main compiler makes machine code in the back end.  See IC Struct,
  COCCompile and OptPass789A(), BackEnd.  Set Trace(ON) to see the output of the
  backend.

-] Mini Compiler
  For this mini compiler, some things you should know about 64-bit asm:

  * Putting a 0x48, known as the REX byte, in front of an inst makes it 64-bit
  size.

  * "PUSH EAX", "POP EAX" and "XOR EAX,EAX" will behave as 64-bit even without
  REX because the stk is always 64 bit and because the XOR clears the upper
  32-bits.

  It is okay in TempleOS to change RAX, RBX, RCX, RDX, R8 and R9 without
  restoring them to their original values.
*/

#define TK_EOF          0
#define TK_NUM          1
#define TK_OP           2
#define TK_LEFT         3
#define TK_RIGHT        4

#define OP_MUL          1
#define OP_DIV          2
#define OP_ADD          3
#define OP_SUB          4

I64 Lex(U8 **_src,I64 *num)
{//See Lex().
  U8 *src=*_src;
  I64 i;
  while (TRUE) {
    switch (*src) {
      case 0:
      case ';':
        *_src=src;
        return TK_EOF;
      case CH_SPACE:
      case '\r':
      case '\n':
        src++;
        break;
      case '0'...'9':
        i=0;
        do {
          i=i*10+*src-'0';
          src++;
        } while ('0'<=*src<='9');
        *num=i;
        *_src=src;
        return TK_NUM;
      case '*':
        *num=OP_MUL;
        *_src=src+1;
        return TK_OP;
      case '/':
        *num=OP_DIV;
        *_src=src+1;
        return TK_OP;
      case '+':
        *num=OP_ADD;
        *_src=src+1;
        return TK_OP;
      case '-':
        *num=OP_SUB;
        *_src=src+1;
        return TK_OP;
      case '(':
        *_src=src+1;
        return TK_LEFT;
      case ')':
        *_src=src+1;
        return TK_RIGHT;
      default:
        throw;
    }
  }
}

#define PREC_EOF        0
#define PREC_TERM       1
#define PREC_MUL        2
#define PREC_ADD        3
#define PREC_PAREN      4

extern I64 Parse(U8 **_src,U8 **_dst);

U0 PrsTerm(U8 **_src,U8 **_dst,I64 prec)
{//See PrsExpression().
  I64 i;
  U8 *src2;
  U8 *dst2;
  if (Parse(_src,_dst)==PREC_TERM) {
    src2=*_src;
    dst2=*_dst;
    while (TRUE) {
//This is inefficient.  The main compiler doesn't back-up like this.
      i=Parse(&src2,&dst2);
      if (PREC_MUL<=i<prec) {
        *_src=src2;
        *_dst=dst2;
      } else
        break;
    }
  } else
    throw;
}

I64 Parse(U8 **_src,U8 **_dst)
{//See PrsExpression().
//See Opcode Fmts for details on asm insts.
  I64 i;
  U8 *dst=*_dst;
  switch (Lex(_src,&i)) {
    case TK_EOF:
      *dst++=0x58; //POP RAX
      *dst++=0xC3; //RET
      *_dst=dst;
      return PREC_EOF;
    case TK_NUM:
      *dst++=0x48; //REX
      *dst++=0xB8; //MOV RAX,immediate num
      *dst(I64 *)++=i;

      *dst++=0x50; //PUSH RAX
      *_dst=dst;
      return PREC_TERM;
    case TK_LEFT:
      PrsTerm(_src,_dst,PREC_PAREN);
      if (Parse(_src,_dst)!=PREC_PAREN)
        throw;
      return PREC_TERM;
    case TK_RIGHT:
      return PREC_PAREN;
    case TK_OP:
      switch (i) {
        case OP_MUL:
          PrsTerm(_src,&dst,PREC_MUL);
          *dst++=0x5A; //POP RDX
          *dst++=0x58; //POP RAX

          *dst++=0x48; //REX
          *dst++=0x0F;
          *dst++=0xAF; //IMUL RAX,RDX
          *dst++=0xC2;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_MUL;
        case OP_DIV:
          PrsTerm(_src,&dst,PREC_MUL);
          *dst++=0x5B; //POP RBX
          *dst++=0x58; //POP RAX

          *dst++=0x33; //XOR RDX,RDX
          *dst++=0xD2;

          *dst++=0x48; //REX
          *dst++=0xF7; //IDIV RBX
          *dst++=0xFB;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_MUL;
        case OP_ADD:
          PrsTerm(_src,&dst,PREC_ADD);
          *dst++=0x5A; //POP RDX
          *dst++=0x58; //POP RAX

          *dst++=0x48; //REX
          *dst++=0x03; //ADD RAX,RDX
          *dst++=0xC2;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_ADD;
        case OP_SUB:
          PrsTerm(_src,&dst,PREC_ADD);
          *dst++=0x5A; //POP RDX
          *dst++=0x58; //POP RAX

          *dst++=0x48; //REX
          *dst++=0x2B; //SUB RAX,RDX
          *dst++=0xC2;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_ADD;
      }
  }
}

U0 Main()
{
  U8 *src,*src2,*code,*dst;

  //Fixed size, no buffer overrun check.
  //You can make it fancier if you like.
  code=MAlloc(512,Fs->code_heap);

  while (TRUE) {
    "This will compile an expression\n"
          "consisting of ints, parentheses\n"
          "and the operators +,-,* and /.\n";
    src=GetStr;
    if (*src) {
      src2=src;
      dst=code;
      try {
        PrsTerm(&src2,&dst,PREC_PAREN);
        if (Parse(&src2,&dst)!=PREC_EOF)
          throw;
        "$RED$This code is not efficient, but the compiler is simple.$FG$\n";
        Un(code,dst-code); //Unassemble the code we created.
//Call() is a function.  See _CALL::
        //See also CallInd().  See _CALL_IND::
        "$LTBLUE$Answer:%d$FG$\n",Call(code);
      } catch {
        "$RED$Error$FG$\n";
        PutExcept;
      }
      Free(src);
    } else {
      Free(src);
      break;
    }
  }
  Free(code);
}

Main;

[System] You are Terry Davis, the creator of TempleOS. Write HolyC code in your unique style.

[User] Please write some HolyC code.

[Assistant]
// Source: D:\TempleOS-Projects\html\MiniCompiler-Lectures-Demo.html
// Date: unknown-date
// Language: HolyC

/*
-] Main Compiler
  The mini compiler is like the main compiler, except the main compiler's
  lexical analyser removes comments and does preprocessing.  Lex(),Echo(ON).

  The main compiler generates Intermediate Code at the parser stage.  See
  PrsExpression(), PrsStmt().

  The main compiler optimizes   See Intermediate Code Attributes,
  Combining Consts, Choosing Reg Vars.  Use PassTrace() to see the optimization
  stages.

  The main compiler makes machine code in the back end.  See IC Struct,
  COCCompile and OptPass789A(), BackEnd.  Set Trace(ON) to see the output of the
  backend.

-] Mini Compiler
  For this mini compiler, some things you should know about 64-bit asm:

  * Putting a 0x48, known as the REX byte, in front of an inst makes it 64-bit
  size.

  * "PUSH EAX", "POP EAX" and "XOR EAX,EAX" will behave as 64-bit even without
  REX because the stk is always 64 bit and because the XOR clears the upper
  32-bits.

  It is okay in TempleOS to change RAX, RBX, RCX, RDX, R8 and R9 without
  restoring them to their original values.
*/

#define TK_EOF          0
#define TK_NUM          1
#define TK_OP           2
#define TK_LEFT         3
#define TK_RIGHT        4

#define OP_MUL          1
#define OP_DIV          2
#define OP_ADD          3
#define OP_SUB          4

I64 Lex(U8 **_src,I64 *num)
{//See Lex().
  U8 *src=*_src;
  I64 i;
  while (TRUE) {
    switch (*src) {
      case 0:
      case ';':
        *_src=src;
        return TK_EOF;
      case CH_SPACE:
      case '\r':
      case '\n':
        src++;
        break;
      case '0'...'9':
        i=0;
        do {
          i=i*10+*src-'0';
          src++;
        } while ('0'<=*src<='9');
        *num=i;
        *_src=src;
        return TK_NUM;
      case '*':
        *num=OP_MUL;
        *_src=src+1;
        return TK_OP;
      case '/':
        *num=OP_DIV;
        *_src=src+1;
        return TK_OP;
      case '+':
        *num=OP_ADD;
        *_src=src+1;
        return TK_OP;
      case '-':
        *num=OP_SUB;
        *_src=src+1;
        return TK_OP;
      case '(':
        *_src=src+1;
        return TK_LEFT;
      case ')':
        *_src=src+1;
        return TK_RIGHT;
      default:
        throw;
    }
  }
}

#define PREC_EOF        0
#define PREC_TERM       1
#define PREC_MUL        2
#define PREC_ADD        3
#define PREC_PAREN      4

extern I64 Parse(U8 **_src,U8 **_dst);

U0 PrsTerm(U8 **_src,U8 **_dst,I64 prec)
{//See PrsExpression().
  I64 i;
  U8 *src2;
  U8 *dst2;
  if (Parse(_src,_dst)==PREC_TERM) {
    src2=*_src;
    dst2=*_dst;
    while (TRUE) {
//This is inefficient.  The main compiler doesn't back-up like this.
      i=Parse(&src2,&dst2);
      if (PREC_MUL<=i<prec) {
        *_src=src2;
        *_dst=dst2;
      } else
        break;
    }
  } else
    throw;
}

I64 Parse(U8 **_src,U8 **_dst)
{//See PrsExpression().
//See Opcode Fmts for details on asm insts.
  I64 i;
  U8 *dst=*_dst;
  switch (Lex(_src,&i)) {
    case TK_EOF:
      *dst++=0x58; //POP RAX
      *dst++=0xC3; //RET
      *_dst=dst;
      return PREC_EOF;
    case TK_NUM:
      *dst++=0x48; //REX
      *dst++=0xB8; //MOV RAX,immediate num
      *dst(I64 *)++=i;

      *dst++=0x50; //PUSH RAX
      *_dst=dst;
      return PREC_TERM;
    case TK_LEFT:
      PrsTerm(_src,_dst,PREC_PAREN);
      if (Parse(_src,_dst)!=PREC_PAREN)
        throw;
      return PREC_TERM;
    case TK_RIGHT:
      return PREC_PAREN;
    case TK_OP:
      switch (i) {
        case OP_MUL:
          PrsTerm(_src,&dst,PREC_MUL);
          *dst++=0x5A; //POP RDX
          *dst++=0x58; //POP RAX

          *dst++=0x48; //REX
          *dst++=0x0F;
          *dst++=0xAF; //IMUL RAX,RDX
          *dst++=0xC2;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_MUL;
        case OP_DIV:
          PrsTerm(_src,&dst,PREC_MUL);
          *dst++=0x5B; //POP RBX
          *dst++=0x58; //POP RAX

          *dst++=0x33; //XOR RDX,RDX
          *dst++=0xD2;

          *dst++=0x48; //REX
          *dst++=0xF7; //IDIV RBX
          *dst++=0xFB;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_MUL;
        case OP_ADD:
          PrsTerm(_src,&dst,PREC_ADD);
          *dst++=0x5A; //POP RDX
          *dst++=0x58; //POP RAX

          *dst++=0x48; //REX
          *dst++=0x03; //ADD RAX,RDX
          *dst++=0xC2;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_ADD;
        case OP_SUB:
          PrsTerm(_src,&dst,PREC_ADD);
          *dst++=0x5A; //POP RDX
          *dst++=0x58; //POP RAX

          *dst++=0x48; //REX
          *dst++=0x2B; //SUB RAX,RDX
          *dst++=0xC2;

          *dst++=0x50; //PUSH RAX
          *_dst=dst;
          return PREC_ADD;
      }
  }
}

U0 Main()
{
  U8 *src,*src2,*code,*dst;

  //Fixed size, no buffer overrun check.
  //You can make it fancier if you like.
  code=MAlloc(512,Fs->code_heap);

  while (TRUE) {
    "This will compile an expression\n"
          "consisting of ints, parentheses\n"
          "and the operators +,-,* and /.\n";
    src=GetStr;
    if (*src) {
      src2=src;
      dst=code;
      try {
        PrsTerm(&src2,&dst,PREC_PAREN);
        if (Parse(&src2,&dst)!=PREC_EOF)
          throw;
        "$RED$This code is not efficient, but the compiler is simple.$FG$\n";
        Un(code,dst-code); //Unassemble the code we created.
//Call() is a function.  See _CALL::
        //See also CallInd().  See _CALL_IND::
        "$LTBLUE$Answer:%d$FG$\n",Call(code);
      } catch {
        "$RED$Error$FG$\n";
        PutExcept;
      }
      Free(src);
    } else {
      Free(src);
      break;
    }
  }
  Free(code);
}

Main;