added globals *install-dir* and *print-width*, parameterized
prettyprinter by screen width decent accumulate-while and accumulate-for
This commit is contained in:
parent
6f934a817b
commit
c8c59b1dfc
|
@ -254,21 +254,13 @@ static double value_to_double(value_t a, char *fname)
|
|||
type_error(fname, "number", a);
|
||||
}
|
||||
|
||||
static value_t return_from_cstr(char *str)
|
||||
{
|
||||
size_t n = strlen(str);
|
||||
value_t v = cvalue_string(n);
|
||||
memcpy(cvalue_data(v), str, n);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_t fl_time_string(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("time.string", nargs, 1);
|
||||
double t = value_to_double(args[0], "time.string");
|
||||
char buf[64];
|
||||
timestring(t, buf, sizeof(buf));
|
||||
return return_from_cstr(buf);
|
||||
return string_from_cstr(buf);
|
||||
}
|
||||
|
||||
value_t fl_path_cwd(value_t *args, uint32_t nargs)
|
||||
|
@ -278,7 +270,7 @@ value_t fl_path_cwd(value_t *args, uint32_t nargs)
|
|||
if (nargs == 0) {
|
||||
char buf[1024];
|
||||
get_cwd(buf, sizeof(buf));
|
||||
return return_from_cstr(buf);
|
||||
return string_from_cstr(buf);
|
||||
}
|
||||
char *ptr = tostring(args[0], "path.cwd");
|
||||
if (set_cwd(ptr))
|
||||
|
@ -294,7 +286,7 @@ value_t fl_os_getenv(value_t *args, uint32_t nargs)
|
|||
if (val == NULL) return NIL;
|
||||
if (*val == 0)
|
||||
return symbol_value(emptystringsym);
|
||||
return cvalue_pinned_cstring(val);
|
||||
return cvalue_static_cstring(val);
|
||||
}
|
||||
|
||||
value_t fl_os_setenv(value_t *args, uint32_t nargs)
|
||||
|
|
|
@ -176,7 +176,7 @@ value_t cvalue_string(size_t sz)
|
|||
return cv;
|
||||
}
|
||||
|
||||
value_t cvalue_pinned_cstring(char *str)
|
||||
value_t cvalue_static_cstring(char *str)
|
||||
{
|
||||
value_t v = cvalue_from_ref(symbol_value(stringtypesym), str, strlen(str),
|
||||
NIL);
|
||||
|
@ -184,6 +184,14 @@ value_t cvalue_pinned_cstring(char *str)
|
|||
return v;
|
||||
}
|
||||
|
||||
value_t string_from_cstr(char *str)
|
||||
{
|
||||
size_t n = strlen(str);
|
||||
value_t v = cvalue_string(n);
|
||||
memcpy(cvalue_data(v), str, n);
|
||||
return v;
|
||||
}
|
||||
|
||||
int isstring(value_t v)
|
||||
{
|
||||
return (iscvalue(v) && ((cvalue_t*)ptr(v))->flags.cstring);
|
||||
|
@ -956,7 +964,7 @@ void cvalues_init()
|
|||
setc(wcstringtypesym, list2(arraysym, wcharsym));
|
||||
|
||||
emptystringsym = symbol("*empty-string*");
|
||||
setc(emptystringsym, cvalue_pinned_cstring(""));
|
||||
setc(emptystringsym, cvalue_static_cstring(""));
|
||||
}
|
||||
|
||||
#define RETURN_NUM_AS(var, type) return(mk_##type((type##_t)var))
|
||||
|
|
|
@ -80,6 +80,7 @@ value_t IOError, ParseError, TypeError, ArgError, UnboundError, MemoryError;
|
|||
value_t DivideError, BoundsError, Error;
|
||||
value_t conssym, symbolsym, fixnumsym, vectorsym, builtinsym;
|
||||
value_t defunsym, defmacrosym, forsym, labelsym, printprettysym;
|
||||
value_t printwidthsym;
|
||||
|
||||
static value_t eval_sexpr(value_t e, uint32_t penv, int tail);
|
||||
static value_t *alloc_words(int n);
|
||||
|
@ -826,14 +827,15 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
break;
|
||||
case F_PROGN:
|
||||
// return last arg
|
||||
pv = &Stack[saveSP]; v = NIL;
|
||||
pv = &Stack[saveSP];
|
||||
if (iscons(*pv)) {
|
||||
while (iscons(cdr_(*pv))) {
|
||||
v = eval(car_(*pv));
|
||||
(void)eval(car_(*pv));
|
||||
*pv = cdr_(*pv);
|
||||
}
|
||||
tail_eval(car_(*pv));
|
||||
}
|
||||
v = NIL;
|
||||
break;
|
||||
case F_TRYCATCH:
|
||||
v = do_trycatch(car(Stack[saveSP]), penv);
|
||||
|
@ -1124,7 +1126,6 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
if (selfevaluating(e)) { SP=saveSP; return e; }
|
||||
SP = penv+2;
|
||||
goto eval_top;
|
||||
break;
|
||||
case F_RAISE:
|
||||
argcount("raise", nargs, 1);
|
||||
raise(Stack[SP-1]);
|
||||
|
@ -1307,6 +1308,8 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
|||
extern void builtins_init();
|
||||
extern void comparehash_init();
|
||||
|
||||
static char *EXEDIR;
|
||||
|
||||
void lisp_init(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -1349,6 +1352,7 @@ void lisp_init(void)
|
|||
forsym = symbol("for");
|
||||
labelsym = symbol("label");
|
||||
set(printprettysym=symbol("*print-pretty*"), T);
|
||||
set(printwidthsym=symbol("*print-width*"), fixnum(SCR_WIDTH));
|
||||
lasterror = NIL;
|
||||
lerrorbuf[0] = '\0';
|
||||
special_apply_form = fl_cons(builtin(F_SPECIAL_APPLY), NIL);
|
||||
|
@ -1374,6 +1378,15 @@ void lisp_init(void)
|
|||
|
||||
cvalues_init();
|
||||
set(symbol("gensym"), guestfunc(gensym));
|
||||
|
||||
char buf[1024];
|
||||
char *exename = get_exename(buf, sizeof(buf));
|
||||
if (exename != NULL) {
|
||||
path_to_dirname(exename);
|
||||
EXEDIR = strdup(exename);
|
||||
setc(symbol("*install-dir*"), cvalue_static_cstring(EXEDIR));
|
||||
}
|
||||
|
||||
builtins_init();
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1475,7 @@ static value_t argv_list(int argc, char *argv[])
|
|||
PUSH(NIL);
|
||||
if (argc > 1) { argc--; argv++; }
|
||||
for(i=argc-1; i >= 0; i--)
|
||||
Stack[SP-1] = fl_cons(cvalue_pinned_cstring(argv[i]), Stack[SP-1]);
|
||||
Stack[SP-1] = fl_cons(cvalue_static_cstring(argv[i]), Stack[SP-1]);
|
||||
return POP();
|
||||
}
|
||||
|
||||
|
@ -1482,11 +1495,11 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
FL_CATCH {
|
||||
print_toplevel_exception();
|
||||
|
||||
lerrorbuf[0] = '\0';
|
||||
lasterror = NIL;
|
||||
ios_puts("\n\n", ios_stderr);
|
||||
goto repl;
|
||||
if (argc > 1) return 1;
|
||||
else goto repl;
|
||||
}
|
||||
load_file("system.lsp");
|
||||
if (argc > 1) { load_file(argv[1]); return 0; }
|
||||
|
|
|
@ -249,7 +249,8 @@ size_t cvalue_arraylen(value_t v);
|
|||
value_t size_wrap(size_t sz);
|
||||
size_t toulong(value_t n, char *fname);
|
||||
value_t cvalue_string(size_t sz);
|
||||
value_t cvalue_pinned_cstring(char *str);
|
||||
value_t cvalue_static_cstring(char *str);
|
||||
value_t string_from_cstr(char *str);
|
||||
int isstring(value_t v);
|
||||
int isnumber(value_t v);
|
||||
value_t cvalue_compare(value_t a, value_t b);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
static ptrhash_t printconses;
|
||||
static u_int32_t printlabel;
|
||||
static int print_pretty;
|
||||
static int SCR_WIDTH = 80;
|
||||
static int R_MARGIN, C_MARGIN, R_EDGE, L_PAD, R_PAD;
|
||||
|
||||
static int HPOS, VPOS;
|
||||
static void outc(char c, ios_t *f)
|
||||
|
@ -250,15 +252,15 @@ static void print_pair(ios_t *f, value_t v, int princ)
|
|||
est = lengthestimate(car_(cd));
|
||||
nextsmall = smallp(car_(cd));
|
||||
ind = (((n > 0) &&
|
||||
((!nextsmall && HPOS>28) || (VPOS > lastv))) ||
|
||||
((!nextsmall && HPOS>L_PAD) || (VPOS > lastv))) ||
|
||||
|
||||
((VPOS > lastv) && (!nextsmall || n==0)) ||
|
||||
|
||||
(HPOS > 50 && !nextsmall) ||
|
||||
(HPOS > R_PAD && !nextsmall) ||
|
||||
|
||||
(HPOS > 74) ||
|
||||
(HPOS > R_MARGIN) ||
|
||||
|
||||
(est!=-1 && (HPOS+est > 78)) ||
|
||||
(est!=-1 && (HPOS+est > R_EDGE)) ||
|
||||
|
||||
((head == LAMBDA || head == labelsym) && !nextsmall) ||
|
||||
|
||||
|
@ -341,8 +343,9 @@ static void do_print(ios_t *f, value_t v, int princ)
|
|||
}
|
||||
else {
|
||||
est = lengthestimate(vector_elt(v,i+1));
|
||||
if (HPOS > 74 || (est!=-1 && (HPOS+est > 78)) ||
|
||||
(HPOS > 40 && !smallp(vector_elt(v,i+1))))
|
||||
if (HPOS > R_MARGIN ||
|
||||
(est!=-1 && (HPOS+est > R_EDGE)) ||
|
||||
(HPOS > C_MARGIN && !smallp(vector_elt(v,i+1))))
|
||||
outindent(newindent, f);
|
||||
else
|
||||
outc(' ', f);
|
||||
|
@ -580,12 +583,28 @@ void cvalue_print(ios_t *f, value_t v, int princ)
|
|||
cvalue_printdata(f, data, cv_len(cv), cv_type(cv), princ, 0);
|
||||
}
|
||||
|
||||
static void set_print_width()
|
||||
{
|
||||
value_t pw = symbol_value(printwidthsym);
|
||||
if (!isfixnum(pw)) return;
|
||||
SCR_WIDTH = numval(pw);
|
||||
R_MARGIN = SCR_WIDTH-6;
|
||||
R_EDGE = SCR_WIDTH-2;
|
||||
C_MARGIN = SCR_WIDTH/2;
|
||||
L_PAD = (SCR_WIDTH*7)/20;
|
||||
R_PAD = L_PAD*2;
|
||||
}
|
||||
|
||||
void print(ios_t *f, value_t v, int princ)
|
||||
{
|
||||
print_pretty = (symbol_value(printprettysym) != NIL);
|
||||
ptrhash_reset(&printconses, 32);
|
||||
if (print_pretty)
|
||||
set_print_width();
|
||||
printlabel = 0;
|
||||
print_traverse(v);
|
||||
HPOS = VPOS = 0;
|
||||
|
||||
do_print(f, v, princ);
|
||||
|
||||
ptrhash_reset(&printconses, 32);
|
||||
}
|
||||
|
|
|
@ -205,27 +205,41 @@
|
|||
;(tt)
|
||||
;(tt)
|
||||
|
||||
(defmacro delay (expr)
|
||||
(let ((g (gensym)))
|
||||
(let ((g (gensym)))
|
||||
(defmacro delay (expr)
|
||||
`(let ((,g ',g))
|
||||
(lambda () (if (eq ,g ',g) (setq ,g ,expr) ,g)))))
|
||||
|
||||
(defun force (p) (p))
|
||||
|
||||
(defmacro accumulate-while (cnd what . body)
|
||||
(let ((first (gensym))
|
||||
(acc (gensym))
|
||||
(forms (f-body body)))
|
||||
`(let ((,first (prog1 (cons ,what nil) ,forms))
|
||||
(,acc nil))
|
||||
(setq ,acc ,first)
|
||||
(acc (gensym)))
|
||||
`(let ((,first nil)
|
||||
(,acc (list nil)))
|
||||
(setq ,first ,acc)
|
||||
(while ,cnd
|
||||
(progn (rplacd ,acc (cons ,what nil))
|
||||
(setq ,acc (cdr ,acc))
|
||||
,forms))
|
||||
,first)))
|
||||
(progn (setq ,acc
|
||||
(cdr (rplacd ,acc (cons ,what nil))))
|
||||
,@body))
|
||||
(cdr ,first))))
|
||||
|
||||
(defmacro accumulate-for (var lo hi what . body)
|
||||
(let ((first (gensym))
|
||||
(acc (gensym)))
|
||||
`(let ((,first nil)
|
||||
(,acc (list nil)))
|
||||
(setq ,first ,acc)
|
||||
(for ,lo ,hi
|
||||
(lambda (,var)
|
||||
(progn (setq ,acc
|
||||
(cdr (rplacd ,acc (cons ,what nil))))
|
||||
,@body)))
|
||||
(cdr ,first))))
|
||||
|
||||
(defun map-indexed (f lst)
|
||||
(if (atom lst) lst
|
||||
(let ((i 0))
|
||||
(accumulate-while (consp lst) (f (car lst) i)
|
||||
(setq lst (cdr lst))
|
||||
(setq i (1+ i))))))
|
||||
(progn (setq lst (cdr lst))
|
||||
(setq i (1+ i)))))))
|
||||
|
|
|
@ -778,11 +778,12 @@ identical to
|
|||
|
||||
design of new toplevel
|
||||
|
||||
system.lsp is compiled into the executable, and contains definitions of
|
||||
(load) and (repl).
|
||||
system.lsp contains definitions of (load) and (toplevel) and is loaded
|
||||
from *install-dir* by a bootstrap loader in C. at the end of system.lsp,
|
||||
we check whether (load) is builtin. if it is, we redefine it and reload
|
||||
system.lsp with the new loader. the C code then invokes (toplevel).
|
||||
|
||||
start with load bound to bootstrap_load (in C)
|
||||
on startup we call load on system, then call it again afterwards
|
||||
(toplevel) either runs a script or a repl using (while T (trycatch ...))
|
||||
|
||||
(load) reads and evaluates every form, keeping track of defined functions
|
||||
and macros (at the top level), and grabs a (main ...) form if it sees
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#endif
|
||||
|
||||
#include "dtypes.h"
|
||||
#include "dirpath.h"
|
||||
|
||||
void get_cwd(char *buf, size_t size)
|
||||
{
|
||||
|
@ -46,6 +47,18 @@ int set_cwd(char *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// destructively convert path to directory part
|
||||
void path_to_dirname(char *path)
|
||||
{
|
||||
char *sep = strrchr(path, PATHSEP);
|
||||
if (sep != NULL) {
|
||||
*sep = '\0';
|
||||
}
|
||||
else {
|
||||
path[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LINUX
|
||||
char *get_exename(char *buf, size_t size)
|
||||
{
|
||||
|
|
|
@ -19,5 +19,6 @@
|
|||
void get_cwd(char *buf, size_t size);
|
||||
int set_cwd(char *buf);
|
||||
char *get_exename(char *buf, size_t size);
|
||||
void path_to_dirname(char *path);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue