Compare commits
3 Commits
efffbafdba
...
83ce75c6ea
Author | SHA1 | Date | |
---|---|---|---|
|
83ce75c6ea | ||
|
42907f19d7 | ||
|
bb42ca7ca4 |
|
@ -84,7 +84,7 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defn apply-table
|
(defn apply-table
|
||||||
"Applies a struct-based rule."
|
"Applies a table-based rule."
|
||||||
[rule parser]
|
[rule parser]
|
||||||
(def curr (current parser))
|
(def curr (current parser))
|
||||||
(def rule-fn (get rule :rule))
|
(def rule-fn (get rule :rule))
|
||||||
|
@ -109,6 +109,9 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
"Renames a rule. By convention, rule names are keywords."
|
"Renames a rule. By convention, rule names are keywords."
|
||||||
[rule name] (put rule :name name))
|
[rule name] (put rule :name name))
|
||||||
|
|
||||||
|
### As noted above: we should not use this
|
||||||
|
### Instead, combinators which might not advance should stash state
|
||||||
|
### These are: !, *, ...?
|
||||||
(defn test
|
(defn test
|
||||||
"Tests a rule: returns whether a rule passes but does not consume any tokens."
|
"Tests a rule: returns whether a rule passes but does not consume any tokens."
|
||||||
[rule parser]
|
[rule parser]
|
||||||
|
@ -122,7 +125,9 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
[rule]
|
[rule]
|
||||||
@{:name (keyword (string "!" (name rule)))
|
@{:name (keyword (string "!" (name rule)))
|
||||||
:rule (fn !* [parser]
|
:rule (fn !* [parser]
|
||||||
(def result (test rule parser))
|
(def origin (stash parser))
|
||||||
|
(def result (apply-rule rule parser))
|
||||||
|
(restore parser origin)
|
||||||
(if-not result
|
(if-not result
|
||||||
(do (advance parser) true)
|
(do (advance parser) true)
|
||||||
nil))})
|
nil))})
|
||||||
|
@ -164,10 +169,7 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
~(set ,name (put ,name :rule (,rule :rule)))
|
~(set ,name (put ,name :rule (,rule :rule)))
|
||||||
~(var ,name (rename ,rule ,(keyword name)))))
|
~(var ,name (rename ,rule ,(keyword name)))))
|
||||||
|
|
||||||
# If we wanted to be robust, we wouldn't hard-code this
|
(comment (defn panic
|
||||||
(defp stop (+ :newline :semicolon :break))
|
|
||||||
|
|
||||||
(defn panic
|
|
||||||
[rule &opt msg]
|
[rule &opt msg]
|
||||||
@{:name (keyword (string "panic-" (name rule)))
|
@{:name (keyword (string "panic-" (name rule)))
|
||||||
:rule (fn panic* [parser]
|
:rule (fn panic* [parser]
|
||||||
|
@ -184,7 +186,11 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
(array/push (parser :errors) the-error)
|
(array/push (parser :errors) the-error)
|
||||||
(array/push (parser :captured) the-error)
|
(array/push (parser :captured) the-error)
|
||||||
true
|
true
|
||||||
)})
|
)}))
|
||||||
|
|
||||||
|
# If we wanted to be robust, we wouldn't hard-code this
|
||||||
|
# To consider: use a stack of "panic-until" on a parser to dynamically decide how far to panic
|
||||||
|
(defp stop (+ :newline :semicolon :break))
|
||||||
|
|
||||||
(defn panic
|
(defn panic
|
||||||
"Panics the parser, consuming all tokens until the rule matches (including the match). It also adds an error node to both the capture and the error stacks."
|
"Panics the parser, consuming all tokens until the rule matches (including the match). It also adds an error node to both the capture and the error stacks."
|
||||||
|
@ -196,7 +202,7 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
(while (not passing)
|
(while (not passing)
|
||||||
(array/push skipped (current parser))
|
(array/push skipped (current parser))
|
||||||
(advance parser)
|
(advance parser)
|
||||||
(set passing (apply-rule rule parser))
|
(set passing (apply-rule stop parser))
|
||||||
(print "phew; I'm done panicking")
|
(print "phew; I'm done panicking")
|
||||||
(pprint (current parser))
|
(pprint (current parser))
|
||||||
(def the-error {:type :error :expected expected :token origin :skipped skipped})
|
(def the-error {:type :error :expected expected :token origin :skipped skipped})
|
||||||
|
@ -204,7 +210,7 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
(array/push (parser :captured) the-error)
|
(array/push (parser :captured) the-error)
|
||||||
(error parser)))
|
(error parser)))
|
||||||
|
|
||||||
(defn *
|
(defn *
|
||||||
"Sequences rules: matches if all rules are matched, in sequence."
|
"Sequences rules: matches if all rules are matched, in sequence."
|
||||||
[& rules]
|
[& rules]
|
||||||
@{:name (keyword (string/join (map name rules) "*"))
|
@{:name (keyword (string/join (map name rules) "*"))
|
||||||
|
@ -213,7 +219,8 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
(var passing true)
|
(var passing true)
|
||||||
(def origin (stash parser))
|
(def origin (stash parser))
|
||||||
(pprint origin)
|
(pprint origin)
|
||||||
(set failing nil)
|
(def failing nil)
|
||||||
|
(def passing true)
|
||||||
(loop [rule :in rules :while passing]
|
(loop [rule :in rules :while passing]
|
||||||
(def pass? (apply-rule rule parser))
|
(def pass? (apply-rule rule parser))
|
||||||
(when (not pass?)
|
(when (not pass?)
|
||||||
|
@ -242,13 +249,13 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
## is this right?
|
## is this right?
|
||||||
|
|
||||||
|
|
||||||
(defn order-1 [& rules]
|
(comment (defn order-1 [& rules]
|
||||||
@{:name (keyword (string/join (map name rules) "*"))
|
@{:name (keyword (string/join (map name rules) "*"))
|
||||||
:rule (fn order-1 [parser]
|
:rule (fn order-1 [parser]
|
||||||
(def result (test (first rules) parser))
|
(def result (test (first rules) parser))
|
||||||
(if result
|
(if result
|
||||||
(apply-rule (order-0 ;rules))
|
(apply-rule (order-0 ;rules)) ### compile error: unknown symbol order-0
|
||||||
nil))})
|
nil))}))
|
||||||
|
|
||||||
(defn capture-group
|
(defn capture-group
|
||||||
"Takes a parser and an origin state: takes everything captured since the origin, gathers it up in a single array, pops it all off the capture stack, and pushes the gathered captures back on the stack."
|
"Takes a parser and an origin state: takes everything captured since the origin, gathers it up in a single array, pops it all off the capture stack, and pushes the gathered captures back on the stack."
|
||||||
|
@ -328,9 +335,9 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
(def parser (new-parser tokens))
|
(def parser (new-parser tokens))
|
||||||
(try
|
(try
|
||||||
(do (apply-rule rule parser) parser)
|
(do (apply-rule rule parser) parser)
|
||||||
([err] err))
|
([err] err)))
|
||||||
|
|
||||||
(upscope
|
(upscope #XXX for easier repl use
|
||||||
|
|
||||||
(defn literal->ast [token] {:type (get token :type) :data (get token :literal) :token token})
|
(defn literal->ast [token] {:type (get token :type) :data (get token :literal) :token token})
|
||||||
|
|
||||||
|
@ -342,7 +349,7 @@ The idea, however, is that Jesus: we must not have test-rule and apply-rule: com
|
||||||
|
|
||||||
(declare expression simple nonbinding)
|
(declare expression simple nonbinding)
|
||||||
|
|
||||||
(defp separator (+ :newline :comma :break))
|
(defp separator (some (+ :newline :comma :break)))
|
||||||
(defp separators? (any (+ :newline :comma :break)))
|
(defp separators? (any (+ :newline :comma :break)))
|
||||||
(defp terminator (some (+ :newline :semicolon :break)))
|
(defp terminator (some (+ :newline :semicolon :break)))
|
||||||
(defp terminators? (any (+ :newline :semicolon :break)))
|
(defp terminators? (any (+ :newline :semicolon :break)))
|
||||||
|
|
4
justfile
4
justfile
|
@ -4,7 +4,7 @@ build:
|
||||||
|
|
||||||
# open a janet repl in a different os window
|
# open a janet repl in a different os window
|
||||||
repl:
|
repl:
|
||||||
kitten @ launch --type=os-window --allow-remote-control --cwd=current --title=hx_repl:ludus
|
kitten @ launch --type=os-window --allow-remote-control --cwd=current --title=hx_repl:ludus --keep-focus
|
||||||
kitten @ send-text -m "title:hx_repl:ludus" "janet -s\n"
|
kitten @ send-text -m "title:hx_repl:ludus" "janet -s\n"
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
|
@ -20,3 +20,5 @@ buffer:
|
||||||
sd "$" "\n" | sd "\n\n" "\n" > .repl-buffer.janet
|
sd "$" "\n" | sd "\n\n" "\n" > .repl-buffer.janet
|
||||||
kitten @ send-text -m "title:hx_repl:ludus" "(import ./.repl-buffer :prefix \"\")"
|
kitten @ send-text -m "title:hx_repl:ludus" "(import ./.repl-buffer :prefix \"\")"
|
||||||
|
|
||||||
|
doc:
|
||||||
|
sd "$" "\n" | sd "\n\n" "\n" | xargs -I _ echo "(doc " _ ")" | kitten @ send-text -m "title:hx_repl:ludus" --stdin
|
||||||
|
|
Loading…
Reference in New Issue
Block a user