瀏覽代碼

Make bestline collapse one-liners

Justine Tunney 3 年之前
父節點
當前提交
512b1a5b87
共有 2 個文件被更改,包括 67 次插入50 次删除
  1. 23 9
      bestline.c
  2. 44 41
      lisp.c

+ 23 - 9
bestline.c

@@ -1799,7 +1799,6 @@ static int enableRawMode(int fd) {
         raw = orig_termios;
         raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
         raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
-        raw.c_oflag &= ~OPOST;
         raw.c_iflag |= IUTF8;
         raw.c_cflag |= CS8;
         raw.c_cc[VMIN] = 1;
@@ -2464,6 +2463,7 @@ static void bestlineRefreshLineForce(struct bestlineState *l) {
 static void bestlineEditInsert(struct bestlineState *l,
                                const char *p, size_t n) {
     if (!bestlineGrow(l, l->len + n + 1)) return;
+    if (*p == ' ' && l->pos && l->buf[l->pos - 1] == ' ') return;
     memmove(l->buf + l->pos + n, l->buf + l->pos, l->len - l->pos);
     memcpy(l->buf + l->pos, p, n);
     l->pos += n;
@@ -3010,6 +3010,16 @@ static void bestlineEditSlurp(struct bestlineState *l) {
 }
 
 static void bestlineEditRaise(struct bestlineState *l) {
+    (void)l;
+}
+
+static char IsBalanced(struct bestlineState *l) {
+    int i, d;
+    for (d = i = 0; i < l->len; ++i) {
+        if (l->buf[i] == '(') ++d;
+        if (l->buf[i] == ')') --d;
+    }
+    return d <= 0;
 }
 
 /**
@@ -3112,14 +3122,18 @@ static ssize_t bestlineEdit(int stdin_fd, int stdout_fd, const char *prompt,
             }
             break;
         case '\r':
-            l.final = 1;
-            free(history[--historylen]);
-            history[historylen] = 0;
-            bestlineEditEnd(&l);
-            bestlineRefreshLineForce(&l);
-            if ((p = (char *)realloc(l.buf, l.len + 1))) l.buf = p;
-            *obuf = l.buf;
-            return l.len;
+            if (IsBalanced(&l)) {
+                l.final = 1;
+                free(history[--historylen]);
+                history[historylen] = 0;
+                bestlineEditEnd(&l);
+                bestlineRefreshLineForce(&l);
+                if ((p = (char *)realloc(l.buf, l.len + 1))) l.buf = p;
+                *obuf = l.buf;
+                return l.len;
+            } else {
+                break;
+            }
         case 033:
             if (nread < 2) break;
             switch (seq[1]) {

+ 44 - 41
lisp.c

@@ -19,35 +19,33 @@
 #include "bestline.h"
 
 #ifndef __COSMOPOLITAN__
-#include <ctype.h>
 #include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include <locale.h>
-#include <limits.h>
 #include <setjmp.h>
 #endif
 
+#define var int
+#define function
 #define Null 0100000
 
+var M[Null * 2];
 jmp_buf undefined;
-int cx, dx, M[Null * 2];
-int kT, kEq, kCar, kCdr, kCond, kAtom, kCons, kQuote;
-char *line = "NIL T CAR CDR ATOM COND CONS QUOTE EQ ";
 
-Set(i, x) {
+var cx, dx, kT, kEq, kCar, kCdr, kCond, kAtom, kCons, kQuote;
+
+function Set(i, x) {
   M[Null + i] = x;
 }
 
-Get(i) {
+function Get(i) {
   return M[Null + i];
 }
 
-Hash(h, c) {
+function Hash(h, c) {
   return h + c * 2;
 }
 
-Intern(x, y, i) {
+function Intern(x, y, i) {
   i &= Null - 1;
   if (x == Get(i) && y == Get(i + 1)) return i;
   if (Get(i)) return Intern(x, y, i + 2);
@@ -56,35 +54,35 @@ Intern(x, y, i) {
   return i;
 }
 
-ReadAtom(h) {
-  int c = ReadChar();
+function ReadAtom(h) {
+  var c = ReadChar();
   if (c <= 32) return ReadAtom(h);
   return Intern(c, c > 41 && dx > 41 ?
                 ReadAtom(Hash(h, c)) : 0,
                 Hash(h, c) - Hash(0, 78));
 }
 
-PrintAtom(x) {
+function PrintAtom(x) {
   do PrintChar(Get(x));
   while ((x = Get(x + 1)));
 }
 
-AddList(x) {
+function AddList(x) {
   return Cons(x, ReadList());
 }
 
-ReadList() {
-  int t = ReadAtom(0);
+function ReadList() {
+  var t = ReadAtom(0);
   if (Get(t) == 41) return 0;
   return AddList(ReadObject(t));
 }
 
-ReadObject(t) {
+function ReadObject(t) {
   if (Get(t) != 40) return t;
   return ReadList();
 }
 
-PrintList(x) {
+function PrintList(x) {
   PrintChar(40);
   if (x < 0) {
     PrintObject(Car(x));
@@ -102,7 +100,7 @@ PrintList(x) {
   PrintChar(41);
 }
 
-PrintObject(x) {
+function PrintObject(x) {
   if (1./x < 0) {
     PrintList(x);
   } else {
@@ -110,77 +108,77 @@ PrintObject(x) {
   }
 }
 
-Print(e) {
+function Print(e) {
   PrintObject(e);
   PrintChar(10);
 }
 
-Read() {
+function Read() {
   return ReadObject(ReadAtom(0));
 }
 
-Car(x) {
+function Car(x) {
   if (x < 0) {
     return Get(x);
   } else {
-    longjmp(undefined, x);
+    Throw(x);
   }
 }
 
-Cdr(x) {
+function Cdr(x) {
   if (x < 0) {
     return Get(x + 1);
   } else {
-    longjmp(undefined, x);
+    Throw(x);
   }
 }
 
-Cons(car, cdr) {
+function Cons(car, cdr) {
   Set(--cx, cdr);
   Set(--cx, car);
   return cx;
 }
 
-Gc(A, x) {
-  int C, B = cx;
+function Gc(A, x) {
+  var C, B = cx;
   x = Copy(x, A, A - B), C = cx;
   while (C < B) Set(--A, Get(--B));
   cx = A;
   return x;
 }
 
-Copy(x, m, k) {
+function Copy(x, m, k) {
   return x < m ? Cons(Copy(Car(x), m, k),
                       Copy(Cdr(x), m, k)) + k : x;
 }
 
-Evlis(m, a) {
+function Evlis(m, a) {
   return m ? Cons(Eval(Car(m), a),
                   Evlis(Cdr(m), a)) : 0;
 }
 
-Pairlis(x, y, a) {
+function Pairlis(x, y, a) {
   return x ? Cons(Cons(Car(x), Car(y)),
                   Pairlis(Cdr(x), Cdr(y), a)) : a;
 }
 
-Assoc(x, y) {
-  if (y >= 0) longjmp(undefined, x);
+function Assoc(x, y) {
+  if (y >= 0) Throw(x);
   if (x == Car(Car(y))) return Cdr(Car(y));
   return Assoc(x, Cdr(y));
 }
 
-Evcon(c, a) {
+function Evcon(c, a) {
   if (Eval(Car(Car(c)), a)) {
     return Eval(Car(Cdr(Car(c))), a);
   } else if (Cdr(c)) {
     return Evcon(Cdr(c), a);
   } else {
-    longjmp(undefined, c);
+    Throw(c);
   }
 }
 
-Apply(f, x, a) {
+function Apply(f, x, a) {
   if (f < 0)      return Eval(Car(Cdr(Cdr(f))), Pairlis(Car(Cdr(f)), x, a));
   if (f == kEq)   return Car(x) == Car(Cdr(x)) ? kT : 0;
   if (f == kCons) return Cons(Car(x), Car(Cdr(x)));
@@ -190,8 +188,8 @@ Apply(f, x, a) {
   return Apply(Assoc(f, a), x, a);
 }
 
-Eval(e, a) {
-  int A = cx;
+function Eval(e, a) {
+  var A = cx;
   if (!e) return 0;
   if (e > 0) return Assoc(e, a);
   if (Car(e) == kQuote) return Car(Cdr(e));
@@ -203,8 +201,8 @@ Eval(e, a) {
   return Gc(A, e);
 }
 
-Lisp() {
-  int x, a;
+function Lisp() {
+  var x, a;
   ReadAtom(0);
   kT = ReadAtom(0);
   kCar = ReadAtom(0);
@@ -228,6 +226,10 @@ Lisp() {
   }
 }
 
+Throw(x) {
+  longjmp(undefined, x);
+}
+
 PrintChar(b) {
   fputwc(b, stdout);
 }
@@ -235,6 +237,7 @@ PrintChar(b) {
 ReadChar() {
   int b, c, t;
   static char *freeme;
+  static char *line = "NIL T CAR CDR ATOM COND CONS QUOTE EQ ";
   if (line || (line = freeme = bestlineWithHistory("* ", "sectorlisp"))) {
     if (*line) {
       c = *line++ & 0377;