Moved macros and helpers to push/instructions.cljc
This commit is contained in:
parent
0d58508bae
commit
d8c97e29e8
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,9 +3,8 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[clojure.pprint :as pprint]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.gp :as gp]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,7 +3,7 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
|
@ -3,9 +3,8 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
@ -3,9 +3,8 @@
|
||||
[propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.tools.metrics :as metrics]
|
||||
[propeller.gp :as gp]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
@ -2,9 +2,8 @@
|
||||
(:require [propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.gp :as gp]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
@ -2,9 +2,8 @@
|
||||
(:require [propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
||||
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.gp :as gp]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
||||
|
@ -1,4 +1,9 @@
|
||||
(ns propeller.push.instructions)
|
||||
(ns propeller.push.instructions
|
||||
(:require [clojure.set]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.utils :as u]
|
||||
#?(:cljs [goog.string :as gstring])
|
||||
#?(:cljs [goog.string.format])))
|
||||
|
||||
;; PushGP instructions are represented as keywords, and stored in an atom. They
|
||||
;; can be either constant literals or functions that take and return a Push state
|
||||
@ -13,3 +18,117 @@
|
||||
:exec_k 2
|
||||
:exec_s 3
|
||||
:exec_y 1})
|
||||
|
||||
|
||||
#?(:clj
|
||||
(def cls->type
|
||||
{Boolean :boolean
|
||||
Short :integer
|
||||
Integer :integer
|
||||
Long :integer
|
||||
BigInteger :integer
|
||||
Double :float
|
||||
BigDecimal :float
|
||||
Float :float
|
||||
Character :char
|
||||
String :string}))
|
||||
|
||||
#?(:cljs
|
||||
(def pred->type
|
||||
[[boolean? :boolean]
|
||||
[int? :integer]
|
||||
[float? :float]
|
||||
[string? :string]
|
||||
[char? :char]]))
|
||||
|
||||
(defn get-literal-type
|
||||
"If a piece of data is a literal, return its corresponding stack name
|
||||
e.g. `:integer`. Otherwise, return `nil`."
|
||||
[data]
|
||||
(or (when (vector? data)
|
||||
(if (empty? data)
|
||||
:generic-vector
|
||||
(keyword (str "vector_" (name (get-literal-type (u/first-non-nil data)))))))
|
||||
#?(:clj (cls->type (type data))
|
||||
:cljs (loop [remaining pred->type]
|
||||
(let [[pred d-type] (first remaining)]
|
||||
(cond
|
||||
(empty? remaining) nil
|
||||
(pred data) d-type
|
||||
:else (recur (rest remaining))))))))
|
||||
|
||||
(defn get-vector-literal-type
|
||||
"Returns the literal stack corresponding to some vector stack."
|
||||
[vector-stack]
|
||||
(get state/vec-stacks vector-stack))
|
||||
|
||||
(defn def-instruction
|
||||
"Defines a Push instruction as a keyword-function pair, and adds it to the
|
||||
instruction table"
|
||||
[instruction function]
|
||||
(swap! instruction-table assoc instruction function))
|
||||
|
||||
(defn make-metadata
|
||||
"Given a generic function, e.g. _dup, and a stack type to instantiate it for,
|
||||
e.g. :char, returns the appropriate stack metadata for that function instance"
|
||||
[function stack]
|
||||
(->> (:stacks (meta function))
|
||||
(replace {:elem (get-vector-literal-type stack)})
|
||||
(cons stack)
|
||||
set
|
||||
(assoc-in (meta function) [:stacks])
|
||||
(#(dissoc % :name))))
|
||||
|
||||
(defn generate-instructions
|
||||
"Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
|
||||
function strings, e.g. [_add, _mult, _eq], automates the generation of all
|
||||
possible combination instructions, which here would be :float_add, :float_mult,
|
||||
:float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
|
||||
and updating the generic function's stack-type metadata. For some vector
|
||||
instructions, the placeholder :elem will be replaced with the stack of the
|
||||
corresponding element type (e.g. for :vector_integer, with :integer)"
|
||||
[stacks functions]
|
||||
(doseq [stack stacks
|
||||
func functions]
|
||||
(let [instruction-name (keyword (str (name stack) (:name (meta func))))
|
||||
metadata (make-metadata func stack)
|
||||
new-func (with-meta (partial func stack) metadata)]
|
||||
(def-instruction instruction-name new-func))))
|
||||
|
||||
|
||||
(defn make-instruction
|
||||
"A utility function for making Push instructions. Takes a state, a function
|
||||
to apply to the args, the stacks to take the args from, and the stack to
|
||||
return the result to. Applies the function to the args (popped from the
|
||||
given stacks), and pushes the result onto the return-stack.
|
||||
|
||||
If the function returns :ignore-instruction, then we will return the
|
||||
initial state unchanged. This allows instructions to fail gracefully
|
||||
without consuming stack values."
|
||||
[state function arg-stacks return-stack]
|
||||
(let [popped-args (state/get-args-from-stacks state arg-stacks)]
|
||||
(if (= popped-args :not-enough-args)
|
||||
state
|
||||
(let [result (apply function (:args popped-args))
|
||||
new-state (:state popped-args)]
|
||||
(if (= result :ignore-instruction)
|
||||
state
|
||||
(state/push-to-stack new-state return-stack result))))))
|
||||
|
||||
(defn get-stack-instructions
|
||||
"Given a set of stacks, returns all instructions that operate on those stacks
|
||||
only. Won't include random instructions unless :random is in the set as well"
|
||||
[stacks]
|
||||
(doseq [[instruction-name function] @instruction-table]
|
||||
(assert
|
||||
(:stacks (meta function))
|
||||
#?(:clj (format
|
||||
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
||||
(name instruction-name))
|
||||
:cljs (gstring/format
|
||||
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
||||
(name instruction-name)))))
|
||||
(for [[instruction-name function] @instruction-table
|
||||
:when (clojure.set/subset? (:stacks (meta function)) stacks)]
|
||||
instruction-name))
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
(ns propeller.push.instructions.bool
|
||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
|
||||
(:require [propeller.push.utils.helpers :refer [make-instruction]]
|
||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
||||
(:require [propeller.push.instructions :refer [def-instruction
|
||||
make-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; BOOLEAN Instructions
|
||||
|
@ -1,9 +1,8 @@
|
||||
(ns propeller.push.instructions.character
|
||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
|
||||
(:require [propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
||||
[propeller.tools.character :as char]
|
||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
make-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; CHAR Instructions
|
||||
|
@ -1,9 +1,8 @@
|
||||
(ns propeller.push.instructions.code
|
||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
|
||||
(:require [propeller.utils :as utils]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
make-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; CODE Instructions
|
||||
|
@ -1,10 +1,6 @@
|
||||
(ns propeller.push.instructions.input-output
|
||||
#?(:cljs (:require-macros
|
||||
[propeller.push.utils.macros :refer [def-instruction
|
||||
generate-instructions]]))
|
||||
(:require [propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
||||
[propeller.push.utils.macros :refer [def-instruction
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
generate-instructions]]))
|
||||
|
||||
;; =============================================================================
|
||||
|
@ -1,8 +1,8 @@
|
||||
(ns propeller.push.instructions.numeric
|
||||
(:require [propeller.push.utils.helpers :refer [make-instruction]]
|
||||
[propeller.tools.math :as math]
|
||||
[propeller.push.utils.macros :refer [def-instruction
|
||||
generate-instructions]]))
|
||||
(:require [propeller.tools.math :as math]
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
generate-instructions
|
||||
make-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; FLOAT and INTEGER Instructions (polymorphic)
|
||||
|
@ -1,13 +1,10 @@
|
||||
(ns propeller.push.instructions.polymorphic
|
||||
#?(:cljs (:require-macros
|
||||
[propeller.push.utils.macros :refer [def-instruction
|
||||
generate-instructions]]))
|
||||
(:require [propeller.utils :as utils]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
||||
[propeller.push.limits :as limit]
|
||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction
|
||||
generate-instructions]])))
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
generate-instructions
|
||||
make-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; Polymorphic Instructions
|
||||
|
@ -1,10 +1,8 @@
|
||||
(ns propeller.push.instructions.string
|
||||
#?(:cljs (:require-macros
|
||||
[propeller.push.utils.macros :refer [def-instruction]]))
|
||||
(:require [clojure.string :as string]
|
||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
||||
[propeller.push.state :as state]
|
||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
make-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; STRING Instructions
|
||||
|
@ -1,11 +1,10 @@
|
||||
(ns propeller.push.instructions.vector
|
||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [generate-instructions]]))
|
||||
(:require [clojure.string]
|
||||
[propeller.utils :as utils]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [get-vector-literal-type
|
||||
make-instruction]]
|
||||
#?(:clj [propeller.push.utils.macros :refer [generate-instructions]])))
|
||||
[propeller.push.instructions :refer [generate-instructions
|
||||
make-instruction
|
||||
get-vector-literal-type]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; VECTOR Instructions
|
||||
|
@ -1,15 +1,14 @@
|
||||
(ns propeller.push.interpreter
|
||||
(:require [propeller.push.instructions :as instructions]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.instructions.input-output :as io]
|
||||
[propeller.push.utils.helpers :refer [get-literal-type]]))
|
||||
[propeller.push.instructions.input-output :as io]))
|
||||
|
||||
(defn interpret-one-step
|
||||
"Takes a Push state and executes the next instruction on the exec stack."
|
||||
[state]
|
||||
(let [popped-state (state/pop-stack state :exec)
|
||||
instruction (first (:exec state))
|
||||
literal-type (get-literal-type instruction)] ; nil for non-literals
|
||||
literal-type (instructions/get-literal-type instruction)] ; nil for non-literals
|
||||
(cond
|
||||
;;
|
||||
;; Recognize functional instruction or input instruction
|
||||
|
@ -1,86 +0,0 @@
|
||||
(ns propeller.push.utils.helpers
|
||||
(:require [clojure.set]
|
||||
[propeller.push.instructions :as instructions]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.utils :as u]
|
||||
#?(:cljs [goog.string :as gstring])
|
||||
#?(:cljs [goog.string.format])))
|
||||
|
||||
;; A utility function for making Push instructions. Takes a state, a function
|
||||
;; to apply to the args, the stacks to take the args from, and the stack to
|
||||
;; return the result to. Applies the function to the args (popped from the
|
||||
;; given stacks), and pushes the result onto the return-stack.
|
||||
;;
|
||||
;; If the function returns :ignore-instruction, then we will return the
|
||||
;; initial state unchanged. This allows instructions to fail gracefully
|
||||
;; without consuming stack values.
|
||||
(defn make-instruction
|
||||
[state function arg-stacks return-stack]
|
||||
(let [popped-args (state/get-args-from-stacks state arg-stacks)]
|
||||
(if (= popped-args :not-enough-args)
|
||||
state
|
||||
(let [result (apply function (:args popped-args))
|
||||
new-state (:state popped-args)]
|
||||
(if (= result :ignore-instruction)
|
||||
state
|
||||
(state/push-to-stack new-state return-stack result))))))
|
||||
|
||||
;; Given a set of stacks, returns all instructions that operate on those stacks
|
||||
;; only. Won't include random instructions unless :random is in the set as well
|
||||
(defn get-stack-instructions
|
||||
[stacks]
|
||||
(doseq [[instruction-name function] @instructions/instruction-table]
|
||||
(assert
|
||||
(:stacks (meta function))
|
||||
#?(:clj (format
|
||||
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
||||
(name instruction-name))
|
||||
:cljs (gstring/format
|
||||
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
||||
(name instruction-name)))))
|
||||
(for [[instruction-name function] @instructions/instruction-table
|
||||
:when (clojure.set/subset? (:stacks (meta function)) stacks)]
|
||||
instruction-name))
|
||||
|
||||
|
||||
#?(:clj
|
||||
(def cls->type
|
||||
{Boolean :boolean
|
||||
Short :integer
|
||||
Integer :integer
|
||||
Long :integer
|
||||
BigInteger :integer
|
||||
Double :float
|
||||
BigDecimal :float
|
||||
Float :float
|
||||
Character :char
|
||||
String :string}))
|
||||
|
||||
#?(:cljs
|
||||
(def pred->type
|
||||
[[boolean? :boolean]
|
||||
[int? :integer]
|
||||
[float? :float]
|
||||
[string? :string]
|
||||
[char? :char]]))
|
||||
|
||||
(defn get-literal-type
|
||||
"If a piece of data is a literal, return its corresponding stack name
|
||||
e.g. `:integer`. Otherwise, return `nil`."
|
||||
[data]
|
||||
(or (when (vector? data)
|
||||
(if (empty? data)
|
||||
:generic-vector
|
||||
(keyword (str "vector_" (name (get-literal-type (u/first-non-nil data)))))))
|
||||
#?(:clj (cls->type (type data))
|
||||
:cljs (loop [remaining pred->type]
|
||||
(let [[pred d-type] (first remaining)]
|
||||
(cond
|
||||
(empty? remaining) nil
|
||||
(pred data) d-type
|
||||
:else (recur (rest remaining))))))))
|
||||
|
||||
(defn get-vector-literal-type
|
||||
"Returns the literal stack corresponding to some vector stack."
|
||||
[vector-stack]
|
||||
(get state/vec-stacks vector-stack))
|
@ -1,36 +0,0 @@
|
||||
(ns propeller.push.utils.macros
|
||||
(:require [propeller.push.instructions :as instructions]
|
||||
[propeller.push.utils.helpers :refer [get-vector-literal-type]]))
|
||||
|
||||
(defn def-instruction
|
||||
"Defines a Push instruction as a keyword-function pair, and adds it to the
|
||||
instruction table"
|
||||
[instruction function]
|
||||
(swap! instructions/instruction-table assoc instruction function))
|
||||
|
||||
(defn make-metadata
|
||||
"Given a generic function, e.g. _dup, and a stack type to instantiate it for,
|
||||
e.g. :char, returns the appropriate stack metadata for that function instance"
|
||||
[function stack]
|
||||
(->> (:stacks (meta function))
|
||||
(replace {:elem (get-vector-literal-type stack)})
|
||||
(cons stack)
|
||||
set
|
||||
(assoc-in (meta function) [:stacks])
|
||||
(#(dissoc % :name))))
|
||||
|
||||
(defn generate-instructions
|
||||
"Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
|
||||
function strings, e.g. [_add, _mult, _eq], automates the generation of all
|
||||
possible combination instructions, which here would be :float_add, :float_mult,
|
||||
:float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
|
||||
and updating the generic function's stack-type metadata. For some vector
|
||||
instructions, the placeholder :elem will be replaced with the stack of the
|
||||
corresponding element type (e.g. for :vector_integer, with :integer)"
|
||||
[stacks functions]
|
||||
(doseq [stack stacks
|
||||
func functions]
|
||||
(let [instruction-name (keyword (str (name stack) (:name (meta func))))
|
||||
metadata (make-metadata func stack)
|
||||
new-func (with-meta (partial func stack) metadata)]
|
||||
(def-instruction instruction-name new-func))))
|
@ -7,8 +7,7 @@
|
||||
[propeller.problems.string-classification :as string-classif]
|
||||
[propeller.push.instructions :as instructions]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]))
|
||||
[propeller.push.state :as state]))
|
||||
|
||||
#_(interpreter/interpret-program
|
||||
'(1 2 :integer_add) state/empty-state 1000)
|
||||
@ -36,7 +35,7 @@
|
||||
; 1000)
|
||||
;
|
||||
;#_(genome/plushy->push
|
||||
; (genome/make-random-plushy (get-stack-instructions #{:float :integer :exec :boolean}) 20))
|
||||
; (genome/make-random-plushy (instructions/get-stack-instructions #{:float :integer :exec :boolean}) 20))
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.software.number-io/instructions
|
||||
; :error-function propeller.problems.software.number-io/error-function
|
||||
|
Loading…
x
Reference in New Issue
Block a user