text:
module Trith; module Math
  ##
  # Arithmetic operators.
  #
  # @see http://www.math.bas.bg/bantchev/articles/divmod.pdf
  module Arithmetic
    ##
    # @param  [Numeric] n
    # @return [Numeric]
    def abs(n)
      n.abs
    end

    ##
    # @param  [Numeric] n
    # @return [Numeric]
    def neg(n)
      -n
    end

    ##
    # @param  [Numeric] n
    # @return [Numeric]
    def inc(n)
      n + 1
    end

    ##
    # @param  [Numeric] n
    # @return [Numeric]
    def dec(n)
      n - 1
    end

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def add(a, b)
      a + b
    end
    alias_method :+, :add

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def sub(a, b)
      a - b
    end
    alias_method :-, :sub

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def mul(a, b)
      a * b
    end
    alias_method :*, :mul

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def div(a, b)
      a / b
    end
    alias_method :'/', :div

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def rem(a, b)
      a.remainder(b)
    end

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def mod(a, b)
      a.modulo(b)
    end
    #alias_method :'%', :mod

    ##
    # @param  [Numeric] a
    # @param  [Numeric] b
    # @return [Numeric]
    def pow(a, b)
      a ** b
    end
    #alias_method :'^', :pow
  end # module Arithmetic
end; end # module Trith::Math


text:
module Trith; module Math
  ##
  # Math constants.
  #
  # @see http://ruby-doc.org/core/classes/Math.html
  module Constants
    # TODO
  end # module Constants
end; end # module Trith::Math

repo_name: trith/trith

repo_language: Ruby

mime_type: text/plain


text:
module Trith; module Math
  ##
  # Math operators.
  #
  # @see http://ruby-doc.org/core/classes/Math.html
  module Operators
    ##
    # @param  [Numeric, #ceil] n
    # @return [Integer]
    def ceil(n)
      n.ceil
    end

    ##
    # @param  [Numeric, #floor] n
    # @return [Integer]
    def floor(n)
      n.floor
    end
  end # module Operators
end; end # module Trith::Math


text:
require File.join(File.dirname(__FILE__), 'spec_helper')

describe 'Trith::VERSION' do
  it "should match the VERSION file" do
    Trith::VERSION.to_s.should == File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).chomp
  end
end


text:
require 'trith'

include  Trith

require 'trith/sys/posix'
describe System::POSIX do
  before(:each) do
    @machine = Machine.new { import Trith::System::POSIX }
  end

  context "Time operations" do
    it "should support the :time operation" do
      @machine.should respond_to(:time)
      @machine.execute { time }.pop.should be_a(Integer)
      @machine.stack.should be_empty
    end
  end

  context "File operations" do
    it "should support the :stdin operation" do
      @machine.should respond_to(:stdin)
      @machine.execute { stdin }.pop.should == $stdin
      @machine.stack.should be_empty
    end

    it "should support the :stdout operation" do
      @machine.should respond_to(:stdout)
      @machine.execute { stdout }.pop.should == $stdout
      @machine.stack.should be_empty
    end

    it "should support the :stderr operation" do
      @machine.should respond_to(:stderr)
      @machine.execute { stderr }.pop.should == $stderr
      @machine.stack.should be_empty
    end

    it "should support the :fileno operation" do
      @machine.should respond_to(:fileno)
      @machine.execute([$stderr]) { fileno }.pop.should == 2
      @machine.stack.should be_empty
    end

    it "should support the :fopen operation"
    it "should support the :fseek operation"

    it "should support the :fread operation" do
      @machine.should respond_to(:fwrite)
      @machine.execute([__FILE__, 'r']) { fopen }.peek.should be_a(IO)
      @machine.execute(["require 'trith'".length]) { fread }.pop.should == "require 'trith'"
      @machine.stack.should be_empty
    end

    it "should support the :fwrite operation" do
      buffer = StringIO.new
      @machine.should respond_to(:fwrite)
      @machine.execute([buffer, "Hello, world!\n"]) { fwrite }.pop.should be_an(Integer)
      buffer.string.should == "Hello, world!\n"
      @machine.stack.should be_empty
    end

    it "should support the :feof operation"
    it "should support the :fflush operation"
    it "should support the :fclose operation"
    it "should support the :fsync operation"
    it "should support the :popen operation"
    it "should support the :pclose operation"
  end
end

require 'trith/lib/openssl'
describe Library::OpenSSL do
  before(:each) do
    @machine = Machine.new { import Trith::Library::OpenSSL }
  end

  context "Random number generator" do
    it "should support the :rand_bytes operation"
  end

  context "Message digest algorithms" do
    it "should support the :md4 operation"
    it "should support the :md5 operation"
    it "should support the :ripemd160 operation"
    it "should support the :sha1 operation"
    it "should support the :sha224 operation"
    it "should support the :sha256 operation"
    it "should support the :sha384 operation"
    it "should support the :sha512 operation"
  end
end


text:
require File.join(File.dirname(__FILE__), 'spec_helper')

describe Trith::Machine do
  context "Execution operators" do
    it "should implement the :reset operator" do
      Machine.new.should respond_to(:reset)
      Machine.new([6, 7]).execute { reset }.to_a.should == []
    end

    it "should implement the :halt operator" do
      Machine.new.should respond_to(:halt)
      Machine.run { push(42).halt }.should == 42
    end

    it "should implement the :nop operator" do
      Machine.new.should respond_to(:nop, :',', :';')
      Machine.run { push(42).nop }.should == 42
    end

    it "should implement the :quote operator" do
      Machine.new.should respond_to(:quote, :'\\', :"'")
      # TODO
    end

    it "should implement the :call operator" do
      Machine.new.should respond_to(:call)
      # TODO
    end

    it "should implement the :times operator" do
      Machine.new.should respond_to(:times)
      # TODO
    end

    it "should implement the :twice operator" do
      Machine.new.should respond_to(:twice, :'2x')
      # TODO
    end

    it "should implement the :thrice operator" do
      Machine.new.should respond_to(:thrice, :'3x')
      # TODO
    end

    it "should implement the :loop operator" do
      Machine.new.should respond_to(:loop)
      # TODO
    end

    it "should implement the :while operator" do
      Machine.new.should respond_to(:while)
      # TODO
    end

    it "should implement the :until operator" do
      Machine.new.should respond_to(:until)
      # TODO
    end

    it "should implement the :branch operator" do
      Machine.new.should respond_to(:branch, :if)
      # TODO
    end

    it "should implement the :when operator" do
      Machine.new.should respond_to(:when)
      # TODO
    end

    it "should implement the :unless operator" do
      Machine.new.should respond_to(:unless)
      # TODO
    end
  end

  context "Stack shufflers" do
    it "should implement the :clear operator" do
      Machine.new.should respond_to(:clear)
      Machine.new([6, 7]).execute { clear }.stack.should == []
    end

    it "should implement the :depth operator" do
      Machine.new.should respond_to(:depth)
      # TODO
    end

    it "should implement the :stack operator" do
      Machine.new.should respond_to(:stack)
      # TODO
    end

    it "should implement the :unstack operator" do
      Machine.new.should respond_to(:unstack)
      # TODO
    end

    it "should implement the :drop operator" do
      Machine.new.should respond_to(:drop)
      Machine.new([6, 7]).execute { drop }.stack.should == [6]
    end

    it "should implement the :drop2 operator" do
      Machine.new.should respond_to(:drop2, :'2drop')
      # TODO
    end

    it "should implement the :drop3 operator" do
      Machine.new.should respond_to(:drop3, :'3drop')
      # TODO
    end

    it "should implement the :dup operator" do
      Machine.new.should respond_to(:dup)
      Machine.new([6, 7]).execute { dup }.stack.should == [6, 7, 7]
    end

    it "should implement the :dup2 operator" do
      Machine.new.should respond_to(:dup2, :'2dup')
      # TODO
    end

    it "should implement the :dup3 operator" do
      Machine.new.should respond_to(:dup3, :'3dup')
      # TODO
    end

    it "should implement the :swap operator" do
      Machine.new.should respond_to(:swap)
      Machine.new([6, 7]).execute { swap }.stack.should == [7, 6]
    end

    it "should implement the :nip operator" do
      Machine.new.should respond_to(:nip)
      # TODO
    end

    it "should implement the :nip2 operator" do
      Machine.new.should respond_to(:nip2, :'2nip')
      # TODO
    end

    it "should implement the :over operator" do
      Machine.new.should respond_to(:over)
      # TODO
    end

    it "should implement the :pick operator" do
      Machine.new.should respond_to(:pick)
      # TODO
    end

    it "should implement the :rot operator" do
      Machine.new.should respond_to(:rot)
      # TODO
    end
  end

  context "Stack combinators" do
    it "should implement the :dip operator" do
      Machine.new.should respond_to(:dip)
      Machine.new([6, 7, 1, [:mul]]).execute { dip }.stack.should == [42, 1]
    end
  end

  context "Arithmetic operators" do
    it "should implement the :abs operator" do
      Machine.new.should respond_to(:abs)
      Machine.run { push(1).abs }.should == 1
      Machine.run { push(-1).abs }.should == 1
    end

    it "should implement the :neg operator" do
      Machine.new.should respond_to(:neg)
      Machine.run { push(6).neg }.should == -6
    end

    it "should implement the :inc operator" do
      Machine.new.should respond_to(:inc)
      Machine.run { push(6).inc }.should == 7
    end

    it "should implement the :dec operator" do
      Machine.new.should respond_to(:dec)
      Machine.run { push(6).dec }.should == 5
    end

    it "should implement the :add operator" do
      Machine.new.should respond_to(:add, :+)
      Machine.run { push(6).push(7).add }.should == 13
    end

    it "should implement the :sub operator" do
      Machine.new.should respond_to(:sub, :-)
      Machine.run { push(6).push(7).sub }.should == -1
    end

    it "should implement the :mul operator" do
      Machine.new.should respond_to(:mul, :*)
      Machine.run { push(6).push(7).mul }.should == 42
    end

    it "should implement the :div operator" do
      Machine.new.should respond_to(:div, :'/')
      Machine.run { push(42).push(7).div }.should == 6
    end

    it "should implement the :rem operator" do
      Machine.new.should respond_to(:rem)
      # TODO
    end

    it "should implement the :mod operator" do
      Machine.new.should respond_to(:mod)
      # TODO
    end

    it "should implement the :pow operator" do
      Machine.new.should respond_to(:pow)
      # TODO
    end
  end

  context "Bitwise operators" do
    it "should implement the :not operator" do
      Machine.new.should respond_to(:not)
      # TODO
    end

    it "should implement the :and operator" do
      Machine.new.should respond_to(:and)
      # TODO
    end

    it "should implement the :or operator" do
      Machine.new.should respond_to(:or)
      # TODO
    end

    it "should implement the :xor operator" do
      Machine.new.should respond_to(:xor)
      # TODO
    end

    it "should implement the :shl operator" do
      Machine.new.should respond_to(:shl)
      # TODO
    end

    it "should implement the :shr operator" do
      Machine.new.should respond_to(:shr)
      # TODO
    end
  end

  context "Boolean predicates" do
    it "should implement the :nilp operator" do
      Machine.new.should respond_to(:nilp, :nil?)
      # TODO
    end

    it "should implement the :boolp operator" do
      Machine.new.should respond_to(:boolp, :bool?)
      # TODO
    end

    it "should implement the :falsep operator" do
      Machine.new.should respond_to(:falsep, :false?)
      # TODO
    end

    it "should implement the :truep operator" do
      Machine.new.should respond_to(:truep, :true?)
      # TODO
    end

    it "should implement the :notp operator" do
      Machine.new.should respond_to(:notp, :not?)
      # TODO
    end

    it "should implement the :andp operator" do
      Machine.new.should respond_to(:andp, :and?)
      # TODO
    end

    it "should implement the :orp operator" do
      Machine.new.should respond_to(:orp, :or?)
      # TODO
    end

    it "should implement the :xorp operator" do
      Machine.new.should respond_to(:xorp, :xor?)
      # TODO
    end
  end

  context "Boolean constructors" do
    it "should implement the :nil operator" do
      Machine.new.should respond_to(:nil)
      # TODO
    end

    it "should implement the :bool operator" do
      Machine.new.should respond_to(:bool)
      # TODO
    end

    it "should implement the :false operator" do
      Machine.new.should respond_to(:false)
      # TODO
    end

    it "should implement the :true operator" do
      Machine.new.should respond_to(:true)
      # TODO
    end
  end

  context "Comparison operators" do
    it "should implement the :cmp operator" do
      Machine.new.should respond_to(:cmp, :<=>)
      # TODO
    end

    it "should implement the :eq operator" do
      Machine.new.should respond_to(:eq, :'=')
      # TODO
    end

    it "should implement the :ne operator" do
      Machine.new.should respond_to(:ne, :'!=')
      # TODO
    end

    it "should implement the :lt operator" do
      Machine.new.should respond_to(:lt, :<)
      # TODO
    end

    it "should implement the :le operator" do
      Machine.new.should respond_to(:le, :<=)
      # TODO
    end

    it "should implement the :gt operator" do
      Machine.new.should respond_to(:gt, :>)
      # TODO
    end

    it "should implement the :ge operator" do
      Machine.new.should respond_to(:ge, :>=)
      # TODO
    end

    it "should implement the :min operator" do
      Machine.new.should respond_to(:min)
      # TODO
    end

    it "should implement the :max operator" do
      Machine.new.should respond_to(:max)
      # TODO
    end
  end

  context "Numeric predicates" do
    it "should implement the :nump operator" do
      Machine.new.should respond_to(:nump, :num?)
      # TODO
    end

    it "should implement the :intp operator" do
      Machine.new.should respond_to(:intp, :int?)
      # TODO
    end

    it "should implement the :infp operator" do
      Machine.new.should respond_to(:infp, :inf?)
      # TODO
    end

    it "should implement the :zerop operator" do
      Machine.new.should respond_to(:zerop, :zero?)
      # TODO
    end

    it "should implement the :onep operator" do
      Machine.new.should respond_to(:onep, :one?)
      # TODO
    end

    it "should implement the :negp operator" do
      Machine.new.should respond_to(:negp, :neg?)
      # TODO
    end

    it "should implement the :posp operator" do
      Machine.new.should respond_to(:posp, :pos?)
      # TODO
    end

    it "should implement the :oddp operator" do
      Machine.new.should respond_to(:oddp, :odd?)
      # TODO
    end

    it "should implement the :evenp operator" do
      Machine.new.should respond_to(:evenp, :even?)
      # TODO
    end
  end

  context "Numeric constructors" do
    it "should implement the :num operator" do
      Machine.new.should respond_to(:num)
      # TODO
    end

    it "should implement the :int operator" do
      Machine.new.should respond_to(:int)
      # TODO
    end

    it "should implement the :inf operator" do
      Machine.new.should respond_to(:inf)
      # TODO
    end
  end

  context "Math constants" do
    it "should implement the :pi operator" do
      Machine.new.should respond_to(:pi)
      # TODO
    end
  end

  context "Math operators" do
    it "should implement the :ceil operator" do
      Machine.new.should respond_to(:ceil)
      # TODO
    end

    it "should implement the :floor operator" do
      Machine.new.should respond_to(:floor)
      # TODO
    end

    it "should implement the :round operator" do
      Machine.new.should respond_to(:round)
      # TODO
    end

    it "should implement the :sq operator" do
      Machine.new.should respond_to(:sq)
      # TODO
    end

    it "should implement the :sqrt operator" do
      Machine.new.should respond_to(:sqrt)
      # TODO
    end

    it "should implement the :cb operator" do
      Machine.new.should respond_to(:cb)
      # TODO
    end

    it "should implement the :cbrt operator" do
      Machine.new.should respond_to(:cbrt)
      # TODO
    end

    it "should implement the :exp operator" do
      Machine.new.should respond_to(:exp)
      # TODO
    end

    it "should implement the :log operator" do
      Machine.new.should respond_to(:log)
      # TODO
    end

    it "should implement the :log2 operator" do
      Machine.new.should respond_to(:log2)
      # TODO
    end

    it "should implement the :log10 operator" do
      Machine.new.should respond_to(:log10)
      # TODO
    end

    it "should implement the :hypot operator" do
      Machine.new.should respond_to(:hypot)
      # TODO
    end

    it "should implement the :cos operator" do
      Machine.new.should respond_to(:cos)
      # TODO
    end

    it "should implement the :cosh operator" do
      Machine.new.should respond_to(:cosh)
      # TODO
    end

    it "should implement the :sin operator" do
      Machine.new.should respond_to(:sin)
      # TODO
    end

    it "should implement the :sinh operator" do
      Machine.new.should respond_to(:sinh)
      # TODO
    end

    it "should implement the :tan operator" do
      Machine.new.should respond_to(:tan)
      # TODO
    end

    it "should implement the :tanh operator" do
      Machine.new.should respond_to(:tanh)
      # TODO
    end

    it "should implement the :acos operator" do
      Machine.new.should respond_to(:acos)
      # TODO
    end

    it "should implement the :acosh operator" do
      Machine.new.should respond_to(:acosh)
      # TODO
    end

    it "should implement the :asin operator" do
      Machine.new.should respond_to(:asin)
      # TODO
    end

    it "should implement the :asinh operator" do
      Machine.new.should respond_to(:asinh)
      # TODO
    end

    it "should implement the :atan operator" do
      Machine.new.should respond_to(:atan)
      # TODO
    end

    it "should implement the :atan2 operator" do
      Machine.new.should respond_to(:atan2)
      # TODO
    end

    it "should implement the :atanh operator" do
      Machine.new.should respond_to(:atanh)
      # TODO
    end
  end

  context "Sequence predicates" do
    it "should implement the :seqp operator" do
      Machine.new.should respond_to(:seqp)
      # TODO
    end

    it "should implement the :emptyp operator" do
      Machine.new.should respond_to(:emptyp)
      # TODO
    end

    it "should implement the :memberp operator" do
      Machine.new.should respond_to(:memberp)
      # TODO
    end

    it "should implement the :anyp operator" do
      Machine.new.should respond_to(:anyp)
      # TODO
    end

    it "should implement the :allp operator" do
      Machine.new.should respond_to(:allp)
      # TODO
    end
  end

  context "Sequence constructors" do
    it "should implement the :seq operator" do
      Machine.new.should respond_to(:seq)
      # TODO
    end

    it "should implement the :cons operator" do
      Machine.new.should respond_to(:cons)
      # TODO
    end

    it "should implement the :uncons operator" do
      Machine.new.should respond_to(:uncons)
      # TODO
    end

    it "should implement the :list operator" do
      Machine.new.should respond_to(:list)
      # TODO
    end

    it "should implement the :iota operator" do
      Machine.new.should respond_to(:iota)
      # TODO
    end

    it "should implement the :range operator" do
      Machine.new.should respond_to(:range)
      # TODO
    end

    it "should implement the :repeat operator" do
      Machine.new.should respond_to(:repeat)
      # TODO
    end

    it "should implement the :cycle operator" do
      Machine.new.should respond_to(:cycle)
      # TODO
    end
  end

  context "Sequence accessors" do
    it "should implement the :length operator" do
      Machine.new.should respond_to(:length)
      # TODO
    end

    it "should implement the :rest operator" do
      Machine.new.should respond_to(:rest)
      # TODO
    end

    it "should implement the :first operator" do
      Machine.new.should respond_to(:first)
      # TODO
    end

    it "should implement the :second operator" do
      Machine.new.should respond_to(:second)
      # TODO
    end

    it "should implement the :third operator" do
      Machine.new.should respond_to(:third)
      # TODO
    end

    it "should implement the :fourth operator" do
      Machine.new.should respond_to(:fourth)
      # TODO
    end

    it "should implement the :fifth operator" do
      Machine.new.should respond_to(:fifth)
      # TODO
    end

    it "should implement the :sixth operator" do
      Machine.new.should respond_to(:sixth)
      # TODO
    end

    it "should implement the :seventh operator" do
      Machine.new.should respond_to(:seventh)
      # TODO
    end

    it "should implement the :eighth operator" do
      Machine.new.should respond_to(:eighth)
      # TODO
    end

    it "should implement the :ninth operator" do
      Machine.new.should respond_to(:ninth)
      # TODO
    end

    it "should implement the :tenth operator" do
      Machine.new.should respond_to(:tenth)
      # TODO
    end

    it "should implement the :nth operator" do
      Machine.new.should respond_to(:nth)
      # TODO
    end

    it "should implement the :last operator" do
      Machine.new.should respond_to(:last)
      # TODO
    end
  end

  context "Sequence operators" do
    it "should implement the :subseq operator" do
      Machine.new.should respond_to(:subseq)
      # TODO
    end

    it "should implement the :concat operator" do
      Machine.new.should respond_to(:concat)
      # TODO
    end

    it "should implement the :uniq operator" do
      Machine.new.should respond_to(:uniq)
      # TODO
    end

    it "should implement the :reverse operator" do
      Machine.new.should respond_to(:reverse)
      # TODO
    end

    it "should implement the :sort operator" do
      Machine.new.should respond_to(:sort)
      # TODO
    end

    it "should implement the :sortby operator" do
      Machine.new.should respond_to(:sortby)
      # TODO
    end

    it "should implement the :flatten operator" do
      Machine.new.should respond_to(:flatten)
      # TODO
    end

    it "should implement the :zip operator" do
      Machine.new.should respond_to(:zip)
      # TODO
    end

    it "should implement the :zip1 operator" do
      Machine.new.should respond_to(:zip1)
      # TODO
    end

    it "should implement the :zip2 operator" do
      Machine.new.should respond_to(:zip2)
      # TODO
    end

    it "should implement the :zip3 operator" do
      Machine.new.should respond_to(:zip3)
      # TODO
    end

    it "should implement the :zip4 operator" do
      Machine.new.should respond_to(:zip4)
      # TODO
    end

    it "should implement the :unzip operator" do
      Machine.new.should respond_to(:unzip)
      # TODO
    end

    it "should implement the :unzip1 operator" do
      Machine.new.should respond_to(:unzip1)
      # TODO
    end

    it "should implement the :unzip2 operator" do
      Machine.new.should respond_to(:unzip2)
      # TODO
    end

    it "should implement the :unzip3 operator" do
      Machine.new.should respond_to(:unzip3)
      # TODO
    end

    it "should implement the :unzip4 operator" do
      Machine.new.should respond_to(:unzip4)
      # TODO
    end
  end

  context "Sequence combinators" do
    it "should implement the :each operator" do
      Machine.new.should respond_to(:each)
      # TODO
    end

    it "should implement the :map operator" do
      Machine.new.should respond_to(:map)
      Machine.new([[1, 2, 3, 4, 5], [:dup, :mul]]).execute { map }.stack.should == [[1, 4, 9, 16, 25]]
    end

    it "should implement the :count operator" do
      Machine.new.should respond_to(:count)
      # TODO
    end

    it "should implement the :filter operator" do
      Machine.new.should respond_to(:filter)
      Machine.new([[1, 2, 3, 4, 5], [2, :mod, 0, :eq]]).execute { filter }.stack.should == [[2, 4]]
    end

    it "should implement the :remove operator" do
      Machine.new.should respond_to(:remove)
      # TODO
    end

    it "should implement the :foldl operator" do
      Machine.new.should respond_to(:foldl, :fold, :reduce)
      Machine.new([[1, 2, 3, 4, 5], 0, [:add]]).execute { foldl }.stack.should == [15]
      Machine.new([[], -1, [:add]]).execute { foldl }.stack.should == [-1]
      Machine.new([[2, 5, 3], 0, [:add]]).execute { foldl }.stack.should == [10]
      Machine.new([[2, 5, 3], 0, [:dup, :mul, :add]]).execute { foldl }.stack.should == [38]
    end

    it "should implement the :foldl1 operator" do
      Machine.new.should respond_to(:foldl1)
    end

    it "should implement the :foldr operator" do
      Machine.new.should respond_to(:foldr)
      # TODO
    end
  end

  context "Textual predicates" do
    it "should implement the :chrp operator" do
      Machine.new.should respond_to(:chrp, :chr?)
      # TODO
    end

    # TODO
  end

  context "Textual constructors" do
    it "should implement the :chr operator" do
      Machine.new.should respond_to(:chr)
      Machine.run([97])  { chr }.should == "a"
      Machine.run([960]) { chr }.should == "\u03c0" # PI
    end

    # TODO
  end

  context "Textual operators" do
    it "should implement the :size operator" do
      Machine.new.should respond_to(:size)
      # TODO
    end
  end

  context "Output operators" do
    it "should implement the :print operator" do
      Machine.new.should respond_to(:print, :print!, :'.')
      # TODO
    end
  end
