Skip to content

Instantly share code, notes, and snippets.

@ShiningRay
Created April 9, 2013 17:24
Show Gist options
  • Save ShiningRay/5347594 to your computer and use it in GitHub Desktop.
Save ShiningRay/5347594 to your computer and use it in GitHub Desktop.
Tiny forth (copy from else where)
class ForthInterpreter
attr_reader :stack, :dict
def initialize
@stack = []
@dict = {
:"." => Proc.new { print @stack.pop },
:".s" => Proc.new { puts @stack },
:cr => Proc.new { puts },
:+ => Proc.new { @stack.push(@stack.pop + @stack.pop) },
:- => Proc.new { s = @stack.pop; m = @stack.pop; @stack.push(m - s) },
:* => Proc.new { ml = @stack.pop; mc = @stack.pop; @stack.push(mc * ml) },
:/ => Proc.new { dv = @stack.pop; dd = @stack.pop; @stack.push(dd / dv) },
:dup => Proc.new { @stack.push(@stack.last) },
:over => Proc.new { @stack.push(@stack[-2]) },
:swap => Proc.new { @stack[-1], @stack[-2] = @stack[-2], @stack[-1] },
:rot => Proc.new { @stack.push(@stack.delete_at(-3)) },
:bye => Proc.new { exit }
}
end
def parse(str)
str.strip.gsub(/\s/, ' ').split(' ').map {
|t| t.to_i == 0 && t != '0' ? t.to_sym : t.to_i }
end
def run(tokens)
tokens.each do |t|
if t.class == Symbol
if @dict.has_key?(t)
instance_eval &@dict[t]
else
puts 'Undefined word.'
return
end
elsif t.class == Fixnum
@stack.push(t)
end
end
puts ' ok'
end
end
f = ForthInterpreter.new
#f.run(f.parse('3 4 + .'))
#f.run(f.parse('5 2 - .'))
#f.run(f.parse('5 5 * .'))
#f.run(f.parse('20 5 / .'))
#f.run(f.parse('5 4 * 2 / 8 + 3 - .'))
#f.run(f.parse('1 2 3 swap . . .'))
#f.run(f.parse('1 2 3 dup . . . .'))
#f.run(f.parse('1 2 over . . .'))
#f.run(f.parse('1 2 3 rot . . .'))
loop do
input = STDIN.gets.strip
f.run(f.parse(input))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment