Have the functionality of INTERCAL's operators (and more!) in Ruby - today

T

T.Oakley

Here's something I cooked up. Quite like an unholy alliance between Ruby and INTERCAL with some hidden functionality thrown in just to fool any unsuspecting reader.

Try not to vomit.


***********Rugetest.rb

require 'Ruge.rb'

puts "\n\ni_to_b"

0.upto(7) do |i|
puts i.itob(8)
end

puts "\n>> and stol"

0.upto(4) do |i|
puts "#{"12345">>i} #{"12345".stol(i)}"
end

puts "\n\t\t*Wrapped*"

bing = Wrapped.new(13...22)
bing << 16

puts "\nCollecting a Wrapped"

bing.collect {|i| p i}

puts "\nBasic arithmetic"

1.upto(15) do |i|
print "#{bing} + #{i} (#{bing.value+i}) = #{bing + i}\n"
end


print "\nMingle 0 and 65535\n#{0.itob}\n#{65535.itob}\n#{0.mingle(65535,32).itob(32)}\n"
print "\n179 select 201\n #{179.itob}\n #{201.itob}\n=#{179.select(201).itob} (#{179.select(201)})\n"



puts "\nUnary ops"
print "77: #{77.itob(16)}\n\nOR: #{77.V.itob}\t#{77.V}\nXOR:#{77.what.itob}\t#{77.what}\nAND:#{77.ampersand.itob}\t#{77.ampersand}\n"




come_from("first") do
puts "Crikey!"
end


puts "\n\nCOME FROM"

come_from_cond("second",lambda {return true}) do
puts "Another crikey!"
end


label("second")
label("first")






************Ruge.rb

# RUGE -- The Ruby Library With No Pronounceable Acronym
#
# Usage: none I can foresee at the moment
# Author: izmash at "uukkul">>1 dot com
#
########################################################################
# DISCLAIMER #
# I take no responsibility for bad habits stemming from using RUGE. #
# RUGE takes no responsibility for the way it was coded in #
########################################################################
#
# New classes:
#
#
#*Wrapped
#
#A new variable type that wraps around when given a value outside its range. Example:
#quux = Wrapped.new(7..13)
#quux << 12
#quux + 2 -> 1
#
#Mixins: Comparable, Enumerable (responds to each like Range would, succ and <=> work on the value of the var)
#
# Public:
# Wrapped#new(Range) Creates a new Wrapped variable which can have NON-FLOAT values specified in Range.
# Wrapped#<<(val) Assigns val to the Wrapped variable. If val is outside range, then coerces it into it.
# Wrapped#range=(range) Sets the range of the Wrapped variable to range
# Wrapped# + - * ** % Currently supported arithmethic.
# Wrapped#inspect Returns value attribute
#
# Attributes:
# Read/write range
# Read-only value
#
#
# Useless toy methods (syntactic... tar?):
#
# The COME FROM collection. Towards a GOTO-less programming style:
#
# come_from(label, &block) Comes from the specified label and executes block
# come_from_cond(label, condblock, &block) Executes block only if condblock returns TRUE
# label(name) Creates a label.
# Multiple COME FROMs can't point to the same label yet. Multithreading...
# NOTE: A come_from must come before it's label.
#
# Extensions to existing classes:
#
#* Fixnum
#
# - Unary logical operators OR, XOR, AND (#uOR, #uXOR and #uAND, respectively)
# These operators perform their respective logical operations on all pairs of adjacent bits,
# the result from the first and last bits going into the first bit of the result.
#
#
#* Integer
# - #to_b(x=16) returns the string representation of the binary representation of the integer using x bits.
#
# - #interleave(b, bits=16) interleaves the integer's bits with the bits of b, reading specified amount
# of bits from each.
# --> ababababab...
#
# - #select(b, len=16) selects bits from a using b, producing len bits as result
# The select operator takes from the first operand whichever bits correspond
# to 1's in the second operand, and packs these bits to the right in the result.
#
#
#* String
# - #b_to_i takes a string representation of a binary number and converts it to decimal
# - # >> shifts string right, wraps around.
# - # stol(amt=1) shifts left amt characters


class Fixnum

