From db02abb114c5988acbcfcee6b08d99bd7825553b Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Thu, 18 Nov 2021 14:23:56 +0100 Subject: [PATCH] also EVAL names and words --- lib/dictionary.rb | 2 +- lib/language/program.rb | 7 ++++--- spec/language_program_spec.rb | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/dictionary.rb b/lib/dictionary.rb index e7c4182..1607fb7 100644 --- a/lib/dictionary.rb +++ b/lib/dictionary.rb @@ -133,7 +133,7 @@ module Rpn add( 'sinv', proc { |stack| Rpn::Core.__todo( stack ) } ) # inverse a variable. ex: 1 'name' sinv # PROGRAM - add( 'eval', proc { |stack| Rpn::Core::Program.eval( stack, self ) } ) # evaluate (run) a program, or recall a variable. ex: 'my_prog' eval + add( 'eval', proc { |stack| Rpn::Core::Program.eval( stack, self ) } ) add( '->', proc { |stack| Rpn::Core.__todo( stack ) } ) # load program local variables. ex: << -> n m << 0 n m for i i + next >> >> # TRIG ON REALS AND COMPLEXES diff --git a/lib/language/program.rb b/lib/language/program.rb index 1e3eb54..68f4703 100644 --- a/lib/language/program.rb +++ b/lib/language/program.rb @@ -3,12 +3,13 @@ module Rpn module Program module_function - # power + # evaluate (run) a program, or recall a variable. ex: 'my_prog' eval def eval( stack, dictionary ) - stack, args = Rpn::Core.stack_extract( stack, [%i[program]] ) + stack, args = Rpn::Core.stack_extract( stack, [%i[program word name]] ) # we trim enclosing «» - parsed_input = Rpn::Parser.new.parse_input( args[0][:value][1..-2] ) + preparsed_input = args[0][:type] == :word ? args[0][:value] : args[0][:value][1..-2] + parsed_input = Rpn::Parser.new.parse_input( preparsed_input ) stack, _dictionary = Rpn::Runner.new.run_input( stack, dictionary, parsed_input ) # TODO: check that STO actually updates dictionary diff --git a/spec/language_program_spec.rb b/spec/language_program_spec.rb index 51b548d..d1e8276 100644 --- a/spec/language_program_spec.rb +++ b/spec/language_program_spec.rb @@ -15,5 +15,19 @@ class TestParser < Test::Unit::TestCase assert_equal [{ value: 4, type: :numeric }, { value: 4, type: :numeric }], stack + + stack = Rpn::Core::Program.eval( [{ value: 4, type: :numeric }, + { value: "'dup'", type: :name }], Rpn::Dictionary.new ) + + assert_equal [{ value: 4, type: :numeric }, + { value: 4, type: :numeric }], + stack + + stack = Rpn::Core::Program.eval( [{ value: 4, type: :numeric }, + { value: 'dup', type: :word }], Rpn::Dictionary.new ) + + assert_equal [{ value: 4, type: :numeric }, + { value: 4, type: :numeric }], + stack end end