bldc/repl/evaldefunc.lisp

131 lines
3.8 KiB
Common Lisp
Raw Normal View History

Squashed 'lispBM/lispBM/' changes from 3836952f..cdfd116c cdfd116c added some tests for partial applications 46d02e9c Added the possibilty to partially apply a closure 788dfa27 debug inspection of local environments in the REPL b28ceec1 shutting down some warnings originating in repl.c d35ef54d small tweak example code 5fa6f453 added some sanity checking of the type of the key used in let bindings 81314729 Updates chibios xmas-dac example so that it builds again 0d1f05ca updates chibios example repl so that it builds again 4ae17fc8 small tweak to texture loading demo. a309e37a added silly texture image for the sdl_texture.lisp example 1dc0e4e6 added texture loading extension and a blit function for drawing sprites on the window 6c249a37 proper scaling on the sleep and timestamp callbacks e65b0b83 ESP32c3 repl up and running 24f93026 work in progress esp32 repl 958a273d work in progress esp32 repl d4fb301b work in progress repl example for ESP platforms (esp32c3 specifically) 7e924bf6 freertos includes correctly, compiles. stiill untested 29b9e3a4 added freeRTOS platform files. Untested currently f3931c13 update README and small tweaks 357bb438 closing one warning 205ca17e small tweak to SDL tree-demo 27c1f601 added a way to explicitly run a custom type destructor and clean up its deference trampoline d955f26e added missing files a94dfb5c Update README.md 0e29e692 added SDL example that draws a tree a5417886 Bugfix in lbm_sdl.c for destructors of window and renderer b3a0e586 Getting started with interfacing LBM and SDL2 7aa2c1d0 started towards custom types with associated destructors for when they are freed by GC a8b33a8d safer behaviour of car and cdr in relation to pointer-types that are not really cons-cells 9fbf02ce fixed some inconsistencies 3051e8e7 update change log 8d002536 handling one warning in 64 bit compile 7794a9b2 added array tests a83f385c Merge branch 'master' of github.com:svenssonjoel/lispbm 21c79aaf fix problem with array parsing in the case of float arrays dc926e59 added script to generate ctags 38046a49 updates to changelog with changes up and including may 22 2022 45b5d6c0 fix potential corner case issue with call-cc on 64 bit platforms ebb100a5 some streamlining of the bind_to_key rest continuation in eval_cps.c 1c9a7df2 Added explicit stack version of defunctionalized evaluator example 2812b7b0 added some more testcases in evaluator.lisp and evaldefunc.lisp 0393bd21 New features in evaluator.lisp and evaldefunc.lisp c6dd4e10 found an evalutor bug related to progn thanks to writing evaluator.lisp and evaldefunc.lisp 5d1bfc75 added continuation passing style evaluator of a mini-lisp as well as a defunctionalized CPS style evaluator for the same mini-lisp a5a6c2a2 removed commented out old code c135b4a3 fix problem related to assoc 8ddd44cc removed some code duplication in eval_cps c625af8e lbmref update a1a7a4b6 lbmref update 12d9f4e9 lbmref update git-subtree-dir: lispBM/lispBM git-subtree-split: cdfd116c655e20bac787a2080b8c601c6bc846ca
2022-07-06 01:18:45 -07:00
(define global-env 'nil)
(defun is-number (e)
(or (eq (type-of e) type-i)
(eq (type-of e) type-u)))
(defun is-symbol (e)
(eq (type-of e) type-symbol))
(defun is-operator (e)
(or (eq e '+)
(eq e '-)
(eq e '=)
(eq e '*)
))
(defun is-closure (e)
(and (eq (type-of e) type-list)
(eq (car e) 'closure)))
(defun add-bindings (env binds)
(match binds
(nil env)
(((? b) . (? rs))
(add-bindings (setassoc env b) rs))))
(defun eval-progn (env args k)
(match args
(nil (apply-cont k nil))
(((? l) . nil) (evald env l k))
(((? l) . (? ls))
(evald env l
(list 'progn-cont env ls k)))))
(defun eval-define (env args k)
(let ((key (car args))
(val (car (cdr args))))
(evald env val
(list 'define-cont key k))))
(defun eval-lambda (env args k)
(apply-cont k (append (cons 'closure args) (list env))))
(defun eval-if (env args k)
(let ((cond-exp (car args))
(then-branch (car (cdr args)))
(else-branch (car (cdr (cdr args)))))
(evald env cond-exp
(list 'if-cont env then-branch else-branch k))))
(defun eval-list (env ls acc k)
(if (eq ls nil)
(apply-cont k acc)
(let (( l (car ls))
( r (cdr ls)))
(evald env l
(list 'list-cont env r acc k)))))
(defun apply-closure (env ls k)
(let ((clo (car ls))
(args (cdr ls))
(ps (car (cdr clo)))
(body (car (cdr (cdr clo))))
(env1 (car (cdr (cdr (cdr clo)))))
(arg-env (zip ps args))
(new-env (add-bindings (append env1 env) arg-env)))
(evald new-env body k)))
(defun apply (env ls k)
(let ((f (car ls)))
(if (is-operator f)
(apply-cont k (eval ls))
(if (is-closure f)
(apply-closure env ls k)
'error))))
(defun apply-cont (k exp)
(match k
(done exp)
((progn-cont (? env) (? ls) (? k1)) (eval-progn env ls k1))
((define-cont (? key) (? k1))
(progn
(setvar 'global-env (acons key exp global-env))
(apply-cont k1 exp)))
((list-cont (? env) (? r) (? acc) (? k1))
(eval-list env r (append acc (list exp)) k1))
((application-cont (? env) (? k1))
(apply env exp k1))
((if-cont (? env) (? then-branch) (? else-branch) (? k1))
(if exp
(evald env then-branch k1)
(evald env else-branch k1)))))
(defun evald (env exp k)
(if (is-operator exp)
(apply-cont k exp)
(if (is-symbol exp)
(let ((res (assoc env exp)))
(if (eq res nil)
(apply-cont k (assoc global-env exp))
(apply-cont k res)))
(if (is-number exp)
(apply-cont k exp)
(match exp
((progn . (? ls)) (eval-progn env ls k))
((define . (? ls)) (eval-define env ls k))
((lambda . (? ls)) (eval-lambda env ls k))
((if . (? ls)) (eval-if env ls k))
((?cons ls) (eval-list env ls nil
(list 'application-cont env k)))
)))))
(define test1 '(define apa 1))
(define test2 '(progn (define apa 1) (define bepa 2) (define cepa 3)))
(define test3 '((lambda (x) (+ x 10)) 1))
(define test4 '(progn (define f (lambda (x) (if (= x 0) 0 (f (- x 1))))) (f 10)))
(define test5 '(progn (define g (lambda (acc x) (if (= x 0) acc (g (+ acc x) (- x 1))))) (g 0 10)))
(define test6 '(progn (define f (lambda (x) (+ x 10)))
(define g (lambda (x) (* x 5)))
(f (g 10))))
(define test7 '(progn (define f (lambda (x) (+ x 10)))
(define g (lambda (x) (* x 5)))
(g (f 10))))