end


text:
require File.join(File.dirname(__FILE__), 'spec_helper')

describe Trith::Compiler do
  # TODO
end


text:
require File.join(File.dirname(__FILE__), 'spec_helper')

describe Trith::Reader do
  it "should not be instantiable" do
    lambda { Trith::Reader.new }.should raise_error(NoMethodError)
  end

  it "should support reading URLs" do
    Trith::Reader.should respond_to(:read_url)
    # TODO
  end

  it "should support reading files" do
    Trith::Reader.should respond_to(:read_files)
    Trith::Reader.should respond_to(:read_file)
    # TODO
  end

  it "should support reading IO objects" do
    Trith::Reader.should respond_to(:read)
    # TODO
  end

  it "should support reading StringIO objects" do
    Trith::Reader.should respond_to(:read)
    lambda { Trith::Reader.read(StringIO.new('123')) }.should_not raise_error
    # TODO
  end

  it "should support reading strings" do
    Trith::Reader.should respond_to(:read)
    lambda { Trith::Reader.read('123') }.should_not raise_error
    # TODO
  end
end


text:
require 'trith'

include  Trith

describe Program do
  # TODO
end


text:
# -*- coding: utf-8 -*-
require File.join(File.dirname(__FILE__), 'spec_helper')

# @see http://rosettacode.org/wiki/Category:Trith
describe "Rosetta Code examples" do
  before(:each) { @stdout, $stdout = $stdout, StringIO.new }
  after(:each)  { $stdout = @stdout }

  # @see http://rosettacode.org/wiki/Empty_program#Trith
  context "Empty program" do
    it "should work" do
      lambda { Machine.run(Reader.read_all("")) }.should_not raise_error
    end
  end

  # @see http://rosettacode.org/wiki/Hello_world/Text#Trith
  context "Hello world/Text" do
    it "should work using :print" do
      code = Reader.read_all(<<-EOF)
        "Goodbye, World!" print
      EOF
      Machine.run(code).should be_nil
      $stdout.string.should == "Goodbye, World!\n"
    end
  end

  # @see http://rosettacode.org/wiki/Sum_and_product_of_an_array#Trith
  context "Sum and product of an array" do
    it "should work using :+ and :foldl" do
      code = Reader.read_all(<<-EOF)
        [1 2 3 4 5] 0 [+] foldl
      EOF
      Machine.run(code).should == 15
    end

    it "should work using :* and :foldl" do
      code = Reader.read_all(<<-EOF)
        [1 2 3 4 5] 1 [*] foldl
      EOF
      Machine.run(code).should == 120
    end
  end

  # @see http://rosettacode.org/wiki/Singly-linked_list/Traversal#Trith
  context "Singly-linked list/Traversal" do
    it "should work using :each" do
      code = Reader.read_all(<<-EOF)
        [1 2 3 4 5] [print] each
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "1\n2\n3\n4\n5\n"
    end
  end

  # @see http://rosettacode.org/wiki/Loops/Infinite#Trith
  context "Loops/Infinite" do
    it "should work using :loop" do
      code = Reader.read_all(<<-EOF)
        ["SPAM" print] loop
      EOF
      #Machine.run(code).should == nil # FIXME: need a timeout/step limit
    end
  end

  # @see http://rosettacode.org/wiki/Loops/Foreach#Trith
  context "Loops/Foreach" do
    it "should work using :each" do
      code = Reader.read_all(<<-EOF)
        [1 2 3 4 5] [print] each
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "1\n2\n3\n4\n5\n"
    end
  end

  # @see http://rosettacode.org/wiki/Loops/While#Trith
  context "Loops/While" do
    it "should work using :/ and :floor" do
      code = Reader.read_all(<<-EOF)
        1024 [dup print 2 / floor] [dup 0 >] while drop
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "1024\n512\n256\n128\n64\n32\n16\n8\n4\n2\n1\n"
    end

    it "should work using :shr" do
      code = Reader.read_all(<<-EOF)
        1024 [dup print 1 shr] [dup 0 >] while drop
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "1024\n512\n256\n128\n64\n32\n16\n8\n4\n2\n1\n"
    end
  end

  # @see http://rosettacode.org/wiki/Loops/Downward_for#Trith
  context "Loops/Downward for" do
    it "should work using :each" do
      code = Reader.read_all(<<-EOF)
        10 inc iota reverse [print] each
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "10\n9\n8\n7\n6\n5\n4\n3\n2\n1\n0\n"
    end

    it "should work using :while" do
      code = Reader.read_all(<<-EOF)
        10 [dup print dec] [dup 0 >=] while drop
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "10\n9\n8\n7\n6\n5\n4\n3\n2\n1\n0\n"
    end
  end

  # @see http://rosettacode.org/wiki/Flatten_a_list#Trith
  context "Flatten a list" do
    it "should work using :flatten" do
      code = Reader.read_all(<<-EOF)
        [[1] 2 [[3 4] 5] [[[]]] [[[6]]] 7 8 []] flatten
      EOF
      Machine.run(code).should == [1, 2, 3, 4, 5, 6, 7, 8]
    end
  end

  # @see http://rosettacode.org/wiki/Array_concatenation#Trith
  context "Array concatenation" do
    it "should work using :concat" do
      code = Reader.read_all(<<-EOF)
        [1 2 3] [4 5 6] concat
      EOF
      Machine.run(code).should == [1, 2, 3, 4, 5, 6]
    end
  end

  # @see http://rosettacode.org/wiki/Copy_a_string#Trith
  context "Copy a string" do
    it "should work using :dup" do
      code = Reader.read_all(<<-EOF)
        "Hello" dup
      EOF
      Machine.run(code).should == "Hello"
    end
  end

  # @see http://rosettacode.org/wiki/Generic_swap#Trith
  context "Generic swap" do
    it "should work using :swap" do
      code = Reader.read_all(<<-EOF)
        swap
      EOF
      Machine.run([1, 2] + code).should == 1
    end
  end

  # @see http://rosettacode.org/wiki/String_length#Trith
  context "String length" do
    it "should work using :length" do
      code = Reader.read_all(<<-EOF)
        "møøse" length
      EOF
      Machine.run(code).should == 5
    end

    it "should work using :size" do
      code = Reader.read_all(<<-EOF)
        "møøse" size
      EOF
      Machine.run(code).should == 7
    end
  end

  # @see http://rosettacode.org/wiki/Higher-order_functions#Trith
  context "Higher-order functions" do
    it "should work using :twice" do
      code = Reader.read_all(<<-EOF)
        : twice 2 times ;
        : hello "Hello, world!" print ;
        [hello] twice
      EOF
      Machine.run(code).should == nil # FIXME
      $stdout.string.should == "Hello, world!\nHello, world!\n"
    end
  end

  # @see http://rosettacode.org/wiki/Conditional_structures#Trith
  context "Conditional structures" do
    it "should work using :branch" do
      code = Reader.read_all(<<-EOF)
        true ["yes" print] ["no" print] branch
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "yes\n"
    end

    it "should work using :when" do
      code = Reader.read_all(<<-EOF)
        true ["yes" print] when
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "yes\n"
    end

    it "should work using :unless" do
      code = Reader.read_all(<<-EOF)
        false ["no" print] unless
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "no\n"
    end
  end

  # @see http://rosettacode.org/wiki/Boolean_values#Trith
  context "Boolean values" do
    it "should work" # TODO
  end

  # @see http://rosettacode.org/wiki/Infinity#Trith
  context "Infinity" do
    it "should work" do
      code = Reader.read_all(<<-EOF)
        : inf 1.0 0.0 / ;
        : -inf inf neg ;
        : inf? abs inf = ;
      EOF
      Machine.run(code).should == nil # FIXME
    end
  end

  # @see http://rosettacode.org/wiki/Character_codes#Trith
  context "Character codes" do
    it "should work with ASCII" do
      code = Reader.read_all(<<-EOF)
        "a" ord print
        97 chr print
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "97\na\n"
    end

    it "should work with Unicode" do
      code = Reader.read_all(<<-EOF)
        "π" ord print
        960 chr print
      EOF
      Machine.run(code).should == nil
      $stdout.string.should == "960\nπ\n"
    end
  end

  # @see http://rosettacode.org/wiki/Greatest_element_of_a_list#Trith
  context "Greatest element of a list" do
    it "should work using :max and :foldl1" do
      code = Reader.read_all(<<-EOF)
        [1 -2 3.1415 0 42 7] [max] foldl1
      EOF
      Machine.run(code).should == 42
    end
  end

  # @see http://rosettacode.org/wiki/Sum_of_squares#Trith
  context "Sum of squares" do
    it "should work using :foldl" do
      code = Reader.read_all(<<-EOF)
        [3 1 4 1 5 9] 0 [dup * +] foldl
      EOF
      Machine.run(code).should == 133
    end
  end

  # @see http://rosettacode.org/wiki/Averages/Arithmetic_mean#Trith
  context "Averages/Arithmetic mean" do
    it "should work using :foldl1" do
      code = Reader.read_all(<<-EOF)
        : mean dup empty? [drop 0] [dup [+] foldl1 swap length /] branch ;
        [3 1 4 1 5 9] mean
      EOF
      Machine.run(code).should == 3 # FIXME
    end
  end

  # @see http://rosettacode.org/wiki/Category:Trith_examples_needing_attention
  # @see http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_Trith
