use #%module-begin for honu modules so top level expressions get printed
macros return whether they terminate parsing
This commit is contained in:
parent
255549c8c8
commit
a7768a13a3
|
@ -17,6 +17,7 @@
|
||||||
[honu-^ ^]
|
[honu-^ ^]
|
||||||
[literal:honu-= =]
|
[literal:honu-= =]
|
||||||
[literal:semicolon |;|]
|
[literal:semicolon |;|]
|
||||||
|
[literal:honu-comma |,|]
|
||||||
[literal:#%braces #%braces]
|
[literal:#%braces #%braces]
|
||||||
[literal:#%parens #%parens])
|
[literal:#%parens #%parens])
|
||||||
)
|
)
|
||||||
|
|
36
collects/honu/core/private/honu-plan
Normal file
36
collects/honu/core/private/honu-plan
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
honu forms -> expanded, parsed into racket code
|
||||||
|
to expand honu forms we have to parse the code again
|
||||||
|
|
||||||
|
1. start with raw honu code
|
||||||
|
2. wrap it with (honu-unparsed-begin ...)
|
||||||
|
3. run macro processor, eventually spit out s-expressions
|
||||||
|
honu macros will only produce honu syntax, but primitive
|
||||||
|
forms can produce s-expressions
|
||||||
|
so what should parsing 'expression' as a syntax class produce?
|
||||||
|
eventually 1 + 1 should be converted into (+ 1 1) but what should be the
|
||||||
|
representation of this as an expression within a macro?
|
||||||
|
x:expression
|
||||||
|
maybe just the unparsed form
|
||||||
|
x == 1 + 1
|
||||||
|
with possibly some accessors to tell stuff about the expression
|
||||||
|
so if a macro appears when an expression wants to parse then the macro
|
||||||
|
will be parsed and the result will be passed along
|
||||||
|
foo x:expression
|
||||||
|
foo some_macro 1 + 1
|
||||||
|
where some_macro is
|
||||||
|
some_macro x:expression => "ok"
|
||||||
|
then foo will get
|
||||||
|
x => "ok"
|
||||||
|
as opposed to
|
||||||
|
x => some_macro 1 + 1
|
||||||
|
when should honu syntax be converted to racket?
|
||||||
|
at the top level. if we know what context we are expanding then we can compile
|
||||||
|
top-level things
|
||||||
|
|
||||||
|
Parsing:
|
||||||
|
macro invocation starts parsing process. parse one expression, get back a top level form and unparsed syntax. the top level form has to be local-expanded to eventually produce some low-level racket syntax (like define).
|
||||||
|
(honu-parse stuff ...)
|
||||||
|
|
||||||
|
(define-syntax (honu-parse stx) ...)
|
||||||
|
|
||||||
|
Should call parse on stx and return
|
|
@ -443,7 +443,7 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|
||||||
#'rest)])))
|
#'rest)])))
|
||||||
|
|
||||||
(define-for-syntax (honu-expand forms)
|
(define-for-syntax (honu-expand forms)
|
||||||
(parse forms))
|
(parse-all forms))
|
||||||
|
|
||||||
(define-for-syntax (honu-compile forms)
|
(define-for-syntax (honu-compile forms)
|
||||||
#'(void))
|
#'(void))
|
||||||
|
@ -452,10 +452,15 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|
||||||
(honu:define-honu-syntax honu-var
|
(honu:define-honu-syntax honu-var
|
||||||
(lambda (code context)
|
(lambda (code context)
|
||||||
(syntax-parse code #:literal-sets (cruft)
|
(syntax-parse code #:literal-sets (cruft)
|
||||||
[(_ name:id honu-= anything . rest)
|
[(_ name:id honu-= . rest)
|
||||||
|
(define-values (parsed unparsed)
|
||||||
|
(parse #'rest))
|
||||||
(values
|
(values
|
||||||
#'(define name anything)
|
(with-syntax ([parsed parsed])
|
||||||
#'rest)])))
|
#'(define name parsed))
|
||||||
|
(with-syntax ([unparsed unparsed])
|
||||||
|
#'unparsed)
|
||||||
|
#t)])))
|
||||||
|
|
||||||
(define-syntax (honu-unparsed-begin stx)
|
(define-syntax (honu-unparsed-begin stx)
|
||||||
(emit-remark "Honu unparsed begin!" stx)
|
(emit-remark "Honu unparsed begin!" stx)
|
||||||
|
@ -469,4 +474,4 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|
||||||
[(_ forms ...)
|
[(_ forms ...)
|
||||||
(begin
|
(begin
|
||||||
(debug "Module begin ~a\n" (syntax->datum #'(forms ...)))
|
(debug "Module begin ~a\n" (syntax->datum #'(forms ...)))
|
||||||
#'(#%plain-module-begin (honu-unparsed-begin forms ...)))]))
|
#'(#%module-begin (honu-unparsed-begin forms ...)))]))
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
(require "macro2.rkt"
|
(require "macro2.rkt"
|
||||||
"operator.rkt"
|
"operator.rkt"
|
||||||
|
(only-in "literals.rkt"
|
||||||
|
semicolon)
|
||||||
(for-syntax syntax/parse
|
(for-syntax syntax/parse
|
||||||
"literals.rkt"
|
"literals.rkt"
|
||||||
"parse2.rkt"
|
"parse2.rkt"
|
||||||
|
@ -18,9 +20,10 @@
|
||||||
(values
|
(values
|
||||||
#'(define (name arg ...)
|
#'(define (name arg ...)
|
||||||
(let-syntax ([do-parse (lambda (stx)
|
(let-syntax ([do-parse (lambda (stx)
|
||||||
(parse #'(code ...)))])
|
(parse-all #'(code ...)))])
|
||||||
(do-parse)))
|
(do-parse)))
|
||||||
#'rest)])))
|
#'rest
|
||||||
|
#t)])))
|
||||||
|
|
||||||
(define-syntax-rule (define-binary-operator name precedence operator)
|
(define-syntax-rule (define-binary-operator name precedence operator)
|
||||||
(begin
|
(begin
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
(syntax-parse stx
|
(syntax-parse stx
|
||||||
[(_ syntax-parse-pattern . more)
|
[(_ syntax-parse-pattern . more)
|
||||||
(values #'(let-syntax ([do-parse (lambda (stx)
|
(values #'(let-syntax ([do-parse (lambda (stx)
|
||||||
(parse stx))])
|
(parse-all stx))])
|
||||||
(do-parse action ...))
|
(do-parse action ...))
|
||||||
#'more)]))))
|
#'more)]))))
|
||||||
#'rest)])))
|
#'rest)])))
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
(require (for-template racket/base
|
(require (for-template racket/base
|
||||||
racket/splicing))
|
racket/splicing))
|
||||||
|
|
||||||
(provide parse)
|
(provide parse parse-all)
|
||||||
|
|
||||||
#;
|
#;
|
||||||
(define-literal-set literals
|
(define-literal-set literals
|
||||||
|
@ -65,8 +65,10 @@
|
||||||
|
|
||||||
(define (semicolon? what)
|
(define (semicolon? what)
|
||||||
(define-literal-set check (semicolon))
|
(define-literal-set check (semicolon))
|
||||||
(and (identifier? what)
|
(define is (and (identifier? what)
|
||||||
((literal-set->predicate check) what)))
|
((literal-set->predicate check) what)))
|
||||||
|
(debug "Semicolon? ~a ~a\n" what is)
|
||||||
|
is)
|
||||||
|
|
||||||
;; 1 + 1
|
;; 1 + 1
|
||||||
;; ^
|
;; ^
|
||||||
|
@ -91,24 +93,32 @@
|
||||||
;; left: (lambda (x) (left (* 1 x)))
|
;; left: (lambda (x) (left (* 1 x)))
|
||||||
;; current: 2
|
;; current: 2
|
||||||
|
|
||||||
|
;; parse one form
|
||||||
|
;; return the parsed stuff and the unparsed stuff
|
||||||
(define (parse input)
|
(define (parse input)
|
||||||
(define (do-parse stream precedence left current)
|
(define (do-parse stream precedence left current)
|
||||||
(debug "parse ~a precedence ~a left ~a current ~a\n" stream precedence left current)
|
(debug "parse ~a precedence ~a left ~a current ~a\n" stream precedence left current)
|
||||||
(syntax-parse stream
|
(syntax-parse stream
|
||||||
[() (left current)]
|
[() (values (left current) #'())]
|
||||||
[(head rest ...)
|
[(head rest ...)
|
||||||
(cond
|
(cond
|
||||||
[(honu-macro? #'head)
|
[(honu-macro? #'head)
|
||||||
(begin
|
(begin
|
||||||
(debug "Honu macro ~a\n" #'head)
|
(debug "Honu macro ~a\n" #'head)
|
||||||
(let-values ([(parsed unparsed)
|
(let-values ([(parsed unparsed terminate?)
|
||||||
((syntax-local-value #'head) #'(head rest ...) #f)])
|
((syntax-local-value #'head) #'(head rest ...) #f)])
|
||||||
(with-syntax ([parsed parsed]
|
(with-syntax ([parsed parsed]
|
||||||
[rest unparsed])
|
[rest unparsed])
|
||||||
(do-parse #'rest precedence (lambda (x)
|
(if terminate?
|
||||||
(with-syntax ([x x])
|
(values (left #'parsed)
|
||||||
#'(begin parsed x)))
|
#'rest)
|
||||||
(left current))
|
(do-parse #'rest precedence
|
||||||
|
(lambda (x) x)
|
||||||
|
#;
|
||||||
|
(lambda (x)
|
||||||
|
(with-syntax ([x x])
|
||||||
|
#'(begin parsed x)))
|
||||||
|
(left #'parsed)))
|
||||||
#;
|
#;
|
||||||
#'(splicing-let-syntax ([more-parsing (lambda (stx)
|
#'(splicing-let-syntax ([more-parsing (lambda (stx)
|
||||||
(do-parse (stx-cdr stx)
|
(do-parse (stx-cdr stx)
|
||||||
|
@ -135,6 +145,9 @@
|
||||||
(lambda (x) x)
|
(lambda (x) x)
|
||||||
(left current)))]
|
(left current)))]
|
||||||
[(semicolon? #'head)
|
[(semicolon? #'head)
|
||||||
|
(values (left current)
|
||||||
|
#'(rest ...))
|
||||||
|
#;
|
||||||
(do-parse #'(rest ...) 0
|
(do-parse #'(rest ...) 0
|
||||||
(lambda (stuff)
|
(lambda (stuff)
|
||||||
(with-syntax ([stuff stuff]
|
(with-syntax ([stuff stuff]
|
||||||
|
@ -151,9 +164,18 @@
|
||||||
[else (syntax-parse #'head
|
[else (syntax-parse #'head
|
||||||
#:literal-sets (cruft)
|
#:literal-sets (cruft)
|
||||||
[x:number (do-parse #'(rest ...)
|
[x:number (do-parse #'(rest ...)
|
||||||
precedence left #'x)]
|
precedence
|
||||||
|
left #'x)]
|
||||||
[(#%parens args ...)
|
[(#%parens args ...)
|
||||||
(debug "function call ~a\n" left)
|
(debug "function call ~a\n" left)
|
||||||
|
(values (left (with-syntax ([current current]
|
||||||
|
[(parsed-args ...)
|
||||||
|
(if (null? (syntax->list #'(args ...)))
|
||||||
|
'()
|
||||||
|
(list (parse-all #'(args ...))))])
|
||||||
|
#'(current parsed-args ...)))
|
||||||
|
#'(rest ...))
|
||||||
|
#;
|
||||||
(do-parse #'(rest ...)
|
(do-parse #'(rest ...)
|
||||||
0
|
0
|
||||||
(lambda (x) x)
|
(lambda (x) x)
|
||||||
|
@ -171,6 +193,24 @@
|
||||||
|
|
||||||
(do-parse input 0 (lambda (x) x) #'(void)))
|
(do-parse input 0 (lambda (x) x) #'(void)))
|
||||||
|
|
||||||
|
(define (empty-syntax? what)
|
||||||
|
(syntax-parse what
|
||||||
|
[() #t]
|
||||||
|
[else #f]))
|
||||||
|
|
||||||
|
(define (parse-all code)
|
||||||
|
(let loop ([all '()]
|
||||||
|
[code code])
|
||||||
|
(define-values (parsed unparsed)
|
||||||
|
(parse code))
|
||||||
|
(debug "Parsed ~a unparsed ~a\n" (syntax->datum parsed)
|
||||||
|
(syntax->datum unparsed))
|
||||||
|
(if (empty-syntax? unparsed)
|
||||||
|
(with-syntax ([(use ...) (reverse (cons parsed all))])
|
||||||
|
#'(begin use ...))
|
||||||
|
(loop (cons parsed all)
|
||||||
|
unparsed))))
|
||||||
|
|
||||||
(define (parse2 forms)
|
(define (parse2 forms)
|
||||||
(debug "parse forms ~a\n" forms)
|
(debug "parse forms ~a\n" forms)
|
||||||
(when (stx-pair? forms)
|
(when (stx-pair? forms)
|
||||||
|
|
|
@ -26,4 +26,9 @@ function test1(){
|
||||||
print(x ^ 2)
|
print(x ^ 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
test1()
|
function test2(x){
|
||||||
|
print(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
test1();
|
||||||
|
test2(5);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[honu-function honu_function]
|
[honu-function honu_function]
|
||||||
[honu-+ honu_plus]
|
[honu-+ honu_plus]
|
||||||
[honu-* honu_times]
|
[honu-* honu_times]
|
||||||
|
[honu-/ honu_division]
|
||||||
[honu-- honu_minus])
|
[honu-- honu_minus])
|
||||||
(rename-in honu/core/private/literals
|
(rename-in honu/core/private/literals
|
||||||
[honu-= =]
|
[honu-= =]
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ stuff)
|
[(_ stuff)
|
||||||
(let ()
|
(let ()
|
||||||
(define output (parse:parse (stx-cdr #'stuff)))
|
(define output (parse:parse-all (stx-cdr #'stuff)))
|
||||||
(printf "Output: ~a\n" (syntax->datum output))
|
(printf "Output: ~a\n" (syntax->datum output))
|
||||||
output)]))
|
output)]))
|
||||||
|
|
||||||
|
@ -36,9 +37,16 @@
|
||||||
}
|
}
|
||||||
foo 5))
|
foo 5))
|
||||||
|
|
||||||
|
#;
|
||||||
|
(fake-module-begin #hx(2))
|
||||||
|
|
||||||
|
(fake-module-begin #hx(1;2))
|
||||||
|
|
||||||
(fake-module-begin #hx(var x = 2;
|
(fake-module-begin #hx(var x = 2;
|
||||||
print(x)))
|
print(x)))
|
||||||
|
|
||||||
|
#|
|
||||||
|
|
||||||
(let ()
|
(let ()
|
||||||
(fake-module-begin #hx(honu_function test(x){
|
(fake-module-begin #hx(honu_function test(x){
|
||||||
print(x)
|
print(x)
|
||||||
|
@ -61,3 +69,4 @@
|
||||||
|
|
||||||
(let ()
|
(let ()
|
||||||
(fake-module-begin #hx(1 honu_plus 1 honu_minus 4 honu_times 8)))
|
(fake-module-begin #hx(1 honu_plus 1 honu_minus 4 honu_times 8)))
|
||||||
|
|#
|
||||||
|
|
Loading…
Reference in New Issue
Block a user