From f5cb35b87255ebbe2d322bcedde6bc7d5f6aebae Mon Sep 17 00:00:00 2001 From: Thomas Albers Raviola Date: Mon, 13 May 2024 21:29:31 +0200 Subject: * Initial commit --- src/core.lisp | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/core.lisp (limited to 'src/core.lisp') diff --git a/src/core.lisp b/src/core.lisp new file mode 100644 index 0000000..6c151ce --- /dev/null +++ b/src/core.lisp @@ -0,0 +1,76 @@ +(in-package #:chains) + +(defun get-var (env key) + (if-let ((slot (assoc key env))) + (cdr slot) + (error "var ~A not found~% ~A~%" key env))) + +;; Built-in functions and variables used inside the interpreter use their own +;; package. This allows the language to have keywords like lambda which +;; otherwise would be reserved words from the cl package + +(defmacro define-function (name (&rest args) &body body) + (let ((siblings (gensym))) + `(make-closure #'(lambda (environment ,siblings ,@args) + (declare (ignore ,siblings)) + ,@body) + ',args + nil + (complement #'identity)))) + +(defmacro define-function* (name (&rest args) (siblings group-predicate) + &body body) + `(make-closure #'(lambda (environment ,siblings ,@args) + ,@body) + ',args + nil + ,group-predicate)) + +(defmacro define-syntax (name (&rest args) &body body) + `(make-closure #'(lambda (environment siblings ,@args) + ,@body) + ',args + t + (complement #'identity))) + +(defmacro define-syntax* (name (&rest args) (siblings group-predicate) + &body body) + `(make-closure #'(lambda (environment ,siblings ,@args) + ,@body) + ',args + t + ,group-predicate)) + +(defparameter *lambda* + (define-syntax lambda (arglist body) + (setf arglist (remove-if #'whitespace-text-p arglist)) + (assert (every #'object-symbolp arglist)) + (setf arglist (mapcar #'cdr arglist)) + (let ((env environment)) + (make-closure #'(lambda (environment siblings &rest args) + (tree-eval (append (pairlis arglist args) + env + environment) + body)) + arglist nil (complement #'identity) env)))) + +(defparameter *syntax* + (define-syntax syntax (arglist body) + (setf arglist (remove-if #'whitespace-text-p arglist)) + (assert (every #'object-symbolp arglist)) + (setf arglist (mapcar #'cdr arglist)) + (let ((env environment)) + (make-closure #'(lambda (environment siblings &rest args) + (tree-eval (append (pairlis arglist args) + env + environment) + body)) + arglist t (complement #'identity) env)))) + +(defparameter *define* + (define-syntax* define (name value) (siblings #'identity) + (assert (object-symbolp (first name))) + (setf name (cdr (first name))) + (setf value (first (tree-eval environment value))) + (tree-eval (acons name value environment) + siblings))) -- cgit v1.2.3