Last active
October 29, 2016 12:37
-
-
Save xsc/a2baff46d43324b640adca5a5ec55198 to your computer and use it in GitHub Desktop.
Useless Language AST (clojure.spec)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; The AST consists of declarations and calls. | |
(s/def :lang/ast | |
(s/keys :req [:lang/declarations :lang/calls])) | |
;; Throughout, we'll use variables/calls identified by their name. | |
(s/def :lang/name | |
(s/and string? #(re-matches #"[a-z]+" %))) | |
(s/def :lang/variable-name | |
:lang/name) | |
(s/def :lang/call-name | |
:lang/name) | |
;; Declarations are maps containing a single variable name. | |
(s/def :lang/declarations | |
(s/coll-of :lang/declaration)) | |
(s/def :lang/declaration | |
(s/keys :req [:lang/variable-name])) | |
;; Calls are maps containing the name of the call and the variables to | |
;; be used as parameters. | |
(s/def :lang/calls | |
(s/coll-of :lang/call)) | |
(s/def :lang/call | |
(s/keys :req [:lang/call-name :lang/call-parameters])) | |
(s/def :lang/call-parameters | |
(s/coll-of :lang/variable-name)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def ^:dynamic *variable-names* nil) | |
(defn variable-name-declared-before-use? | |
[n] | |
(or (not *variable-names*) | |
(contains? *variable-names* n))) | |
(s/def :lang/variable-name | |
(s/and :lang/name variable-name-declared-before-use?)) | |
(defn verify-ast | |
[{:keys [lang/declarations] :as ast}] | |
(let [variable-names (set (map :lang/variable-name declarations))] | |
(binding [*variable-names* variable-names] | |
(s/explain-data :lang/ast ast)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn variable-names-declared-before-use? | |
[{:keys [lang/declarations lang/calls]}] | |
(let [valid-variable-name? (set (map :lang/variable-name declarations)) | |
used-variable-names (mapcat :lang/call-parameters calls)] | |
(every? valid-variable-name? used-variable-names))) | |
(s/def :lang/ast-with-predicates | |
(s/and :lang/ast | |
variable-names-declared-before-use?)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(s/def :lang/valid-ast | |
(s/with-specialisation | |
:lang/ast | |
(fn [ast] | |
{:lang/variable-name (variable-name-declared? ast) | |
:lang/declarations variable-names-unique?}))) | |
;; or as constant specialisation: | |
(defn valid-ast-spec | |
[ast] | |
(s/specialised | |
:lang/ast | |
{:lang/variable-name (variable-name-declared? ast) | |
:lang/declarations variable-names-unique?})) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment