Commits

Steven! Ragnarök committed 8ec2eaf

Implement <, >, and =. Not too happy with the = hack.

Comments (0)

Files changed (2)

15/lib/stacker.rb

+require "pry"
+
 module Stacker
+  # Module containing functions of the Stacker language.
+  module Functions
+    def ADD
+      @input_stack.inject(:+)
+    end
+
+    def SUBTRACT
+      @input_stack.inject(:-)
+    end
+
+    def MULTIPLY
+      @input_stack.inject(:*)
+    end
+
+    def DIVIDE
+      @input_stack.inject(:/)
+    end
+
+    def MOD
+      @input_stack.inject(:%)
+    end
+
+    def <
+      @input_stack.inject(:<) ? :true : :false
+    end
+
+    def >
+      @input_stack.inject(:>) ? :true : :false
+    end
+
+    # Since "=" is not a valid Ruby method name, we use EQUAL and alias the
+    # command in the interpreter.
+    def EQUAL
+      @input_stack.inject(:==) ? :true : :false
+    end
+  end
+
   class Interpreter
+    include Functions
+
     attr_reader :stack
 
-    COMMANDS = %w[ADD SUBTRACT]
-
     def initialize
       @stack = []
       @input_stack = []
 
     def execute command
       unless commands.include? command
-        command = if command == command.to_i.to_s
-                    command.to_i
-                  else
-                    command.to_s
-                  end
-
-        @input_stack.push command
+        @input_stack.push cast_type command
       else
-        @stack << send(command)
+        @stack << send(parse_command(command))
         @input_stack.clear
       end
     end
 
-    def commands
-      public_methods.select{ |m| m =~ /[A-Z]+/ }.map(&:to_s)
+    # Casts integers to integers, leaves all else unchanged.
+    def cast_type command
+      if command == command.to_i.to_s
+        command.to_i
+      else
+        command
+      end
     end
 
-    def ADD
-      @input_stack.inject(&:+)
+    # Translate commands into valid Ruby method names where needed.
+    def parse_command command
+      case command
+      when '='
+        'EQUAL'
+      else
+        command
+      end
     end
 
-    def SUBTRACT
-      @input_stack.inject(&:-)
-    end
-
-    def MULTIPLY
-      @input_stack.inject(&:*)
-    end
-
-    def DIVIDE
-      @input_stack.inject(&:/)
-    end
-
-    def MOD
-      @input_stack.inject(:%)
+    # All the commands available to the Stacker interpreter. There is a small
+    # hack to add "=".
+    def commands
+      Functions.public_instance_methods.map(&:to_s) << "="
     end
   end
 end
+

15/stacker_test.rb

   end
 
   it "implements <" do
-    skip
     execute %w[
       3
       10
   end
 
   it "implements >" do
-    skip
     execute %w[
       3
       10
   end
 
   it "implements =" do
-    skip
     execute %w[
       1
       1
   end
 
   it "implements the IF command" do
-    skip
     execute %w[
       :true
       IF