symbol-def #1
|
@ -13,11 +13,13 @@ Returns t if tst is true for every item in lst, or nil on the first false item."
|
|||
"(load filename)
|
||||
Open the Lisp file on the SD card and load the contents into the workspace."
|
||||
(with-sd-card (str filename)
|
||||
(let ((lst nil))
|
||||
(loop
|
||||
(let ((form (read str)))
|
||||
(unless form (return))
|
||||
(print (second form))
|
||||
(eval form)))))
|
||||
(setf lst (cons (quote (second form)) lst))
|
||||
(eval form)))
|
||||
(reverse lst))))
|
||||
|
||||
(defun rgb (r g b)
|
||||
"(rgb r g b)
|
||||
|
@ -172,33 +174,66 @@ Returns a list with all items for which tst is true removed from lst."
|
|||
Returns a list with all items for which tst is false removed from lst."
|
||||
(mapcan #'(lambda (x) (when (funcall tst x) (list x))) lst))
|
||||
|
||||
(defvar *rtc-port* 1)
|
||||
|
||||
(defun rtc-set (hr min)
|
||||
"(rtc-set hr min)
|
||||
Set the time on a DS3231 RTC. Times are in BCD, so use
|
||||
the appropriate reader macro, e.g. (rtc-set #x12 #x34)
|
||||
for 12:34. Assumes seconds are zero."
|
||||
(with-i2c (str *rtc-port* #x68)
|
||||
(write-byte 0 str)
|
||||
(write-byte 0 str)
|
||||
(write-byte min str)
|
||||
(write-byte hr str)))
|
||||
(defvar *packages* nil)
|
||||
|
||||
(defun rtc-get ()
|
||||
(with-i2c (str *rtc-port* #x68)
|
||||
(write-byte 0 str)
|
||||
(restart-i2c str 3)
|
||||
(reverse
|
||||
(list
|
||||
(read-byte str)
|
||||
(read-byte str)
|
||||
(read-byte str)))))
|
||||
(defun load-package (filename )
|
||||
(let* ((filename (concatenate 'string filename ".pkg"))
|
||||
(forms (load filename)))
|
||||
(setf *packages*
|
||||
|
||||
(defun rtc-now ()
|
||||
"(rtc-now)
|
||||
Set the time using the RTC."
|
||||
(now (rtc-get)))
|
||||
(defun save-package (filename lst)
|
||||
(with-sd-card (str filename 2)
|
||||
(dolist (f lst)
|
||||
(symbol-def f str))))
|
||||
|
||||
(defun add-to-package (filename list)
|
||||
(with-sd-card (str filename 1)
|
||||
(dolist (f lst)
|
||||
(symbol-def f str))))
|
||||
|
||||
(defun %edit (fun)
|
||||
(cond
|
||||
((null *cmds*) fun)
|
||||
((eq (car *cmds*) #\b) (pop *cmds*) fun)
|
||||
((eq (car *cmds*) #\e) (pop *cmds*) (%edit (list fun)))
|
||||
((eq (car *cmds*) #\h) (pop *cmds*) (%edit (cons 'highlight (list fun))))
|
||||
((consp (car *cmds*))
|
||||
(let ((val (cdar *cmds*)))
|
||||
(case (caar *cmds*)
|
||||
(#\r (pop *cmds*) (%edit val))
|
||||
((#\c #\i) (pop *cmds*) (%edit (cons val fun)))
|
||||
(#\f (cond
|
||||
((null fun) nil)
|
||||
((equal val fun) (pop *cmds*) (%edit fun))
|
||||
((atom fun) fun)
|
||||
(t (cons (%edit (car fun)) (%edit (cdr fun)))))))))
|
||||
((atom fun) (pop *cmds*) (%edit fun))
|
||||
((eq (car *cmds*) #\d) (pop *cmds*) (%edit (cons (car fun) (%edit (cdr fun)))))
|
||||
((eq (car *cmds*) #\a) (pop *cmds*) (%edit (cons (%edit (car fun)) (cdr fun))))
|
||||
((eq (car *cmds*) #\x) (pop *cmds*) (%edit (cdr fun)))
|
||||
(t fun)))
|
||||
|
||||
(defun edit (name)
|
||||
(let ((fun (eval name))
|
||||
cc)
|
||||
(setq *cmds* nil)
|
||||
(loop
|
||||
(write-byte 12)
|
||||
(setq cc (append cc (list #\h)))
|
||||
(setq *cmds* cc)
|
||||
(pprint (%edit fun))
|
||||
(setq cc (butlast cc))
|
||||
(let ((c (get-key)))
|
||||
(case c
|
||||
(#\q (set name fun) (return name))
|
||||
(#\s (setq *cmds* cc) (set name (%edit fun)) (return name))
|
||||
(#\z (when cc (setq cc (butlast cc))))
|
||||
((#\r #\c #\i #\f #\e)
|
||||
(write-byte 11) (princ c) (princ #\:)
|
||||
(setq cc (append cc (list (cons c (read))))))
|
||||
((#\d #\a #\x #\b)
|
||||
(setq cc (append cc (list c))))
|
||||
(t (write-byte 7)))))))
|
||||
|
||||
)lisplibrary";
|
||||
|
||||
|
|
|
@ -49,6 +49,87 @@ fn_now(object *args, object *env)
|
|||
return cons(hours, cons(minutes, cons(seconds, NULL)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hyperprint(object *form, int lm, pfun_t pfun)
|
||||
{
|
||||
if (atom(form)) {
|
||||
if (isbuiltin(form, NOTHING)) {
|
||||
printsymbol(form, pfun);
|
||||
} else {
|
||||
printobject(form, pfun);
|
||||
}
|
||||
} else if (quoted(form)) {
|
||||
pfun('\'');
|
||||
hyperprint(car(cdr(form)), lm + 1, pfun);
|
||||
} else {
|
||||
lm = lm + PPINDENT;
|
||||
bool fits = (subwidth(form, PPWIDTH - lm - PPINDENT) >= 0);
|
||||
int special = 0, extra = 0; bool separate = true;
|
||||
object *arg = car(form);
|
||||
|
||||
if (symbolp(arg) && builtinp(arg->name)) {
|
||||
uint8_t minmax = getminmax(builtin(arg->name));
|
||||
if (minmax == 0327 || minmax == 0313) {
|
||||
special = 2; // defun, setq, setf, defvar
|
||||
} else if (minmax == 0317 || minmax == 0017 ||
|
||||
minmax == 0117 || minmax == 0123) {
|
||||
special = 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (form != NULL) {
|
||||
if (atom(form)) {
|
||||
pfstring(PSTR(" . "), pfun);
|
||||
printobject(form, pfun);
|
||||
pfun(')');
|
||||
return;
|
||||
} else if (separate) {
|
||||
pfun('(');
|
||||
separate = false;
|
||||
} else if (special) {
|
||||
pfun(' ');
|
||||
special--;
|
||||
} else if (fits) {
|
||||
pfun(' ');
|
||||
} else {
|
||||
pln(pfun);
|
||||
indent(lm, ' ', pfun);
|
||||
}
|
||||
|
||||
hyperprint(car(form), lm+extra, pfun);
|
||||
form = cdr(form);
|
||||
}
|
||||
pfun(')');
|
||||
}
|
||||
}
|
||||
|
||||
object *
|
||||
fn_sym_def(object *args, object *env)
|
||||
{
|
||||
(void) env;
|
||||
|
||||
object *obj = first(args);
|
||||
pfun_t pfun = pstreamfun(cdr(args));
|
||||
#if defined(gfxsupport)
|
||||
if (pfun == gfxwrite) ppwidth = GFXPPWIDTH;
|
||||
#endif
|
||||
object *pair = findvalue(obj, env);
|
||||
object *var = car(pair);
|
||||
object *val = cdr(pair);
|
||||
pln(pfun);
|
||||
|
||||
if (consp(val) && symbolp(car(val)) && builtin(car(val)->name) == LAMBDA) {
|
||||
hyperprint(cons(bsymbol(DEFUN), cons(var, cdr(val))), 0, pfun);
|
||||
} else {
|
||||
hyperprint(cons(bsymbol(DEFVAR), cons(var, cons(quote(val), NULL))), 0, pfun);
|
||||
}
|
||||
|
||||
pln(pfun);
|
||||
ppwidth = PPWIDTH;
|
||||
return bsymbol(NOTHING);
|
||||
}
|
||||
|
||||
object *
|
||||
fn_lambdap(object *arg, object *env)
|
||||
{
|
||||
|
@ -65,70 +146,11 @@ fn_lambdap(object *arg, object *env)
|
|||
return nil;
|
||||
}
|
||||
|
||||
object *
|
||||
sp_pform(object *args, object *env)
|
||||
{
|
||||
pfun_t pfun = pserial;
|
||||
object *sym = car(args);
|
||||
object *str = car(cdr(args));
|
||||
object *obj;
|
||||
|
||||
if (!boundp(sym, env)) {
|
||||
error2(PSTR("symbol isn't bound"));
|
||||
}
|
||||
|
||||
if (str == nil) {
|
||||
obj = startstring();
|
||||
pfun = pstr;
|
||||
} else if (!eq(str, tee)) {
|
||||
pfun = pstreamfun(args);
|
||||
}
|
||||
|
||||
#if defined(gfxsupport)
|
||||
if (pfun == gfxwrite) ppwidth = GFXPPWIDTH;
|
||||
#endif
|
||||
|
||||
pln(pfun);
|
||||
|
||||
object *pair = eval(sym, env);
|
||||
object *var = car(pair);
|
||||
object *val = cdr(pair);
|
||||
|
||||
if (consp(val)) {
|
||||
pfstring(PSTR("consp val"), pfun); pln(pfun);
|
||||
}
|
||||
|
||||
if (var->name == LAMBDA) {
|
||||
pfstring(PSTR("var->name == LAMBDA"), pfun); pln(pfun);
|
||||
}
|
||||
|
||||
if (builtin(val->name) == LAMBDA) {
|
||||
pfstring(PSTR("builtin -> LAMBDA"), pfun); pln(pfun);
|
||||
}
|
||||
|
||||
// if (consp(val) && symbolp(car(val)) && builtin(car(val)->name) == LAMBDA) {
|
||||
// superprint(cons(bsymbol(DEFUN), cons(var, cdr(val))), 0, pfun);
|
||||
// } else if (consp(val) && car(val)->type == CODE) {
|
||||
// superprint(cons(bsymbol(DEFCODE), cons(var, cdr(val))), 0, pfun);
|
||||
// } else if (consp(val) && var->name == LAMBDA) {
|
||||
// superprint(cons(bsymbol(DEFUN), cons(sym, val)), 0, pfun);
|
||||
// } else {
|
||||
// superprint(cons(bsymbol(DEFVAR), cons(var, cons(quote(val), NULL))), 0, pfun);
|
||||
// }
|
||||
|
||||
pln(pfun);
|
||||
ppwidth = PPWIDTH;
|
||||
|
||||
if (str == nil) {
|
||||
return obj;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Symbol names
|
||||
const char stringlambdap[] PROGMEM = "lambdap";
|
||||
const char stringnow[] PROGMEM = "now";
|
||||
const char stringpform[] PROGMEM = "pform";
|
||||
const char string_sym_def[] PROGMEM = "symbol-def";
|
||||
|
||||
// Documentation strings
|
||||
|
||||
|
@ -142,11 +164,18 @@ const char docnow[] PROGMEM = "(now [hh mm ss])\n"
|
|||
const char docpform[] PROGMEM = "(pform form str)\n"
|
||||
"Print a form to a stream in a manner suitable for writing to storage.";
|
||||
|
||||
const char doc_sym_def[] PROGMEM = "(symbol-def symbol [str])\n"
|
||||
"Prints the definition of a symbol (variable or function) defined in\n"
|
||||
"ulisp using the pretty printer."
|
||||
"If str is specified it prints to the specified stream.\n"
|
||||
"It returns no value.";
|
||||
|
||||
|
||||
// Symbol lookup table
|
||||
const tbl_entry_t lookup_table2[] PROGMEM = {
|
||||
{ stringlambdap, fn_lambdap, 0211, doclambdap },
|
||||
{ stringnow, fn_now, 0203, docnow },
|
||||
{ stringpform, sp_pform, 0322, docpform },
|
||||
{ string_sym_def, fn_sym_def, 0212, doc_sym_def },
|
||||
};
|
||||
|
||||
// Table cross-reference functions
|
||||
|
|
Loading…
Reference in New Issue