Compare commits

..

6 commits

Author SHA1 Message Date
simon 94fe77b883 parser.cljs has been replaced with parser.cljc. 2016-03-10 21:35:10 +00:00
simon 85a51f4591 Merge branch 'beforethebreak' 2016-03-10 21:26:03 +00:00
simon 7c7657c309 This commit contains most of what's been written so far, and it all compiles.
However, the parser does not work (because it depends on eval), and also the
parser can't currently be linked into core and I don't know why not. Still,
significant progress.
2016-03-10 21:21:20 +00:00
simon 3bd1d7f298 WARNING! Does not currently compile, but I think that's probably not
related to this code - I think it's junk in the working directory.
2016-03-04 08:25:25 +00:00
simon 1d23b45dbd Added the parser, and using the cljs variant of the parser engine, but it's
still not working properly.
2016-03-04 00:57:02 +00:00
simon 2c567a65f1 Added the new declarative parser. 2016-03-03 23:57:56 +00:00
3 changed files with 24 additions and 59 deletions

View file

@ -1,11 +1,11 @@
(ns ^:figwheel-always mw3.core (ns ^:figwheel-always mw3.core
(:use mw3.utils)
(:use-macros [dommy.template :only [node deftemplate]]) (:use-macros [dommy.template :only [node deftemplate]])
(:require-macros [cljs.core.async.macros :refer [go]]) (:require-macros [cljs.core.async.macros :refer [go]])
(:require (:require
[mw3.rulesets :as rulesets] [mw3.rulesets :as rulesets]
[dommy.core :as dommy :refer-macros [sel sel1]] [dommy.core :as dommy :refer-macros [sel sel1]]
[dommy.template :as temp])) [dommy.template :as temp]
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -101,6 +101,17 @@
[:pre {:id (str "rule-feedback-" index) :class "rule-feedback"}] [:pre {:id (str "rule-feedback-" index) :class "rule-feedback"}]
]) ])
;; (deftemplate rule-editors
;; ;; Constructs, as a `div`, a set of rule editors for the rules in the ruleset with
;; ;; this `ruleset-name`.
;; [ruleset-name]
;; [:div
;; (vec
;; (map
;; #(rule-editor % %)
;; (rulesets/rulesets ruleset-name)
;; (range)))])
(defn load-ruleset (defn load-ruleset
"Loads the ruleset with the specified `name` into a set of rule editors" "Loads the ruleset with the specified `name` into a set of rule editors"
[name] [name]

View file

@ -1,11 +1,15 @@
(ns ^:figwheel-always mw3.core (ns ^:figwheel-always mw3.core
(:use mw3.utils (:use [mw3.utils :only [error member?]]
[clojure.string :only [split trim triml]]) [clojure.string :only [split trim triml]]
(:require [instaparse.core :as insta])) #?(:cljs
[cljs.reader :only [read-string]]))
(:require [instaparse.core :as insta])
)
;; error thrown when an attempt is made to set a reserved property ;; error thrown when an attempt is made to set a reserved property
(def reserved-properties-error (def reserved-properties-error
"The properties 'x' and 'y' of a cell are reserved and should not be set in rule actions") "The properties 'x' and 'y' of a cell are reserved and should not be set in rule actions")
;; error thrown when a rule cannot be parsed. Slots are for ;; error thrown when a rule cannot be parsed. Slots are for
;; (1) rule text ;; (1) rule text
;; (2) cursor showing where in the rule text the error occurred ;; (2) cursor showing where in the rule text the error occurred
@ -200,39 +204,6 @@
([comp1 quantity property-condition] ([comp1 quantity property-condition]
(generate-neighbours-condition comp1 quantity property-condition 1))) (generate-neighbours-condition comp1 quantity property-condition 1)))
;; (def s1 "if 3 neighbours have state equal to forest then state should be forest")
;; (def s2 "if some neighbours have state equal to forest then state should be forest")
;; (def s3 "if more than 3 neighbours have state equal to forest then state should be forest")
;; (def s4 "if fewer than 3 neighbours have state equal to forest then state should be forest")
;; (def s5 "if all neighbours have state equal to forest then state should be forest")
;; (def s6 "if more than 3 neighbours within 2 have state equal to forest then state should be forest")
;; (nth (simplify (parse-rule s1)) 2)
;; (second (nth (simplify (parse-rule s1)) 2))
;; (nth (simplify (parse-rule s2)) 2)
;; (map simplify (nth (simplify (parse-rule s2)) 2))
;; ;; (second (nth (simplify (parse-rule s2)) 2))
;; ;; (nth (simplify (parse-rule s3)) 2)
;; (second (nth (simplify (parse-rule s3)) 2))
;; (map simplify (second (nth (simplify (parse-rule s3)) 2)))
;; ;; (nth (simplify (parse-rule s4)) 2)
;; ;; (second (nth (simplify (parse-rule s4)) 2))
;; ;; (nth (simplify (parse-rule s5)) 2)
;; ;; (second (nth (simplify (parse-rule s5)) 2))
;; ;; (nth (simplify (parse-rule s6)) 2)
;; ;; (second (nth (simplify (parse-rule s6)) 2))
;; ;; (generate (nth (nth (simplify (parse-rule s5)) 2) 4))
;; ;; (generate (nth (simplify (parse-rule s2)) 2))
;; ;; (generate (nth (simplify (parse-rule s1)) 2))
;; (generate-neighbours-condition '= 3 '(= (:state cell) :forest) 1)
;; (generate-neighbours-condition (nth (simplify (parse-rule s3)) 2))
;; (generate-neighbours-condition (nth (simplify (parse-rule s2)) 2))
;; (generate-neighbours-condition (nth (simplify (parse-rule s1)) 2))
(defn generate (defn generate
"Generate code for this (fragment of a) parse tree" "Generate code for this (fragment of a) parse tree"
[tree] [tree]
@ -352,5 +323,7 @@
[rule] [rule]
(assert (string? rule)) (assert (string? rule))
(let [tree (simplify (parse-rule rule))] (let [tree (simplify (parse-rule rule))]
(if (rule? tree) (eval (generate tree)) (if (rule? tree) #?(:clj (eval (generate tree))
:cljs (generate tree))
(throw-parse-exception tree)))) (throw-parse-exception tree))))

