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/operations'
|
||||||
require_relative './language/program'
|
require_relative './language/program'
|
||||||
require_relative './language/stack'
|
require_relative './language/stack'
|
||||||
|
require_relative './language/string'
|
||||||
require_relative './language/time-date'
|
require_relative './language/time-date'
|
||||||
|
|
||||||
module Rpl
|
module Rpl
|
||||||
|
@ -33,7 +34,7 @@ module Rpl
|
||||||
args << elt
|
args << elt
|
||||||
end
|
end
|
||||||
|
|
||||||
[stack, args.reverse]
|
[stack, args]
|
||||||
end
|
end
|
||||||
|
|
||||||
def __todo( stack )
|
def __todo( stack )
|
||||||
|
|
|
@ -94,13 +94,13 @@ module Rpl
|
||||||
add( 'same', proc { |stack| Rpl::Core.__todo( stack ) } ) # boolean operator same (equal)
|
add( 'same', proc { |stack| Rpl::Core.__todo( stack ) } ) # boolean operator same (equal)
|
||||||
|
|
||||||
# STRING
|
# 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( '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( '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( '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( '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
|
# BRANCH
|
||||||
add( 'if', proc { |stack| Rpl::Core.__todo( stack ) } ) # if <test-instruction> then <true-instructions> else <false-instructions> end
|
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]
|
addable = %i[numeric string name]
|
||||||
stack, args = Rpl::Core.stack_extract( stack, [addable, addable] )
|
stack, args = Rpl::Core.stack_extract( stack, [addable, addable] )
|
||||||
|
|
||||||
result = { type: case args[0][:type]
|
result = { type: case args[1][:type]
|
||||||
when :name
|
when :name
|
||||||
:name
|
:name
|
||||||
when :string
|
when :string
|
||||||
:string
|
:string
|
||||||
when :numeric
|
when :numeric
|
||||||
if args[1][:type] == :numeric
|
if args[0][:type] == :numeric
|
||||||
:numeric
|
:numeric
|
||||||
else
|
else
|
||||||
:string
|
:string
|
||||||
|
@ -26,11 +26,11 @@ module Rpl
|
||||||
|
|
||||||
result[:value] = case result[:type]
|
result[:value] = case result[:type]
|
||||||
when :name
|
when :name
|
||||||
"'#{args[0][:value]}#{args[1][:value]}'"
|
"'#{args[1][:value]}#{args[0][:value]}'"
|
||||||
when :string
|
when :string
|
||||||
"\"#{args[0][:value]}#{args[1][:value]}\""
|
"\"#{args[1][:value]}#{args[0][:value]}\""
|
||||||
when :numeric
|
when :numeric
|
||||||
args[0][:value] + args[1][:value]
|
args[1][:value] + args[0][:value]
|
||||||
end
|
end
|
||||||
|
|
||||||
result[:base] = 10 if result[:type] == :numeric # TODO: what if operands have other bases ?
|
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, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||||
|
|
||||||
stack << { type: :numeric, base: 10,
|
stack << { type: :numeric, base: 10,
|
||||||
value: args[0][:value] - args[1][:value] }
|
value: args[1][:value] - args[0][:value] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# negation
|
# negation
|
||||||
|
@ -59,7 +59,7 @@ module Rpl
|
||||||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||||
|
|
||||||
stack << { type: :numeric, base: 10,
|
stack << { type: :numeric, base: 10,
|
||||||
value: args[0][:value] * args[1][:value] }
|
value: args[1][:value] * args[0][:value] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# division
|
# division
|
||||||
|
@ -69,7 +69,7 @@ module Rpl
|
||||||
raise 'Division by 0' if args[0][:value].zero?
|
raise 'Division by 0' if args[0][:value].zero?
|
||||||
|
|
||||||
stack << { type: :numeric, base: 10,
|
stack << { type: :numeric, base: 10,
|
||||||
value: args[0][:value] / args[1][:value] }
|
value: args[1][:value] / args[0][:value] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# inverse
|
# inverse
|
||||||
|
@ -87,7 +87,7 @@ module Rpl
|
||||||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
||||||
|
|
||||||
stack << { type: :numeric, base: 10,
|
stack << { type: :numeric, base: 10,
|
||||||
value: args[0][:value]**args[1][:value] }
|
value: args[1][:value]**args[0][:value] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# rpn_square root
|
# rpn_square root
|
||||||
|
@ -133,9 +133,9 @@ module Rpl
|
||||||
def base( stack )
|
def base( stack )
|
||||||
stack, args = Rpl::Core.stack_extract( stack, [%i[numeric], %i[numeric]] )
|
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
|
end
|
||||||
|
|
||||||
# 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0
|
# 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Rpl
|
||||||
def swap( stack )
|
def swap( stack )
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[any any] )
|
stack, args = Rpl::Core.stack_extract( stack, %i[any any] )
|
||||||
|
|
||||||
stack << args[1] << args[0]
|
stack << args[0] << args[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
# drop first stack entry
|
# drop first stack entry
|
||||||
|
@ -36,7 +36,7 @@ module Rpl
|
||||||
def rot( stack )
|
def rot( stack )
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[any any any] )
|
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
|
end
|
||||||
|
|
||||||
# duplicate first stack entry
|
# duplicate first stack entry
|
||||||
|
@ -55,6 +55,8 @@ module Rpl
|
||||||
n = args[0][:value]
|
n = args[0][:value]
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||||
|
|
||||||
|
args.reverse!
|
||||||
|
|
||||||
2.times do
|
2.times do
|
||||||
n.times.each do |i|
|
n.times.each do |i|
|
||||||
stack << args[ i ]
|
stack << args[ i ]
|
||||||
|
@ -70,6 +72,8 @@ module Rpl
|
||||||
n = args[0][:value]
|
n = args[0][:value]
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||||
|
|
||||||
|
args.reverse!
|
||||||
|
|
||||||
n.times.each do |i|
|
n.times.each do |i|
|
||||||
stack << args[ i ]
|
stack << args[ i ]
|
||||||
end
|
end
|
||||||
|
@ -89,6 +93,8 @@ module Rpl
|
||||||
n = args[0][:value]
|
n = args[0][:value]
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||||
|
|
||||||
|
args.reverse!
|
||||||
|
|
||||||
(1..(n - 1)).each do |i|
|
(1..(n - 1)).each do |i|
|
||||||
stack << args[ i ]
|
stack << args[ i ]
|
||||||
end
|
end
|
||||||
|
@ -103,6 +109,8 @@ module Rpl
|
||||||
n = args[0][:value]
|
n = args[0][:value]
|
||||||
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
stack, args = Rpl::Core.stack_extract( stack, %i[any] * args[0][:value] )
|
||||||
|
|
||||||
|
args.reverse!
|
||||||
|
|
||||||
stack << args[n - 1]
|
stack << args[n - 1]
|
||||||
|
|
||||||
(0..(n - 2)).each do |i|
|
(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 }],
|
assert_equal [{ value: 2, type: :numeric }],
|
||||||
args
|
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 }],
|
{ value: 2, type: :numeric }],
|
||||||
[:any, [:numeric]]
|
[:any, [:numeric]]
|
||||||
assert_equal [],
|
assert_equal [],
|
||||||
stack
|
stack
|
||||||
assert_equal [{ value: 1, type: :numeric },
|
assert_equal [{ value: 2, type: :numeric },
|
||||||
{ value: 2, type: :numeric }],
|
{ value: "test", type: :string }],
|
||||||
args
|
args
|
||||||
end
|
end
|
||||||
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