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

📄 flow.c

📁 A very small LISP implementation with several packages and demo programs.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 22dec07abu * (c) Software Lab. Alexander Burger */#include "pico.h"static void redefMsg(any x, any y) {   outFile *oSave = OutFile;   FILE *stdSave = StdOut;   OutFile = NULL,  StdOut = stderr;   outString("# ");   print(x);   if (y)      space(), print(y);   outString(" redefined\n");   OutFile = oSave,  StdOut = stdSave;}static void putSrc(any s, any k) {   if (!isNil(val(Dbg)) && !isExt(s) && InFile && InFile->name) {      any x, y;      cell c1;      Push(c1, boxCnt(InFile->src));      data(c1) = cons(data(c1), mkStr(InFile->name));      if (!k) {         if (isNil(x = get(s, Dbg)))            put(s, Dbg, cons(data(c1), Nil));         else            car(x) = data(c1);      }      else if (isNil(x = get(s, Dbg)))         put(s, Dbg, cons(Nil, cons(data(c1), Nil)));      else {         for (y = cdr(x); isCell(y); y = cdr(y))            if (caar(y) == k) {               cdar(y) = data(c1);               drop(c1);               return;            }         cdr(x) = cons(cons(k, data(c1)), cdr(x));      }      drop(c1);   }}static void redefine(any ex, any s, any x) {   NeedSym(ex,s);   CheckVar(ex,s);   if (!isNil(val(s))  &&  s != val(s)  &&  !equal(x,val(s)))      redefMsg(s, NULL);   val(s) = x;   putSrc(s, NULL);}// (quote . any) -> anyany doQuote(any x) {return cdr(x);}// (as 'any1 . any2) -> any2 | NILany doAs(any x) {   x = cdr(x);   if (isNil(EVAL(car(x))))      return Nil;   return cdr(x);}// (pid 'pid|lst . exe) -> anyany doPid(any x) {   any y;   x = cdr(x);   if (!isCell(y = EVAL(car(x))))      return equal(y, val(Pid))? EVAL(cdr(x)) : Nil;   do      if (equal(car(y), val(Pid)))         return EVAL(cdr(x));   while (isCell(y = cdr(y)));   return Nil;}// (lit 'any) -> anyany doLit(any x) {   x = cadr(x);   if (isNum(x = EVAL(x)) || isSym(x) && x==val(x) || isCell(x) && isNum(car(x)))      return x;   return cons(Quote, x);}// (eval 'any ['cnt]) -> anyany doEval(any x) {   cell c1;   bindFrame *p;   x = cdr(x),  Push(c1, EVAL(car(x))),  x = cdr(x);   if (!isNum(x = EVAL(car(x))) || !(p = Env.bind))      data(c1) = EVAL(data(c1));   else {      int cnt, n, i;      bindFrame *q;      for (cnt = (int)unBox(x), n = 0;;) {         ++n;         if (p->i <= 0) {            if (p->i-- == 0) {               for (i = 0;  i < p->cnt;  ++i) {                  x = val(p->bnd[i].sym);                  val(p->bnd[i].sym) = p->bnd[i].val;                  p->bnd[i].val = x;               }               if (p->cnt  &&  p->bnd[0].sym == At  &&  !--cnt)                  break;            }         }         if (!(q = Env.bind->link))            break;         Env.bind->link = q->link,  q->link = p,  p = q;      }      Env.bind = p;      data(c1) = EVAL(data(c1));      for (;;) {         if (p->i < 0) {            if (++p->i == 0)               for (i = p->cnt;  --i >= 0;) {                  x = val(p->bnd[i].sym);                  val(p->bnd[i].sym) = p->bnd[i].val;                  p->bnd[i].val = x;               }         }         if (!--n)            break;         q = Env.bind->link, Env.bind->link = q->link,  q->link = p,  p = q;      }      Env.bind = p;   }   return Pop(c1);}// (run 'any ['cnt]) -> anyany doRun(any x) {   cell c1;   bindFrame *p;   x = cdr(x),  data(c1) = EVAL(car(x)),  x = cdr(x);   if (!isNum(data(c1))) {      Save(c1);      if (!isNum(x = EVAL(car(x))) || !(p = Env.bind))         data(c1) = isSym(data(c1))? val(data(c1)) : run(data(c1));      else {         int cnt, n, i;         bindFrame *q;         for (cnt = (int)unBox(x), n = 0;;) {            ++n;            if (p->i <= 0) {               if (p->i-- == 0) {                  for (i = 0;  i < p->cnt;  ++i) {                     x = val(p->bnd[i].sym);                     val(p->bnd[i].sym) = p->bnd[i].val;                     p->bnd[i].val = x;                  }                  if (p->cnt  &&  p->bnd[0].sym==At  &&  !--cnt)                     break;               }            }            if (!(q = Env.bind->link))               break;            Env.bind->link = q->link,  q->link = p,  p = q;         }         Env.bind = p;         data(c1) = isSym(data(c1))? val(data(c1)) : prog(data(c1));         for (;;) {            if (p->i < 0) {               if (++p->i == 0)                  for (i = p->cnt;  --i >= 0;) {                     x = val(p->bnd[i].sym);                     val(p->bnd[i].sym) = p->bnd[i].val;                     p->bnd[i].val = x;                  }            }            if (!--n)               break;            q = Env.bind->link, Env.bind->link = q->link,  q->link = p,  p = q;         }         Env.bind = p;      }      drop(c1);   }   return data(c1);}// (def 'sym 'any) -> sym// (def 'sym 'sym 'any) -> symany doDef(any ex) {   any x, y;   cell c1, c2, c3;   x = cdr(ex),  Push(c1, EVAL(car(x)));   NeedSym(ex,data(c1));   CheckVar(ex,data(c1));   x = cdr(x),  Push(c2, EVAL(car(x)));   if (!isCell(cdr(x))) {      if (!equal(data(c2), y = val(data(c1)))) {         if (!isNil(y)  &&  data(c1) != y)            redefMsg(data(c1), NULL);         Touch(ex,data(c1));         val(data(c1)) = data(c2);      }      putSrc(data(c1), NULL);   }   else {      x = cdr(x),  Push(c3, EVAL(car(x)));      if (!equal(data(c3), y = get(data(c1), data(c2)))) {         if (!isNil(y))            redefMsg(data(c1), data(c2));         Touch(ex,data(c1));         put(data(c1), data(c2), data(c3));      }      putSrc(data(c1), data(c2));   }   return Pop(c1);}// (de sym . any) -> symany doDe(any ex) {   redefine(ex, cadr(ex), cddr(ex));   return cadr(ex);}// (dm sym . fun) -> sym// (dm (sym . cls) . fun) -> sym// (dm (sym sym [. cls]) . fun) -> symany doDm(any ex) {   any x, y, msg, cls;   x = cdr(ex);   if (!isCell(car(x)))      msg = car(x),  cls = val(Class);   else {      msg = caar(x);      cls = !isCell(cdar(x))? cdar(x) :         get(isNil(cddar(x))? val(Class) : cddar(x), cadar(x));   }   if (msg != T)      redefine(ex, msg, val(Meth));   if (isSym(cdr(x))) {      y = val(cdr(x));      for (;;) {         if (!isCell(y) || !isCell(car(y)))            err(ex, msg, "Bad message");         if (caar(y) == msg) {            x = car(y);            break;         }         y = cdr(y);      }   }   for (y = val(cls);  isCell(y) && isCell(car(y));  y = cdr(y))      if (caar(y) == msg) {         if (!equal(cdr(x), cdar(y)))            redefMsg(msg, cls);         cdar(y) = cdr(x);         putSrc(cls, msg);         return msg;      }   if (!isCell(car(x)))      val(cls) = cons(x, val(cls));   else      val(cls) = cons(cons(caar(x), cdr(x)), val(cls));   putSrc(cls, msg);   return msg;}/* Evaluate method invocation */static any evMethod(any o, any expr, any x) {   any y = car(expr);   methFrame m;   struct {  // bindFrame      struct bindFrame *link;      int i, cnt;      struct {any sym; any val;} bnd[length(y)+3];   } f;   m.link = Env.meth;   m.key = TheKey;   m.cls = TheCls;   f.link = Env.bind,  Env.bind = (bindFrame*)&f;   f.i = sizeof(f.bnd) / (2*sizeof(any)) - 2;   f.cnt = 1,  f.bnd[0].sym = At,  f.bnd[0].val = val(At);   while (isCell(y)) {      f.bnd[f.cnt].sym = car(y);      f.bnd[f.cnt].val = EVAL(car(x));      ++f.cnt, x = cdr(x), y = cdr(y);   }   if (isNil(y)) {      while (--f.i > 0) {         x = val(f.bnd[f.i].sym);         val(f.bnd[f.i].sym) = f.bnd[f.i].val;         f.bnd[f.i].val = x;      }      f.bnd[f.cnt].sym = This;      f.bnd[f.cnt++].val = val(This);      val(This) = o;      Env.meth = &m;      x = prog(cdr(expr));   }   else if (y != At) {      f.bnd[f.cnt].sym = y,  f.bnd[f.cnt++].val = val(y),  val(y) = x;      while (--f.i > 0) {         x = val(f.bnd[f.i].sym);         val(f.bnd[f.i].sym) = f.bnd[f.i].val;         f.bnd[f.i].val = x;      }      f.bnd[f.cnt].sym = This,  f.bnd[f.cnt++].val = val(This),  val(This) = o;      Env.meth = &m;      x = prog(cdr(expr));   }   else {      int n, cnt;      cell *arg;      cell c[n = cnt = length(x)];      while (--n >= 0)         Push(c[n], EVAL(car(x))),  x = cdr(x);      while (--f.i > 0) {         x = val(f.bnd[f.i].sym);         val(f.bnd[f.i].sym) = f.bnd[f.i].val;         f.bnd[f.i].val = x;      }      n = Env.next,  Env.next = cnt;      arg = Env.arg,  Env.arg = c;      f.bnd[f.cnt].sym = This;      f.bnd[f.cnt++].val = val(This);      val(This) = o;      Env.meth = &m;      x = prog(cdr(expr));      if (cnt)         drop(c[cnt-1]);      Env.arg = arg,  Env.next = n;   }   while (--f.cnt >= 0)      val(f.bnd[f.cnt].sym) = f.bnd[f.cnt].val;   Env.bind = f.link;   Env.meth = Env.meth->link;   return x;}any method(any x) {   any y, z;   if (isCell(y = val(x))) {      if (isCell(car(y))) {         if (caar(y) == TheKey)            return cdar(y);         for (;;) {            z = y;            if (!isCell(y = cdr(y)))               return NULL;            if (!isCell(car(y)))               break;            if (caar(y) == TheKey) {               cdr(z) = cdr(y),  cdr(y) = val(x),  val(x) = y;               return cdar(y);            }         }      }      do         if (x = method(car(TheCls = y)))            return x;      while (isCell(y = cdr(y)));   }   return NULL;}// (box 'any) -> symany doBox(any x) {   x = cdr(x);   return consSym(EVAL(car(x)), Nil);}// (new ['flg|num] ['typ ['any ..]]) -> objany doNew(any ex) {   any x, y, *p;   cell c1, c2;   x = cdr(ex);   Push(c1, consSym(Nil,Nil));   if (isCell(y = EVAL(car(x))))      val(data(c1)) = y;   else {      if (!isNil(y)) {         p = Extern + hash(tail(data(c1)) = newId(isNum(y)? (int)unDig(y)/2 : 1));         mkExt(data(c1));         *p = cons(data(c1),*p);      }      x = cdr(x),  y = EVAL(car(x));      NeedLst(ex,y);      val(data(c1)) = y;   }   TheKey = T,  TheCls = Nil;   if (y = method(data(c1)))      evMethod(data(c1), y, cdr(x));   else {      Push(c2, Nil);      while (isCell(x = cdr(x))) {         data(c2) = EVAL(car(x)),  x = cdr(x);         put(data(c1), data(c2), EVAL(car(x)));      }   }   return Pop(c1);}// (type 'any) -> lstany doType(any ex) {   any x, y, z;   x = cdr(ex),  x = EVAL(car(x));   if (isSym(x)) {      Fetch(ex,x);      z = x = val(x);      while (isCell(x)) {         if (!isCell(car(x))) {            y = x;            while (isSym(car(x))) {               if (!isCell(x = cdr(x)))                  return isNil(x)? y : Nil;               if (z == x)                  return Nil;            }            return Nil;         }         if (z == (x = cdr(x)))            return Nil;      }   }   return Nil;}static bool isa(any ex, any cls, any x) {   any z;   z = x = val(x);   while (isCell(x)) {      if (!isCell(car(x))) {         while (isSym(car(x))) {            if (isExt(car(x)))               return NO;            if (cls == car(x) || isa(ex, cls, car(x)))               return YES;            if (!isCell(x = cdr(x)) || z == x)               return NO;         }         return NO;      }      if (z == (x = cdr(x)))         return NO;   }   return NO;}// (isa 'cls|typ 'any) -> obj | NILany doIsa(any ex) {   any x;   cell c1;   x = cdr(ex),  Push(c1, EVAL(car(x)));   x = cdr(x),  x = EVAL(car(x));   drop(c1);   if (isSym(x)) {      if (isSym(data(c1))) {         Fetch(ex,x);         return isa(ex, data(c1), x)? x : Nil;      }      while (isCell(data(c1))) {         Fetch(ex,x);         if (!isa(ex, car(data(c1)), x))            return Nil;         data(c1) = cdr(data(c1));      }      return x;   }   return Nil;}// (method 'msg 'obj) -> funany doMethod(any ex) {   any x, y;   x = cdr(ex),  y = EVAL(car(x));   x = cdr(x),  x = EVAL(car(x));   NeedSym(ex,x);   Fetch(ex,x);   TheKey = y;   return method(x)? : Nil;}// (meth 'obj ..) -> anyany doMeth(any ex) {   any x, y;   cell c1;   x = cdr(ex),  Push(c1, EVAL(car(x)));   NeedSym(ex,data(c1));   Fetch(ex,data(c1));   for (TheKey = car(ex); ; TheKey = val(TheKey)) {      if (!isSym(TheKey))         err(ex, car(ex), "Bad message");      if (isNum(val(TheKey))) {         TheCls = Nil;         if (y = method(data(c1))) {            x = evMethod(data(c1), y, cdr(x));            drop(c1);            return x;         }         err(ex, TheKey, "Bad message");      }   }}// (send 'msg 'obj ['any ..]) -> anyany doSend(any ex) {   any x, y;   cell c1, c2;   x = cdr(ex),  Push(c1,  EVAL(car(x)));   NeedSym(ex,data(c1));   x = cdr(x),  Push(c2,  EVAL(car(x)));   NeedSym(ex,data(c2));   Fetch(ex,data(c2));   TheKey = data(c1),  TheCls = Nil;   if (y = method(data(c2))) {      x = evMethod(data(c2), y, cdr(x));      drop(c1);      return x;   }   err(ex, TheKey, "Bad message");}// (try 'msg 'obj ['any ..]) -> anyany doTry(any ex) {   any x, y;   cell c1, c2;   x = cdr(ex),  Push(c1,  EVAL(car(x)));   NeedSym(ex,data(c1));   x = cdr(x),  Push(c2,  EVAL(car(x)));   if (isSym(data(c2))) {      if (isExt(data(c2))) {         if (!isLife(data(c2)))            return Nil;         db(ex,data(c2),1);      }      TheKey = data(c1),  TheCls = Nil;      if (y = method(data(c2))) {         x = evMethod(data(c2), y, cdr(x));         drop(c1);         return x;      }

⌨️ 快捷键说明

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