View file

@ -5,21 +5,11 @@
#?(:cljs (js/Error. message) #?(:cljs (js/Error. message)
:clj (Exception. message))) :clj (Exception. message)))
(defn nth
"I'm getting a compilation error saying `nth` isn't defined; so I'm defining it."
[collection index]
{:pre [(and (coll? collection) (integer? index) (or (zero? index) (pos? index)))]}
(cond
(empty? collection) nil
(zero? index) (first collection)
:true (nth (rest collection) (dec index))))
(defn abs (defn abs
"Surprisingly, Clojure doesn't seem to have an abs function, or else I've "Surprisingly, Clojure doesn't seem to have an abs function, or else I've
missed it. So here's one of my own. Maps natural numbers onto themselves, missed it. So here's one of my own. Maps natural numbers onto themselves,
and negative integers onto natural numbers. Also maps negative real numbers and negative integers onto natural numbers. Also maps negative real numbers
onto positive real numbers. onto positive real numbers.
* `n` a number, on the set of real numbers." * `n` a number, on the set of real numbers."
[n] [n]
(if (neg? n) (- 0 n) n)) (if (neg? n) (- 0 n) n))
@ -43,11 +33,9 @@
[world cell] [world cell]
(merge cell {:generation (get-int-or-zero cell :generation)})) (merge cell {:generation (get-int-or-zero cell :generation)}))
(defn in-bounds (defn in-bounds
"True if x, y are in bounds for this world (i.e., there is a cell at x, y) "True if x, y are in bounds for this world (i.e., there is a cell at x, y)
else false. else false.
* `world` a world as defined above; * `world` a world as defined above;
* `x` a number which may or may not be a valid x coordinate within that world; * `x` a number which may or may not be a valid x coordinate within that world;
* `y` a number which may or may not be a valid y coordinate within that world." * `y` a number which may or may not be a valid y coordinate within that world."
@ -89,7 +77,6 @@
(defn get-cell (defn get-cell
"Return the cell a x, y in this world, if any. "Return the cell a x, y in this world, if any.
* `world` a world as defined above; * `world` a world as defined above;
* `x` a number which may or may not be a valid x coordinate within that world; * `x` a number which may or may not be a valid x coordinate within that world;
* `y` a number which may or may not be a valid y coordinate within that world." * `y` a number which may or may not be a valid y coordinate within that world."
@ -99,7 +86,6 @@
(defn get-int (defn get-int
"Get the value of a property expected to be an integer from a map; if not present (or not an integer) return 0. "Get the value of a property expected to be an integer from a map; if not present (or not an integer) return 0.
* `map` a map; * `map` a map;
* `key` a symbol or keyword, presumed to be a key into the `map`." * `key` a symbol or keyword, presumed to be a key into the `map`."
[map key] [map key]
@ -113,7 +99,6 @@
"Return the population of this species in this cell. Currently a synonym for "Return the population of this species in this cell. Currently a synonym for
`get-int`, but may not always be (depending whether species are later `get-int`, but may not always be (depending whether species are later
implemented as actors) implemented as actors)
* `cell` a map; * `cell` a map;
* `species` a keyword representing a species which may populate that cell." * `species` a keyword representing a species which may populate that cell."
[cell species] [cell species]
@ -139,18 +124,15 @@
(defn get-neighbours (defn get-neighbours
"Get the neighbours to distance depth of a cell in this world. "Get the neighbours to distance depth of a cell in this world.
Several overloads: Several overloads:
* `world` a world, as described in world.clj; * `world` a world, as described in world.clj;
* `cell` a cell within that world * `cell` a cell within that world
Gets immediate neighbours of the specified cell. Gets immediate neighbours of the specified cell.
* `world` a world, as described in world.clj; * `world` a world, as described in world.clj;
* `cell` a cell within that world * `cell` a cell within that world
* `depth` an integer representing the depth to search from the * `depth` an integer representing the depth to search from the
`cell` `cell`
Gets neighbours within the specified distance of the cell. Gets neighbours within the specified distance of the cell.
* `world` a world, as described in world.clj; * `world` a world, as described in world.clj;
* `x` an integer representing an x coordinate in that world; * `x` an integer representing an x coordinate in that world;
* `y` an integer representing an y coordinate in that world; * `y` an integer representing an y coordinate in that world;
@ -202,7 +184,6 @@
(defn get-neighbours-with-state (defn get-neighbours-with-state
"Get the neighbours to distance depth of the cell at x, y in this world which "Get the neighbours to distance depth of the cell at x, y in this world which
have this state. have this state.
* `world` a world, as described in `world.clj`; * `world` a world, as described in `world.clj`;
* `cell` a cell within that world; * `cell` a cell within that world;
* `depth` an integer representing the distance from [x,y] that * `depth` an integer representing the distance from [x,y] that
@ -231,7 +212,6 @@
(get-least-cell cells property #?(:cljs 900719925474099 (get-least-cell cells property #?(:cljs 900719925474099
:clj (Integer/MAX_VALUE))))) :clj (Integer/MAX_VALUE)))))
(defn- set-cell-property (defn- set-cell-property
"If this `cell`s x and y properties are equal to these `x` and `y` values, "If this `cell`s x and y properties are equal to these `x` and `y` values,
return a cell like this cell but with the value of this `property` set to return a cell like this cell but with the value of this `property` set to
@ -272,3 +252,4 @@
(merge %2 cell) (merge %2 cell)
%2)) %2))
world)) world))