lips icon indicating copy to clipboard operation
lips copied to clipboard

Write define-library macro

Open jcubic opened this issue 5 years ago • 1 comments

Since syntax-rules is almost working I should try to write the library using syntax-rules first.

jcubic avatar Aug 14 '20 19:08 jcubic

this lips macros can be used as base:

;; ---------------------------------------------------------------------------------------
(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 (. lips 'Environment) (concat "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))))

(module Math
        (define (square x)
          "(square x)
          
          Function square argument"
          (* x x))
        (export square))

(import square Math)
(square 10)

The code should be rewritten as syntax macro and Environment should be replaced with custom class:

(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)))

jcubic avatar Aug 14 '20 20:08 jcubic

Duplicate of #129

jcubic avatar Feb 20 '24 23:02 jcubic