Add input handler and refactor interpreter
This commit is contained in:
parent
ca33a46627
commit
69142757ce
@ -28,28 +28,9 @@
|
||||
:integer_eq
|
||||
:exec_dup
|
||||
:exec_if
|
||||
:boolean_and
|
||||
:boolean_or
|
||||
:boolean_not
|
||||
:boolean_eq
|
||||
:string_eq
|
||||
:string_take
|
||||
:string_drop
|
||||
:string_reverse
|
||||
:string_concat
|
||||
:string_length
|
||||
:string_includes?
|
||||
'close
|
||||
0
|
||||
1
|
||||
true
|
||||
false
|
||||
""
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"A"
|
||||
"C"
|
||||
"G"
|
||||
"T"))
|
||||
1))
|
||||
|
||||
(defn error-function
|
||||
"Finds the behaviors and errors of an individual. The error is the absolute
|
||||
|
3
src/propeller/problems/software/number_io.clj
Normal file
3
src/propeller/problems/software/number_io.clj
Normal file
@ -0,0 +1,3 @@
|
||||
(ns propeller.problems.software.number-io)
|
||||
|
||||
|
@ -3,11 +3,19 @@
|
||||
[propeller.push.utils :refer [def-instruction]]))
|
||||
|
||||
;; =============================================================================
|
||||
;; INPUT and OUTPUT Instructions
|
||||
;; INPUT Instructions
|
||||
;; =============================================================================
|
||||
|
||||
;; Pushes the input labeled :in1 on the inputs map onto the :exec stack
|
||||
(def-instruction
|
||||
:in1
|
||||
(fn [state]
|
||||
(state/push-to-stack state :exec (:in1 (:input state)))))
|
||||
;; Allows Push to handle input instructions of the form :inN, e.g. :in2, taking
|
||||
;; elements thus labeled from the :input stack and pushing them onto the :exec
|
||||
;; stack. We can tell whether a particular inN instruction is valid if N-1
|
||||
;; values are on the input stack.
|
||||
(defn handle-input-instruction
|
||||
[state instruction]
|
||||
(if-let [input (instruction (:input state))]
|
||||
(state/push-to-stack state :exec input)
|
||||
(throw (Exception. (str "Undefined input instruction " instruction)))))
|
||||
|
||||
;; =============================================================================
|
||||
;; OUTPUT and PRINT Instructions
|
||||
;; =============================================================================
|
||||
|
@ -1,34 +1,38 @@
|
||||
(ns propeller.push.interpreter
|
||||
(:require [propeller.push.core :as push]
|
||||
[propeller.push.state :as state]))
|
||||
[propeller.push.state :as state]
|
||||
[propeller.push.utils :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)
|
||||
first-instruction-raw (first (:exec state))
|
||||
first-instruction (if (keyword? first-instruction-raw)
|
||||
(first-instruction-raw @push/instruction-table)
|
||||
first-instruction-raw)]
|
||||
instruction (first (:exec state))
|
||||
literal-type (get-literal-type instruction)] ; nil for non-literals
|
||||
(cond
|
||||
(fn? first-instruction)
|
||||
(first-instruction popped-state)
|
||||
;
|
||||
(integer? first-instruction)
|
||||
(state/push-to-stack popped-state :integer first-instruction)
|
||||
;
|
||||
(string? first-instruction)
|
||||
(state/push-to-stack popped-state :string first-instruction)
|
||||
;
|
||||
(seq? first-instruction)
|
||||
(update popped-state :exec #(concat %2 %1) first-instruction)
|
||||
;
|
||||
(or (= first-instruction true) (= first-instruction false))
|
||||
(state/push-to-stack popped-state :boolean first-instruction)
|
||||
;
|
||||
;;
|
||||
;; Recognize functional instruction or input instruction
|
||||
(keyword? instruction)
|
||||
(if-let [function (instruction @push/instruction-table)]
|
||||
(function popped-state)
|
||||
(io/handle-input-instruction popped-state instruction))
|
||||
;;
|
||||
;; Recognize constant literal instruction
|
||||
literal-type
|
||||
(if (= :generic-vector literal-type)
|
||||
;; Empty vector gets pushed on all vector stacks
|
||||
(reduce #(update-in % [%2] conj []) popped-state
|
||||
[:vector_boolean :vector_float :vector_integer :vector_string])
|
||||
(state/push-to-stack popped-state literal-type instruction))
|
||||
;;
|
||||
;; Recognize parenthesized group of instructions
|
||||
(seq? instruction)
|
||||
(update popped-state :exec #(concat %2 %1) instruction)
|
||||
;;
|
||||
:else
|
||||
(throw (Exception. (str "Unrecognized Push instruction in program: "
|
||||
(name first-instruction-raw)))))))
|
||||
(name instruction)))))))
|
||||
|
||||
(defn interpret-program
|
||||
"Runs the given problem starting with the stacks in start-state."
|
||||
|
@ -51,11 +51,21 @@
|
||||
;; :integer. Otherwise, return nil"
|
||||
(defn get-literal-type
|
||||
[data]
|
||||
(let [literals {:boolean (fn [thing] (or (true? thing) (false? thing)))
|
||||
:char char?
|
||||
:float float?
|
||||
:integer integer?
|
||||
:string string?}]
|
||||
(let [literals {:boolean (fn [thing] (or (true? thing) (false? thing)))
|
||||
:char char?
|
||||
:float float?
|
||||
:integer integer?
|
||||
:string string?
|
||||
:vector_boolean (fn [thing] (and (vector? thing)
|
||||
(or (true? (first thing))
|
||||
(false? (first thing)))))
|
||||
:vector_float (fn [thing] (and (vector? thing)
|
||||
(float? (first thing))))
|
||||
:vector_integer (fn [thing] (and (vector? thing)
|
||||
(integer? (first thing))))
|
||||
:vector_string (fn [thing] (and (vector? thing)
|
||||
(string? (first thing))))
|
||||
:generic-vector (fn [thing] (= [] thing))}]
|
||||
(first (for [[stack function] literals
|
||||
:when (function data)]
|
||||
stack))))
|
||||
|
@ -1,5 +1,10 @@
|
||||
(ns propeller.utils)
|
||||
|
||||
(defn get-vector-literal-type
|
||||
"Returns the literal stack corresponding to some vector stack."
|
||||
[vector-stack]
|
||||
(keyword (clojure.string/replace (str vector-stack) ":vector_" "")))
|
||||
|
||||
(defn indexof
|
||||
"Returns the first index of an element in a collection. If the element is not
|
||||
present in the collection, returns -1."
|
||||
@ -26,9 +31,6 @@
|
||||
ERC-producing functions to a constant literal."
|
||||
[instructions]
|
||||
(let [instruction (rand-nth instructions)]
|
||||
(if (fn? instruction) (instruction) instruction)))
|
||||
|
||||
(defn get-vector-literal-type
|
||||
"Returns the literal stack corresponding to some vector stack."
|
||||
[vector-stack]
|
||||
(keyword (clojure.string/replace (str vector-stack) ":vector_" "")))
|
||||
(if (fn? instruction)
|
||||
(instruction)
|
||||
instruction)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user