if expressions, done

This commit is contained in:
Scott Richmond 2024-05-08 13:50:26 -04:00
parent f3256f7d12
commit c36a140c6b

View File

@ -48,7 +48,8 @@
(= type current-type)) (= type current-type))
### Parsing functions ### Parsing functions
(declare nonbinding binding synthetic) # forward declarations
(declare simple nonbinding expr toplevel synthetic)
# errors # errors
(def terminators [:break :newline :semicolon :eof]) (def terminators [:break :newline :semicolon :eof])
@ -66,7 +67,7 @@
(has-value? breaking ttype)) (has-value? breaking ttype))
(defn- panic [parser message] (defn- panic [parser message]
# (print "Panic in the parser: " message) (print "Panic in the parser: " message)
(def origin (current parser)) (def origin (current parser))
(advance parser) (advance parser)
(def skipped @[origin]) (def skipped @[origin])
@ -74,7 +75,6 @@
(array/push skipped (current parser)) (array/push skipped (current parser))
(advance parser)) (advance parser))
(array/push skipped (current parser)) (array/push skipped (current parser))
# (advance parser)
(def err {:type :error :data skipped :token origin :msg message}) (def err {:type :error :data skipped :token origin :msg message})
(update parser :errors array/push err) (update parser :errors array/push err)
(error err)) (error err))
@ -88,6 +88,9 @@
(defn- expect-ret [parser type] (defn- expect-ret [parser type]
(try (expect parser type) ([e] e))) (try (expect parser type) ([e] e)))
(defn- capture [parse-fn parser]
(try (parse-fn parser) ([e] e)))
# atoms # atoms
(defn- bool [parser] (defn- bool [parser]
(expect parser :bool) (expect parser :bool)
@ -223,7 +226,7 @@
(advance parser) (advance parser)
ast) ast)
(defn- set [parser] (defn- sett [parser]
(def origin (current parser)) (def origin (current parser))
(advance parser) (advance parser)
(def ast {:type :set :data @[] :token origin}) (def ast {:type :set :data @[] :token origin})
@ -268,11 +271,13 @@
(defn- iff [parser] (defn- iff [parser]
(def ast {:type :if :data @[] :token (current parser)}) (def ast {:type :if :data @[] :token (current parser)})
(advance parser) #consume the if (advance parser) #consume the if
(update ast array/push :data (simple parser)) (array/push (ast :data) (capture simple parser))
(when-let [err (expect-ret parser :then)] (update ast array/push :data err)) (when-let [err (expect-ret parser :then)] (array/push (ast :data) err))
(update ast array/push :data (nonbinding parser)) (advance parser)
(when-let [err (expect-ret parser :else)] (update ast array/push :data err)) (array/push (ast :data) (capture nonbinding parser))
(update ast array/push :data (nonbinding parser)) (when-let [err (expect-ret parser :else)] (array/push (ast :data) err))
(advance parser)
(array/push (ast :data) (capture nonbinding parser))
ast) ast)
(defn- condd [parser]) (defn- condd [parser])
@ -377,7 +382,7 @@
:startdict (dict parser) :startdict (dict parser)
:startset (sett parser) :startset (sett parser)
:word (word parser) :word (word parser)
:if (unreachable) :if (iff parser)
:cond (unreachable) :cond (unreachable)
:match (unreachable) :match (unreachable)
:with (unreachable) :with (unreachable)
@ -409,7 +414,7 @@
:startdict (dict parser) :startdict (dict parser)
:startset (sett parser) :startset (sett parser)
:word (word parser) :word (word parser)
:if (unreachable) :if (iff parser)
:cond (unreachable) :cond (unreachable)
:match (unreachable) :match (unreachable)
:with (unreachable) :with (unreachable)
@ -423,8 +428,8 @@
(import ./scanner :as s) (import ./scanner :as s)
(do (do
#(comment #(comment
(def source "if foo then else baz")
(def scanned (s/scan "#{}")) (def scanned (s/scan source))
(def a-parser (new-parser scanned)) (def a-parser (new-parser scanned))
(def parsed (nonbinding a-parser)) (def parsed (nonbinding a-parser))
(-> parsed) (-> parsed)