mirror of
https://github.com/richardharrington/robotwar.git
synced 2024-05-31 11:41:29 +00:00
Merge branch 'lex-re'
This commit is contained in:
commit
0ca4fac91c
|
@ -3,6 +3,5 @@
|
|||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.5.1"]
|
||||
[org.clojure/core.match "0.2.0-rc3"]]
|
||||
:dependencies [[org.clojure/clojure "1.5.1"]]
|
||||
:main hs-robotwar.core)
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
(ns hs-robotwar.core)
|
||||
|
||||
(use '[clojure.core.match :only (match)])
|
||||
(use '[clojure.set :only (union)])
|
||||
(use '[clojure.string :only (split join)])
|
||||
|
||||
(def operators "-+*/=#<>")
|
||||
|
||||
(def operators #{\= \< \> \# \+ \- \* \/})
|
||||
(def lex-re (re-pattern (str "[" operators "]|[^" operators "\\s]+")))
|
||||
(def operators-set (set (map str operators)))
|
||||
|
||||
(def registers (union (set (map #(-> % char str) (range (int \A) (inc (int \Z)))))
|
||||
#{"AIM" "SHOT" "RADAR" "DAMAGE" "SPEEDX" "SPEEDY" "RANDOM" "INDEX"}))
|
||||
|
||||
(def commands (union (set (map str operators))
|
||||
#{"TO" "IF" "GOTO" "GOSUB" "ENDSUB"}))
|
||||
(def commands (union operators-set #{"TO" "IF" "GOTO" "GOSUB" "ENDSUB"}))
|
||||
|
||||
(defn conj-with-metadata
|
||||
[coll s n]
|
||||
(conj coll {:token-str s, :pos n}))
|
||||
(defn re-seq-with-pos
|
||||
"returns a sequence of 2-element vectors: [match position]"
|
||||
[re initial-s]
|
||||
(loop [s initial-s,
|
||||
end-of-previous-word 0
|
||||
acc []]
|
||||
(if (empty? s)
|
||||
acc
|
||||
(if-let [next-match (re-find re s)]
|
||||
(let [idx-start (.indexOf s next-match)
|
||||
idx-end (+ idx-start (count next-match))]
|
||||
(recur (subs s idx-end)
|
||||
(+ end-of-previous-word idx-end)
|
||||
(conj acc [next-match (+ end-of-previous-word idx-start)])))
|
||||
acc))))
|
||||
|
||||
(defn build-lex-metadata
|
||||
[s n]
|
||||
{:token-str s, :pos n})
|
||||
|
||||
(defn lex-line
|
||||
[initial-line]
|
||||
(loop
|
||||
[[head & tail :as line] initial-line
|
||||
partial-token []
|
||||
saved-pos 0
|
||||
result []]
|
||||
(let [close-partial-token (fn [] (conj-with-metadata result (apply str partial-token) saved-pos))
|
||||
current-pos (- (count initial-line) (count line))
|
||||
parsing-token? (not (empty? partial-token))]
|
||||
(match [head parsing-token?]
|
||||
[(:or \; nil) true ] (close-partial-token)
|
||||
[(:or \; nil) false] result
|
||||
[(:or \space \t) true ] (recur tail [] nil (close-partial-token))
|
||||
[(:or \space \t) false] (recur tail [] nil result)
|
||||
; if it's an operator and we're currently parsing a token,
|
||||
; close the partial token and recur on the same character.
|
||||
[(_ :guard operators) true ] (recur line [] nil (close-partial-token))
|
||||
[(_ :guard operators) false] (recur tail
|
||||
[]
|
||||
nil
|
||||
(conj-with-metadata result (str head) current-pos))
|
||||
[_ true ] (recur tail (conj partial-token head) saved-pos result)
|
||||
[_ false] (recur tail (conj partial-token head) current-pos result)))))
|
||||
[line]
|
||||
(map #(apply build-lex-metadata %)
|
||||
(re-seq-with-pos lex-re line)))
|
||||
|
||||
(defn lex
|
||||
[src-code]
|
||||
(mapcat lex-line (split src-code #"\n")))
|
||||
|
||||
(defn merge-lexed-tokens
|
||||
"helper function for conjoining minus signs to next token
|
||||
|
@ -49,10 +49,6 @@
|
|||
{:token-str (str (:token-str first-token) (:token-str second-token))
|
||||
:pos (:pos first-token)})
|
||||
|
||||
(defn lex
|
||||
[src-code]
|
||||
(mapcat lex-line (split src-code #"\n")))
|
||||
|
||||
(defn str->int
|
||||
"Like Integer/parseInt, but returns nil on failure"
|
||||
[s]
|
||||
|
|
Loading…
Reference in New Issue
Block a user