rpl.rb/lib/core/stack.rb

155 lines
3.9 KiB
Ruby
Raw Normal View History

2021-12-07 16:09:17 +01:00
# frozen_string_literal: true
module Rpl
2021-12-07 15:50:58 +01:00
module Lang
module Core
module_function
2021-12-07 15:50:58 +01:00
# swap 2 first stack entries
def swap( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any] )
2021-12-07 15:50:58 +01:00
stack << args[0] << args[1]
[stack, dictionary]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# drop n first stack entries
def dropn( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] )
stack, _args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] )
[stack, dictionary]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# drop all stack entries
def del( _stack, dictionary )
[[], dictionary]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# rotate 3 first stack entries
def rot( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any any any] )
2021-12-07 15:50:58 +01:00
stack << args[1] << args[0] << args[2]
[stack, dictionary]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# duplicate n first stack entries
def dupn( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] )
2021-12-08 13:14:42 +01:00
n = args[0][:value].to_i
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] )
2021-12-07 15:50:58 +01:00
args.reverse!
2021-12-07 15:50:58 +01:00
2.times do
n.times.each do |i|
stack << args[ i ]
end
end
2021-12-07 15:50:58 +01:00
[stack, dictionary]
end
2021-12-07 15:50:58 +01:00
# push a copy of the given stack level onto the stack
def pick( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] )
2021-12-08 13:14:42 +01:00
n = args[0][:value].to_i
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] )
2021-12-07 15:50:58 +01:00
args.reverse!
2021-12-07 15:50:58 +01:00
n.times.each do |i|
stack << args[ i ]
end
stack << args[0]
[stack, dictionary]
end
2021-12-07 15:50:58 +01:00
# give stack depth
def depth( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack << { type: :numeric, base: 10, value: stack.size }
[stack, dictionary]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# move a stack entry to the top of the stack
def roll( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] )
n = args[0][:value]
stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] )
2021-12-07 15:50:58 +01:00
args.reverse!
2021-12-07 15:50:58 +01:00
(1..(n - 1)).each do |i|
stack << args[ i ]
end
stack << args[0]
[stack, dictionary]
end
2021-12-07 15:50:58 +01:00
# move the element on top of the stack to a higher stack position
def rolld( stack, dictionary )
2021-12-07 15:50:58 +01:00
stack, args = Rpl::Lang::Core.stack_extract( stack, [%i[numeric]] )
n = args[0][:value]
stack, args = Rpl::Lang::Core.stack_extract( stack, %i[any] * args[0][:value] )
2021-12-07 15:50:58 +01:00
args.reverse!
2021-12-07 15:50:58 +01:00
stack << args[n - 1]
2021-12-07 15:50:58 +01:00
(0..(n - 2)).each do |i|
stack << args[ i ]
end
[stack, dictionary]
end
2021-12-08 13:15:33 +01:00
# implemented in Rpl
2021-12-07 15:50:58 +01:00
# push a copy of the element in stack level 2 onto the stack
def over( stack, dictionary )
2021-12-08 13:15:33 +01:00
stack << { value: '« 2 pick »',
type: :program }
Rpl::Lang::Core.eval( stack, dictionary )
end
# drop first stack entry
def drop( stack, dictionary )
stack << { value: '« 1 dropn »',
type: :program }
Rpl::Lang::Core.eval( stack, dictionary )
end
# drop 2 first stack entries
def drop2( stack, dictionary )
stack << { value: '« 2 dropn »',
type: :program }
Rpl::Lang::Core.eval( stack, dictionary )
end
# duplicate first stack entry
def dup( stack, dictionary )
stack << { value: '« 1 dupn »',
type: :program }
Rpl::Lang::Core.eval( stack, dictionary )
end
# duplicate 2 first stack entries
def dup2( stack, dictionary )
stack << { value: '« 2 dupn »',
type: :program }
Rpl::Lang::Core.eval( stack, dictionary )
2021-12-07 15:50:58 +01:00
end
end
end
end