From 220f602da1f6735f3b180c10a74313ec76c04959 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Fri, 16 Aug 2024 14:27:28 +0100 Subject: [goforthanddie.rb] More functions, also names, also refactoring lists --- goforthanddie.rb | 229 +++++++++++++++++++++++++++---------------------------- 1 file changed, 114 insertions(+), 115 deletions(-) diff --git a/goforthanddie.rb b/goforthanddie.rb index 58aac52..176df46 100755 --- a/goforthanddie.rb +++ b/goforthanddie.rb @@ -1,155 +1,153 @@ #!/usr/bin/env ruby -def getmarkedlist(stack, markerautoclear) - h = [] - wm = false - loop do - t = stack.pop - wm = t == :mark - break if wm - h << t - break if stack.empty? +def getlist(stack, markermode, markerautoclear) + if markermode + 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.reverse + else + n = stack.pop + stack.pop(n) end - stack.push(:mark) if wm && !markerautoclear - h end def handle(str, stack, markermode, markerautoclear, destructiveprint) exit if str.nil? str.split.each do |token| case token - when /[0-9]+/ + when /[+-][0-9]+/ stack.push(token.to_i) - when "+" + when "+", "add", "plus" a, b = stack.pop(2) stack.push(a + b) - when ".+" - if markermode - h = getmarkedlist(stack, markerautoclear) - stack.push(h.sum) - else - n = stack.pop - h = stack.pop(n) - stack.push(h.sum) - end - when "-" + when ".+", ".add", ".plus", ".sum" + h = getlist(stack, markermode, markerautoclear) + stack.push(h.sum) + when "-", "sub", "subtract", "minus" a, b = stack.pop(2) stack.push(a - b) - when "*" + when "*", "mul", "multiply", "times" a, b = stack.pop(2) stack.push(a * b) - when "/" + when "/", "div", "divide" a, b = stack.pop(2) stack.push(a / b) - when "%" + when "%", "mod", "modulate", "rem", "remainder" a, b = stack.pop(2) stack.push(a % b) when "d", "roll" n = stack.pop d = stack.pop n.times { stack.push(rand(d) + 1) } - when "p" + when "c", "copy", "dup" + h = stack.pop + stack.push(h) + stack.push(h) + when ".c", ".copy", ".dup" + h = getlist(stack, markermode, markerautoclear) + stack.push(*h) + stack.push(:mark) if markermode && !markerautoclear + stack.push(*h) + when "s", "swap" + a, b = stack.pop(2) + stack.push(b, a) + when "r", "rot", "rotate" + a, b, c = stack.pop(3) + stack.push(b, c, a) + when ".r", ".rot", ".rotate" + c = stack.pop + h = getlist(stack, markermode, markerautoclear) + stack.push(*h.rotate(c)) + when "o", "over" + a, b = stack.pop(2) + stack.push(a, b, a) + when "p", "print" 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) + x = stack.pop + h = getlist(stack, markermode, markerautoclear) + + 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) 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 + k = stack.pop + h = getlist(stack, markermode, markerautoclear) + h.sort! + stack.push(*h.pop(k)) 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 - when ">" + k = stack.pop + h = getlist(stack, markermode, markerautoclear) + h.sort! + stack.push(*h.shift(k)) + when ">", "gt", "greaterthan" 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 "<" + when ".>", ".gt", ".greaterthan" + c = stack.pop + h = getlist(stack, markermode, markerautoclear) + stack.push(h.count{ |d| c > d }) + when ">=", "gteq", "greaterthanorequalto" + c = stack.pop + h = stack.pop + stack.push(c >= h ? 1 : 0) + when ".>=", ".gteq", ".greaterthanorequalto" + c = stack.pop + h = getlist(stack, markermode, markerautoclear) + stack.push(h.count{ |d| c >= d }) + when "=", "eq", "equalto" + c = stack.pop + h = stack.pop + stack.push(c == h ? 1 : 0) + when ".=", ".eq", ".equalto" + c = stack.pop + h = getlist(stack, markermode, markerautoclear) + stack.push(h.count{ |d| c == d }) + when "<=", "lteq", "lessthanorequalto" + c = stack.pop + h = stack.pop + stack.push(c <= h ? 1 : 0) + when ".<=", ".lteq", ".lessthanorequalto" + c = stack.pop + h = getlist(stack, markermode, markerautoclear) + stack.push(h.count{ |d| c <= d }) + when "<", "lt", "lessthan" 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 "!" + when ".<", ".lt", ".lessthan" + c = stack.pop + h = getlist(stack, markermode, markerautoclear) + stack.push(h.count{ |d| c < d }) + when "!", "drop" stack.pop - when ".!" - if markermode - getmarkedlist(stack, markerautoclear) - else - n = stack.pop - stack.pop(n) - end + when ".!", ".drop" + getlist(stack, markermode, markerautoclear) when "m", "mark" stack.push(:mark) when "~s", "~stack" puts stack.join(" ") - when "~mm" + when "~mm", "~markermode" markermode = !markermode - when "~mac" + when "~mac", "~markerautoclear" markerautoclear = !markerautoclear - when "~dp" + when "~dp", "~destructiveprint" destructiveprint = !destructiveprint when "~state" print "Stack: " @@ -157,24 +155,25 @@ def handle(str, stack, markermode, markerautoclear, destructiveprint) print "Marker Mode: #{markermode ? "ON " : "OFF"} " puts "Marker Auto-Clear: #{markerautoclear ? "ON " : "OFF"}" puts "Destructive Print: #{destructiveprint ? "ON " : "OFF"}" - when "~q" + when "~q", "~quit" exit else puts "I don't know how to #{token}!" end end + [markermode, markerautoclear, destructiveprint] end -stack = [] -markermode = true -markerautoclear = false -destructiveprint = true +stk = [] +mm = true +mac = false +dp = true if $stdin.tty? loop do print "> " - handle(gets, stack, markermode, markerautoclear, destructiveprint) + mm, mac, dp = handle(gets, stk, mm, mac, dp) end else - handle($stdin.read, stack, markermode, markerautoclear, destructiveprint) + mm, mac, dp = handle($stdin.read, stk, mm, mac, dp) end -- cgit v1.2.1