diff --git a/TODO.xit b/TODO.xit index 114eed8..5b5d164 100644 --- a/TODO.xit +++ b/TODO.xit @@ -21,7 +21,7 @@ Finish interpreter [ ] Merge new interpreter Write a compiler: desugaring -[ ] `...` to `..._` in tuple & list patterns +[~] `...` to `..._` in tuple & list patterns [ ] placeholder partial application to anonymous lambda [ ] 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 only called inside loop or fn forms [ ] check ns accesses +[ ] prevent import cycles [ ] splattern is last member in a pattern [ ] -----List/Tuple [ ] -----Dict/Struct/Set -[ ] prevent import cycles Write a compiler: optimization [ ] devise tail call optimization diff --git a/src/ludus/grammar.clj b/src/ludus/grammar.clj index 644c71d..52a6cd9 100644 --- a/src/ludus/grammar.clj +++ b/src/ludus/grammar.clj @@ -4,35 +4,25 @@ (declare expression pattern) -;(def separator (choice :separator [:comma :newline :break])) (defp separator choice [:comma :newline :break]) -;(def separators (quiet (one+ separator))) (defp separators quiet one+ separator) -;(def terminator (choice :terminator [:newline :semicolon :break])) (defp terminator choice [:newline :semicolon :break]) -;(def terminators (quiet (one+ terminator))) (defp terminators quiet one+ terminator) -;(def nls? (quiet (zero+ :nls :newline))) (defp nls? quiet zero+ :newline) -;(def splat (group (order-1 :splat [(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 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]) -;(def tuple-pattern-term (flat (choice :tuple-pattern-term [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 group order-1 [(quiet :lparen) @@ -65,29 +55,30 @@ (quiet :rbrace) ]) -(defp guard order-0 [(quiet :when) expression]) +(defp guard order-0 [(quiet :if) expression]) (defp pattern flat choice [literal :ignored :placeholder typed :word - :keyword + :keyword + :else tuple-pattern dict-pattern struct-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 group order-1 [(quiet :match) expression nls? - (quiet :with) (quiet :lbrace) - (quiet (zero+ terminator)) - (one+ match-entry) - (quiet :rbrace) - ]) +(defp match-old group order-1 [(quiet :match) expression nls? + (quiet :with) (quiet :lbrace) + (quiet (zero+ terminator)) + (one+ match-entry) + (quiet :rbrace) + ]) (defp if-expr group order-1 [(quiet :if) nls? @@ -105,11 +96,26 @@ (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)) + (one+ cond-entry) + (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) pattern (quiet :equals) @@ -229,11 +235,12 @@ (flat (choice :loop-body [fn-clause compound-loop]))]) (defp expression flat choice [fn-expr - match + ;match loop-expr let-expr if-expr - cond-expr + ;cond-expr + when-expr spawn receive synthetic diff --git a/src/ludus/interpreter.clj b/src/ludus/interpreter.clj index 0ff06d1..4ccdfc9 100644 --- a/src/ludus/interpreter.clj +++ b/src/ludus/interpreter.clj @@ -275,7 +275,7 @@ ;(println "Matching " value " with pattern type " (:type pattern)) (let [ctx @ctx-vol] (case (:type pattern) - (:placeholder :ignored) + (:placeholder :ignored :else) {:success true :ctx {}} (:number :nil :true :false :string :keyword) @@ -843,6 +843,8 @@ :ref-expr (interpret-ref ast ctx) + :when-expr (interpret-ast (-> ast :data first) ctx) + ; ::ast/spawn (interpret-spawn ast ctx) ; ::ast/receive (interpret-receive ast ctx) @@ -961,8 +963,11 @@ (do (def source " - let @{...x} = @{:a 1, :b 2, :c 3} - x + let x = (1, 2) + when x is { + (y, 2) if eq (y, 1) -> :onetwo + _ -> :not_x + } ") (println "") diff --git a/src/ludus/interpreter_new.clj b/src/ludus/interpreter_new.clj index 3c7c268..2a5815e 100644 --- a/src/ludus/interpreter_new.clj +++ b/src/ludus/interpreter_new.clj @@ -5,13 +5,13 @@ [ludus.scanner :as s])) (def source - "#{a as :number} + "when x is { true -> true } " ) (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) diff --git a/src/ludus/scanner.clj b/src/ludus/scanner.clj index a4c5ea8..368da41 100644 --- a/src/ludus/scanner.clj +++ b/src/ludus/scanner.clj @@ -8,7 +8,7 @@ "List of Ludus reserved words." ;; see ludus-spec repo for more info {"as" :as ;; impl for `import`; not yet for patterns - "cond" :cond ;; impl + ;"cond" :cond ;; impl "do" :do ;; impl "else" :else ;; impl "false" :false ;; impl -> literal word @@ -17,7 +17,7 @@ "import" :import ;; impl "let" :let ;; impl "loop" :loop ;; impl - "match" :match ;; impl + ; "match" :match ;; impl "nil" :nil ;; impl -> literal word "ns" :ns ;; impl ;; "panic!" :panic ;; impl (should be a function) @@ -25,7 +25,7 @@ "ref" :ref ;; impl "then" :then ;; impl "true" :true ;; impl -> literal word - "with" :with ;; impl + ;"with" :with ;; impl ;; actor model/concurrency "receive" :receive @@ -40,6 +40,7 @@ "test" :test "when" :when ;; "module" :module ;; not necessary if we don't have datatypes + "is" :is }) (def literal-words {