mirror of
https://github.com/samsonjs/sectorlisp.git
synced 2026-03-25 09:05:48 +00:00
Make bestline collapse one-liners
This commit is contained in:
parent
51d469be88
commit
512b1a5b87
2 changed files with 67 additions and 50 deletions
32
bestline.c
32
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]) {
|
||||
|
|
|
|||
85
lisp.c
85
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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue