[honu] wrap expressions with a semicolon at the end of them in (%semicolon ...)
This commit is contained in:
parent
b055ce9fe0
commit
dccdcb0550
|
@ -36,7 +36,7 @@
|
||||||
[literal:honu-<- <-]
|
[literal:honu-<- <-]
|
||||||
[honu-map map]
|
[honu-map map]
|
||||||
[honu-flow \|]
|
[honu-flow \|]
|
||||||
[honu-dot |.|]
|
[honu-dot %dot]
|
||||||
[honu-string=? string_equal]
|
[honu-string=? string_equal]
|
||||||
[honu-cons ::]
|
[honu-cons ::]
|
||||||
[honu-and and] [honu-and &&]
|
[honu-and and] [honu-and &&]
|
||||||
|
@ -46,10 +46,10 @@
|
||||||
[honu-structure struct]
|
[honu-structure struct]
|
||||||
[literal:honu-prefix prefix]
|
[literal:honu-prefix prefix]
|
||||||
[literal:honu-then then]
|
[literal:honu-then then]
|
||||||
[literal:colon :]
|
[literal:colon %colon]
|
||||||
[literal:honu-in in]
|
[literal:honu-in in]
|
||||||
[literal:semicolon |;|]
|
[literal:semicolon %semicolon]
|
||||||
[literal:honu-comma |,|]
|
[literal:honu-comma %comma]
|
||||||
[literal:#%brackets #%brackets]
|
[literal:#%brackets #%brackets]
|
||||||
[literal:#%braces #%braces]
|
[literal:#%braces #%braces]
|
||||||
[literal:#%parens #%parens])
|
[literal:#%parens #%parens])
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
syntax/parse/experimental/splicing
|
syntax/parse/experimental/splicing
|
||||||
scheme/splicing
|
scheme/splicing
|
||||||
macro-debugger/emit
|
macro-debugger/emit
|
||||||
|
racket/pretty
|
||||||
"debug.rkt"
|
"debug.rkt"
|
||||||
"contexts.rkt"
|
"contexts.rkt"
|
||||||
"util.rkt"
|
"util.rkt"
|
||||||
|
@ -474,5 +475,5 @@ Then, in the pattern above for 'if', 'then' would be bound to the following synt
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ forms ...)
|
[(_ forms ...)
|
||||||
(begin
|
(begin
|
||||||
(debug "Module begin ~a\n" (syntax->datum #'(forms ...)))
|
(debug "Module begin ~a\n" (pretty-format (syntax->datum #'(forms ...))))
|
||||||
#'(#%module-begin (honu-unparsed-begin forms ...)))]))
|
#'(#%module-begin (honu-unparsed-begin forms ...)))]))
|
||||||
|
|
|
@ -38,10 +38,15 @@
|
||||||
(lambda (code context)
|
(lambda (code context)
|
||||||
(syntax-parse code #:literal-sets (cruft)
|
(syntax-parse code #:literal-sets (cruft)
|
||||||
#:literals (honu-=)
|
#:literals (honu-=)
|
||||||
[(_ name:id honu-= . rest)
|
[(_ name:id honu-= one:honu-expression . rest)
|
||||||
|
(values #'(define name one.result)
|
||||||
|
#'rest
|
||||||
|
#t)
|
||||||
;; parse one expression
|
;; parse one expression
|
||||||
|
#;
|
||||||
(define-values (parsed unparsed)
|
(define-values (parsed unparsed)
|
||||||
(parse #'rest))
|
(parse #'rest))
|
||||||
|
#;
|
||||||
(values
|
(values
|
||||||
(with-syntax ([parsed parsed])
|
(with-syntax ([parsed parsed])
|
||||||
#'(define name parsed))
|
#'(define name parsed))
|
||||||
|
|
|
@ -100,6 +100,7 @@
|
||||||
;; removes syntax that causes expression parsing to stop
|
;; removes syntax that causes expression parsing to stop
|
||||||
(define (strip-stops code)
|
(define (strip-stops code)
|
||||||
(define-syntax-class stopper #:literal-sets (cruft)
|
(define-syntax-class stopper #:literal-sets (cruft)
|
||||||
|
#;
|
||||||
[pattern semicolon]
|
[pattern semicolon]
|
||||||
[pattern honu-comma]
|
[pattern honu-comma]
|
||||||
[pattern colon])
|
[pattern colon])
|
||||||
|
@ -227,11 +228,23 @@
|
||||||
0
|
0
|
||||||
(lambda (x) x)
|
(lambda (x) x)
|
||||||
(left final)))]
|
(left final)))]
|
||||||
|
|
||||||
[(stopper? #'head)
|
[(stopper? #'head)
|
||||||
(values (left final)
|
(values (left final)
|
||||||
stream)]
|
stream)]
|
||||||
[else
|
[else
|
||||||
(syntax-parse #'(head rest ...) #:literal-sets (cruft)
|
(syntax-parse #'(head rest ...) #:literal-sets (cruft)
|
||||||
|
[((semicolon more ...) . rest)
|
||||||
|
#;
|
||||||
|
(define-values (parsed unparsed)
|
||||||
|
(do-parse #'(more ...)
|
||||||
|
0
|
||||||
|
(lambda (x) x)
|
||||||
|
#f))
|
||||||
|
#;
|
||||||
|
(when (not (stx-null? unparsed))
|
||||||
|
(raise-syntax-error 'parse "found unparsed input" unparsed))
|
||||||
|
(values (parse-all #'(more ...)) #'rest)]
|
||||||
[(function:honu-function . rest)
|
[(function:honu-function . rest)
|
||||||
(values #'function.result #'rest)]
|
(values #'function.result #'rest)]
|
||||||
#;
|
#;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
parse-error
|
parse-error
|
||||||
left-bracket right-bracket
|
left-bracket right-bracket
|
||||||
left-brace right-brace
|
left-brace right-brace
|
||||||
|
semicolon
|
||||||
block-comment
|
block-comment
|
||||||
end-of-line-comment])
|
end-of-line-comment])
|
||||||
|
|
||||||
|
@ -67,13 +68,13 @@
|
||||||
#;
|
#;
|
||||||
[block-comment (token-whitespace)]
|
[block-comment (token-whitespace)]
|
||||||
["/*" (token-block-comment)]
|
["/*" (token-block-comment)]
|
||||||
["." (token-identifier '|.|)]
|
["." (token-identifier '%dot)]
|
||||||
["," (token-identifier '|,|)]
|
["," (token-identifier '%comma)]
|
||||||
[":" (token-identifier ':)]
|
[":" (token-identifier '%colon)]
|
||||||
["'" (token-identifier 'quote)]
|
["'" (token-identifier 'quote)]
|
||||||
["`" (token-identifier 'quasiquote)]
|
["`" (token-identifier 'quasiquote)]
|
||||||
[operator (token-identifier (string->symbol lexeme))]
|
[operator (token-identifier (string->symbol lexeme))]
|
||||||
[";" (token-identifier '|;|)]
|
[";" (token-semicolon)]
|
||||||
;; strip the quotes from the resulting string
|
;; strip the quotes from the resulting string
|
||||||
;; TODO: find a more optimal way
|
;; TODO: find a more optimal way
|
||||||
[string (let ()
|
[string (let ()
|
||||||
|
@ -109,7 +110,8 @@
|
||||||
block-comment parse-error
|
block-comment parse-error
|
||||||
identifier left-parens right-parens
|
identifier left-parens right-parens
|
||||||
left-bracket right-bracket
|
left-bracket right-bracket
|
||||||
left-brace right-brace)
|
left-brace right-brace
|
||||||
|
semicolon)
|
||||||
|
|
||||||
;; returns #t if an entire comment was read (with an ending newline)
|
;; returns #t if an entire comment was read (with an ending newline)
|
||||||
(define (read-until-end-of-line input)
|
(define (read-until-end-of-line input)
|
||||||
|
@ -294,6 +296,63 @@
|
||||||
|
|
||||||
(define (do-empty current tokens table)
|
(define (do-empty current tokens table)
|
||||||
(reverse current))
|
(reverse current))
|
||||||
|
|
||||||
|
(define (contains-semicolon? syntax)
|
||||||
|
(syntax-case syntax (%semicolon #%braces #%parens)
|
||||||
|
[(%semicolon x ...) #t]
|
||||||
|
[#%braces #t]
|
||||||
|
[(#%braces x ...) #t]
|
||||||
|
#;
|
||||||
|
[(#%parens x ...) #t]
|
||||||
|
[else #f]))
|
||||||
|
|
||||||
|
;; wraps syntax objects with (%semicolon ...)
|
||||||
|
;; it will search backwards through the list of already created syntax objects
|
||||||
|
;; until it either runs out of syntax objects or finds one already wrapped with
|
||||||
|
;; (%semicolon ...)
|
||||||
|
;;
|
||||||
|
;; if the original input is '1 + 2; 3 + 4;' this will get read as
|
||||||
|
;; (1 + 2 %semicolon 3 + 4 %semicolon)
|
||||||
|
;; then parsing will start from the front. when %semicolon is reached we will have
|
||||||
|
;; the following (current is always backwards).
|
||||||
|
;; current: (2 + 1)
|
||||||
|
;; do-semicolon will search this for a syntax object containing (%semicolon ...) but
|
||||||
|
;; since one doesn't appear the entire expression will be reversed and wrapped thus
|
||||||
|
;; resulting in
|
||||||
|
;; (%semicolon 1 + 2)
|
||||||
|
;;
|
||||||
|
;; Now parsing continues with (3 + 4 %semicolon). When the next %semicolon is hit we
|
||||||
|
;; will have
|
||||||
|
;; current: (4 + 3 (%semicolon 1 + 2))
|
||||||
|
;;
|
||||||
|
;; So do-semicolon will find (%semicolon 1 + 2) and leave stop processing there,
|
||||||
|
;; resulting in
|
||||||
|
;; ((%semicolon 3 + 4) (%semicolon 1 + 2))
|
||||||
|
;;
|
||||||
|
;; The entire list will be reversed at the end of parsing.
|
||||||
|
(define (do-semicolon current tokens table)
|
||||||
|
;; (debug "Do semicolon on ~a\n" current)
|
||||||
|
(define-values (wrap ok)
|
||||||
|
(let loop ([found '()]
|
||||||
|
[rest current])
|
||||||
|
(match rest
|
||||||
|
[(list) (values found rest)]
|
||||||
|
[(list (and (? contains-semicolon?) head) rest* ...)
|
||||||
|
(values found rest)]
|
||||||
|
[(list head rest ...)
|
||||||
|
(loop (cons head found) rest)])))
|
||||||
|
(define semicolon (make-syntax `(%semicolon ,@wrap)
|
||||||
|
;; FIXME: this is probably the wrong token
|
||||||
|
;; to get source location from
|
||||||
|
(car tokens)
|
||||||
|
source))
|
||||||
|
|
||||||
|
(do-parse (cons semicolon ok)
|
||||||
|
(cdr tokens)
|
||||||
|
table))
|
||||||
|
|
||||||
|
(define (semicolon? tokens)
|
||||||
|
(is-first-token token-semicolon? tokens))
|
||||||
|
|
||||||
(define (left-parens? tokens)
|
(define (left-parens? tokens)
|
||||||
(is-first-token token-left-parens? tokens))
|
(is-first-token token-left-parens? tokens))
|
||||||
|
@ -334,7 +393,8 @@
|
||||||
(define do-left-bracket (make-encloser '#%brackets "}" right-bracket?))
|
(define do-left-bracket (make-encloser '#%brackets "}" right-bracket?))
|
||||||
(define do-left-brace (make-encloser '#%braces "]" right-brace?))
|
(define do-left-brace (make-encloser '#%braces "]" right-brace?))
|
||||||
|
|
||||||
(define dispatch-table (list [list atom? do-atom]
|
(define dispatch-table (list [list semicolon? do-semicolon]
|
||||||
|
[list atom? do-atom]
|
||||||
[list left-parens? do-left-parens]
|
[list left-parens? do-left-parens]
|
||||||
[list left-bracket? do-left-bracket]
|
[list left-bracket? do-left-bracket]
|
||||||
[list left-brace? do-left-brace]
|
[list left-brace? do-left-brace]
|
||||||
|
|
|
@ -9,24 +9,24 @@ class Xml(data){
|
||||||
}
|
}
|
||||||
|
|
||||||
Element(name){
|
Element(name){
|
||||||
new Xml(get_element(data, name));
|
new Xml(get_element(data, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
Value(){
|
Value(){
|
||||||
get_text(data);
|
get_text(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
getData(){ data }
|
getData(){ data }
|
||||||
};
|
}
|
||||||
|
|
||||||
read_xml(){
|
read_xml(){
|
||||||
xml_permissive_xexprs(true);
|
xml_permissive_xexprs(true)
|
||||||
xml_xml_to_xexpr(xml_document_element(xml_read_xml()));
|
xml_xml_to_xexpr(xml_document_element(xml_read_xml()))
|
||||||
}
|
}
|
||||||
|
|
||||||
loadXml(file){
|
loadXml(file){
|
||||||
with_input_from_file(file){
|
with_input_from_file(file){
|
||||||
new Xml(read_xml());
|
new Xml(read_xml())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,23 +34,23 @@ starts_with(start, what){
|
||||||
substring(what, 0, string_length(start)) string_equal start
|
substring(what, 0, string_length(start)) string_equal start
|
||||||
}
|
}
|
||||||
|
|
||||||
var xml = loadXml("test.xml");
|
var xml = loadXml("test.xml")
|
||||||
printf("xml ~a\n", xml);
|
printf("xml ~a\n", xml)
|
||||||
printf("data: ~a\n", xml.getData());
|
printf("data: ~a\n", xml.getData())
|
||||||
printf("table1: ~a\n", xml.Descendants("Table1"));
|
printf("table1: ~a\n", xml.Descendants("Table1"))
|
||||||
|
|
||||||
struct test{name, address};
|
struct test{name, address}
|
||||||
|
|
||||||
var addresses = linq from add in xml.Descendants("Table1")
|
var addresses = linq from add in xml.Descendants("Table1")
|
||||||
where true
|
where true
|
||||||
orderby add.Element("familyName").Value()
|
orderby add.Element("familyName").Value()
|
||||||
select test(add.Element("familyName").Value(),
|
select test(add.Element("familyName").Value(),
|
||||||
add.Element("address").Value());
|
add.Element("address").Value())
|
||||||
|
|
||||||
printf("addresses ~a\n", addresses);
|
printf("addresses ~a\n", addresses)
|
||||||
|
|
||||||
for add in addresses do {
|
for add in addresses do {
|
||||||
printf("name ~a address ~a\n", add.name, add.address);
|
printf("name ~a address ~a\n", add.name, add.address)
|
||||||
}
|
}
|
||||||
|
|
||||||
for xs in linq from foo in xml.Descendants("Table1")
|
for xs in linq from foo in xml.Descendants("Table1")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user