Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;; -*- lexical-binding: t -*-
- ;; this will only work if lexical-binding is t
- ;; this does not yet support non-toplevel defun/defvar expressions
- ;; we need a
- ;; thing that pushes globals to fns/vars
- ;; and returns a body with nil in place of them
- ;; (labels (P (sexp) (cond ((atom? sexp) ...) ...)))
- ;; needs to handle defuns declared in defuns, defvars declared in defuns,
- ;; whatever stuff you can do
- (defmacro defmodule (module-name export-list &rest body)
- (labels ((defun? (sexp) (and (listp sexp)
- (eq (car sexp) 'defun)))
- (defun-name (sexp) (cadr sexp))
- (defun-args (sexp) (caddr sexp))
- (defun-body (sexp) (cadddr sexp))
- (defvar? (sexp) (and (listp sexp)
- (eq (car sexp) 'defvar)))
- (defvar-name (sexp) (cadr sexp))
- (defvar-value (sexp) (caddr sexp))
- (export? (sym) (member sym (cdr export-list))))
- (let ((fns nil)
- (vars nil)
- (b nil))
- (dolist (sexp body)
- (cond ((defun? sexp)
- (if (export? (defun-name sexp))
- (push sexp b)
- (push sexp fns)))
- ((defvar? sexp)
- (push sexp vars))
- (t
- (push sexp b))))
- `(let (,@(mapcar (lambda (def) (list (defvar-name def)
- (defvar-value def)))
- vars))
- (labels (,@(mapcar (lambda (fn) (list (defun-name fn)
- (defun-args fn)
- (defun-body fn)))
- fns))
- ,@b)))))
Add Comment
Please, Sign In to add comment