tisp

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

commit ed83f3386d60aae9fd66e131bef08c9cf575b00a
parent 531c97634da9a15e9d1f865d5d50ef25cd58ba5c
Author: Ed van Bruggen <edvb@uw.edu>
Date:   Sat, 21 Mar 2020 00:50:00 -0700

Stort procedure name to be displayed

Diffstat:
tibs/string.c | 2+-
tisp.c | 64+++++++++++++++++++++++++++++++++++++++-------------------------
tisp.h | 38+++++++++++---------------------------
3 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/tibs/string.c b/tibs/string.c @@ -28,7 +28,7 @@ typedef Val (*MkFn)(Tsp, char*); /* TODO string tib: lower upper strpos strsub */ -/* TODO simplify by using fmemopen and tisp_print */ +/* TODO simplify by using fmemopen/funopen and tisp_print */ static Val val_string(Tsp st, Val args, MkFn mk_fn) { diff --git a/tisp.c b/tisp.c @@ -342,7 +342,8 @@ mk_rat(int num, int den) return mk_int(num); Val ret = emalloc(sizeof(struct Val)); ret->t = RATIO; - ret->v.n = (Ratio){ num, den }; + ret->v.n.num = num; + ret->v.n.den = den; return ret; } @@ -376,19 +377,21 @@ mk_sym(Tsp st, char *s) } Val -mk_prim(Prim pr) +mk_prim(Prim pr, char *name) { Val ret = emalloc(sizeof(struct Val)); ret->t = PRIMITIVE; - ret->v.pr = pr; + ret->v.pr.name = name; + ret->v.pr.pr = pr; return ret; } Val -mk_func(Type t, Val args, Val body, Hash env) +mk_func(Type t, char *name, Val args, Val body, Hash env) { Val ret = emalloc(sizeof(struct Val)); ret->t = t; + ret->v.f.name = name; ret->v.f.args = args; ret->v.f.body = body; ret->v.f.env = env; @@ -542,6 +545,7 @@ read_sym(Tsp st) } /* return read string containing a list */ +/* TODO read pair after as well, allow lambda((x) (* x 2))(4) */ static Val read_pair(Tsp st) { @@ -689,20 +693,21 @@ tisp_eval_seq(Tsp st, Hash env, Val v) /* evaluate procedure f of name v with arguments */ static Val -eval_proc(Tsp st, Hash env, Val v, Val f, Val args) +eval_proc(Tsp st, Hash env, Val f, Val args) { Val ret; Hash e; switch (f->t) { case PRIMITIVE: - return (*f->v.pr)(st, env, args); + return (*f->v.pr.pr)(st, env, args); case FUNCTION: /* tail call into the function body with the extended env */ if (!(args = tisp_eval_list(st, env, args))) return NULL; /* FALLTHROUGH */ case MACRO: - tsp_arg_num(args, v->t == SYMBOL ? v->v.s : "lambda", list_len(f->v.f.args)); + tsp_arg_num(args, f->v.f.name ? f->v.f.name : "anonymous", + list_len(f->v.f.args)); e = hash_new(8, f->v.f.env); /* TODO call hash_extend in hash_new to know new hash size */ if (!(hash_extend(e, f->v.f.args, args))) @@ -734,7 +739,7 @@ tisp_eval(Tsp st, Hash env, Val v) case PAIR: if (!(f = tisp_eval(st, env, car(v)))) return NULL; - return eval_proc(st, env, car(v), f, cdr(v)); + return eval_proc(st, env, f, cdr(v)); default: return v; } @@ -748,10 +753,10 @@ tisp_print(FILE *f, Val v) { switch (v->t) { case NONE: - fprintf(f, "#<void>"); + fputs("#<void>", f); break; case NIL: - fprintf(f, "()"); + fputs("()", f); break; case INTEGER: fprintf(f, "%d", (int)num(v)); @@ -770,14 +775,15 @@ tisp_print(FILE *f, Val v) case SYMBOL: fputs(v->v.s, f); break; - case PRIMITIVE: - fprintf(f, "#<primitive>"); - break; case FUNCTION: - fprintf(f, "#<function>"); - break; case MACRO: - fprintf(f, "#<macro>"); + fprintf(f, "#<%s%s%s>", /* if proc name is not null print it */ + v->t == FUNCTION ? "function" : "macro", + v->v.pr.name ? ":" : "", + v->v.pr.name ? v->v.pr.name : ""); + break; + case PRIMITIVE: + fprintf(f, "#<primitive:%s>", v->v.pr.name); break; case PAIR: putc('(', f); @@ -787,7 +793,7 @@ tisp_print(FILE *f, Val v) putc(' ', f); tisp_print(f, car(v)); } else { - fprintf(f, " . "); + fputs(" . ", f); tisp_print(f, v); break; } @@ -913,8 +919,14 @@ prim_get(Tsp st, Hash env, Val args) return NULL; tsp_arg_type(prop, "get", SYMBOL); switch (v->t) { + case PRIMITIVE: + if (!strncmp(prop->v.s, "name", 4)) + return mk_str(st, v->v.pr.name); + break; case FUNCTION: case MACRO: + if (!strncmp(prop->v.s, "name", 4)) + return mk_str(st, v->v.f.name); if (!strncmp(prop->v.s, "body", 4)) return v->v.f.body; if (!strncmp(prop->v.s, "args", 4)) @@ -948,7 +960,7 @@ static Val prim_lambda(Tsp st, Hash env, Val args) { tsp_arg_min(args, "lambda", 2); - return mk_func(FUNCTION, car(args), cdr(args), env); + return mk_func(FUNCTION, NULL, car(args), cdr(args), env); } /* creates new tisp defined macro */ @@ -956,7 +968,7 @@ static Val prim_macro(Tsp st, Hash env, Val args) { tsp_arg_min(args, "macro", 2); - return mk_func(MACRO, car(args), cdr(args), env); + return mk_func(MACRO, NULL, car(args), cdr(args), env); } /* creates new variable of given name and value @@ -968,20 +980,22 @@ prim_define(Tsp st, Hash env, Val args) { Val sym, val; tsp_arg_min(args, "define", 2); - if (car(args)->t == PAIR) { - sym = caar(args); + if (car(args)->t == PAIR) { /* create function if given argument list */ + sym = caar(args); /* first element of argument list is function name */ if (sym->t != SYMBOL) tsp_warnf("define: incorrect format," " expected symbol for function name, received %s", type_str(sym->t)); - val = mk_func(FUNCTION, cdar(args), cdr(args), env); - } else if (car(args)->t == SYMBOL) { + val = mk_func(FUNCTION, sym->v.s, cdar(args), cdr(args), env); + } else if (car(args)->t == SYMBOL) { /* create variable */ sym = car(args); val = tisp_eval(st, env, cadr(args)); - } else - tsp_warn("define: incorrect format, no variable name found"); + } else tsp_warn("define: incorrect format, no variable name found"); if (!val) return NULL; + /* set procedure name if it was previously anoymous */ + if (val->t & (FUNCTION|MACRO) && !val->v.f.name) + val->v.f.name = sym->v.s; hash_add(env, sym->v.s, val); return st->none; } diff --git a/tisp.h b/tisp.h @@ -45,7 +45,7 @@ type_str(TYPE), type_str(ARG->t)); \ } while(0) -#define tsp_env_name_fn(NAME, FN) tisp_env_add(st, #NAME, mk_prim(prim_##FN)) +#define tsp_env_name_fn(NAME, FN) tisp_env_add(st, #NAME, mk_prim(prim_##FN, #NAME)) #define tsp_env_fn(NAME) tsp_env_name_fn(NAME, NAME) #define tsp_include_tib(NAME) void tib_env_##NAME(Tsp) @@ -67,11 +67,6 @@ struct Val; typedef struct Val *Val; typedef struct Tsp *Tsp; -/* fraction */ -typedef struct { - double num, den; -} Ratio; - typedef struct Entry *Entry; typedef struct Hash { @@ -83,20 +78,6 @@ typedef struct Hash { struct Hash *next; } *Hash; -/* basic function written in C, not lisp */ -typedef Val (*Prim)(Tsp, Hash, Val); - -/* function written directly in lisp instead of C */ -typedef struct { - Val args; - Val body; - Hash env; -} Func; - -typedef struct { - Val car, cdr; -} Pair; - /* possible tisp object types */ typedef enum { NONE = 1 << 0, @@ -116,15 +97,18 @@ typedef enum { /* TODO rename to math ? */ #define EXPRESSION (NUMBER | SYMBOL | PAIR) +/* bultin function written in C, not tisp */ +typedef Val (*Prim)(Tsp, Hash, Val); + /* tisp object */ struct Val { Type t; /* NONE, NIL */ union { - Ratio n; /* INTEGER, DECIMAL, RATIO */ - char *s; /* STRING, SYMBOL */ - Prim pr; /* PRIMITIVE */ - Func f; /* FUNCTION */ - Pair p; /* PAIR */ + char *s; /* STRING, SYMBOL */ + struct { double num, den; } n; /* NUMBER */ + struct { char *name; Prim pr; } pr; /* PRIMITIVE */ + struct { char *name; Val args, body; Hash env; } f; /* FUNCTION */ + struct { Val car, cdr; } p; /* PAIR */ } v; }; @@ -146,8 +130,8 @@ Val mk_dec(double d); Val mk_rat(int num, int den); Val mk_str(Tsp st, char *s); Val mk_sym(Tsp st, char *s); -Val mk_prim(Prim prim); -Val mk_func(Type t, Val args, Val body, Hash env); +Val mk_prim(Prim prim, char *name); +Val mk_func(Type t, char *name, Val args, Val body, Hash env); Val mk_pair(Val a, Val b); Val mk_list(Tsp st, int n, Val *a);