Merge pull request #8 from NicMcPhee/limit-dup-times
Limit stack size when using `_dup_times` and `_dup_items`
This commit is contained in:
commit
f2e4cf0e1e
@ -5,6 +5,7 @@
|
|||||||
(:require [propeller.utils :as utils]
|
(:require [propeller.utils :as utils]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
[propeller.push.utils.helpers :refer [make-instruction]]
|
||||||
|
[propeller.push.utils.globals :as globals]
|
||||||
#?(:clj
|
#?(:clj
|
||||||
[propeller.push.utils.macros :refer [def-instruction
|
[propeller.push.utils.macros :refer [def-instruction
|
||||||
generate-instructions]])))
|
generate-instructions]])))
|
||||||
@ -29,7 +30,8 @@
|
|||||||
;; its argument (since that would negate the effect of the duplication). The
|
;; its argument (since that would negate the effect of the duplication). The
|
||||||
;; number n is determined by the top INTEGER. For n = 0, equivalent to POP.
|
;; number n is determined by the top INTEGER. For n = 0, equivalent to POP.
|
||||||
;; For n = 1, equivalent to NOOP. For n = 2, equivalent to DUP. Negative values
|
;; For n = 1, equivalent to NOOP. For n = 2, equivalent to DUP. Negative values
|
||||||
;; of n are treated as 0
|
;; of n are treated as 0. The final number of items on the stack is limited to
|
||||||
|
;; globals/max-stack-items.
|
||||||
(def _dup_times
|
(def _dup_times
|
||||||
^{:stacks #{:integer}}
|
^{:stacks #{:integer}}
|
||||||
(fn [stack state]
|
(fn [stack state]
|
||||||
@ -38,7 +40,8 @@
|
|||||||
(and (not= stack :integer)
|
(and (not= stack :integer)
|
||||||
(not (state/empty-stack? state :integer))
|
(not (state/empty-stack? state :integer))
|
||||||
(not (state/empty-stack? state stack))))
|
(not (state/empty-stack? state stack))))
|
||||||
(let [n (state/peek-stack state :integer)
|
(let [n (min (state/peek-stack state :integer)
|
||||||
|
(inc (- globals/max-stack-items (state/stack-size state stack))))
|
||||||
popped-state (state/pop-stack state :integer)
|
popped-state (state/pop-stack state :integer)
|
||||||
top-item (state/peek-stack popped-state stack)
|
top-item (state/peek-stack popped-state stack)
|
||||||
top-item-dup (take (- n 1) (repeat top-item))]
|
top-item-dup (take (- n 1) (repeat top-item))]
|
||||||
@ -50,12 +53,14 @@
|
|||||||
;; Duplicates the top n items on the stack, one time each. The number n is
|
;; Duplicates the top n items on the stack, one time each. The number n is
|
||||||
;; determined by the top INTEGER. If n <= 0, no items will be duplicated. If
|
;; determined by the top INTEGER. If n <= 0, no items will be duplicated. If
|
||||||
;; fewer than n items are on the stack, the entire stack will be duplicated.
|
;; fewer than n items are on the stack, the entire stack will be duplicated.
|
||||||
|
;; The final number of items on the stack is limited to globals/max-stack-items.
|
||||||
(def _dup_items
|
(def _dup_items
|
||||||
^{:stacks #{:integer}}
|
^{:stacks #{:integer}}
|
||||||
(fn [stack state]
|
(fn [stack state]
|
||||||
(if (state/empty-stack? state :integer)
|
(if (state/empty-stack? state :integer)
|
||||||
state
|
state
|
||||||
(let [n (state/peek-stack state :integer)
|
(let [n (min (state/peek-stack state :integer)
|
||||||
|
(- globals/max-stack-items (state/stack-size state stack)))
|
||||||
popped-state (state/pop-stack state :integer)
|
popped-state (state/pop-stack state :integer)
|
||||||
top-items (take n (get popped-state stack))]
|
top-items (take n (get popped-state stack))]
|
||||||
(state/push-to-stack-many popped-state stack top-items)))))
|
(state/push-to-stack-many popped-state stack top-items)))))
|
||||||
|
@ -35,6 +35,11 @@
|
|||||||
[state stack]
|
[state stack]
|
||||||
(empty? (get state stack)))
|
(empty? (get state stack)))
|
||||||
|
|
||||||
|
;; Returns the stack size
|
||||||
|
(defn stack-size
|
||||||
|
[state stack]
|
||||||
|
(count (get state stack)))
|
||||||
|
|
||||||
;; Returns the top item on the stack
|
;; Returns the top item on the stack
|
||||||
(defn peek-stack
|
(defn peek-stack
|
||||||
[state stack]
|
[state stack]
|
||||||
|
11
src/propeller/push/utils/globals.cljc
Normal file
11
src/propeller/push/utils/globals.cljc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
(ns propeller.push.utils.globals)
|
||||||
|
|
||||||
|
;; =============================================================================
|
||||||
|
;; Values used by the Push instructions to keep the stack sizes within
|
||||||
|
;; reasonable limits.
|
||||||
|
;; =============================================================================
|
||||||
|
|
||||||
|
;; Limits the number of items that can be duplicated onto a stack at once.
|
||||||
|
;; We might want to extend this to limit all the different that things may be
|
||||||
|
;; placed on a stack.
|
||||||
|
(def max-stack-items 100)
|
Loading…
x
Reference in New Issue
Block a user