Compare commits

...

3 Commits

Author SHA1 Message Date
Scott Richmond
c5d04ddd66 some unfinished work on string interpolation 2024-05-08 17:42:10 -04:00
Scott Richmond
3466b075af add easy patterns, start work on string interpolation 2024-05-08 17:31:47 -04:00
Scott Richmond
736f1024c3 fix nil parser bug, start work on patterns 2024-05-08 17:24:29 -04:00
2 changed files with 51 additions and 19 deletions

View File

@ -161,16 +161,15 @@
(defn- nill [parser] (defn- nill [parser]
(expect parser :nil) (expect parser :nil)
(def curr (current parser))
(advance parser) (advance parser)
{:type :nil :token (current parser)} {:type :nil :token curr})
)
(defn- str [parser] (defn- str [parser]
(expect parser :string) (expect parser :string)
(def curr (-> parser current)) (def curr (-> parser current))
(advance parser) (advance parser)
{:type :string :data (curr :literal) :token curr} {:type :string :data (curr :literal) :token curr})
)
# words & synthetic expressions # words & synthetic expressions
(def separates [:break :newline :comma]) (def separates [:break :newline :comma])
@ -311,6 +310,44 @@
ast) ast)
### patterns ### patterns
(declare pattern)
(defn- placeholder [parser]
(expect parser :placeholder :ignored)
(def origin (current parser))
(advance parser)
{:type :placeholder :token origin})
(defn- word-pattern [parser]
(expect parser :word)
(def origin (current parser))
(advance parser)
{:type :word :data (origin :lexeme) :token origin})
(defn- tuple-pattern [parser])
(defn- list-pattern [parser])
(defn- dict-pattern [parser])
(defn- string-pattern [parser])
(defrec pattern [parser]
(case (-> parser current type)
:nil (nill parser)
:true (bool parser)
:false (bool parser)
:keyword (kw parser)
:number (number parser)
:string (str parser)
:word (word-pattern parser)
:placeholder (placeholder parser)
:lparen (tuple-pattern parser)
:lbracket (list-pattern parser)
:startdict (dict-pattern parser)
:interpolated (string-pattern parser)
(panic parser "expected pattern")
))
### conditional forms ### conditional forms
# if {simple} then {nonbinding} else {nonbinding} # if {simple} then {nonbinding} else {nonbinding}
@ -338,6 +375,7 @@
(while (terminates? parser) (advance parser))) (while (terminates? parser) (advance parser)))
# {simple} -> {nonbinding} {terminator} # {simple} -> {nonbinding} {terminator}
### TODO: add placeholder as valid lhs
(defn- when-clause [parser] (defn- when-clause [parser]
(try (try
(do (do
@ -513,18 +551,12 @@
(import ./scanner :as s) (import ./scanner :as s)
(do (do
#(comment #(comment
(def source `when { (def source `"foo {bar} \{baz"`)
a -> b
foo -> bar quux
-> baz
c -> d
}
`)
(def scanned (s/scan source)) (def scanned (s/scan source))
(def a-parser (new-parser scanned)) # (def a-parser (new-parser scanned))
(def parsed (whenn a-parser)) # (def parsed (whenn a-parser))
(-> parsed) # (-> parsed)
# (map (fn [t] (t :type)) (scanned :tokens)) (first (scanned :tokens))
) )

View File

@ -187,7 +187,6 @@
:else (add-error scanner (string "Unexpected " curr " after number " num "."))))) :else (add-error scanner (string "Unexpected " curr " after number " num ".")))))
(recur scanner (buffer char) false)) (recur scanner (buffer char) false))
## TODO: activate string interpolation
(defn- add-string (defn- add-string
[scanner] [scanner]
(print "Adding string") (print "Adding string")
@ -197,9 +196,10 @@
"{" (recur (advance scanner) (buffer/push buff char) true) "{" (recur (advance scanner) (buffer/push buff char) true)
# allow multiline strings # allow multiline strings
"\n" (recur (update (advance scanner) :line inc) (buffer/push buff char) interpolate?) "\n" (recur (update (advance scanner) :line inc) (buffer/push buff char) interpolate?)
### TODO: add interpolated strings "\"" (add-token (advance scanner) (if interpolate? :interpolated :string)(string buff))
### :string -> (if (interpolate? :interpolated :string)) ### FIXME: Actually add the escaped character to the string;
"\"" (add-token (advance scanner) :string (string buff)) ### The only weird escapy-thing is actually the lbrace
### So only do anything fancy if the next char is "{"
"\\" (let [next (next-char scanner) "\\" (let [next (next-char scanner)
scanner (if (= next "\n") scanner (if (= next "\n")
(update scanner :line inc) (update scanner :line inc)