tisp

tiny lisp
git clone git://edryd.org/tisp
Log | Files | Refs | LICENSE

commit 9f2fab05f10c87c29cfedda884d2ad84fdc74f8e
parent c245f59b0d0a07317361074049f6cb4a28441523
Author: Ed van Bruggen <edvb@uw.edu>
Date:   Tue, 27 Oct 2020 22:54:21 -0700

Support optional missing argument list for lambda

Creates function with one argument called 'it'. Also use @ as shorthand
prefix.

Diffstat:
test.c | 2++
tib/doc.tsp | 4+++-
tib/io.tsp | 18+++++++++---------
tisp.c | 27++++++++++++++++++---------
4 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/test.c b/test.c @@ -178,6 +178,8 @@ char *tests[][2] = { { "(= '(1 2 3) '(1))", "Nil" }, { "(= '((1 2) 3 4) '((1 2) 3 4))", "True" }, { "(= '((1 b) 3 4) '((1 2) 3 4))", "Nil" }, + { "(= (lambda (it) it) @it)", "True" }, + { "(= @it (lambda (x) x))", "Nil" }, { "def", NULL }, { "(def foo 4)", "#<void>" }, diff --git a/tib/doc.tsp b/tib/doc.tsp @@ -34,7 +34,9 @@ "Get the property of the given value depending on its type") (lambda "(lambda args . body)" - "Create anonymous function") + "(lambda body)" + "Create anonymous function" + " If only body is given, create function with one argument labeled 'it'") (macro "(macro args . body)" "Create anonymous macro") diff --git a/tib/io.tsp b/tib/io.tsp @@ -1,18 +1,18 @@ (def (run file) (eval (parse (read file)))) (def (print . str) (apply write (list* 'stdout Nil str))) -(def (newline . file) +(def (newline . file) ; TODO space and tab functions, accept number of instead (if (or (nil? file) (nil? (cdr file))) (write (car (or file '(stdout))) file "\n") (error 'newline "only zero or one file can be given"))) (def (display . str) - (map (lambda (s) - (cond - ((string? s) (print "\"" s "\"")) - ((true? s) (print s)) ; don't quote True since it's self evaluating - ((symbol? s) (print "'" s)) - ((pair? s) (print "'" s)) - (else (print s)))) - str)) + (map @(cond + ((string? it) (print "\"" it "\"")) + ((true? it) (print it)) ; don't quote True since it's self evaluating + ((symbol? it) (print "'" it)) + ((pair? it) (print "'" it)) + (else (print it))) + str) + (Void)) (def (displayln . str) (apply display str) (newline)) (def (println . str) (apply print str) (newline)) diff --git a/tisp.c b/tisp.c @@ -558,11 +558,12 @@ read_pair(Tsp st) Val tisp_read(Tsp st) { - char *shorthands[] = { + char *prefix[] = { "'", "quote", "`", "quasiquote", ",@", "unquote-splice", /* always check before , */ ",", "unquote", + "@", "lambda", }; skip_ws(st, 1); if (strlen(st->file+st->filec) == 0) /* empty list */ @@ -572,19 +573,19 @@ tisp_read(Tsp st) /* TODO support | for symbols */ if (tsp_fget(st) == '"') /* strings */ return read_str(st); - for (int i = 0; i < LEN(shorthands); i += 2) { /* character prefixes */ - if (!strncmp(st->file+st->filec, shorthands[i], strlen(shorthands[i]))) { + for (int i = 0; i < LEN(prefix); i += 2) { /* character prefix */ + if (!strncmp(st->file+st->filec, prefix[i], strlen(prefix[i]))) { Val v; - tsp_fincn(st, strlen(shorthands[i])); + tsp_fincn(st, strlen(prefix[i])); if (!(v = tisp_read(st))) return NULL; - return mk_list(st, 2, mk_sym(st, shorthands[i+1]), v); + return mk_list(st, 2, mk_sym(st, prefix[i+1]), v); } } if (issym(tsp_fget(st))) /* symbols */ return read_sym(st); - if (tsp_fget(st) == '(') - return tsp_finc(st), read_pair(st, ')'); + if (tsp_fget(st) == '(') /* list */ + return tsp_finc(st), read_pair(st); tsp_warnf("could not read given input '%c'", st->file[st->filec]); } @@ -930,8 +931,16 @@ prim_get(Tsp st, Hash env, Val args) static Val form_lambda(Tsp st, Hash env, Val args) { - tsp_arg_min(args, "lambda", 2); - return mk_func(TSP_FUNC, NULL, car(args), cdr(args), env); + Val params, body; + tsp_arg_min(args, "lambda", 1); + if (nilp(cdr(args))) { /* if only 1 argument is given, auto fill func parameters */ + params = mk_pair(mk_sym(st, "it"), st->nil); + body = args; + } else { + params = car(args); + body = cdr(args); + } + return mk_func(TSP_FUNC, NULL, params, body, env); } /* creates new tisp defined macro */