From 279598fd1d5aace000231e4e85e5f9967634ce81 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Thu, 14 May 2015 07:46:30 -0400 Subject: - Multi-line comments have returned. --- src/lux/base.clj | 6 ------ src/lux/lexer.clj | 27 ++++++++++++++++++--------- src/lux/reader.clj | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/lux/base.clj b/src/lux/base.clj index 3ac994043..9ea255132 100644 --- a/src/lux/base.clj +++ b/src/lux/base.clj @@ -32,18 +32,12 @@ (defn T [& elems] (to-array elems)) -;; (definline T [& elems] -;; `(to-array (list ~@elems))) (defn V [tag value] (to-array [tag value])) -;; (definline V [tag value] -;; `(to-array [~tag ~value])) (defn R [& kvs] (to-array kvs)) -;; (definline R [& kvs] -;; `(to-array (list ~@kvs))) (defn get$ [slot ^objects record] (aget record slot)) diff --git a/src/lux/lexer.clj b/src/lux/lexer.clj index 31258bc4b..2ee8088d3 100644 --- a/src/lux/lexer.clj +++ b/src/lux/lexer.clj @@ -35,23 +35,32 @@ (return (&/V "lux;Meta" (&/T meta (&/V "White_Space" white-space)))))) (def ^:private lex-single-line-comment - (|do [[_ [meta _]] (&reader/read-text "##") - [_ [_ comment]] (&reader/read-regex #"^(.*)$")] + (|do [_ (&reader/read-text "##") + [_ [meta comment]] (&reader/read-regex #"^(.*)$")] (return (&/V "lux;Meta" (&/T meta (&/V "Comment" comment)))))) (defn ^:private lex-multi-line-comment [_] (|do [_ (&reader/read-text "#(") - [meta comment] (&/try-all% (&/|list (|do [[_ [meta comment]] (&reader/read-regex #"(?is)^((?!#\().)*?(?=\)#)")] - (return comment)) - (|do [[_ [meta pre]] (&reader/read-regex #"(?is)^(.+?(?=#\())") - [_ inner] (lex-multi-line-comment nil) - [_ [_ post]] (&reader/read-regex #"(?is)^(.+?(?=\)#))")] - (return (str pre "#(" inner ")#" post))))) + [meta comment] (&/try-all% (&/|list (|do [[_ [meta comment]] (&reader/read-regex #"(?is)^(?!#\()(.*?(?=\)#))") + ;; :let [_ (prn 'immediate comment)] + _ (&reader/read-text ")#")] + (return (&/T meta comment))) + (|do [;; :let [_ (prn 'pre/_0)] + [_ [meta pre]] (&reader/read-regex+ #"(?is)^(.*?)(#\(|$)") + ;; :let [_ (prn 'pre pre)] + [_ [_ [_ inner]]] (lex-multi-line-comment nil) + ;; :let [_ (prn 'inner inner)] + [_ [_ post]] (&reader/read-regex #"(?is)^(.+?(?=\)#))") + ;; :let [_ (prn 'post post (str pre "#(" inner ")#" post))] + ] + (return (&/T meta (str pre "#(" inner ")#" post)))))) + ;; :let [_ (prn 'lex-multi-line-comment (str comment ")#"))] _ (&reader/read-text ")#")] (return (&/V "lux;Meta" (&/T meta (&/V "Comment" comment)))))) (def ^:private lex-comment - (&/try-all% (&/|list lex-single-line-comment))) + (&/try-all% (&/|list lex-single-line-comment + (lex-multi-line-comment nil)))) (do-template [ ] (def diff --git a/src/lux/reader.clj b/src/lux/reader.clj index 69c95ea6a..c25870168 100644 --- a/src/lux/reader.clj +++ b/src/lux/reader.clj @@ -26,12 +26,28 @@ output)) ))) +(defn ^:private with-lines [body] + (fn [state] + (matchv ::M/objects [(body (&/get$ &/$SOURCE state))] + [["lux;Right" [reader* match]]] + (return* (&/set$ &/$SOURCE reader* state) + match) + + [["lux;Left" msg]] + (fail* msg) + ))) + ;; [Exports] (defn ^:private re-find! [^java.util.regex.Pattern regex line] (let [matcher (.matcher regex line)] (when (.find matcher) (.group matcher 0)))) +(defn ^:private re-find1! [^java.util.regex.Pattern regex line] + (let [matcher (.matcher regex line)] + (when (.find matcher) + (.group matcher 1)))) + (defn ^:private re-find3! [^java.util.regex.Pattern regex line] (let [matcher (.matcher regex line)] (when (.find matcher) @@ -42,10 +58,12 @@ (defn read-regex [regex] (with-line (fn [file-name line-num column-num ^String line] - (if-let [^String match (re-find! regex line)] - (let [match-length (.length match) + (if-let [^String match (do ;; (prn '[regex line] [regex line]) + (re-find! regex line))] + (let [;; _ (prn 'match match) + match-length (.length match) line* (.substring line match-length)] - (if (empty? line*) + (if (.isEmpty line*) (&/V "Done" (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) match))) (&/V "Yes" (&/T (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) match)) (&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*)))))) @@ -57,12 +75,34 @@ (if-let [[^String match tok1 tok2] (re-find3! regex line)] (let [match-length (.length match) line* (.substring line match-length)] - (if (empty? line*) + (if (.isEmpty line*) (&/V "Done" (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) (&/T tok1 tok2)))) (&/V "Yes" (&/T (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) (&/T tok1 tok2))) (&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*)))))) (&/V "No" (str "[Reader Error] Pattern failed: " regex)))))) +(defn read-regex+ [regex] + (with-lines + (fn [reader] + (loop [prefix "" + reader* reader] + (matchv ::M/objects [reader*] + [["lux;Nil" _]] + (&/V "lux;Left" "[Reader Error] EOF") + + [["lux;Cons" [[_ [[file-name line-num column-num] ^String line]] + reader**]]] + (if-let [^String match (do ;; (prn 'read-regex+ regex line) + (re-find1! regex line))] + (let [match-length (.length match) + line* (.substring line match-length)] + (if (.isEmpty line*) + (recur (str prefix match "\n") reader**) + (&/V "lux;Right" (&/T (&/|cons (&/V "lux;Meta" (&/T (&/T file-name line-num (+ column-num match-length)) line*)) + reader**) + (&/V "lux;Meta" (&/T (&/T file-name line-num column-num) (str prefix match))))))) + (&/V "lux;Left" (str "[Reader Error] Pattern failed: " regex)))))))) + (defn read-text [^String text] (with-line (fn [file-name line-num column-num ^String line] -- cgit v1.2.3