From 512b1a5b87a1ce77e1cfc8cfbca66bccedb950d0 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 29 Nov 2021 07:17:57 -0800 Subject: [PATCH] Make bestline collapse one-liners --- bestline.c | 32 ++++++++++++++------ lisp.c | 85 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 67 insertions(+), 50 deletions(-) diff --git a/bestline.c b/bestline.c index 23ffd64..a9a32bd 100644 --- a/bestline.c +++ b/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]) { diff --git a/lisp.c b/lisp.c index 8fe1c11..bc85972 100644 --- a/lisp.c +++ b/lisp.c @@ -19,35 +19,33 @@ #include "bestline.h" #ifndef __COSMOPOLITAN__ -#include #include -#include -#include #include -#include #include #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;