From 27b688b96d7a260b8445586be17f0e256370b32d Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Tue, 4 Jun 2024 14:25:22 -0400 Subject: [PATCH] interpret loop & recur! --- janet/base.janet | 2 +- janet/interpreter.janet | 64 +++++++++++++++++++++++++++++++++-------- janet/parser.janet | 10 +++---- janet/validate.janet | 10 +++---- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/janet/base.janet b/janet/base.janet index 6829484..7286adb 100644 --- a/janet/base.janet +++ b/janet/base.janet @@ -151,7 +151,7 @@ (def ctx { "print!" print! "prn" prn - "eq" deep= + "eq?" deep= "bool" bool "and" ludus/and "or" ludus/or diff --git a/janet/interpreter.janet b/janet/interpreter.janet index 53fe9f3..42f25ac 100644 --- a/janet/interpreter.janet +++ b/janet/interpreter.janet @@ -460,9 +460,49 @@ # TODO for Computer Class (defn- pkg [ast ctx] (todo "pkgs")) -(defn- loopp [ast ctx] (todo "loops")) +(defn- loopp [ast ctx] + (print "looping!") + (def data (ast :data)) + (def args (interpret (data 0) ctx)) + (when (ast :match) (break ((ast :match) 0 args))) + (def clauses (data 1)) + (def len (length clauses)) + (def loop-ctx @{:^parent ctx}) + (defn match-fn [i args] + (print "calling inner loop fn") + (print "for the " i "th time") + (when (= len i) + (error {:node ast :value args :msg "no match"})) + (def clause (clauses i)) + (def [patt guard expr] clause) + (def match? + (match-pattern patt args loop-ctx)) + (when (not (match? :success)) + (print "no match") + (break (match-fn (inc i) args))) + (print "matched!") + (def body-ctx (match? :ctx)) + (def guard? (if guard + (b/bool (interpret guard body-ctx)) true)) + (print "passed guard") + (when (not guard?) + (break (match-fn (inc i) args))) + (interpret expr body-ctx)) + (set (ast :match) match-fn) + (set (loop-ctx :^recur) match-fn) + (print "ATTACHED MATCH-FN") + (match-fn 0 args)) -(defn- recur [ast ctx] (todo "recur")) +(defn- recur [ast ctx] + (print "recurring!") + (def passed (ast :data)) + (def args (interpret passed ctx)) + (def match-fn (resolve-name :^recur ctx)) + (print "match fn in ctx:") + (pp (ctx :^recur)) + (pp match-fn) + (pp ctx) + (match-fn 0 args)) # TODO for 0.1.0 (defn- testt [ast ctx] (todo "test")) @@ -553,21 +593,21 @@ # (when (has-errors? validated) (break (validated :errors))) # (def cleaned (get-in parsed [:ast :data 1])) # (pp cleaned) - # (interpret (parsed :ast) @{:^parent b/ctx}) - (try (interpret (parsed :ast) @{:^parent b/ctx}) - ([e] (print "Ludus panicked!: " - (if (struct? e) (error (e :msg)) (error e))))) + (interpret (parsed :ast) @{:^parent b/ctx}) + # (try (interpret (parsed :ast) @{:^parent b/ctx}) + # ([e] (print "Ludus panicked!: " + # (if (struct? e) (error (e :msg)) (error e))))) ) (do (set source ` -fn foo { - "a doc, another doc" - () -> :foo - (_) -> :bar +loop (10) with { + (0) -> :done! + (x) -> { + print! (x) + recur (dec (x)) + } } - -doc! (foo) `) (def result (run)) (b/show result) diff --git a/janet/parser.janet b/janet/parser.janet index 44c4b3a..204b540 100644 --- a/janet/parser.janet +++ b/janet/parser.janet @@ -935,7 +935,7 @@ (expect parser :loop) (advance parser) (def args (tup parser)) (expect parser :with) (advance parser) - (def clauses (case (-> parser current type) + (def {:clauses clauses} (case (-> parser current type) :lparen (fn-simple parser) :lbrace (fn-clauses parser) )) @@ -1132,14 +1132,14 @@ ) -# (do -(comment -(def source `(foo as :bar, 12, :foo, _thing) +(do +# (comment +(def source `recur (x) `) (def scanned (s/scan source)) (print "\n***NEW PARSE***\n") (def a-parser (new-parser scanned)) -(def parsed (pattern a-parser)) +(def parsed (recur a-parser)) ) diff --git a/janet/validate.janet b/janet/validate.janet index 9cf6215..a157cd0 100644 --- a/janet/validate.janet +++ b/janet/validate.janet @@ -768,16 +768,14 @@ Deferred until a later iteration of Ludus: (import ./base :as b) -(do -# (comment +# (do +(comment (def source ` -fn foo -fn bar () -> foo () -fn foo () -> bar () +dec (12) `) (def scanned (s/scan source)) (def parsed (p/parse scanned)) -(def validated (valid parsed)) +(def validated (valid parsed b/ctx)) # (get-in validated [:status :declared]) # (validated :ctx) )