how to wrap functions from a context without prefixing?

Q&A's, tips, howto's
Locked
conan
Posts: 52
Joined: Sat Oct 22, 2011 12:14 pm

how to wrap functions from a context without prefixing?

Post by conan »

This is a mock-up to simplify my question.
I got these scheme:
  • hin.lsp

    Code: Select all

    (context 'hin)
    
    (define (hin-show)
    	(println "from hin.lsp"))
    
  • wrappers.lsp

    Code: Select all

    (load "hin.lsp")
    
    (define (wrap-one)
    	(context hin)
    	(hin-show) ; this wont work
    	(context MAIN))
    
  • main.lsp

    Code: Select all

    (load "wrappers.lsp")
    
    (wrap-one)
    
File hin.lsp contains 244 symbols (functions and constants) autogenerated. It's a DSL for HTML5.

File wrappers.lsp contains functions to wrap snippets of reusable code like: header, navbar, sidebar, you-get-the-idea.

File main.lsp calls functions from wrappers.lsp.

Now, the context switch shown in function wrap-one wont produce the desired result. I think it's because the double pass newlisp parser does. So on the first pass (hin-show) gets transformed into (MAIN:hin-show).

The idea of hin.lsp is to be able to wrote code like this:

Code: Select all

(html lang= "en"
	(head
		(title "Some title"))
	(body
		(p class= "shiny" "Lore ipsum...")))
If I have to prefix every call with "hin:" or even with an alias like "h:" hin's while purpose is defeated, which is to be as close to HTML syntax as possible.

My question is: what's the best way to wrap functions calls from hin inside a function defined in another context without prefixing hin calls?

I'm trying to build a macro to parse those calls by my own and prefix when appropriate, it will be used like this:

Code: Select all

(define (wrap-one)
	(wrap-in-context
		(...))) ; calls to hin functions
But I'm having problems recurring inside the macro. And now I'm thinking all this extra parsing could make the whole idea to work too slow. Anyway, I'm digressing. Back to the point: any ideas about how to avoid prepending all calls with context name?

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: how to wrap functions from a context without prefixing?

Post by xytroxon »

Here is a small example of how newLISP can use the power of
"context" to create an html5 dsl.

Code: Select all

; This module and program code is run
; together as one file to make it easier
; to experiment with.

; ----------------------------------------
; module file "html5.lsp" code section

(context 'html5)

(define (html5:html) (string "<html>" (join (args)) "</html>"))
(define (html5:head) (string "<head>" (join (args)) "</head>"))
(define (html5:title) (string "<title>" (join (args)) "</title>"))
(define (html5:body) (string "<body>" (join (args)) "</body>"))
(define (html5:div) (string "<div>" (join (args)) "</div>"))
(define (html5:h1) (string "<h1>" (join (args)) "</h1>"))
(define (html5:p) (string "<p>" (join (args)) "</p>"))

(context MAIN)

; -----------------------------------------
; program file code section
; uncomment next line when code is in two files
;(load "html5.lsp") 

; create copy of html5 context
(new html5 'page)

; switch into the copy of html5 context
(context page) 

; Welcome to a DSL (Domain Specific Language)
; for working with html5 tags
; No more: (html5:html (html5:head...
; Just use: (html (head ...

; Note inside this context "div" is now redefined.
; If you need to divide, use (MAIN:div num1 num2)
; But only because it was redefined in this context
; (add num1 num2) does not need to be (MAIN:add num1 num2) etc... 

(setq output
  (html
    (head
      (title "page title")
    )
    (body
      (div
        (h1 "Page Heading")
        (p "Text for page.")
      )
    )
  )
)
(context MAIN)

(println page:output)
; Uncomment next line to make html page
; that you can view in browser.
;(write-file "my.html" page:output)
(exit)
-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

conan
Posts: 52
Joined: Sat Oct 22, 2011 12:14 pm

Re: how to wrap functions from a context without prefixing?

Post by conan »

Thanks for your reply xytroxon. However I'm looking for a different concept. I'm still not there, but my idea is that only proper HTML5 code comes from my DSL, my objective is to produce valid HTML without the need to validate it.

Anyway I found a partial answer to my previous question, first I did this wraper:

Code: Select all

(define-macro (wrap-in-context:wrap-in-context ctx-new)
	(eval
		(doargs (arg)
			(read-expr
				(replace {\w+:} (string arg) "" 0) (eval ctx-new)))))
Problem is that it replaces any context, so I wrote another one:

Code: Select all

(define-macro (replace-this-context:replace-this-context ctx-old ctx-new)
	(eval
		(doargs (arg)
			(read-expr
				(replace (string (eval ctx-old) ":") (string arg) "" 0) (eval ctx-new)))))
And it kind of solves my issue, but I'm still not satisfied because while I can wrap data in a context different from the one I'll replace, I cannot build functions with arguments, because those arguments get the context I wanna replace. So I have to juggle with data, and that's not cool.

So I'm still looking for a better solution.

Anyway, if you or someone else wanna take a look, I just uploaded it here:

https://github.com/conan-lugmen/newlisp-hin.git

Please note it's not alpha nor beta software... maybe omega :P

Current work is still in the dev branch, master is old and probably non-functional. Also I found a couple of bugs recently that are becoming hard to track with the current definition if hin:hin (which grew too big), so I'll be changing stuff there these days.

Locked