Simplify conditional forms: when, if, etc.

This commit is contained in:
Scott Richmond 2023-05-31 11:18:55 -06:00
parent 67e230c714
commit c8c74fbd49
5 changed files with 45 additions and 32 deletions

View File

@ -21,7 +21,7 @@ Finish interpreter
[ ] Merge new interpreter [ ] Merge new interpreter
Write a compiler: desugaring Write a compiler: desugaring
[ ] `...` to `..._` in tuple & list patterns [~] `...` to `..._` in tuple & list patterns
[ ] placeholder partial application to anonymous lambda [ ] placeholder partial application to anonymous lambda
[ ] word -> :[word] word in pairs (patterns & expressions) [ ] word -> :[word] word in pairs (patterns & expressions)
@ -31,10 +31,10 @@ Write a compiler: correctness
[ ] check that recur is in tail position [ ] check that recur is in tail position
[ ] check that recur is only called inside loop or fn forms [ ] check that recur is only called inside loop or fn forms
[ ] check ns accesses [ ] check ns accesses
[ ] prevent import cycles
[ ] splattern is last member in a pattern [ ] splattern is last member in a pattern
[ ] -----List/Tuple [ ] -----List/Tuple
[ ] -----Dict/Struct/Set [ ] -----Dict/Struct/Set
[ ] prevent import cycles
Write a compiler: optimization Write a compiler: optimization
[ ] devise tail call optimization [ ] devise tail call optimization

View File

