⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 A very small LISP implementation with several packages and demo programs.
💻 C
📖 第 1 页 / 共 5 页
字号:
   return x;}/* Read one token */any token(any x, int c) {   int i;   any y, *h;   cell c1;   if (!Chr)      Env.get();   if (skip(c) < 0)      return NULL;   if (Chr == '"') {      Env.get();      if (Chr == '"') {         Env.get();         return Nil;      }      testEsc();      i = 0,  Push(c1, y = box(Chr));      while (Env.get(), Chr != '"' && testEsc())         byteSym(Chr, &i, &y);      Env.get();      return consStr(y = Pop(c1));   }   if (Chr >= '0' && Chr <= '9') {      i = 0,  Push(c1, y = box(Chr));      while (Env.get(), Chr >= '0' && Chr <= '9' || Chr == '.')         byteSym(Chr, &i, &y);      return symToNum(Pop(c1), (int)unDig(val(Scl)) / 2, '.', 0);   }   {      char nm[bufSize(x)];      bufString(x, nm);      if (Chr >= 'A' && Chr <= 'Z' || Chr == '\\' || Chr >= 'a' && Chr <= 'z' || strchr(nm,Chr)) {         if (Chr == '\\')            Env.get();         i = 0,  Push(c1, y = box(Chr));         while (Env.get(),               Chr >= '0' && Chr <= '9' || Chr >= 'A' && Chr <= 'Z' ||               Chr == '\\' || Chr >= 'a' && Chr <= 'z' || strchr(nm,Chr) ) {            if (Chr == '\\')               Env.get();            byteSym(Chr, &i, &y);         }         y = Pop(c1);         if (x = findHash(y, h = Intern + hash(y)))            return x;         x = consSym(Nil,y);         *h = cons(x,*h);         return x;      }   }   y = box(c = getChar());   Env.get();   if (x = findHash(y, Intern + hash(y)))      return x;   return mkChar(c);}// (read ['sym1 ['sym2]]) -> anyany doRead(any ex) {   any x;   if (!isCell(x = cdr(ex)))      x = read1(0);   else {      cell c1;      Push(c1, EVAL(car(x)));      NeedSym(ex, data(c1));      x = cdr(x),  x = EVAL(car(x));      NeedSym(ex,x);      x = token(data(c1), symChar(name(x))) ?: Nil;      drop(c1);   }   if (!InFile  &&  Chr == '\n')      Chr = 0;   return x;}long waitFd(any ex, int fd, long ms) {   any x;   cell c1, c2;   int i, j, m, n;   long t;   bool flg;   fd_set rdSet, wrSet;   struct timeval *tp, tv;#ifndef __linux__   struct timeval tt;#endif   Save(c1);   do {      if (ms >= 0)         t = ms,  tp = &tv;      else         t = LONG_MAX,  tp = NULL;      FD_ZERO(&rdSet);      FD_ZERO(&wrSet);      m = 0;      if (fd >= 0) {         if (inReady(fd))            tp = &tv,  t = 0;         else            FD_SET(m = fd, &rdSet);      }      if (Hear) {         if (inReady(Hear))            tp = &tv,  t = 0;         else {            FD_SET(Hear, &rdSet);            if (Hear > m)               m = Hear;         }      }      for (x = data(c1) = val(Run); isCell(x); x = cdr(x)) {         if (isNeg(caar(x))) {            if ((n = (int)unDig(cadar(x)) / 2) < t)               tp = &tv,  t = n;         }         else if (inReady(n = (int)unDig(caar(x)) / 2))            tp = &tv,  t = 0;         else {            FD_SET(n, &rdSet);            if (n > m)               m = n;         }      }      if (Spkr) {         FD_SET(Spkr, &rdSet);         if (Spkr > m)            m = Spkr;      }      for (i = 0; i < Children; ++i) {         if (Child[i].pid) {            FD_SET(Child[i].hear, &rdSet);            if (Child[i].hear > m)               m = Child[i].hear;            if (Child[i].cnt) {               FD_SET(Child[i].tell, &wrSet);               if (Child[i].tell > m)                  m = Child[i].tell;            }         }      }      if (tp) {         tv.tv_sec = t / 1000;         tv.tv_usec = t % 1000 * 1000;#ifndef __linux__         gettimeofday(&tt,NULL);         t = tt.tv_sec*1000 + tt.tv_usec/1000;#endif      }      while (select(m+1, &rdSet, &wrSet, NULL, tp) < 0) {         if (errno != EINTR) {            val(Run) = Nil;            err(ex, NULL, "Select error: %s", strerror(errno));         }         if (Signal)            sighandler(ex);      }      if (tp) {#ifdef __linux__         t -= tv.tv_sec*1000 + tv.tv_usec/1000;#else         gettimeofday(&tt,NULL);         t = tt.tv_sec*1000 + tt.tv_usec/1000 - t;#endif         if (ms > 0  &&  (ms -= t) < 0)            ms = 0;      }      for (flg = NO, i = 0; i < Children; ++i) {         if (Child[i].pid) {            if (FD_ISSET(Child[i].hear, &rdSet)) {               static byte *buf;               if (!buf)                  buf = alloc(NULL, PIPE_BUF - sizeof(int));               if (rdBytes(Child[i].hear, (byte*)&n, sizeof(int)) && rdBytes(Child[i].hear, buf, n)) {                  flg = YES;                  for (j = 0; j < Children; ++j)                     if (j != i  &&  Child[j].pid)                        wrChild(j, buf, n);               }               else {                  Child[i].pid = 0;                  close(Child[i].hear),  close(Child[i].tell);                  free(Child[i].buf);                  continue;               }            }            if (FD_ISSET(Child[i].tell, &wrSet)) {               n = *(int*)(Child[i].buf + Child[i].ofs);               if (wrBytes(Child[i].tell, Child[i].buf + Child[i].ofs + sizeof(int), n)) {                  Child[i].ofs += sizeof(int) + n;                  if (2 * Child[i].ofs >= Child[i].cnt) {                     if (Child[i].cnt -= Child[i].ofs) {                        memcpy(Child[i].buf, Child[i].buf + Child[i].ofs, Child[i].cnt);                        Child[i].buf = alloc(Child[i].buf, Child[i].cnt);                     }                     Child[i].ofs = 0;                  }               }               else {                  Child[i].pid = 0;                  close(Child[i].hear),  close(Child[i].tell);                  free(Child[i].buf);               }            }         }      }      if (!flg && Spkr && FD_ISSET(Spkr,&rdSet) && rdBytes(Spkr,(byte*)&m,sizeof(int)) && Child[m].pid)         wrChild(m, TBuf, sizeof(TBuf));      for (x = data(c1); isCell(x); x = cdr(x))         if (isNeg(caar(x))) {            if ((n = (int)(unDig(cadar(x)) / 2 - t)) > 0)               setDig(cadar(x), (long)2*n);            else {               setDig(cadar(x), unDig(caar(x)));               Push(c2,val(At)),  val(At) = caar(x);               prog(cddar(x));               val(At) = Pop(c2);            }         }      if (Hear  &&  (inReady(Hear) || FD_ISSET(Hear, &rdSet))) {         if ((data(c2) = rdHear()) == NULL)            close(Hear),  closeInFile(Hear),  Hear = 0;         else if (data(c2) == T)            Sync = YES;         else {            Save(c2);            evList(data(c2));            drop(c2);         }         FD_SET(Hear, &rdSet);      }      for (x = data(c1); isCell(x); x = cdr(x))         if (!isNeg(caar(x)) &&  (inReady(n = (int)unDig(caar(x))/2) || FD_ISSET(n, &rdSet))) {            Push(c2,val(At)),  val(At) = caar(x);            prog(cdar(x));            val(At) = Pop(c2);            FD_SET(n, &rdSet);         }      if (Signal)         sighandler(ex);   } while (ms  &&  fd >= 0 && !FD_ISSET(fd, &rdSet));   drop(c1);   return ms;}// (wait ['cnt] . prg) -> anyany doWait(any ex) {   any x, y;   long ms;   x = cdr(ex);   ms = isNil(y = EVAL(car(x)))? -1 : xCnt(ex,y);   x = cdr(x);   while (isNil(y = prog(x)))      if (!(ms = waitFd(ex, -1, ms)))         return prog(x);   return y;}// (sync) -> flgany doSync(any ex) {   byte *p;   int n, cnt;   if (!Mic || !Hear)      return Nil;   p = (byte*)&Slot;   cnt = sizeof(int);   do {      if ((n = write(Mic, p, cnt)) < 0) {         if (errno != EINTR)            writeErr("sync");         if (Signal)            sighandler(ex);      }      p += n;   } while (cnt -= n);   Sync = NO;   do      waitFd(ex, Hear, -1);   while (!Sync);   return T;}// (hear 'num|sym) -> anyany doHear(any ex) {   any x;   int fd;   x = cdr(ex),  x = EVAL(car(x));   NeedAtom(ex,x);   if (Hear)      close(Hear),  closeInFile(Hear);   if (isNum(x)) {      fd = (int)xCnt(ex,x);      if (fd >= InFDs || !InFiles[fd])         badFd(ex,x);      Hear = fd;   }   else {      char nm[pathSize(x)];      pathString(x, nm);      while ((fd = open(nm, O_RDONLY)) < 0) {         if (errno != EINTR)            openErr(ex, nm);         if (Signal)            sighandler(ex);      }      initInFile(Hear = fd, strdup(nm));   }   return x;}// (tell 'sym ['any ..]) -> anyany doTell(any x) {   any y;   ptr pbSave, ppSave;   byte buf[PIPE_BUF];   if (!Tell && !Children)      return Nil;   tellBeg(&pbSave, &ppSave, buf);   do      x = cdr(x),  prTell(y = EVAL(car(x)));   while (isCell(cdr(x)));   tellEnd(&pbSave, &ppSave);   return y;}// (poll 'cnt) -> cnt | NILany doPoll(any ex) {   any x;   int fd;   fd_set fdSet;   struct timeval tv;   x = cdr(ex),  x = EVAL(car(x));   if (inReady(fd = (int)xCnt(ex,x)))      return x;   FD_ZERO(&fdSet);   FD_SET(fd, &fdSet);   tv.tv_sec = tv.tv_usec = 0;   while (select(fd+1, &fdSet, NULL, NULL, &tv) < 0)      if (errno != EINTR)         err(ex, NULL, "Poll error: %s", strerror(errno));   return FD_ISSET(fd, &fdSet)? x : Nil;}// (key ['cnt]) -> symany doKey(any ex) {   any x;   int c;   byte buf[2];   fflush(stdout);   setRaw();   x = cdr(ex);   if (!waitFd(ex, STDIN_FILENO, isNil(x = EVAL(car(x)))? -1 : xCnt(ex,x)))      return Nil;   if (!rdBytes(STDIN_FILENO, buf, 1))      return Nil;   if ((c = buf[0]) == 0xFF)      c = TOP;   else if (c & 0x80) {      if ((c & 0x20) == 0) {         if (!rdBytes(STDIN_FILENO, buf, 1))            return Nil;         c = (c & 0x1F) << 6 | buf[0] & 0x3F;      }      else {         if (!rdBytes(STDIN_FILENO, buf, 2))            return Nil;         c = ((c & 0xF) << 6 | buf[0] & 0x3F) << 6 | buf[1] & 0x3F;      }   }   return mkChar(c);}// (peek) -> symany doPeek(any ex __attribute__((unused))) {   if (!Chr)      Env.get();   return Chr<0? Nil : mkChar(Chr);}// (char) -> sym// (char 'cnt) -> sym// (char T) -> sym// (char 'sym) -> cntany doChar(any ex) {   any x = cdr(ex);   if (!isCell(x)) {      if (!Chr)         Env.get();      x = Chr<0? Nil : mkChar(getChar());      Env.get();      return x;   }   if (isNum(x = EVAL(car(x))))      return IsZero(x)? Nil : mkChar(unDig(x) / 2);   if (isSym(x))      return x == T? mkChar(TOP) : boxCnt(symChar(name(x)));   atomError(ex,x);}// (skip ['sym]) -> symany doSkip(any ex) {   any x;   x = cdr(ex),  x = EVAL(car(x));   NeedSym(ex,x);   return skip(symChar(name(x)))<0? Nil : mkChar(Chr);}// (eol) -> flgany doEol(any ex __attribute__((unused))) {   return InFile && Chr=='\n' || Chr<=0? T : Nil;}// (eof ['flg]) -> flgany doEof(any x) {   x = cdr(x);   if (!isNil(EVAL(car(x)))) {      Chr = -1;      return T;   }   if (!Chr)      Env.get();   return Chr < 0? T : Nil;}// (from 'any ..) -> symany doFrom(any ex) {   any x;   int res, i, j, ac = length(x = cdr(ex)), p[ac];   cell c[ac];   char *av[ac];   if (ac == 0)      return Nil;   for (i = 0;;) {      Push(c[i], evSym(x));      av[i] = alloc(NULL, bufSize(data(c[i]))),  bufString(data(c[i]), av[i]);      p[i] = 0;      if (++i == ac)         break;      x = cdr(x);   }   res = -1;   if (!Chr)      Env.get();   while (Chr >= 0) {      for (i = 0; i < ac; ++i) {         for (;;) {            if (av[i][p[i]] == (byte)Chr) {               if (av[i][++p[i]])                  break;               Env.get();               res = i;               goto done;            }            if (!p[i])               break;            for (j = 1; --p[i]; ++j)               if (memcmp(av[i], av[i]+j, p[i]) == 0)                  break;         }      }      Env.get();   }done:   i = 0;  do      free(av[i]);   while (++i < ac);   drop(c[0]);   return res < 0? Nil : data(c[res]);}// (till 'any ['flg]) -> lst|symany doTill(any ex) {   any x;   int i;   cell c1;   x = evSym(cdr(ex));   {      char buf[bufSize(x)];      bufString(x, buf);      if (!Chr)         Env.get();      if (Chr < 0 || strchr(buf,Chr))         return Nil;      x = cddr(ex);      if (isNil(EVAL(car(x)))) {         Push(c1, x = cons(mkChar(getChar()), Nil));         while (Env.get(), Chr > 0 && !strchr(buf,Chr))            x = cdr(x) = cons(mkChar(getChar()), Nil);         return Pop(c1);      }      Push(c1, boxChar(getChar(), &i, &x));      while (Env.get(), Chr > 0 && !strchr(buf,Chr))         charSym(getChar(), &i, &x);      return consStr(Pop(c1));   }}static inline bool eol(void) {   if (Chr < 0)      return YES;   if (Chr == '\n') {      Chr = 0;      return YES;   }   if (Chr == '\r') {      Env.get();      if (Chr == '\n')         Chr = 0;      return YES;   }   return NO;}// (line 'flg ['cnt ..]) -> lst|symany doLine(any ex) {   any x, y, z;   bool pack;   int i, n;   cell c1;   if (!Chr)      Env.get();   if (eol())      return Nil;   x = cdr(ex);   if (pack = !isNil(EVAL(car(x))))      Push(c1, boxChar(getChar(), &i, &z));   else      Push(c1, cons(mkChar(getChar()), Nil));   if (!isCell(x = cdr(x)))      y = data(c1);   else {      if (!pack)         z = data(c1);      data(c1) = y = cons(data(c1), Nil);      for (;;) {         n = (int)evCnt(ex,x);         while (--n) {            if (Env.get(), eol()) {               if (pack)                  car(y) = consStr(car(y));               return Pop(c1);            }            if (pack)               charSym(getChar(), &i, &z);            else               z = cdr(z) = cons(mkChar(getChar()), Nil);         }         if (pack)            car(y) = consStr(car(y));         if (!isCell(x = cdr(x))) {            pack = NO;            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -