Compare commits

..

No commits in common. "2cfe9fdffc3fb779f4716ca84d2b3b7527353c8d" and "b5def30348850526591fd884aaec2c5f2f09f88e" have entirely different histories.

3 changed files with 50 additions and 99 deletions

View File

@ -259,18 +259,13 @@
(def sequels [:lparen :keyword]) (def sequels [:lparen :keyword])
(defn- word-expr [parser] (defn- word [parser]
(expect parser :word) (expect parser :word)
(if (has-value? sequels (-> parser peek type)) (break (synthetic parser))) (if (has-value? sequels (-> parser peek type)) (break (synthetic parser)))
(def curr (-> parser current)) (def curr (-> parser current))
(advance parser) (advance parser)
{:type :word :data (curr :lexeme) :token curr}) {:type :word :data (curr :lexeme) :token curr}
)
(defn- word-only [parser]
(expect parser :word)
(def curr (current parser))
(advance parser)
{:type :word :data (curr :lexeme) :token curr})
(defn- args [parser] (defn- args [parser]
(def origin (current parser)) (def origin (current parser))
@ -294,7 +289,7 @@
(set (ast :partial) true) (set (ast :partial) true)
(advance parser) (advance parser)
{:type :placeholder :token origin})) {:type :placeholder :token origin}))
(capture nonbinding parser))) (try (nonbinding parser) ([e] e))))
(array/push (ast :data) term) (array/push (ast :data) term)
(try (separators parser) (try (separators parser)
([e] (pp e) (array/push (ast :data) e)))) ([e] (pp e) (array/push (ast :data) e))))
@ -302,21 +297,20 @@
ast) ast)
(defn- synth-root [parser] (defn- synth-root [parser]
(print "parsing synth root")
(def origin (current parser)) (def origin (current parser))
(advance parser) (advance parser)
(case (type origin) (case (type origin)
:word {:type :word :data (origin :lexeme) :token origin} :word {:type :word :data (origin :lexeme) :token origin}
:keyword {:type :keyword :data (origin :literal) :token origin} :keyword {:type :keyword :data (origin :literal) :token origin}
:pkg-name {:type :pkg-name :data (origin :lexeme) :token origin} :pkg-name {:type :pkg-name :data (origin :lexem) :token origin}
(panic parser "expected word, keyword, or package") (panic parser "expected word, keyword, or package")
) )
) )
(defrec synthetic [parser] (defrec synthetic [parser]
(print "parsing synthetic")
(def origin (current parser)) (def origin (current parser))
(def ast {:type :synthetic :data @[(synth-root parser)] :token origin}) (def ast {:type :synthetic :data @[(synth-root origin)] :token origin})
(advance parser)
(while (has-value? sequels (-> parser current type)) (while (has-value? sequels (-> parser current type))
(def term (def term
(case (-> parser current type) (case (-> parser current type)
@ -339,7 +333,7 @@
(def err {:type :error :token origin :msg "unclosed paren"}) (def err {:type :error :token origin :msg "unclosed paren"})
(array/push (parser :errors) err) (array/push (parser :errors) err)
(error err)) (error err))
(def term (capture nonbinding parser)) (def term (try (nonbinding parser) ([e] e)))
(array/push (ast :data) term) (array/push (ast :data) term)
(try (separators parser) (try (separators parser)
([e] (pp e) (array/push (ast :data) e)))) ([e] (pp e) (array/push (ast :data) e))))
@ -360,10 +354,10 @@
(def term (if (check parser :splat) (def term (if (check parser :splat)
(do (do
(advance parser) (advance parser)
(def splatted (try (word-only parser) ([e] e))) (def splatted (try (word parser) ([e] e)))
{:type :splat :data splatted :token origin} {:type :splat :data splatted :token origin}
) )
(capture nonbinding parser))) (try (nonbinding parser) ([e] e))))
(array/push (ast :data) term) (array/push (ast :data) term)
(try (separators parser) (try (separators parser)
([e] (array/push (ast :data) e)))) ([e] (array/push (ast :data) e))))
@ -384,10 +378,10 @@
(def term (if (check parser :splat) (def term (if (check parser :splat)
(do (do
(advance parser) (advance parser)
(def splatted (capture word-only parser)) (def splatted (capture word parser))
{:type :splat :data splatted :token origin} {:type :splat :data splatted :token origin}
) )
(capture nonbinding parser))) (try (nonbinding parser) ([e] e))))
(array/push (ast :data) term) (array/push (ast :data) term)
(try (separators parser) (try (separators parser)
([e] (array/push (ast :data) e)))) ([e] (array/push (ast :data) e))))
@ -406,11 +400,11 @@
(error err)) (error err))
(def origin (current parser)) (def origin (current parser))
(def term (case (type origin) (def term (case (type origin)
:splat {:type :splat :data (capture word-only (advance parser)) :token origin} :splat {:type :splat :data (try (word (advance parser)) ([e] e)) :token origin}
:word (try (word-only parser) ([e] e)) :word (try (word parser) ([e] e))
:keyword (do :keyword (do
(def key (try (kw parser) ([e] e))) (def key (try (kw parser) ([e] e)))
(def value (capture nonbinding parser)) (def value (try (nonbinding parser) ([e] e)))
{:type :pair :data [key value] :token origin}) {:type :pair :data [key value] :token origin})
(try (panic parser (string expect "expected dict term, got " (type origin))) ([e] e)) (try (panic parser (string expect "expected dict term, got " (type origin))) ([e] e))
)) ))
@ -454,9 +448,9 @@
(def term (if (check parser :splat) (def term (if (check parser :splat)
(do (do
(advance parser) (advance parser)
(def splatted (when (check parser :word) (word-only parser))) (def splatted (if (check parser :word) (word parser) nil))
{:type :splat :data splatted :token origin}) {:type :splat :data splatted :token origin})
(capture pattern parser))) (try (pattern parser) ([e] e))))
(array/push (ast :data) term) (array/push (ast :data) term)
(try (separators parser) (try (separators parser)
([e] (pp e) (array/push (ast :data) e)))) ([e] (pp e) (array/push (ast :data) e))))
@ -477,9 +471,9 @@
(def term (if (check parser :splat) (def term (if (check parser :splat)
(do (do
(advance parser) (advance parser)
(def splatted (when (check parser :word) (word-only parser))) (def splatted (if (check parser :word) (word parser) nil))
{:type :splat :data splatted :token origin}) {:type :splat :data splatted :token origin})
(capture pattern parser))) (try (pattern parser) ([e] e))))
(array/push (ast :data) term) (array/push (ast :data) term)
(try (separators parser) (try (separators parser)
([e] (array/push (ast :data) e)))) ([e] (array/push (ast :data) e))))
@ -498,8 +492,8 @@
(error err)) (error err))
(def origin (current parser)) (def origin (current parser))
(def term (case (type origin) (def term (case (type origin)
:splat {:type :splat :data (when (check (advance parser) :word) (word-only parser)) :token origin} :splat {:type :splat :data (try (word (advance parser)) ([_] nil)) :token origin}
:word (capture word-pattern parser) :word (try (word parser) ([e] e))
:keyword (do :keyword (do
(def key (capture kw parser)) (def key (capture kw parser))
(def value (capture pattern parser)) (def value (capture pattern parser))
@ -664,49 +658,39 @@
(expect parser :with) (advance parser) (expect parser :with) (advance parser)
(try (try
(do (do
(expect parser :lbrace) (var lbrace (current parser)) (advance parser) (expect parser :lbrace) (advance parser)
(accept-many parser ;terminators) (accept-many parser ;terminators)
(def data @[])
(def clauses @[]) (def clauses @[])
(array/push clauses (with-clause parser)) (array/push clauses (with-clause parser))
(accept-many parser ;terminators) (accept-many parser ;terminators)
(while (not (check parser :rbrace)) (while (not (check parser :rbrace))
(if (check parser :eof) (if (check parser :eof)
(error {:type :error :data [clauses] :token lbrace :msg "unclosed brace"})) (error {:type :error :data data :token origin :msg "unclosed brace"}))
(array/push clauses (with-clause parser)) (array/push clauses (with-clause parser))
(accept-many parser ;terminators)) (accept-many parser ;terminators))
(advance parser) # consume closing brace (array/push data clauses)
(accept-many parser :newline) (accept-many parser :newline)
(expect parser :then) (advance parser) (expect parser :then) (advance parser)
(def then (nonbinding parser)) (array/push data (nonbinding parser))
(accept-many parser :newline) (accept-many parser :newline)
(expect parser :else) (advance parser) (expect parser :else) (advance parser)
(expect parser :lbrace) (set lbrace (current parser)) (advance parser) (array/push data (nonbinding parser))
(accept-many parser ;terminators) {:type :with :data data :token origin})
(def else @[])
(while (not (check parser :rbrace))
(when (check parser :eof) (error {:type :error :token lbrace :data [else] :msg "unclosed brace"}))
(array/push else (match-clause parser)))
(advance parser)
{:type :with :data [clauses then else] :token origin})
([err] err) ([err] err)
) )
) )
### function forms ### function forms
(defn- fn-simple [parser] (defn- fn-simple [parser]
(print "parsing simple function body")
(try (try
(do (do
(def lhs (tup-pattern parser)) (def lhs (tup-pattern parser))
(print "parsed lhs")
(def guard (when (check parser :if) (def guard (when (check parser :if)
(advance parser) (advance parser)
(simple parser))) (simple parser)))
(print "parsed guard")
(expect parser :arrow) (advance parser) (expect parser :arrow) (advance parser)
(print "parsed arrow")
(def rhs (nonbinding parser)) (def rhs (nonbinding parser))
(print "parsed rhs")
[[lhs guard rhs]] [[lhs guard rhs]]
) )
([err] err) ([err] err)
@ -734,7 +718,6 @@
) )
(defn- fn-clauses [parser] (defn- fn-clauses [parser]
(print "parsing fn clauses")
(def origin (current parser)) (def origin (current parser))
(expect parser :lbrace) (advance parser) (expect parser :lbrace) (advance parser)
(accept-many parser ;terminators) (accept-many parser ;terminators)
@ -745,31 +728,25 @@
(array/push data (capture fn-clause parser))) (array/push data (capture fn-clause parser)))
data) data)
(defn- lambda [parser]
(def origin (current parser))
(expect parser :fn) (advance parser)
{:type :fn :data (fn-simple parser) :token origin})
(defn- fnn [parser] (defn- fnn [parser]
(if (= :lparen (-> parser peek type)) (break (lambda parser)))
(try (try
(do (do
(print "parsing named function")
(def origin (current parser)) (def origin (current parser))
(expect parser :fn) (advance parser) (expect parser :fn) (advance parser)
(print "consumed `fn`") (def name (word parser))
(print "next token: ")
(pp (current parser))
(def name (-> parser word-only (get :data)))
(print "function name: ")
(pp name)
(def data (case (-> parser current type) (def data (case (-> parser current type)
:lbrace (fn-clauses parser) :lbrace (fn-clauses parser)
:lparen (fn-simple parser) :lparen (fn-simple parser)
(panic parser (string "expected clause or clauses, got " (-> current parser type))))) (panic parser (string "expected clause or clauses, got " (-> current parser type)))))
{:type :fn :name name :data data :token origin}) {:type :fn :name name :data data :token origin}
)
([err] err))) ([err] err)))
(defn- lambda [parser]
(def origin (current parser))
(expect parser :fn) (advance parser)
{:type :fn :data (fn-simple parser) :token origin})
### compoound forms ### compoound forms
(defn- block [parser] (defn- block [parser]
(def origin (current parser)) (def origin (current parser))
@ -793,10 +770,7 @@
(expect parser :do) (advance parser) (expect parser :do) (advance parser)
(def data @[]) (def data @[])
(array/push data (capture simple parser)) (array/push data (capture simple parser))
(print "added first expression. current token:")
(pp (current parser))
(while (check parser :pipeline) (while (check parser :pipeline)
(advance parser)
(accept-many parser :newline) (accept-many parser :newline)
(array/push data (capture simple parser))) (array/push data (capture simple parser)))
{:type :do :data data :token origin}) {:type :do :data data :token origin})
@ -807,7 +781,7 @@
(expect parser :ref) (advance parser) (expect parser :ref) (advance parser)
(try (try
(do (do
(def name (-> parser word-only (get :data))) (def name (word parser))
(expect parser :equals) (advance parser) (expect parser :equals) (advance parser)
(def value (nonbinding parser)) (def value (nonbinding parser))
{:type :ref :data value :name name :token origin}) {:type :ref :data value :name name :token origin})
@ -833,7 +807,7 @@
(do (do
(def origin (current parser)) (def origin (current parser))
(expect parser :pkg) (advance parser) (expect parser :pkg) (advance parser)
(def name (-> parser pkg-name (get :data))) (def name (pkg-name parser))
(expect parser :lbrace) (advance parser) (expect parser :lbrace) (advance parser)
(accept-many parser ;terminators) (accept-many parser ;terminators)
(def data @[]) (def data @[])
@ -848,7 +822,7 @@
(def key (capture kw parser)) (def key (capture kw parser))
(def value (capture simple parser)) (def value (capture simple parser))
(array/push data {:type :pair :data [key value] :token origin})) (array/push data {:type :pair :data [key value] :token origin}))
:word (array/push (capture word-only parser)) :word (array/push (capture word parser))
(panic parser "expected dict term")) (panic parser "expected dict term"))
(terminator parser)) (terminator parser))
{:type :pkg :data data :token origin :name name}) {:type :pkg :data data :token origin :name name})
@ -859,7 +833,7 @@
(do (do
(def origin (current parser)) (def origin (current parser))
(expect parser :ns) (advance parser) (expect parser :ns) (advance parser)
(def name (-> parser pkg-name (get :data))) (def name (pkg-name parser))
(def body (block parser)) (def body (block parser))
{:type :ns :data body :name name :token origin}) {:type :ns :data body :name name :token origin})
([err] err))) ([err] err)))
@ -869,9 +843,7 @@
(expect parser :import) (advance parser) (expect parser :import) (advance parser)
(def path (str parser)) (def path (str parser))
(expect parser :as) (advance parser) (expect parser :as) (advance parser)
(def name-parser (if (check parser :pkg-name) pkg-name word-only)) (def name (pkg-name parser))
(def name
(-> parser name-parser (get :data)))
{:type :import :data path :name name :token origin}) {:type :import :data path :name name :token origin})
### tests ### tests
@ -902,21 +874,14 @@
(defn- repeatt [parser] (defn- repeatt [parser]
(def origin (current parser)) (def origin (current parser))
(advance parser)
(def times (case (-> parser current type) (def times (case (-> parser current type)
:number (num parser) :number (num parser)
:word (word-only parser) :word (word parser)
(panic parser "expected number or word") (panic parser "expected number or word")
)) ))
(def body (block parser)) (def body (block parser))
{:type :repeat :data [times body] :token origin}) {:type :repeat :data [times body] :token origin})
### panics
(defn- panicc [parser]
(def origin (current parser))
(expect parser :panic) (advance parser)
{:type :panic :data (nonbinding parser) :token origin})
### expressions ### expressions
# four levels of expression complexity: # four levels of expression complexity:
# simple (atoms, collections, synthetic expressions; no conditionals or binding or blocks) # simple (atoms, collections, synthetic expressions; no conditionals or binding or blocks)
@ -939,10 +904,9 @@
:lbracket (list parser) :lbracket (list parser)
:startdict (dict parser) :startdict (dict parser)
:startset (sett parser) :startset (sett parser)
:word (word-expr parser) :word (word parser)
:pkg-name (pkg-name parser) :pkg-name (pkg-name parser)
:recur (recur parser) :recur (recur parser)
:panic (panicc parser)
(panic parser (string expect "expected simple expression, got " (type curr))) (panic parser (string expect "expected simple expression, got " (type curr)))
) )
) )
@ -972,7 +936,7 @@
:startset (sett parser) :startset (sett parser)
# synthetic # synthetic
:word (word-expr parser) :word (word parser)
:pkg-name (pkg-name parser) :pkg-name (pkg-name parser)
:recur (recur parser) :recur (recur parser)
@ -991,13 +955,6 @@
# blocks # blocks
:lbrace (block parser) :lbrace (block parser)
# looping forms
:loop (loopp parser)
:repeat (repeatt parser)
# panic!
:panic (panicc parser)
(panic parser (string "expected nonbinding expression, got " (type curr))) (panic parser (string "expected nonbinding expression, got " (type curr)))
) )
) )
@ -1021,7 +978,7 @@
:lbracket (list parser) :lbracket (list parser)
:startdict (dict parser) :startdict (dict parser)
:startset (sett parser) :startset (sett parser)
:word (word-expr parser) :word (word parser)
:pkg-name (pkg-name parser) :pkg-name (pkg-name parser)
:recur (recur parser) :recur (recur parser)
:if (iff parser) :if (iff parser)
@ -1030,9 +987,6 @@
:with (withh parser) :with (withh parser)
:do (doo parser) :do (doo parser)
:lbrace (block parser) :lbrace (block parser)
:loop (loopp parser)
:repeat (repeatt parser)
:panic (panicc parser)
(panic parser (string "expected expression, got " (type curr))) (panic parser (string "expected expression, got " (type curr)))
) )
) )
@ -1081,14 +1035,13 @@
(do (do
#(comment #(comment
(def source ` (def source `
panic! foo fn foo (x) -> :foo
`) `)
(def scanned (s/scan source)) (def scanned (s/scan source))
(def a-parser (new-parser scanned)) (def a-parser (new-parser scanned))
(def parsed (script a-parser))
(print "\n***NEW PARSE***\n") (print "\n***NEW PARSE***\n")
(def parsed (toplevel a-parser)) (print (pp-ast parsed))
# (print (pp-ast parsed))
(pp parsed)
) )
@ -1096,3 +1049,4 @@ panic! foo
# TODO: # TODO:
# DECIDE: # DECIDE:
# - when to use a flat try/catch format, and when to use capture/expect-ret to get values instead of errors # - when to use a flat try/catch format, and when to use capture/expect-ret to get values instead of errors

View File

@ -264,7 +264,7 @@
"\n" (add-token (update scanner :line inc) :newline) "\n" (add-token (update scanner :line inc) :newline)
"\\" (add-token scanner :backslash) "\\" (add-token scanner :backslash)
"=" (add-token scanner :equals) "=" (add-token scanner :equals)
">" (add-token scanner :pipeline) ">" (add-token (add-token scanner :break) :pipeline)
## two-character tokens ## two-character tokens
## -> ## ->

View File

@ -13,8 +13,5 @@ Tracking here, before I start writing this code, the kinds of validation we're h
* first-level property access with pkg, e.g. `Foo :bar`--bar must be on Foo * first-level property access with pkg, e.g. `Foo :bar`--bar must be on Foo
* recur in tail position in `loop` forms * recur in tail position in `loop` forms
* recur not called outside of `loop` forms * recur not called outside of `loop` forms
* arity checking where possible
- loop forms
- try to resolve function name, if you can, check arity of call
) )