@ -4,35 +4,25 @@
(declare expression pattern) (declare expression pattern)
;(def separator (choice :separator [:comma :newline :break]))
(defp separator choice [:comma :newline :break]) (defp separator choice [:comma :newline :break])
;(def separators (quiet (one+ separator)))
(defp separators quiet one+ separator) (defp separators quiet one+ separator)
;(def terminator (choice :terminator [:newline :semicolon :break]))
(defp terminator choice [:newline :semicolon :break]) (defp terminator choice [:newline :semicolon :break])
;(def terminators (quiet (one+ terminator)))
(defp terminators quiet one+ terminator) (defp terminators quiet one+ terminator)
;(def nls? (quiet (zero+ :nls :newline)))
(defp nls? quiet zero+ :newline) (defp nls? quiet zero+ :newline)
;(def splat (group (order-1 :splat [(quiet :splat) :word])))
(defp splat group order-1 [(quiet :splat) :word]) (defp splat group order-1 [(quiet :splat) :word])
;(def splattern (group (order-1 :splat [(quiet :splat) (maybe (flat (choice :splatted [:word :ignored :placeholder])))])))
(defp patt-splat-able flat choice [:word :ignored :placeholder]) (defp patt-splat-able flat choice [:word :ignored :placeholder])
(defp splattern group order-1 [(quiet :splat) (maybe patt-splat-able)]) (defp splattern group order-1 [(quiet :splat) (maybe patt-splat-able)])
;(def literal (flat (choice :literal [:nil :true :false :number :string])))
(defp literal flat choice [:nil :true :false :number :string]) (defp literal flat choice [:nil :true :false :number :string])
;(def tuple-pattern-term (flat (choice :tuple-pattern-term [pattern splattern])))
(defp tuple-pattern-term flat choice [pattern splattern]) (defp tuple-pattern-term flat choice [pattern splattern])
;(def tuple-pattern-entry (weak-order :tuple-pattern-entry [tuple-pattern-term separators]))
(defp tuple-pattern-entry weak-order [tuple-pattern-term separators]) (defp tuple-pattern-entry weak-order [tuple-pattern-term separators])
(defp tuple-pattern group order-1 [(quiet :lparen) (defp tuple-pattern group order-1 [(quiet :lparen)
@ -65,7 +55,7 @@
(quiet :rbrace) (quiet :rbrace)
]) ])
(defp guard order-0 [(quiet :when) expression]) (defp guard order-0 [(quiet :if) expression])
(defp pattern flat choice [literal (defp pattern flat choice [literal
:ignored :ignored
@ -73,16 +63,17 @@
typed typed
:word :word
:keyword :keyword
:else
tuple-pattern tuple-pattern
dict-pattern dict-pattern
struct-pattern struct-pattern
list-pattern]) list-pattern])
(defp match-clause group weak-order :match-clause [pattern (maybe guard) (quiet :rarrow) expression]) (defp match-clause group weak-order [pattern (maybe guard) (quiet :rarrow) expression])
(defp match-entry weak-order [match-clause terminators]) (defp match-entry weak-order [match-clause terminators])
(defp match group order-1 [(quiet :match) expression nls? (defp match-old group order-1 [(quiet :match) expression nls?
(quiet :with) (quiet :lbrace) (quiet :with) (quiet :lbrace)
(quiet (zero+ terminator)) (quiet (zero+ terminator))
(one+ match-entry) (one+ match-entry)
@ -105,11 +96,26 @@
(defp cond-entry weak-order [cond-clause terminators]) (defp cond-entry weak-order [cond-clause terminators])
(defp cond-expr group order-1 [(quiet :cond) (quiet :lbrace) (defp cond-old group order-1 [(quiet :cond) (quiet :lbrace)
(quiet (zero+ terminator)) (quiet (zero+ terminator))
(one+ cond-entry) (one+ cond-entry)
(quiet :rbrace)]) (quiet :rbrace)])
(defp match group order-1 [expression nls?
(quiet :is) (quiet :lbrace)
(quiet (zero+ terminator))
(one+ match-entry)
(quiet :rbrace)])
(defp cond-expr group order-1 [(quiet :lbrace)
(quiet (zero+ terminator))
(one+ cond-entry)
(quiet :rbrace)])
(defp when-tail flat choice [match cond-expr])
(defp when-expr weak-order [(quiet :when) when-tail])
(defp let-expr group order-1 [(quiet :let) (defp let-expr group order-1 [(quiet :let)
pattern pattern
(quiet :equals) (quiet :equals)
@ -229,11 +235,12 @@
(flat (choice :loop-body [fn-clause compound-loop]))]) (flat (choice :loop-body [fn-clause compound-loop]))])
(defp expression flat choice [fn-expr (defp expression flat choice [fn-expr
match ;match
loop-expr loop-expr
let-expr let-expr
if-expr if-expr
cond-expr ;cond-expr
when-expr
spawn spawn
receive receive
synthetic synthetic

View File

@ -275,7 +275,7 @@
;(println "Matching " value " with pattern type " (:type pattern)) ;(println "Matching " value " with pattern type " (:type pattern))
(let [ctx @ctx-vol] (let [ctx @ctx-vol]
(case (:type pattern) (case (:type pattern)
(:placeholder :ignored) (:placeholder :ignored :else)
{:success true :ctx {}} {:success true :ctx {}}
(:number :nil :true :false :string :keyword) (:number :nil :true :false :string :keyword)
@ -843,6 +843,8 @@
:ref-expr (interpret-ref ast ctx) :ref-expr (interpret-ref ast ctx)
:when-expr (interpret-ast (-> ast :data first) ctx)
; ::ast/spawn (interpret-spawn ast ctx) ; ::ast/spawn (interpret-spawn ast ctx)
; ::ast/receive (interpret-receive ast ctx) ; ::ast/receive (interpret-receive ast ctx)
@ -961,8 +963,11 @@
(do (do
(def source " (def source "
let @{...x} = @{:a 1, :b 2, :c 3} let x = (1, 2)
x when x is {
(y, 2) if eq (y, 1) -> :onetwo
_ -> :not_x
}
") ")
(println "") (println "")

View File

@ -5,13 +5,13 @@
[ludus.scanner :as s])) [ludus.scanner :as s]))
(def source (def source
"#{a as :number} "when x is { true -> true }
" "
) )
(def tokens (-> source s/scan :tokens)) (def tokens (-> source s/scan :tokens))
(def result (p/apply-parser g/dict-pattern tokens)) (def result (p/apply-parser g/when-expr tokens))
(-> result :data) (-> result :data)

View File

@ -8,7 +8,7 @@
"List of Ludus reserved words." "List of Ludus reserved words."
;; see ludus-spec repo for more info ;; see ludus-spec repo for more info
{"as" :as ;; impl for `import`; not yet for patterns {"as" :as ;; impl for `import`; not yet for patterns
"cond" :cond ;; impl ;"cond" :cond ;; impl
"do" :do ;; impl "do" :do ;; impl
"else" :else ;; impl "else" :else ;; impl
"false" :false ;; impl -> literal word "false" :false ;; impl -> literal word
@ -17,7 +17,7 @@
"import" :import ;; impl "import" :import ;; impl
"let" :let ;; impl "let" :let ;; impl
"loop" :loop ;; impl "loop" :loop ;; impl
"match" :match ;; impl ; "match" :match ;; impl
"nil" :nil ;; impl -> literal word "nil" :nil ;; impl -> literal word
"ns" :ns ;; impl "ns" :ns ;; impl
;; "panic!" :panic ;; impl (should be a function) ;; "panic!" :panic ;; impl (should be a function)
@ -25,7 +25,7 @@
"ref" :ref ;; impl "ref" :ref ;; impl
"then" :then ;; impl "then" :then ;; impl
"true" :true ;; impl -> literal word "true" :true ;; impl -> literal word
"with" :with ;; impl ;"with" :with ;; impl
;; actor model/concurrency ;; actor model/concurrency
"receive" :receive "receive" :receive
@ -40,6 +40,7 @@
"test" :test "test" :test
"when" :when "when" :when
;; "module" :module ;; not necessary if we don't have datatypes ;; "module" :module ;; not necessary if we don't have datatypes
"is" :is
}) })
(def literal-words { (def literal-words {