end


text:
require 'trith'

include  Trith

describe Optimizer do
  describe Reader::LiteralCanonicalization do
    it "should canonicalize :nil instructions" do
      optimized[:nil].should == [nil]
    end

    it "should canonicalize :true and :false instructions" do
      optimized[:false].should == [false]
      optimized[:true].should  == [true]
    end
  end

  describe Optimizer::EmptyQuotationElimination do
    it "should replace empty quotations with the :nop instruction" do
      optimized[[]].should == [:nop]
      optimized[true, [], [], :branch].should == [true, :nop, :nop, :branch]
    end
  end

  describe Optimizer::QuotationFactoring do
    it "should convert quotations into gensym definitions" do
      optimized[[]].first.should be_instance_of(Symbol)
      optimized[[:+], :call].first.should be_instance_of(Symbol)
    end
  end

  describe Optimizer::TailRecursionAnalysis do
    it "should replace tail recursion with the :recur pseudo-instruction" do
      optimized[1, :+, :input].should == [1, :+, :recur]
    end
  end

  describe Optimizer::ConstantArithmeticFolding do
    it "should evaluate constant integer negation" do
      optimized[-1, :neg].should == [1]
      optimized[ 0, :neg].should == [0]
      optimized[ 1, :neg].should == [-1]
    end

    it "should evaluate constant integer increments" do
      optimized[-1, :inc].should == [0]
      optimized[ 0, :inc].should == [1]
      optimized[ 1, :inc].should == [2]
    end

    it "should evaluate constant integer decrements" do
      optimized[-1, :dec].should == [-2]
      optimized[ 0, :dec].should == [-1]
      optimized[ 1, :dec].should == [0]
    end

    it "should evaluate constant integer addition" do
      optimized[1, 2, :+].should == [3]
    end

    it "should evaluate constant integer subtraction" do
      optimized[4, 5, :-].should == [-1]
    end

    it "should evaluate constant integer multiplication" do
      optimized[6, 7, :*].should == [42]
    end

    it "should evaluate constant integer division when the remainder is zero" do
      optimized[8, 1, :'/'].should == [8]
      optimized[8, 4, :'/'].should == [2]
    end

    it "should not evaluate constant integer division when the remainder is not zero" do
      optimized[8, 3, :'/'].should == [8, 3, :'/']
    end

    it "should evaluate constant integer modulo and remainder operations" do
      optimized[ 13,  4, :mod].should == [1]
      optimized[ 13,  4, :rem].should == [1]
      optimized[ 13, -4, :mod].should == [-3]
      optimized[ 13, -4, :rem].should == [1]
      optimized[-13,  4, :mod].should == [3]
      optimized[-13,  4, :rem].should == [-1]
      optimized[-13, -4, :mod].should == [-1]
      optimized[-13, -4, :rem].should == [-1]
    end

    it "should evaluate constant integer exponentiation" do
      optimized[2, 0, :pow].should == [1]
      optimized[2, 1, :pow].should == [2]
      optimized[2, 4, :pow].should == [16]
    end

    it "should evaluate constant integer absolute values" do
      optimized[ 0, :abs].should == [0]
      optimized[ 1, :abs].should == [1]
      optimized[-1, :abs].should == [1]
    end

    it "should evaluate constant integer maxima and minima" do
      optimized[ 0, 1, :max].should == [1]
      optimized[ 1, 1, :max].should == [1]
      optimized[-1, 1, :max].should == [1]

      optimized[ 0, 1, :min].should == [0]
      optimized[ 1, 1, :min].should == [1]
      optimized[-1, 1, :min].should == [-1]
    end
  end

  describe Optimizer::ConstantBitwiseFolding do
    it "should evaluate constant bitwise operations"
  end

  describe Optimizer::ConstantComparisonFolding do
    it "should evaluate constant comparison operations" do
      optimized[-1, 0, :cmp].should == [-1]
      optimized[ 0, 0, :cmp].should == [0]
      optimized[ 1, 0, :cmp].should == [1]

      optimized[-1, 0, :eq].should == [false]
      optimized[ 0, 0, :eq].should == [true]
      optimized[ 1, 0, :eq].should == [false]

      optimized[-1, 0, :ne].should == [true]
      optimized[ 0, 0, :ne].should == [false]
      optimized[ 1, 0, :ne].should == [true]

      %w(== < <= > >=).map(&:to_sym).each do |op| # FIXME
        optimized[-1, 0, op].should == [-1.send(op, 0)]
        optimized[ 0, 0, op].should == [ 0.send(op, 0)]
        optimized[ 1, 0, op].should == [ 1.send(op, 0)]
      end
    end
  end

  describe Optimizer::ConstantBranchFolding do
    it "should evaluate constant branch operations" do
      optimized[true,   :a, :b, :branch].should == [:a]
      optimized[:true,  :a, :b, :branch].should == [:a]
      optimized[false,  :a, :b, :branch].should == [:b]
      optimized[:false, :a, :b, :branch].should == [:b]

      optimized[:a, :b, :c, :branch].should == [:a, :b, :c, :branch]
    end
  end

  describe Optimizer::AlgebraicSimplification do
    it "should simplify constant integer addition" do
      optimized[:x, 0, :+].should == [:x]
      optimized[0, :x, :+].should == [:x]
    end

    it "should simplify constant integer subtraction" do
      optimized[:x, 0, :-].should  == [:x]
      optimized[:x, :x, :-].should == [0]
    end

    it "should simplify constant integer multiplication" do
      optimized[:x, 0, :*].should == [0]
      optimized[0, :x, :*].should == [0]
      optimized[:x, 1, :*].should == [:x]
      optimized[1, :x, :*].should == [:x]
    end

    it "should simplify constant integer division" do
      optimized[:x, 1, :'/'].should  == [:x]
      optimized[:x, :x, :'/'].should == [1]
    end

    it "should simplify constant integer exponentiation" do
      optimized[:x, 0, :pow].should == [1]
      optimized[:x, 1, :pow].should == [:x]
    end
  end

  describe Optimizer::StrengthReduction do
    it "should reduce constant integer addition" do
      optimized[:x, 1, :+].should == [:x, :inc]
      optimized[1, :x, :+].should == [:x, :inc]
    end

    it "should reduce constant integer subtraction" do
      optimized[:x, 1, :-].should  == [:x, :dec]
      optimized[:x, :x, :-].should == [:x, :drop, 0]
      optimized[0, :x, :-].should  == [:x, :neg]
      optimized[1, :x, :-].should  == [:x, :neg, :inc]
    end

    it "should reduce constant integer multiplication" do
      optimized[:x, 2, :*].should == [:x, :dup, :+]
    end

    it "should reduce constant integer division" do
      optimized[:x, :x, :'/'].should == [:x, :drop, 1]
    end

    it "should reduce constant integer exponentiation" do
      optimized[:x, 2, :pow].should == [:x, :dup, :*]
      optimized[:x, 3, :pow].should == [:x, :dup, :dup, :*, :*]
    end
  end

  describe Optimizer::RedundantCodeElimination do
    it "should eliminate redundant :dup/:drop instruction sequences" do
      optimized[:dup3, :drop3].should            == []
      optimized[:dup2, :drop2].should            == []
      optimized[:dup2, :drop, :drop].should      == []
      optimized[:dup, :drop].should              == []
      optimized[1, :dup, 2, :swap, :drop].should == [1, 2]
    end
  end

  def optimized
    proxy = OpenStruct.new(:example => self)
    class << proxy
      def [](*instructions)
        example.optimize(*instructions)
      end
    end
    proxy
  end

  def optimize(*input)
    described_class.transform(Program.new(:input => input)).definitions[:input]
  end
end


text:
require 'trith'
include Trith

module Trith
  module Spec
    module Matchers
      def self.define(name, &declarations)
        define_method name do |*expected|
          ::Spec::Matchers::Matcher.new(name, *expected, &declarations)
        end
      end

      define :underflow_stack do
        match do |proc|
          proc.should raise_error(Machine::StackUnderflowError)
        end
      end
    end
  end
end

Spec::Runner.configure do |config|
  config.include(Trith::Spec::Matchers)
end


text:
require File.join(File.dirname(__FILE__), 'spec_helper')

describe Trith::Cache do
  before :all do
    @cache = Trith::Cache.load(File.join(File.dirname(__FILE__), '..', 'etc', 'trith-core.nt'))
  end

  it "should be an RDF repository" do
    @cache.should be_an(RDF::Repository)
  end

  it "should know whether a given function is cached" do
    @cache.should respond_to(:has_function?)
    @cache.should have_function(Trith::Function.new("http://trith.org/core/dup"))
    @cache.should have_function(RDF::URI("http://trith.org/core/dup"))
    @cache.should_not have_function(Trith::Function.new)
    @cache.should_not have_function(RDF::URI("http://example.org/myfunction"))
    @cache.should_not have_function(RDF::Node.new)
  end

  it "should know whether a function with a given label is cached" do
    @cache.should respond_to(:has_label?)
    @cache.should have_label(:bool?)
    @cache.should_not have_label(:foobar)
  end

  it "should enumerate the cached functions" do
    @cache.should respond_to(:each_function)
    @cache.each_function do |function|
      function.should be_a(Trith::Function)
    end
    @cache.each_function.should be_a(RDF::Enumerator)
  end

  it "should find cached functions by their labels" do
    @cache.should respond_to(:find_functions)
    @cache.find_functions do |function|
      function.should be_a(Trith::Function)
    end
    @cache.find_functions.should be_a(RDF::Enumerator)
    @cache.find_functions(:label => :dup).to_a.size.should == 1
  end
end


text:
require File.join(File.dirname(__FILE__), 'spec_helper')

