many bugfixes; desugar pairs with word shorthand in dicts
This commit is contained in:
parent
2cfe9fdffc
commit
68e96bf223
|
@ -1,20 +1,15 @@
|
|||
### A recursive descent parser for Ludus
|
||||
|
||||
### We still need to scan some things
|
||||
(os/cd "janet") # when in repl to do relative imports
|
||||
#(os/cd "janet") # when in repl to do relative imports
|
||||
(import ./scanner :as s)
|
||||
|
||||
### First, some mutual recursion helpers
|
||||
(defn unreachable
|
||||
"A function that errors out if called."
|
||||
[&] (error "reached the unreachable"))
|
||||
|
||||
(defmacro declare
|
||||
"Forward-declares a function name, so that it can be called in a mutually recursive manner."
|
||||
[& names]
|
||||
(def bindings @[])
|
||||
(loop [name :in names]
|
||||
(def binding ~(var ,name unreachable))
|
||||
(def binding ~(var ,name nil))
|
||||
(array/push bindings binding))
|
||||
~(upscope ,;bindings))
|
||||
|
||||
|
@ -22,7 +17,7 @@
|
|||
"Defines a function depended on by another function, that has been forward `declare`d."
|
||||
[name & forms]
|
||||
(if-not (dyn name) (error "recursive functions must be declared before they are defined"))
|
||||
~(set ,name (defn ,name ,;forms)))
|
||||
~(set ,name (defn- ,name ,;forms)))
|
||||
|
||||
### Next: a data structure for a parser
|
||||
(defn- new-parser
|
||||
|
@ -139,7 +134,7 @@
|
|||
|
||||
# atoms
|
||||
(defn- bool [parser]
|
||||
(expect parser :bool)
|
||||
(expect parser :true :false)
|
||||
(def curr (-> parser current))
|
||||
(def ttype (type curr))
|
||||
(def value (if (= ttype :true) true false))
|
||||
|
@ -194,9 +189,6 @@
|
|||
{:type :word :data (first-token :lexeme) :token first-token}
|
||||
:else {:type :error :msg "string interpolations/patterns must be single words"}))
|
||||
|
||||
(def foo [{:foo :bar}])
|
||||
(-> foo first (get :foo))
|
||||
|
||||
(defn- is-error? [data]
|
||||
(cond
|
||||
(buffer? data) false
|
||||
|
@ -360,7 +352,7 @@
|
|||
(def term (if (check parser :splat)
|
||||
(do
|
||||
(advance parser)
|
||||
(def splatted (try (word-only parser) ([e] e)))
|
||||
(def splatted (capture word-only parser))
|
||||
{:type :splat :data splatted :token origin}
|
||||
)
|
||||
(capture nonbinding parser)))
|
||||
|
@ -412,7 +404,7 @@
|
|||
(def key (try (kw parser) ([e] e)))
|
||||
(def value (capture nonbinding parser))
|
||||
{:type :pair :data [key value] :token origin})
|
||||
(try (panic parser (string expect "expected dict term, got " (type origin))) ([e] e))
|
||||
(try (panic parser (string "expected dict term, got " (type origin))) ([e] e))
|
||||
))
|
||||
(array/push (ast :data) term)
|
||||
(try (separators parser) ([e] (array/push (ast :data) e))))
|
||||
|
@ -499,12 +491,16 @@
|
|||
(def origin (current parser))
|
||||
(def term (case (type origin)
|
||||
:splat {:type :splat :data (when (check (advance parser) :word) (word-only parser)) :token origin}
|
||||
:word (capture word-pattern parser)
|
||||
:word (do
|
||||
(def word (capture word-pattern parser))
|
||||
(def name (word :data))
|
||||
(def key {:type :keyword :data (keyword name) :token origin})
|
||||
{:type :pair :data [key word] :token origin})
|
||||
:keyword (do
|
||||
(def key (capture kw parser))
|
||||
(def value (capture pattern parser))
|
||||
{:type :pair :data [key value] :token origin})
|
||||
(try (panic parser (string expect "expected dict term, got " (type origin))) ([e] e))
|
||||
(try (panic parser (string "expected dict term, got " (type origin))) ([e] e))
|
||||
))
|
||||
(array/push (ast :data) term)
|
||||
(try (separators parser) ([e] (array/push (ast :data) e))))
|
||||
|
@ -743,6 +739,7 @@
|
|||
(if (check parser :eof)
|
||||
(error {:type :error :token origin :data data :msg "unclosed brace"}))
|
||||
(array/push data (capture fn-clause parser)))
|
||||
(advance parser)
|
||||
data)
|
||||
|
||||
(defn- lambda [parser]
|
||||
|
@ -781,6 +778,7 @@
|
|||
(error {:type :error :token origin :data data :msg "unclosed brace"}))
|
||||
(array/push data (capture expr parser))
|
||||
(terminator parser))
|
||||
(advance parser)
|
||||
{:type :block :data data :token origin})
|
||||
|
||||
### TODO: decide whether this design works
|
||||
|
@ -943,7 +941,7 @@
|
|||
:pkg-name (pkg-name parser)
|
||||
:recur (recur parser)
|
||||
:panic (panicc parser)
|
||||
(panic parser (string expect "expected simple expression, got " (type curr)))
|
||||
(panic parser (string "expected simple expression, got " (type curr)))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -1017,6 +1015,7 @@
|
|||
:number (num parser)
|
||||
:keyword (kw parser)
|
||||
:string (str parser)
|
||||
:interpolated (interpolated parser)
|
||||
:lparen (tup parser)
|
||||
:lbracket (list parser)
|
||||
:startdict (dict parser)
|
||||
|
@ -1060,6 +1059,12 @@
|
|||
(capture terminator parser))
|
||||
{:type :script :data lines :token origin})
|
||||
|
||||
(defn parse [scanned]
|
||||
(def parser (new-parser scanned))
|
||||
(def ast (script parser))
|
||||
(set (parser :ast) ast)
|
||||
parser)
|
||||
|
||||
(defn- indent-by [n]
|
||||
(def indentation @"")
|
||||
(repeat n (buffer/push indentation ".."))
|
||||
|
@ -1081,12 +1086,13 @@
|
|||
(do
|
||||
#(comment
|
||||
(def source `
|
||||
panic! foo
|
||||
"foo {bar} baz"
|
||||
`)
|
||||
(def scanned (s/scan source))
|
||||
(def a-parser (new-parser scanned))
|
||||
(print "\n***NEW PARSE***\n")
|
||||
(def parsed (toplevel a-parser))
|
||||
(def a-parser (new-parser scanned))
|
||||
(def parsed (script a-parser))
|
||||
|
||||
# (print (pp-ast parsed))
|
||||
(pp parsed)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user