def sh
(self.to_i.itob >> 1).btoi
end

#Unary operators. The aliases provide an INTERCAL mnemonic for each op.

def uOR
self.sh | self.to_i
end
alias :V :uOR

def uXOR
self.sh ^ self.to_i
end
alias :what :uXOR


def uAND
self.sh & self.to_i
end
alias :ampersand :uAND
end

class Integer
#Converts num to a binary number represented as a string, using specified number of bits.
def to_b(bits=16)
num = self.to_i
a = ""

bits.-(1).downto(0) do |i|
a << num.to_s
end

a
end

alias :itob :to_b

#LSB -> MSB ababababab....
#len is the length of the product

def interleave(b,len=16)
a = self.to_i
c = ""

0.upto(len-1) do |i|
c << a.to_s << b.to_s
end

c.reverse.btoi
end

alias :mingle :interleave
alias :change :interleave

def select(b,len=16)
a = self.to_i
c = ""

0.upto(len-1) do |i|
c << a.to_s if b == 1
end

c.reverse.btoi
end

alias :sqiggle :select


end







class String
#Converts a string representation of a binary number to a number.
def b_to_i
qq=self.to_s

zork = 0
(0...qq.length).each do |i|
zork += (qq.reverse.chr.to_i)*2**i
end
zork

end
alias :btoi :b_to_i

#Shifts string to right amt steps (wraps around)
def >>(amt)

amt %= self.length

return self if amt == 0
return self[-amt..-1]<<self[0...self.length-amt]

end

#Shifts string left amt steps
def stol(amt=1)

amt %= self.length

return self if amt == 0

return self[-(self.length-amt)..-1]<<self[0...amt]
end
end


class Wrapped
include Comparable
include Enumerable

attr_reader :range, :value
@value = 0

def checkType(val)
raise TypeError, "Trying to use a Float in a Wrapped" if val.class == Float
end
private :checkType

def getval(val)
if self.range === val
return val
elsif val > self.range.last
temp = (val - self.range.last)
return wrapadd(temp,self.range.last)

else
temp = (self.range.first - val)
return wrapadd(-temp,self.range.first)
end
end

private :getval


def +(val)
checkType(val)
wrapadd(val)
end

def -(val)
checkType(val)
wrapadd(-val)
end

def *(val)
checkType(val)
getval(self.value * val)
end

def **(val)
checkType(val)
getval(self.value ** val)
end

def %(val)
checkType(val)
getval(self.value % val)
end

def <=>(val)
checkType(val)
self.value <=> val.to_i
end

def value=(val)
@value = val
end

private :value=

#Adds or substracts val from orig, and returns the result. DOES NOT modify anything
#(The name is a tad misleading)
def wrapadd(val, orig=self.value)
checkType(val)
x = self.range.first
y = self.range.last
tempvalue = orig - x
rlen = (y - x) + 1
modu = (tempvalue + val) % rlen
return modu+x

end
private :wrapadd

#assign a value, wraps around each end of the range. Use this instead of =
#uses self#getval to check what the result of the assignment is.
#NO FLOATS
def <<(val)
checkType(val)
self.value = getval(val)
self

end

#set the range. Translates (x...y) to (x..y-1)
def range=(range)
raise "#{range.class} != Range" if range.class != Range
temp = range.dup
temp = Range.new(range.first,range.last-1) if range.exclude_end?
@range = temp
end

def initialize(range)
self.range = range
self
end

def to_s
self.value.to_s
end

def to_i
self.value.to_i
end

def succ
temp = Wrapped.new(self.range)
temp << self.value + 1
end

def each(&block)
self.range.each {|i| yield i}
end

def inspect
self.value.to_i
end
end

class Cfr
@@labels = {}

def Cfr.procfor(name)
@@labels[name]
end

def Cfr.labels
@@labels
end

def initialize(name, block, condblock=proc {true})
@@labels[name] = [block,condblock]
end

end

def come_from(label,&block)
Cfr.new(label, block)
end

def come_from_cond(label, condblock, &block)
Cfr.new(label, block, condblock)
end

def label(name)
temp = Cfr.procfor(name)
temp[0].call if temp[0].class == Proc and temp[1].call == true
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top