Skip to content

Instantly share code, notes, and snippets.

@Sose

Sose/spec.cljs Secret

Created May 26, 2021 04:23
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/97dac8f1785d87d282d20e97fe1d41eb to your computer and use it in GitHub Desktop.
Save Sose/97dac8f1785d87d282d20e97fe1d41eb to your computer and use it in GitHub Desktop.
(ns kilppari.spec
(:require [clojure.spec.alpha :as s]))
(s/def ::v (s/or :variable keyword?
:value number?))
(s/def ::command keyword?)
(defmulti by-command (fn [[command _]] command))
(defmethod by-command :move [_]
(s/tuple ::command ::v))
(defmethod by-command :turn [_]
(s/tuple ::command ::v))
(defmethod by-command :repeat [_]
(s/tuple ::command ::v ::script))
(defmethod by-command :pen [_]
(s/tuple ::command #(or (= % :up) (= % :down))))
(defmethod by-command :let [_]
(s/tuple ::command keyword? number?))
(defmethod by-command :function [_]
(s/tuple ::command keyword? (s/coll-of keyword?) ::script))
(defmethod by-command :call [_]
(s/tuple ::command keyword? number?))
(s/def ::instruction (s/multi-spec by-command :instruction))
(s/def ::start (s/tuple #(= :start %) number? number? number?))
;; a (sub)script is a vector of instructions
(s/def ::script (s/coll-of ::instruction))
;; main scripts must have a "start instruction" at the beginning
(s/def ::main-script (fn [[start & rest]]
(s/and (s/valid? ::start start)
(s/valid? ::script rest))))
(def test-sc [[:start 1 2 3] [:call :circle "invalid"]])
(s/valid? ::script (rest test-sc)) ;; => false as expected
(s/valid? ::main-script test-sc) ;; => true !!! should be false?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment