Skip to content

Instantly share code, notes, and snippets.

@Sose
Created May 21, 2021 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sose/9a68caa42bd0e25fe70e9d353b3503fe to your computer and use it in GitHub Desktop.
Save Sose/9a68caa42bd0e25fe70e9d353b3503fe to your computer and use it in GitHub Desktop.
(ns kilppari-reagent.parsing
(:require [instaparse.core :as insta :refer-macros [defparser]]
[cljs.core.match :refer-macros [match]]))
(defparser turtle-parser
"S = line* <end?>
<line> = (<comment> <eol>) | <empty-line> | (<whitespace*> command <comment?> <eol>)
<empty-line> = <whitespace*> <eol>
<command> = move | turn-right | turn-left | repeat | pen | function | call
<whitespace> = ' ' | '\t'
<comment> = <whitespace>* <#'//[ a-zA-Z0-9]*'>
pen = <'pen '> ('up' | 'down')
move = <'move '> n
turn-right = <'turn-right '> n
turn-left = <'turn-left '> n
repeat = <'repeat '> n <comment?> <eol> line* <end>
function = <'fn '> fn-name args? <comment?> <eol> line* <endfn>
args = <whitespace+> #'[a-zA-Z0-9]+'
call = <'call '> fn-name
end = <whitespace*> <'end'>
endfn = <whitespace*> <'endfn'>
fn-name = #'[a-zA-Z0-9]+'
n = #'[012345679]+'
eol = '\n'")
(defn str->int [s]
(js/parseInt s))
;; TODO: I missed there's a insta/transform function
(defn process-line [line]
(match line
[:move [:n n]] [:move (str->int n)]
[:turn-right [:n n]] [:turn-right (str->int n)]
[:turn-left [:n n]] [:turn-left (str->int n)]
[:pen x] [:pen (keyword x)]
[:repeat [:n n] & x] [:repeat (str->int n) (into [] (map process-line x))]
[:function [:fn-name fn-name] & x] [:function fn-name
{:instructions (into [] (map process-line x))}]
[:function [:fn-name fn-name] [:args args] & x] [:function fn-name
{:args args
:instructions (into [] (map process-line x))}]
[:call [:fn-name fn-name]] [:call fn-name]
[:call [:fn-name fn-name] [:args args]] [:call fn-name args]
[:end] [:end]
:else line))
(defn parse-turtle [str]
(let [res (turtle-parser str)]
(when (= (first res) :S)
(->> (rest res)
(map process-line)
(into [])))))
kilppari-reagent.parsing> (insta/parse turtle-parser (:default-script @kilppari-reagent.state/app-state))
;; => Parse
kilppari-reagent.parsing> (insta/get-failure (insta/parse turtle-parser (:default-script @kilppari-reagent.state/app-state)))
;; => Parse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment