Compare commits
3 commits
e114a05207
...
42f02e8e94
Author | SHA1 | Date | |
---|---|---|---|
|
42f02e8e94 | ||
|
8e7c50fc66 | ||
|
3809c4b58b |
7 changed files with 77 additions and 20 deletions
|
@ -5,6 +5,7 @@ require_relative './language/mode'
|
|||
require_relative './language/operations'
|
||||
require_relative './language/program'
|
||||
require_relative './language/stack'
|
||||
require_relative './language/string'
|
||||
require_relative './language/time-date'
|
||||
|
||||
module Rpl
|
||||
|
@ -33,7 +34,7 @@ module Rpl
|
|||
args << elt
|
||||
end
|
||||
|
||||
[stack, args.reverse]
|
||||
[stack, args]
|
||||
end
|
||||
|
||||
def __todo( stack )
|
||||
|
|
|
@ -94,13 +94,13 @@ module Rpl
|
|||
add( 'same', proc { |stack| Rpl::Core.__todo( stack ) } ) # boolean operator same (equal)
|
||||
|
||||
# STRING
|
||||
add( '->str', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert an object into a string
|
||||
add( '->str', proc { |stack| Rpl::Core.to_string( stack ) } )
|
||||
add( 'str->', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert a string into an object
|
||||
add( 'chr', proc { |stack| Rpl::Core.__todo( stack ) } ) # convert ASCII character code in stack level 1 into a string
|
||||
add( 'num', proc { |stack| Rpl::Core.__todo( stack ) } ) # return ASCII code of the first character of the string in stack level 1 as a real number
|
||||
add( 'size', proc { |stack| Rpl::Core.__todo( stack ) } ) # return the length of the string
|
||||
add( 'size', proc { |stack| Rpl::Core.size( stack ) } )
|
||||
add( 'pos', proc { |stack| Rpl::Core.__todo( stack ) } ) # seach for the string in level 1 within the string in level 2
|
||||
add( 'sub', proc { |stack| Rpl::Core.__todo( stack ) } ) # return a substring of the string in level 3
|
||||
add( 'sub', proc { |stack| Rpl::Core.sub( stack ) } )
|
||||
|
||||
# BRANCH
|
||||
add( 'if', proc { |stack| Rpl::Core.__todo( stack ) } ) # if <test-instruction> then <true-instructions> else <false-instructions> end
|
||||
|
|
|
@ -7,13 +7,13 @@ module Rpl
|
|||
addable = %i[numeric string name]
|
||||
stack, args = Rpl::Core.stack_extract( stack, [addable, addable] )
|
||||
|
||||
result = { type: case args[0][:type]
|
||||
result = { type: case args[1][:type]
|
||||
when :name
|
||||
:name
|
||||
when :string
|
||||
:string
|
||||
when :numeric
|
||||
if args[1][:type] == :numeric
|
||||
if args[0][:type] == :numeric
|
||||
:numeric
|
||||
else
|
||||
:string
|
||||
|
@ -26,11 +26,11 @@ module Rpl
|
|||
|
||||
result[:value] = case result[:type]
|
||||
when :name
|
||||
"'#{args[0][:value]}#{args[1][:value]}'"
|
||||
"'#{args[1][:value]}#{args[0][:value]}'"
|
||||
when :string
|
||||
"\"#{args[0][:value]}#{args[1][:value]}\""
|
||||
"\"#{args[1][:value]}#{args[0][:value]}\""
|
||||
when :numeric
|
||||
args[0][:value] + args[1][:value]
|
||||
args[1][:value] + args[0][:value]
|
||||
end
|
||||
|
||||
result[:base] = 10 if result[:type] == :numeric # TODO: what if operands have other bases ?
|
||||
|
@ -43,7 +43,7 @@ module Rpl
|
|||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||
|
||||
stack << { type: :numeric, base: 10,
|
||||
value: args[0][:value] - args[1][:value] }
|
||||
value: args[1][:value] - args[0][:value] }
|
||||
end
|
||||
|
||||
# negation
|
||||
|
@ -59,7 +59,7 @@ module Rpl
|
|||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||
|
||||
stack << { type: :numeric, base: 10,
|
||||
value: args[0][:value] * args[1][:value] }
|
||||
value: args[1][:value] * args[0][:value] }
|
||||
end
|
||||
|
||||
# division
|
||||
|
@ -69,7 +69,7 @@ module Rpl
|
|||
raise 'Division by 0' if args[0][:value].zero?
|
||||
|
||||
stack << { type: :numeric, base: 10,
|
||||
value: args[0][:value] / args[1][:value] }
|
||||
value: args[1][:value] / args[0][:value] }
|
||||
end
|
||||
|
||||
# inverse
|
||||
|
@ -87,7 +87,7 @@ module Rpl
|
|||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||
|
||||
stack << { type: :numeric, base: 10,
|
||||
value: args[0][:value]**args[1][:value] }
|
||||
value: args[1][:value]**args[0][:value] }
|
||||
end
|
||||
|
||||
# rpn_square root
|
||||
|
@ -133,9 +133,9 @@ module Rpl
|
|||
def base( stack )
|
||||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||
|
||||
args[0][:base] = args[1][:value]
|
||||
args[1][:base] = args[0][:value]
|
||||
|
||||
stack << args[0]
|
||||
stack << args[1]
|
||||
end
|
||||
|
||||
# 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0
|
||||
|
|
|
@ -6,7 +6,7 @@ module Rpl
|
|||
def swap( stack )
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[any any] )
|
||||
|
||||
stack << args[1] << args[0]
|
||||
stack << args[0] << args[1]
|
||||
end
|
||||
|
||||
# drop first stack entry
|
||||
|
@ -36,7 +36,7 @@ module Rpl
|
|||
def rot( stack )
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[any any any] )
|
||||
|
||||
stack << args[1] << args[2] << args[0]
|
||||
stack << args[1] << args[0] << args[2]
|
||||
end
|
||||
|
||||
# duplicate first stack entry
|
||||
|
@ -55,6 +55,8 @@ module Rpl
|
|||
n = args[0][:value]
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||
|
||||
args.reverse!
|
||||
|
||||
2.times do
|
||||
n.times.each do |i|
|
||||
stack << args[ i ]
|
||||
|
@ -70,6 +72,8 @@ module Rpl
|
|||
n = args[0][:value]
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||
|
||||
args.reverse!
|
||||
|
||||
n.times.each do |i|
|
||||
stack << args[ i ]
|
||||
end
|
||||
|
@ -89,6 +93,8 @@ module Rpl
|
|||
n = args[0][:value]
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||
|
||||
args.reverse!
|
||||
|
||||
(1..(n - 1)).each do |i|
|
||||
stack << args[ i ]
|
||||
end
|
||||
|
@ -103,6 +109,8 @@ module Rpl
|
|||
n = args[0][:value]
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||
|
||||
args.reverse!
|
||||
|
||||
stack << args[n - 1]
|
||||
|
||||
(0..(n - 2)).each do |i|
|
||||
|
|
31
lib/language/string.rb
Normal file
31
lib/language/string.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
module Rpl
|
||||
module Core
|
||||
module_function
|
||||
|
||||
# convert an object into a string
|
||||
def to_string( stack )
|
||||
stack, args = Rpl::Core.stack_extract( stack, :any )
|
||||
|
||||
stack << { type: :string,
|
||||
value: args[0][:value].to_s }
|
||||
end
|
||||
|
||||
# return the length of the string
|
||||
def size( stack )
|
||||
stack, args = Rpl::Core.stack_extract( stack, %i[string] )
|
||||
|
||||
stack << { type: :numeric,
|
||||
base: 10,
|
||||
value: args[0][:value].length }
|
||||
end
|
||||
|
||||
# return a substring of the string in level 3
|
||||
def sub( stack )
|
||||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric], %i[string]] )
|
||||
|
||||
puts "#{args[0][:value]}[#{args[1][:value]}..#{args[2][:value]}]"
|
||||
stack << { type: :string,
|
||||
value: args[2][:value][args[1][:value]..args[0][:value]] }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -15,13 +15,13 @@ class TestParser < Test::Unit::TestCase
|
|||
assert_equal [{ value: 2, type: :numeric }],
|
||||
args
|
||||
|
||||
stack, args = Rpl::Core.stack_extract [{ value: 1, type: :numeric },
|
||||
stack, args = Rpl::Core.stack_extract [{ value: "test", type: :string },
|
||||
{ value: 2, type: :numeric }],
|
||||
[:any, [:numeric]]
|
||||
assert_equal [],
|
||||
stack
|
||||
assert_equal [{ value: 1, type: :numeric },
|
||||
{ value: 2, type: :numeric }],
|
||||
assert_equal [{ value: 2, type: :numeric },
|
||||
{ value: "test", type: :string }],
|
||||
args
|
||||
end
|
||||
end
|
||||
|
|
17
spec/language_string_spec.rb
Normal file
17
spec/language_string_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test/unit'
|
||||
|
||||
require_relative '../lib/core'
|
||||
|
||||
class TestLanguageString < Test::Unit::TestCase
|
||||
def test_sub
|
||||
stack = Rpl::Core.sub( [{ value: 'test', type: :string },
|
||||
{ value: 1, type: :numeric, base: 10 },
|
||||
{ value: 2, type: :numeric, base: 10 }] )
|
||||
|
||||
assert_equal [{ value: 'es', type: :string }],
|
||||
stack
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue