implement IFTE and IFT

This commit is contained in:
Gwenhael Le Moine 2021-11-24 16:34:13 +01:00
parent a26c059394
commit b7d748ac5d
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
4 changed files with 53 additions and 4 deletions

View file

@ -1,5 +1,6 @@
require 'bigdecimal/math'
require_relative './language/branch'
require_relative './language/general'
require_relative './language/mode'
require_relative './language/operations'

View file

@ -101,8 +101,8 @@ module Rpl
add( 'xor', proc { |stack| Rpl::Core.xor( stack ) } )
add( 'not', proc { |stack| Rpl::Core.not( stack ) } )
add( 'same', proc { |stack| Rpl::Core.same( stack ) } )
add( 'true', proc { |stack| Rpl::Core.true( stack ) } )
add( 'false', proc { |stack| Rpl::Core.false( stack ) } )
add( 'true', proc { |stack| Rpl::Core.true( stack ) } ) # specific
add( 'false', proc { |stack| Rpl::Core.false( stack ) } ) # specific
# STRING
add( '->str', proc { |stack| Rpl::Core.to_string( stack ) } )
@ -124,8 +124,8 @@ module Rpl
add( 'for', proc { |stack| Rpl::Core.__todo( stack ) } ) # <start> <end> for <variable> <instructions> next|<step> step
add( 'next', proc { |stack| Rpl::Core.__todo( stack ) } ) # used with start and for
add( 'step', proc { |stack| Rpl::Core.__todo( stack ) } ) # used with start and for
add( 'ift', proc { |stack| Rpl::Core.__todo( stack ) } ) # similar to if-then-end, <test-instruction> <true-instruction> ift
add( 'ifte', proc { |stack| Rpl::Core.__todo( stack ) } ) # similar to if-then-else-end, <test-instruction> <true-instruction> <false-instruction> ifte
add( 'ift', proc { |stack| Rpl::Core.ift( stack, self ) } )
add( 'ifte', proc { |stack| Rpl::Core.ifte( stack, self ) } )
add( 'do', proc { |stack| Rpl::Core.__todo( stack ) } ) # do <instructions> until <condition> end
add( 'until', proc { |stack| Rpl::Core.__todo( stack ) } ) # used with do
add( 'while', proc { |stack| Rpl::Core.__todo( stack ) } ) # while <test-instruction> repeat <loop-instructions> end

19
lib/language/branch.rb Normal file
View file

@ -0,0 +1,19 @@
module Rpl
module Core
module_function
# similar to if-then-end, <test-instruction> <true-instruction> ift
def ift( stack, dictionary )
ifte( stack << { type: :word, value: 'nop' }, dictionary )
end
# similar to if-then-else-end, <test-instruction> <true-instruction> <false-instruction> ifte
def ifte( stack, dictionary )
stack, args = Rpl::Core.stack_extract( stack, [%i[program word], %i[program word], %i[boolean]] )
stack << args[ args[2][:value] ? 1 : 0 ]
Rpl::Core.eval( stack, dictionary )
end
end
end

View file

@ -0,0 +1,29 @@
# coding: utf-8
# frozen_string_literal: true
require 'test/unit'
require_relative '../lib/core'
require_relative '../lib/dictionary'
require_relative '../lib/parser'
require_relative '../lib/runner'
class TestLanguageBranch < Test::Unit::TestCase
def test_ifte
stack = Rpl::Core.ifte( [{ type: :boolean, value: true },
{ type: :program, value: '« 2 3 + »' },
{ type: :program, value: '« 2 3 - »' }],
Rpl::Dictionary.new )
assert_equal [{ value: 5, type: :numeric, base: 10 }],
stack
stack = Rpl::Core.ifte( [{ type: :boolean, value: false },
{ type: :program, value: '« 2 3 + »' },
{ type: :program, value: '« 2 3 - »' }],
Rpl::Dictionary.new )
assert_equal [{ value: -1, type: :numeric, base: 10 }],
stack
end
end