lips icon indicating copy to clipboard operation
lips copied to clipboard

define-library and import (R7RS)

Open jcubic opened this issue 4 years ago • 3 comments

This feature should be added to version 1.0

This is early implementation of module macro before I've knew about define-library or even before I've started working on R7RS spec, it can be refactored into R7RS library.

;; -----------------------------------------------------------------------------
(define-macro (module name . body)
  "(module module-name . body)

   Macro for defining modules inside you can use define to create functions.
   And use export name to add that name to defined environment."
  (let ((parent (. (current-environment) '__parent__))
        (module-name (gensym)))
    `(let ((,module-name (new-module ,(symbol->string name))))
       (define-macro (export name) `(--> ,,module-name (set ',name ,name)))
       ,@body
       (--> ,parent (set ',name ,module-name)))))

;; -----------------------------------------------------------------------------
(define-macro (import name module)
  "(input function-name module)

   Macro for importing function from module"
  `(define ,name (--> ,module (get ',name))))

;; -----------------------------------------------------------------------------
(define-class Module Object
  (constructor
    (lambda (self name env)
      (set-obj! self 'env env)
      (set-obj! self 'name name)))
  (get 
    (lambda (self name)
       (--> self.env (get name))))
  (set
    (lambda (self name function)
      (--> self.env (set name function))))
  (toString
     (lambda (self)
       (string-append "#<Module(" self.name ")>"))))

;; -----------------------------------------------------------------------------
(define (new-module name)
  "(new-module name)

   Create new empty module object with empty env."
  (let ((env (new lips.Environment
                  (string-append "module-" (--> name (toLowerCase))))))
    (new Module name env)))

;; -----------------------------------------------------------------------------
(module Math
        (define (square_ x)
          "(Math::square x)
          
          Function square argument"
          (* x x))
        (export square_))

(import square_ Math)

(display (square_ 10))
(newline)

jcubic avatar Feb 17 '21 16:02 jcubic

For now the macro works like this:

(define-library (example life)
  (define (life)
    (+ 1 2))
  (export life))

(let ()
  (import (example life))
  (print (life)))

the export need to be at the end.

jcubic avatar Feb 28 '21 11:02 jcubic