mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Add LISP interpreter
This commit is contained in:
parent
4f98ad1054
commit
d31bebdd2d
84 changed files with 9081 additions and 0 deletions
304
tool/plinko/lib/printf.c
Normal file
304
tool/plinko/lib/printf.c
Normal file
|
@ -0,0 +1,304 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/plinko/lib/char.h"
|
||||
#include "tool/plinko/lib/plinko.h"
|
||||
#include "tool/plinko/lib/print.h"
|
||||
#include "tool/plinko/lib/printf.h"
|
||||
#include "tool/plinko/lib/time.h"
|
||||
|
||||
static inline long GetVarInt(va_list va, signed char t) {
|
||||
if (t <= 0) return va_arg(va, int);
|
||||
return va_arg(va, long);
|
||||
}
|
||||
|
||||
static int PrintStr(int fd, const char *s, int cols) {
|
||||
int n, j, k = 0, i = 0;
|
||||
n = strlen(s);
|
||||
k += PrintIndent(fd, +cols - n);
|
||||
while (i < n) k += PrintChar(fd, s[i++]);
|
||||
k += PrintIndent(fd, -cols - n);
|
||||
return k;
|
||||
}
|
||||
|
||||
int Printf(const char *f, ...) {
|
||||
int n;
|
||||
va_list va;
|
||||
va_start(va, f);
|
||||
n = Vfnprintf(f, va, 1, 0);
|
||||
va_end(va);
|
||||
return n;
|
||||
}
|
||||
|
||||
int Fprintf(int fd, const char *f, ...) {
|
||||
int n;
|
||||
va_list va;
|
||||
va_start(va, f);
|
||||
n = Vfnprintf(f, va, fd, 0);
|
||||
va_end(va);
|
||||
return n;
|
||||
}
|
||||
|
||||
int Fnprintf(int fd, int n, const char *f, ...) {
|
||||
va_list va;
|
||||
va_start(va, f);
|
||||
n = Vfnprintf(f, va, fd, n);
|
||||
va_end(va);
|
||||
return n;
|
||||
}
|
||||
|
||||
int Vfprintf(const char *f, va_list va, int fd) {
|
||||
return Vfnprintf(f, va, fd, 0);
|
||||
}
|
||||
|
||||
int Vfnprintf(const char *f, va_list va, int fd, int n) {
|
||||
enum { kPlain, kEsc, kCsi };
|
||||
static int recursive;
|
||||
dword t, u;
|
||||
const char *s;
|
||||
signed char type;
|
||||
char quot, ansi, gotr, pdot, zero;
|
||||
int b, c, i, x, y, si, prec, cols, sign;
|
||||
gotr = false;
|
||||
t = rdtsc();
|
||||
--g_ftrace;
|
||||
--__strace;
|
||||
++recursive;
|
||||
for (ansi = 0;;) {
|
||||
for (;;) {
|
||||
if (!(c = *f++ & 0377) || c == L'%') break;
|
||||
if (c >= 0300) {
|
||||
for (b = 0200; c & b; b >>= 1) {
|
||||
c ^= b;
|
||||
}
|
||||
while ((*f & 0300) == 0200) {
|
||||
c <<= 6;
|
||||
c |= *f++ & 0177;
|
||||
}
|
||||
}
|
||||
switch (ansi) {
|
||||
case kPlain:
|
||||
if (c == 033) {
|
||||
ansi = kEsc;
|
||||
} else if (c != L'\n' && c != L'\r') {
|
||||
n += GetMonospaceCharacterWidth(c);
|
||||
} else {
|
||||
n = 0;
|
||||
}
|
||||
break;
|
||||
case kEsc:
|
||||
if (c == '[') {
|
||||
ansi = kCsi;
|
||||
} else {
|
||||
ansi = kPlain;
|
||||
}
|
||||
break;
|
||||
case kCsi:
|
||||
if (0x40 <= c && c <= 0x7e) {
|
||||
ansi = kPlain;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unreachable;
|
||||
}
|
||||
EmitFormatByte:
|
||||
PrintChar(fd, c);
|
||||
}
|
||||
if (!c) break;
|
||||
prec = 0;
|
||||
pdot = 0;
|
||||
cols = 0;
|
||||
quot = 0;
|
||||
type = 0;
|
||||
zero = 0;
|
||||
sign = 1;
|
||||
for (;;) {
|
||||
switch ((c = *f++)) {
|
||||
default:
|
||||
goto EmitFormatByte;
|
||||
case L'n':
|
||||
PrintNewline(fd);
|
||||
n = 0;
|
||||
break;
|
||||
case L'l':
|
||||
++type;
|
||||
continue;
|
||||
case L'0':
|
||||
case L'1':
|
||||
case L'2':
|
||||
case L'3':
|
||||
case L'4':
|
||||
case L'5':
|
||||
case L'6':
|
||||
case L'7':
|
||||
case L'8':
|
||||
case L'9':
|
||||
si = pdot ? prec : cols;
|
||||
si *= 10;
|
||||
si += c - '0';
|
||||
goto UpdateCols;
|
||||
case L'*':
|
||||
si = va_arg(va, int);
|
||||
UpdateCols:
|
||||
if (pdot) {
|
||||
prec = si;
|
||||
} else {
|
||||
if (si < 0) {
|
||||
si = -si;
|
||||
sign = -1;
|
||||
} else if (!si) {
|
||||
zero = 1;
|
||||
}
|
||||
cols = si;
|
||||
}
|
||||
continue;
|
||||
case L'-':
|
||||
sign = -1;
|
||||
continue;
|
||||
case L'.':
|
||||
pdot = 1;
|
||||
continue;
|
||||
case L'_':
|
||||
case L',':
|
||||
case L'\'':
|
||||
quot = c;
|
||||
continue;
|
||||
case L'I':
|
||||
if (depth >= 0) {
|
||||
n += PrintDepth(fd, depth);
|
||||
} else {
|
||||
n += PrintIndent(fd, sp * 2);
|
||||
}
|
||||
break;
|
||||
case L'J':
|
||||
if (depth >= 0) {
|
||||
n += PrintDepth(fd, depth - 1);
|
||||
} else {
|
||||
n += PrintIndent(fd, (sp - 1) * 2);
|
||||
}
|
||||
break;
|
||||
case L'V':
|
||||
y = depth >= 0 ? depth : sp;
|
||||
if (y) {
|
||||
n += PrintIndent(fd, (y - 1) * 2);
|
||||
n += PrintChar(fd, L'├');
|
||||
n += PrintChar(fd, L'─');
|
||||
}
|
||||
break;
|
||||
case L'W':
|
||||
y = depth >= 0 ? depth : sp;
|
||||
if (y) {
|
||||
n += PrintIndent(fd, (y - 1) * 2);
|
||||
n += PrintChar(fd, L'│');
|
||||
n += PrintChar(fd, L' ');
|
||||
}
|
||||
break;
|
||||
case L'X':
|
||||
y = depth >= 0 ? depth : sp;
|
||||
if (y) {
|
||||
n += PrintIndent(fd, (y - 1) * 2);
|
||||
n += PrintChar(fd, L'└');
|
||||
n += PrintChar(fd, L'─');
|
||||
}
|
||||
break;
|
||||
case L'p':
|
||||
if (simpler) goto SimplePrint;
|
||||
// fallthrough
|
||||
case L'P':
|
||||
n += PrettyPrint(fd, va_arg(va, int),
|
||||
MAX(0, depth > 0 ? n - depth * 3 : n));
|
||||
break;
|
||||
case L'T':
|
||||
PrintTree(fd, va_arg(va, int), n);
|
||||
break;
|
||||
case L'R':
|
||||
gotr = true;
|
||||
n += PrintInt(fd, ClocksToNanos(tick, t), cols * sign, quot, zero, 10,
|
||||
true);
|
||||
break;
|
||||
case L'S':
|
||||
SimplePrint:
|
||||
n += Print(fd, va_arg(va, int));
|
||||
break;
|
||||
case L'A':
|
||||
y = va_arg(va, int);
|
||||
x = va_arg(va, int);
|
||||
n += PrintChar(fd, L'[');
|
||||
n += PrintArgs(fd, y, x, 0);
|
||||
n += PrintChar(fd, L']');
|
||||
break;
|
||||
case L'K':
|
||||
if ((b = va_arg(va, int)) < 0) {
|
||||
PrintChar(fd, L'(');
|
||||
for (;;) {
|
||||
n += Print(fd, Car(Car(b)));
|
||||
if ((b = Cdr(b)) >= 0) break;
|
||||
PrintChar(fd, L' ');
|
||||
}
|
||||
PrintChar(fd, L')');
|
||||
} else {
|
||||
n += Print(fd, b);
|
||||
}
|
||||
break;
|
||||
case L'd':
|
||||
n += PrintInt(fd, GetVarInt(va, type), cols * sign, quot, zero, 10,
|
||||
true);
|
||||
break;
|
||||
case L'u':
|
||||
n +=
|
||||
PrintInt(fd, GetVarInt(va, type), cols * sign, quot, zero, 10, 0);
|
||||
break;
|
||||
case L'b':
|
||||
n += PrintInt(fd, GetVarInt(va, type), cols * sign, quot, zero, 2, 0);
|
||||
break;
|
||||
case L'o':
|
||||
n += PrintInt(fd, GetVarInt(va, type), cols * sign, quot, zero, 8, 0);
|
||||
break;
|
||||
case L'x':
|
||||
n +=
|
||||
PrintInt(fd, GetVarInt(va, type), cols * sign, quot, zero, 16, 0);
|
||||
break;
|
||||
case L's':
|
||||
s = va_arg(va, const char *);
|
||||
if (!s) s = "NULL";
|
||||
n += PrintStr(fd, s, cols * sign);
|
||||
break;
|
||||
case L'c':
|
||||
n += PrintChar(fd, va_arg(va, int));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
--recursive;
|
||||
++g_ftrace;
|
||||
++__strace;
|
||||
if (!recursive) {
|
||||
u = rdtsc();
|
||||
if (gotr) {
|
||||
tick = u;
|
||||
} else {
|
||||
tick -= u >= t ? u - t : ~t + u + 1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue