aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgoforthanddie.rb188
1 files changed, 141 insertions, 47 deletions
diff --git a/goforthanddie.rb b/goforthanddie.rb
index 0a24300..58aac52 100755
--- a/goforthanddie.rb
+++ b/goforthanddie.rb
@@ -1,15 +1,22 @@
#!/usr/bin/env ruby
-# d20+1 # 20 1 d 1 + p
-# 10d6k8 # 6 10 d 10 8 keep 8 .+ p
-# 3d6>2 # 6 3 d 3 2 > p
-# 3d12/2 # 12 3 d + + 2 / p
-
-stack = []
+def getmarkedlist(stack, markerautoclear)
+ h = []
+ wm = false
+ loop do
+ t = stack.pop
+ wm = t == :mark
+ break if wm
+ h << t
+ break if stack.empty?
+ end
+ stack.push(:mark) if wm && !markerautoclear
+ h
+end
-loop do
- print "> "
- gets.split.each do |token|
+def handle(str, stack, markermode, markerautoclear, destructiveprint)
+ exit if str.nil?
+ str.split.each do |token|
case token
when /[0-9]+/
stack.push(token.to_i)
@@ -17,9 +24,14 @@ loop do
a, b = stack.pop(2)
stack.push(a + b)
when ".+"
- n = stack.pop
- h = stack.pop(n)
- stack.push(h.sum)
+ if markermode
+ h = getmarkedlist(stack, markerautoclear)
+ stack.push(h.sum)
+ else
+ n = stack.pop
+ h = stack.pop(n)
+ stack.push(h.sum)
+ end
when "-"
a, b = stack.pop(2)
stack.push(a - b)
@@ -37,50 +49,132 @@ loop do
d = stack.pop
n.times { stack.push(rand(d) + 1) }
when "p"
- puts stack.pop
- when "s"
- puts stack.join(" ")
- when "ex", "explode"
- x = stack.pop
- n = stack.pop
- h = stack.pop(n)
- lm = 0
- loop do
- m = h.count(x)
- break if m == lm
- (m-lm).times { h << (rand(x) + 1) }
- lm = m
+ t = stack.pop
+ puts t
+ stack.push(t) unless destructiveprint
+ when ".ex", ".explode"
+ if markermode
+ x = stack.pop
+ h = getmarkedlist(stack, markerautoclear)
+ h.reverse!
+ lm = 0
+ loop do
+ m = h.count(x)
+ break if m == lm
+ (m-lm).times { h << (rand(x) + 1) }
+ lm = m
+ end
+ stack.push(*h)
+ else
+ x = stack.pop
+ n = stack.pop
+ h = stack.pop(n)
+ lm = 0
+ loop do
+ m = h.count(x)
+ break if m == lm
+ (m-lm).times { h << (rand(x) + 1) }
+ lm = m
+ end
+ stack.push(*h)
+ end
+ when ".k", ".kh", ".keep", ".keephigh", ".keephighest"
+ if markermode
+ k = stack.pop
+ h = getmarkedlist(stack, markerautoclear)
+ h.sort!
+ stack.push(*h.pop(k))
+ else
+ k = stack.pop
+ n = stack.pop
+ h = stack.pop(n).sort
+ stack.push(*h.pop(k))
+ end
+ when ".kl", ".keeplow", ".keeplowest"
+ if markermode
+ k = stack.pop
+ h = getmarkedlist(stack, markerautoclear)
+ h.sort!
+ stack.push(*h.shift(k))
+ else
+ k = stack.pop
+ n = stack.pop
+ h = stack.pop(n).sort
+ stack.push(*h.shift(k))
end
- stack.push(*h)
- when "k", "kh", "keep", "keephigh", "keephighest"
- k = stack.pop
- n = stack.pop
- h = stack.pop(n).sort
- stack.push(*h.pop(k))
- when "kl", "keeplow", "keeplowest"
- k = stack.pop
- n = stack.pop
- h = stack.pop(n).sort
- stack.push(*h.shift(k))
when ">"
- t = stack.pop
- n = stack.pop
- h = stack.pop(n)
- stack.push(h.count{ |d| d > t })
+ c = stack.pop
+ h = stack.pop
+ stack.push(c > h ? 1 : 0)
+ when ".>"
+ if markermode
+ c = stack.pop
+ h = getmarkedlist(stack, markerautoclear)
+ stack.push(h.count{ |d| c > d })
+ else
+ c = stack.pop
+ n = stack.pop
+ h = stack.pop(n)
+ stack.push(h.count{ |d| c > d })
+ end
when "<"
- t = stack.pop
- n = stack.pop
- h = stack.pop(n)
- stack.push(h.count{ |d| d < t })
+ c = stack.pop
+ h = stack.pop
+ stack.push(c < h ? 1 : 0)
+ when ".<"
+ if markermode
+ c = stack.pop
+ h = getmarkedlist(stack, markerautoclear)
+ stack.push(h.count{ |d| c < d })
+ else
+ c = stack.pop
+ n = stack.pop
+ h = stack.pop(n)
+ stack.push(h.count{ |d| c < d })
+ end
when "!"
stack.pop
when ".!"
- n = stack.pop
- stack.pop(n)
- when "q"
+ if markermode
+ getmarkedlist(stack, markerautoclear)
+ else
+ n = stack.pop
+ stack.pop(n)
+ end
+ when "m", "mark"
+ stack.push(:mark)
+ when "~s", "~stack"
+ puts stack.join(" ")
+ when "~mm"
+ markermode = !markermode
+ when "~mac"
+ markerautoclear = !markerautoclear
+ when "~dp"
+ destructiveprint = !destructiveprint
+ when "~state"
+ print "Stack: "
+ pp stack
+ print "Marker Mode: #{markermode ? "ON " : "OFF"} "
+ puts "Marker Auto-Clear: #{markerautoclear ? "ON " : "OFF"}"
+ puts "Destructive Print: #{destructiveprint ? "ON " : "OFF"}"
+ when "~q"
exit
else
puts "I don't know how to #{token}!"
end
end
end
+
+stack = []
+markermode = true
+markerautoclear = false
+destructiveprint = true
+
+if $stdin.tty?
+ loop do
+ print "> "
+ handle(gets, stack, markermode, markerautoclear, destructiveprint)
+ end
+else
+ handle($stdin.read, stack, markermode, markerautoclear, destructiveprint)
+end