This commit is contained in:
Jonas Maier 2022-12-29 10:03:25 +01:00
parent 8c8c603b47
commit e69e9bd0f9
4 changed files with 82 additions and 38 deletions

95
lisp
View File

@ -27,37 +27,47 @@
)
)
(defun fold(init fun list)
; left fold
(defun foldl(init fun list)
(cond
((pair? list)
(fold (fun init (hd list)) fun (tl list))
(foldl (fun init (hd list)) fun (tl list))
)
(else
init)
(else init)
)
)
; right fold
(defun foldr(init fun list)
(cond
((pair? list)
(fun (hd list) (foldr init fun (tl list)))
)
(else init)
)
)
(assert (= 10
(fold 0 (.\ (x y) (+ x y)) '(1 2 3 4))
(foldl 0 (.\ (x y) (+ x y)) '(1 2 3 4))
))
(defun flip(fun)
(.\ (x y) (fun y x))
)
(def rev (fold nil (flip cons) ..))
(def rev (foldl nil (flip cons) ..))
(assert (= '(4 3 2 1)
(rev '(1 2 3 4))
))
(defun concat(xs ys)
(fold ys (flip cons) (rev xs))
(foldl ys (flip cons) (rev xs))
)
(assert (= '(1 2 3 4 5 6) (concat '(1 2 3) '(4 5 6))))
(def flatten (fold nil concat ..))
(def flatten (foldl nil concat ..))
(assert (=
'(1 2 3 4)
@ -110,22 +120,12 @@
)
)
(defun and(a b)
(cond (a (cond (b true))))
)
(defun all(pred? list)
(fold true and (map pred? list))
)
(defun or(a b)
(defun map(fun list)
(cond
(a true)
(b true)
((nil? list) list)
(else (cons (fun (hd list)) (map fun (tl list))))
)
)
(defun any(pred? list)
(fold nil or (map pred? list))
)
(defun range(from to)
(cond
@ -133,6 +133,24 @@
(else (cons from (range (+ 1 from) to)))
)
)
(assert (= '(1 2 3) (range 1 4)))
(defmacro and(a b)
`(cond (#a #b))
)
(defun all (pred? list)
(foldr true and (map pred? list))
)
(defmacro or(a b)
`(cond
(#a true)
(#b true)
)
)
(defun any(pred? list)
(foldl nil or (map pred? list))
)
(defun divides?(x y)
(= 0 (% y x))
@ -156,13 +174,6 @@
)
)
(defun map(fun list)
(cond
((nil? list) list)
(else (cons (fun (hd list)) (map fun (tl list))))
)
)
(defun mapi.aux(fun list idx)
(cond
((nil? list) list)
@ -339,11 +350,11 @@ Point
(symcat 'he 'he 'ho)
(typedfun max ((list? values))
(fold 0 (.\ (x y) (cond ((< x y) y) (else x))) values)
(foldl 0 (.\ (x y) (cond ((< x y) y) (else x))) values)
)
(typedfun min ((list? values))
(fold 1000000000 (.\ (x y) (cond ((< x y) x) (else y))) values)
(foldl 1000000000 (.\ (x y) (cond ((< x y) x) (else y))) values)
)
(defun split.aux(delimiter array)
@ -366,9 +377,9 @@ Point
(snd (split.aux delimiter (cons delimiter array)))
)
(typedfun sum((list? x)) (fold 0 + x))
(typedfun sum((list? x)) (foldl 0 + x))
(defun succ(x) (+ 1 x))
(typedfun len((list? x)) (fold 0 succ x))
(typedfun len((list? x)) (foldl 0 succ x))
(defun pow(a b)
(cond
((= 0 b) 1)
@ -544,7 +555,7 @@ Point
)
(defun new.(fields)
(fold
(foldl
nil
(.\ (struct new_field)
(progn
@ -561,7 +572,7 @@ Point
(defmacro sn(fields)
(cond
((list? fields)
`'#(fold
`'#(foldl
nil
(.\ (struct new_field)
(progn
@ -750,5 +761,19 @@ PPoint.new
q
(PPoint? q)
(def nums (range 1 20000))
(def nils (map nil? nums))
'(end of program)
(defun heavy_calc(folding _)
(folding true and nils)
)
'foldr
(map (heavy_calc foldr ..) (range 1 40))
'foldl
(map (heavy_calc foldl ..) (range 1 40))
'(end of program)

13
lisp.c
View File

@ -38,7 +38,7 @@ int main(void)
lisp[fsize] = 0;
init();
//dump();
// dump();
char *lisp_ptr = &lisp[0];
char **cursor = &lisp_ptr;
@ -54,5 +54,16 @@ int main(void)
gc();
int memory = mem_usage();
char *unit[] = {"", "K", "M", "G", "T"};
char **mem_unit = &unit[0];
while (memory >= (1 << 13))
{
mem_unit++;
memory /= 1024;
}
printf("We used %d%sB of memory for the lisp values\n", memory, *mem_unit);
return 0;
}

2
lisp.h
View File

@ -89,6 +89,8 @@ char *get_symbol_str(ptr s);
ptr get_symbol_binding(ptr s);
ptr (*get_fn_ptr(ptr i))(ptr);
int mem_usage(void);
// eval an expression
// might have side effects
ptr eval(ptr i);

10
mem.c
View File

@ -130,7 +130,7 @@ void init(void)
}
else
{
mem[i].next_free = ~0;
mem[i].next_free = i;
}
}
@ -473,9 +473,15 @@ ptr get_nil(ptr i)
void new_binding(ptr symbol, ptr expression)
{
sym_t *sym = &symbols[get_symbol(symbol)];
if (sym->binding != UNBOUND) {
if (sym->binding != UNBOUND)
{
printf("Definitions cannot be shadowed.\nOffending symbol: %s.\n", &sym->name[0]);
assert(initialized == MEM_INITIALIZING);
}
sym->binding = expression;
}
int mem_usage(void)
{
return sizeof(mem) + sizeof(symbols);
}