describe Trith::Function do
  before :each do
    @fn = Trith::Function.new
  end

  it "should have an RDF representation" do
    @fn.should respond_to(:to_rdf)
    @fn.to_rdf.should be_an(RDF::Graph)
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:asin" do
  it "is implemented" do
    Machine.new.should respond_to(:asin)
  end

  it "requires one operand" do
    lambda { Machine.run([:asin]) }.should underflow_stack
    lambda { Machine.run([nil, :asin]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:atan2" do
  it "is implemented" do
    Machine.new.should respond_to(:atan2)
  end

  it "requires two operands" do
    lambda { Machine.run([:atan2]) }.should underflow_stack
    lambda { Machine.run([nil, :atan2]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :atan2]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:sin" do
  it "is implemented" do
    Machine.new.should respond_to(:sin)
  end

  it "requires one operand" do
    lambda { Machine.run([:sin]) }.should underflow_stack
    lambda { Machine.run([nil, :sin]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:cbrt" do
  it "is implemented" do
    Machine.new.should respond_to(:cbrt)
  end

  it "requires one operand" do
    lambda { Machine.run([:cbrt]) }.should underflow_stack
    lambda { Machine.run([nil, :cbrt]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:tanh" do
  it "is implemented" do
    Machine.new.should respond_to(:tanh)
  end

  it "requires one operand" do
    lambda { Machine.run([:tanh]) }.should underflow_stack
    lambda { Machine.run([nil, :tanh]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:rem" do
  it "is implemented" do
    Machine.new.should respond_to(:rem)
  end

  it "requires two operands" do
    lambda { Machine.run([:rem]) }.should underflow_stack
    lambda { Machine.run([nil, :rem]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :rem]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:sign" do
  it "is implemented" do
    Machine.new.should respond_to(:sign)
  end

  it "requires one operand" do
    lambda { Machine.run([:sign]) }.should underflow_stack
    lambda { Machine.run([nil, :sign]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:cb" do
  it "is implemented" do
    Machine.new.should respond_to(:cb)
  end

  it "requires one operand" do
    lambda { Machine.run([:cb]) }.should underflow_stack
    lambda { Machine.run([nil, :cb]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:cosh" do
  it "is implemented" do
    Machine.new.should respond_to(:cosh)
  end

  it "requires one operand" do
    lambda { Machine.run([:cosh]) }.should underflow_stack
    lambda { Machine.run([nil, :cosh]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:cos" do
  it "is implemented" do
    Machine.new.should respond_to(:cos)
  end

  it "requires one operand" do
    lambda { Machine.run([:cos]) }.should underflow_stack
    lambda { Machine.run([nil, :cos]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:asinh" do
  it "is implemented" do
    Machine.new.should respond_to(:asinh)
  end

  it "requires one operand" do
    lambda { Machine.run([:asinh]) }.should underflow_stack
    lambda { Machine.run([nil, :asinh]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:round" do
  it "is implemented" do
    Machine.new.should respond_to(:round)
  end

  it "requires two operands" do
    lambda { Machine.run([:round]) }.should underflow_stack
    lambda { Machine.run([nil, :round]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :round]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:pow" do
  it "is implemented" do
    Machine.new.should respond_to(:pow)
  end

  it "requires two operands" do
    lambda { Machine.run([:pow]) }.should underflow_stack
    lambda { Machine.run([nil, :pow]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :pow]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:log2" do
  it "is implemented" do
    Machine.new.should respond_to(:log2)
  end

  it "requires one operand" do
    lambda { Machine.run([:log2]) }.should underflow_stack
    lambda { Machine.run([nil, :log2]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:gcd" do
  it "is implemented" do
    Machine.new.should respond_to(:gcd)
  end

  it "requires two operands" do
    lambda { Machine.run([:gcd]) }.should underflow_stack
    lambda { Machine.run([nil, :gcd]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :gcd]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:atanh" do
  it "is implemented" do
    Machine.new.should respond_to(:atanh)
  end

  it "requires one operand" do
    lambda { Machine.run([:atanh]) }.should underflow_stack
    lambda { Machine.run([nil, :atanh]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:sinh" do
  it "is implemented" do
    Machine.new.should respond_to(:sinh)
  end

  it "requires one operand" do
    lambda { Machine.run([:sinh]) }.should underflow_stack
    lambda { Machine.run([nil, :sinh]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:mod" do
  it "is implemented" do
    Machine.new.should respond_to(:mod)
  end

  it "requires two operands" do
    lambda { Machine.run([:mod]) }.should underflow_stack
    lambda { Machine.run([nil, :mod]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :mod]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:pi" do
  it "is implemented" do
    Machine.new.should respond_to(:pi)
  end

  it "requires no operands" do
    lambda { Machine.run([:pi]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:acosh" do
  it "is implemented" do
    Machine.new.should respond_to(:acosh)
  end

  it "requires one operand" do
    lambda { Machine.run([:acosh]) }.should underflow_stack
    lambda { Machine.run([nil, :acosh]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:neg" do
  it "is implemented" do
    Machine.new.should respond_to(:neg)
  end

  it "requires one operand" do
    lambda { Machine.run([:neg]) }.should underflow_stack
    lambda { Machine.run([nil, :neg]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:exp" do
  it "is implemented" do
    Machine.new.should respond_to(:exp)
  end

  it "requires one operand" do
    lambda { Machine.run([:exp]) }.should underflow_stack
    lambda { Machine.run([nil, :exp]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:div" do
  it "is implemented" do
    Machine.new.should respond_to(:div, :'/')
  end

  it "requires two operands" do
    lambda { Machine.run([:div]) }.should underflow_stack
    lambda { Machine.run([nil, :div]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :div]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:log10" do
  it "is implemented" do
    Machine.new.should respond_to(:log10)
  end

  it "requires one operand" do
    lambda { Machine.run([:log10]) }.should underflow_stack
    lambda { Machine.run([nil, :log10]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:rand" do
  it "is implemented" do
    Machine.new.should respond_to(:rand)
  end

  it "requires no operands" do
    lambda { Machine.run([:rand]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:acos" do
  it "is implemented" do
    Machine.new.should respond_to(:acos)
  end

  it "requires one operand" do
    lambda { Machine.run([:acos]) }.should underflow_stack
    lambda { Machine.run([nil, :acos]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:inc" do
  it "is implemented" do
    Machine.new.should respond_to(:inc)
  end

  it "requires one operand" do
    lambda { Machine.run([:inc]) }.should underflow_stack
    lambda { Machine.run([nil, :inc]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:add" do
  it "is implemented" do
    Machine.new.should respond_to(:add, :+)
  end

  it "requires two operands" do
    lambda { Machine.run([:add]) }.should underflow_stack
    lambda { Machine.run([nil, :add]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :add]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:dec" do
  it "is implemented" do
    Machine.new.should respond_to(:dec)
  end

  it "requires one operand" do
    lambda { Machine.run([:dec]) }.should underflow_stack
    lambda { Machine.run([nil, :dec]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:fact" do
  it "is implemented" do
    Machine.new.should respond_to(:fact)
  end

  it "requires one operand" do
    lambda { Machine.run([:fact]) }.should underflow_stack
    lambda { Machine.run([nil, :fact]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:sub" do
  it "is implemented" do
    Machine.new.should respond_to(:sub, :-)
  end

  it "requires two operands" do
    lambda { Machine.run([:sub]) }.should underflow_stack
    lambda { Machine.run([nil, :sub]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :sub]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:fib" do
  it "is implemented" do
    Machine.new.should respond_to(:fib)
  end

  it "requires one operand" do
    lambda { Machine.run([:fib]) }.should underflow_stack
    lambda { Machine.run([nil, :fib]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:floor" do
  it "is implemented" do
    Machine.new.should respond_to(:floor)
  end

  it "requires one operand" do
    lambda { Machine.run([:floor]) }.should underflow_stack
    lambda { Machine.run([nil, :floor]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:atan" do
  it "is implemented" do
    Machine.new.should respond_to(:atan)
  end

  it "requires one operand" do
    lambda { Machine.run([:atan]) }.should underflow_stack
    lambda { Machine.run([nil, :atan]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:ceil" do
  it "is implemented" do
    Machine.new.should respond_to(:ceil)
  end

  it "requires one operand" do
    lambda { Machine.run([:ceil]) }.should underflow_stack
    lambda { Machine.run([nil, :ceil]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:sq" do
  it "is implemented" do
    Machine.new.should respond_to(:sq)
  end

  it "requires one operand" do
    lambda { Machine.run([:sq]) }.should underflow_stack
    lambda { Machine.run([nil, :sq]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:mul" do
  it "is implemented" do
    Machine.new.should respond_to(:mul, :*)
  end

  it "requires two operands" do
    lambda { Machine.run([:mul]) }.should underflow_stack
    lambda { Machine.run([nil, :mul]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :mul]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:abs" do
  it "is implemented" do
    Machine.new.should respond_to(:abs)
  end

  it "requires one operand" do
    lambda { Machine.run([:abs]) }.should underflow_stack
    lambda { Machine.run([nil, :abs]) }.should_not underflow_stack
  end

  it "returns a number"
  it "returns the absolute magnitude of the operand"
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:tan" do
  it "is implemented" do
    Machine.new.should respond_to(:tan)
  end

  it "requires one operand" do
    lambda { Machine.run([:tan]) }.should underflow_stack
    lambda { Machine.run([nil, :tan]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:hypot" do
  it "is implemented" do
    Machine.new.should respond_to(:hypot)
  end

  it "requires two operands" do
    lambda { Machine.run([:hypot]) }.should underflow_stack
    lambda { Machine.run([nil, :hypot]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :hypot]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:log" do
  it "is implemented" do
    Machine.new.should respond_to(:log)
  end

  it "requires two operands" do
    lambda { Machine.run([:log]) }.should underflow_stack
    lambda { Machine.run([nil, :log]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :log]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:expm1" do
  it "is implemented" do
    Machine.new.should respond_to(:expm1)
  end

  it "requires one operand" do
    lambda { Machine.run([:expm1]) }.should underflow_stack
    lambda { Machine.run([nil, :expm1]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:sqrt" do
  it "is implemented" do
    Machine.new.should respond_to(:sqrt)
  end

  it "requires one operand" do
    lambda { Machine.run([:sqrt]) }.should underflow_stack
    lambda { Machine.run([nil, :sqrt]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:log1p" do
  it "is implemented" do
    Machine.new.should respond_to(:log1p)
  end

  it "requires two operands" do
    lambda { Machine.run([:log1p]) }.should underflow_stack
    lambda { Machine.run([nil, :log1p]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :log1p]) }.should_not underflow_stack
  end
end


text:
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe "math:lcm" do
  it "is implemented" do
    Machine.new.should respond_to(:lcm)
  end

  it "requires two operands" do
    lambda { Machine.run([:lcm]) }.should underflow_stack
    lambda { Machine.run([nil, :lcm]) }.should underflow_stack
    lambda { Machine.run([nil, nil, :lcm]) }.should_not underflow_stack
  end
end


text:
<http://trith.org/lang/> <http://purl.org/dc/terms/creator> "Arto Bendiken" .
<http://trith.org/lang/> <http://purl.org/dc/terms/modified> "2010-05-23" .
<http://trith.org/lang/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Ontology> .
<http://trith.org/lang/> <http://www.w3.org/2000/01/rdf-schema#comment> "Trith vocabulary."@en .
<http://trith.org/lang/> <http://www.w3.org/2000/01/rdf-schema#label> "Trith" .
<http://trith.org/lang/> <http://www.w3.org/2000/01/rdf-schema#seeAlso> <http://datagraph.org/bendiken/foaf> .
<http://trith.org/lang/> <http://xmlns.com/foaf/0.1/maker> <http://ar.to/#self> .
<http://trith.org/lang/Function> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://trith.org/lang/Function> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .
<http://trith.org/lang/Function> <http://www.w3.org/2000/01/rdf-schema#comment> ""@en .
<http://trith.org/lang/Function> <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://trith.org/lang/> .
<http://trith.org/lang/Function> <http://www.w3.org/2000/01/rdf-schema#label> "Function" .
<http://trith.org/lang/Function> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://trith.org/lang/Operator> .
<http://trith.org/lang/Operator> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://trith.org/lang/Operator> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .
<http://trith.org/lang/Operator> <http://www.w3.org/2000/01/rdf-schema#comment> ""@en .
<http://trith.org/lang/Operator> <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://trith.org/lang/> .
<http://trith.org/lang/Operator> <http://www.w3.org/2000/01/rdf-schema#label> "Operator" .
<http://trith.org/lang/Operator> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.w3.org/2000/01/rdf-schema#Resource> .
<http://trith.org/lang/Primitive> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class> .
<http://trith.org/lang/Primitive> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .
<http://trith.org/lang/Primitive> <http://www.w3.org/2000/01/rdf-schema#comment> ""@en .
<http://trith.org/lang/Primitive> <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://trith.org/lang/> .
<http://trith.org/lang/Primitive> <http://www.w3.org/2000/01/rdf-schema#label> "Primitive" .
<http://trith.org/lang/Primitive> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://trith.org/lang/Operator> .
<http://trith.org/lang/arity> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/1999/02/22-rdf-syntax-ns#Property> .
<http://trith.org/lang/arity> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .
<http://trith.org/lang/arity> <http://www.w3.org/2000/01/rdf-schema#comment> ""@en .
<http://trith.org/lang/arity> <http://www.w3.org/2000/01/rdf-schema#domain> <http://trith.org/lang/Operator> .
<http://trith.org/lang/arity> <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://trith.org/lang/> .
<http://trith.org/lang/arity> <http://www.w3.org/2000/01/rdf-schema#label> "label" .
<http://trith.org/lang/arity> <http://www.w3.org/2000/01/rdf-schema#range> <http://www.w3.org/2001/XMLSchema#integer> .
<http://trith.org/lang/code> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/1999/02/22-rdf-syntax-ns#Property> .
<http://trith.org/lang/code> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .
<http://trith.org/lang/code> <http://www.w3.org/2000/01/rdf-schema#comment> ""@en .
<http://trith.org/lang/code> <http://www.w3.org/2000/01/rdf-schema#domain> <http://trith.org/lang/Operator> .
<http://trith.org/lang/code> <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://trith.org/lang/> .
<http://trith.org/lang/code> <http://www.w3.org/2000/01/rdf-schema#label> "code" .
<http://trith.org/lang/code> <http://www.w3.org/2000/01/rdf-schema#range> <http://www.w3.org/1999/02/22-rdf-syntax-ns#List> .


text:
@base          <http://trith.org/core/> .
@prefix trith: <http://trith.org/lang/> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix dc:    <http://purl.org/dc/terms/> .
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .
@prefix doap:  <http://usefulinc.com/ns/doap#> .

<abs> a trith:Function ;
  rdfs:label         "abs" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<dup> 0 <lt> (<neg>) (<nop>) <branch>) .

<add> a trith:Function, trith:Primitive ;
  rdfs:label         "add", "+" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<and> a trith:Function, trith:Primitive ;
  rdfs:label         "and" ;
  rdfs:comment       "Bitwise AND" ;
  trith:arity        2 ;
  trith:code         () .

<andp> a trith:Function ;
  rdfs:label         "andp", "and?" ;
  rdfs:comment       "Logical AND" ;
  trith:arity        2 ;
  trith:code         (<swap> <dup> (<swap> <dup> (<swap> <drop>) (<drop2> <false>) <branch>) (<drop2> <false>) <branch>) .

<bool> a trith:Function ;
  rdfs:label         "bool" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         ((<true>) (<false>) <branch>) .

<boolp> a trith:Function ;
  rdfs:label         "boolp", "bool?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<dup> <truep> <swap> <falsep> <orp>) .

<branch> a trith:Function, trith:Primitive ;
  rdfs:label         "branch", "if" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         () .

<call> a trith:Function, trith:Primitive ;
  rdfs:label         "call" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<ceil> a trith:Function ;
  rdfs:label         "ceil" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<chr> a trith:Function, trith:Primitive ;
  rdfs:label         "chr" ;
  rdfs:comment       "" ;
  rdfs:seeAlso       <ord> ;
  trith:arity        1 ;
  trith:code         () .

<chrp> a trith:Function, trith:Primitive ;
  rdfs:label         "chrp", "chr?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<clear> a trith:Function, trith:Primitive ;
  rdfs:label         "clear" ;
  rdfs:comment       "Clear the data stack" ;
  trith:arity        0 ;
  trith:code         () .

<cmp> a trith:Function, trith:Primitive ;
  rdfs:label         "cmp", "<=>" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<concat> a trith:Function ;
  rdfs:label         "concat" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<swap> <reverse> <swap> (<dup> <first> <swap> <rest> <swap> <rot> <cons> <swap>) (<dup> <emptyp>) <until> <drop> <reverse>) .

<cons> a trith:Function, trith:Primitive ;
  rdfs:label         "cons" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<depth> a trith:Function ;
  rdfs:label         "depth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<stack> <dup> <length> () <cons> <concat> <unstack>) .

<dec> a trith:Function ;
  rdfs:label         "dec" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (1 <sub>) .

<dip> a trith:Function, trith:Primitive ;
  rdfs:label         "dip" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<div> a trith:Function ;
  rdfs:label         "div", "/" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<drop> a trith:Function, trith:Primitive ;
  rdfs:label         "drop" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<drop2> a trith:Function ;
  rdfs:label         "drop2", "2drop" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         ((<drop>) <twice>) .

<drop3> a trith:Function ;
  rdfs:label         "drop3", "3drop" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         ((<drop>) <thrice>) .

<dup> a trith:Function, trith:Primitive ;
  rdfs:label         "dup" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<dup2> a trith:Function, trith:Primitive ;
  rdfs:label         "dup2", "2dup" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<dup3> a trith:Function, trith:Primitive ;
  rdfs:label         "dup3", "3dup" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         () .

<each> a trith:Function ;
  rdfs:label         "each" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<eighth> a trith:Function ;
  rdfs:label         "eighth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (7 <nth>) .

<emptyp> a trith:Function ;
  rdfs:label         "emptyp", "empty?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<length> <zerop>) .

<eq> a trith:Function, trith:Primitive ;
  rdfs:label         "eq", "=" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<evenp> a trith:Function ;
  rdfs:label         "evenp", "even?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (2 <mod> <zerop>) .

<exactp> a trith:Function ;
  rdfs:label         "exactp", "exact?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<inexactp> <notp>) .

<false> a trith:Function ;
  rdfs:label         "false" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         (<quote> <false>) .

<falsep> a trith:Function ;
  rdfs:label         "falsep", "false?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<false> <eq>) .

<fifth> a trith:Function ;
  rdfs:label         "fifth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (4 <nth>) .

<first> a trith:Function, trith:Primitive ;
  rdfs:label         "first" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<flatten> a trith:Function ;
  rdfs:label         "flatten" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<floor> a trith:Function ;
  rdfs:label         "floor" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<fourth> a trith:Function ;
  rdfs:label         "fourth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (3 <nth>) .

<ge> a trith:Function ;
  rdfs:label         "ge", ">=" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<gt> a trith:Function ;
  rdfs:label         "gt", ">" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<cmp> <onep>) .

<halt> a trith:Function, trith:Primitive ;
  rdfs:label         "halt" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         () .

<inc> a trith:Function ;
  rdfs:label         "inc" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (1 <add>) .

<inexactp> a trith:Function ;
  rdfs:label         "inexactp", "inexact?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<exactp> <notp>) .

<inf> a trith:Function ;
  rdfs:label         "inf" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (1.0 0.0 <div>) .

<infp> a trith:Function ;
  rdfs:label         "infp", "inf?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<abs> <inf> <eq>) .

<intp> a trith:Function, trith:Primitive ;
  rdfs:label         "intp", "int?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<iota> a trith:Function ;
  rdfs:label         "iota" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<last> a trith:Function ;
  rdfs:label         "last" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<le> a trith:Function ;
  rdfs:label         "le", "<=" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<length> a trith:Function ;
  rdfs:label         "length" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (0 (<rest> <swap> <inc>) (<swap> <dup> <emptyp>) <until> <drop>) .

<list> a trith:Function ;
  rdfs:label         "list" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (() <swap> (<cons>) <swap> <times> <reverse>) .

<loop> a trith:Function ;
  rdfs:label         "loop" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<dup> <call> (<loop>) <call>) .

<lt> a trith:Function ;
  rdfs:label         "lt", "<" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<cmp> -1 <eq>) .

<map> a trith:Function ;
  rdfs:label         "map" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<max> a trith:Function ;
  rdfs:label         "max" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<dup2> <gt> (<drop>) (<swap> <drop>) <branch>) .

<memberp> a trith:Function ;
  rdfs:label         "memberp", "member?" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<min> a trith:Function ;
  rdfs:label         "min" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<dup2> <lt> (<drop>) (<swap> <drop>) <branch>) .

<mod> a trith:Function ;
  rdfs:label         "mod" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<mul> a trith:Function ;
  rdfs:label         "mul", "*" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (0 <swap> <abs> (<over> <add>) <swap> <times> <nip>) . # FIXME: negative operands

<ne> a trith:Function ;
  rdfs:label         "ne", "!=" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<eq> <notp>) .

<neg> a trith:Function ;
  rdfs:label         "neg" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (0 <swap> <sub>) .

<negp> a trith:Function ;
  rdfs:label         "negp", "neg?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (0 <lt>) .

<nil> a trith:Function ;
  rdfs:label         "nil" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         (<quote> <nil>) .

<nilp> a trith:Function ;
  rdfs:label         "nilp", "nil?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<nil> <eq>) .

<ninth> a trith:Function ;
  rdfs:label         "ninth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (8 <nth>) .

<nip> a trith:Function ;
  rdfs:label         "nip" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<swap> <drop>) .

<nip2> a trith:Function ;
  rdfs:label         "nip2", "2nip" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         (<swap> <drop> <swap> <drop>) .

<nop> a trith:Function ;
  rdfs:label         "nop", ",", ";" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         (<nil> <drop>) .

<not> a trith:Function ;
  rdfs:label         "not" ;
  rdfs:comment       "Bitwise NOT" ;
  trith:arity        1 ;
  trith:code         (<neg> <dec>) .

<notp> a trith:Function ;
  rdfs:label         "notp", "not?" ;
  rdfs:comment       "Logical NOT" ;
  trith:arity        1 ;
  trith:code         ((<false>) (<true>) <branch>) .

<nth> a trith:Function ;
  rdfs:label         "nth" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         ((<rest>) <swap> <times> <first>) .

<num> a trith:Function, trith:Primitive ;
  rdfs:label         "num" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<nump> a trith:Function, trith:Primitive ;
  rdfs:label         "nump", "num?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<oddp> a trith:Function ;
  rdfs:label         "oddp", "odd?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<evenp> <notp>) .

<onep> a trith:Function ;
  rdfs:label         "onep", "one?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (1 <eq>) .

<or> a trith:Function, trith:Primitive ;
  rdfs:label         "or" ;
  rdfs:comment       "Bitwise OR" ;
  trith:arity        2 ;
  trith:code         () .

<ord> a trith:Function, trith:Primitive ;
  rdfs:label         "ord" ;
  rdfs:comment       "" ;
  rdfs:seeAlso       <chr> ;
  trith:arity        1 ;
  trith:code         () .

<orp> a trith:Function ;
  rdfs:label         "orp", "or?" ;
  rdfs:comment       "Logical OR" ;
  trith:arity        2 ;
  trith:code         (<swap> <dup> (<swap> <drop>) (<drop>) <branch>) .

<over> a trith:Function ;
  rdfs:label         "over" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<dup2> <drop>) .

<pick> a trith:Function ;
  rdfs:label         "pick" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         (<dup3> <drop2>) .

<posp> a trith:Function ;
  rdfs:label         "posp", "pos?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (0 <gt>) .

<pow> a trith:Function ;
  rdfs:label         "pow" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<print> a trith:Function ;
  rdfs:label         "print", "print!", "." ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<quote> a trith:Function, trith:Primitive ;
  rdfs:label         "quote", "\\", "'" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<foldl> a trith:Function ;
  rdfs:label         "foldl", "fold", "reduce" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         () . # TODO

<foldl1> a trith:Function ;
  rdfs:label         "foldl1" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         (<swap> <dup> <emptyp> (<drop2> <nil>) (<dup> <rest> <swap> <first> <rot> <foldl>) <branch>) .

<range> a trith:Function ;
  rdfs:label         "range" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<rem> a trith:Function ;
  rdfs:label         "rem" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<reset> a trith:Function ;
  rdfs:label         "reset" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         (<clear> <halt>) .

<rest> a trith:Function, trith:Primitive ;
  rdfs:label         "rest" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<reverse> a trith:Function ;
  rdfs:label         "reverse" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<rot> a trith:Function, trith:Primitive ;
  rdfs:label         "rot" ;
  rdfs:comment       "" ;
  trith:arity        3 ;
  trith:code         () .

<second> a trith:Function ;
  rdfs:label         "second" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (1 <nth>) .

<seq> a trith:Function, trith:Primitive ;
  rdfs:label         "seq" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<seqp> a trith:Function, trith:Primitive ;
  rdfs:label         "seqp", "seq?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<seventh> a trith:Function ;
  rdfs:label         "seventh" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (6 <nth>) .

<shl> a trith:Function, trith:Primitive ;
  rdfs:label         "shl" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<shr> a trith:Function, trith:Primitive ;
  rdfs:label         "shr" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<sixth> a trith:Function ;
  rdfs:label         "sixth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (5 <nth>) .

<size> a trith:Function, trith:Primitive ;
  rdfs:label         "size" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<stack> a trith:Function ;
  rdfs:label         "stack" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         (<depth> <list>) .

<sub> a trith:Function, trith:Primitive ;
  rdfs:label         "sub", "-" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<swap> a trith:Function, trith:Primitive ;
  rdfs:label         "swap" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () .

<tenth> a trith:Function ;
  rdfs:label         "tenth" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (9 <nth>) .

<text> a trith:Function ;
  rdfs:label         "text" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<textp> a trith:Function ;
  rdfs:label         "textp", "text?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () . # TODO

<third> a trith:Function ;
  rdfs:label         "third" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (2 <nth>) .

<thrice> a trith:Function ;
  rdfs:label         "thrice", "3x" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (3 <times>) .

<times> a trith:Function ;
  rdfs:label         "times" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         ((<dec> <over> <call>) (<dup> <zerop>) <until> <drop2>) .

<true> a trith:Function ;
  rdfs:label         "true" ;
  rdfs:comment       "" ;
  trith:arity        0 ;
  trith:code         (<quote> <true>) .

<truep> a trith:Function ;
  rdfs:label         "truep", "true?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<true> <eq>) .

<twice> a trith:Function ;
  rdfs:label         "twice", "2x" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (2 <times>) .

<uncons> a trith:Operator ;
  rdfs:label         "uncons" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (<dup> <first> <swap> <rest>) .

<unless> a trith:Function ;
  rdfs:label         "unless" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         ((<nop>) <swap> <branch>) .

<unstack> a trith:Function, trith:Primitive ;
  rdfs:label         "unstack" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         () .

<until> a trith:Function ;
  rdfs:label         "until" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         ((<notp>) <concat> <while>) .

<when> a trith:Function ;
  rdfs:label         "when" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         ((<nop>) <branch>) .

<while> a trith:Function ;
  rdfs:label         "while" ;
  rdfs:comment       "" ;
  trith:arity        2 ;
  trith:code         () . # TODO

<xor> a trith:Function, trith:Primitive ;
  rdfs:label         "xor" ;
  rdfs:comment       "Bitwise XOR" ;
  trith:arity        2 ;
  trith:code         () .

<xorp> a trith:Function ;
  rdfs:label         "xorp", "xor?" ;
  rdfs:comment       "Logical XOR" ;
  trith:arity        2 ;
  trith:code         (<swap> <dup> (<swap> (<drop> <false>) (<nop>) <branch>) (<drop> <dup> (<nop>) (<drop> <false>) <branch>) <branch>) .

<zerop> a trith:Function ;
  rdfs:label         "zerop", "zero?" ;
  rdfs:comment       "" ;
  trith:arity        1 ;
  trith:code         (0 <eq>) .