Make bestline collapse one-liners

This commit is contained in:
Justine Tunney 2021-11-29 07:17:57 -08:00
parent 51d469be88
commit 512b1a5b87
2 changed files with 67 additions and 50 deletions

View file

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

85
lisp.c
View file

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