rpl.rb/lib/core/stack.rb

127 lines
2.6 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
2022-02-10 14:33:09 +01:00
def swap
args = stack_extract( %i[any any] )
2022-02-10 14:33:09 +01:00
@stack << args[0] << args[1]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# drop n first stack entries
2022-02-10 14:33:09 +01:00
def dropn
args = stack_extract( [%i[numeric]] )
2022-02-10 14:33:09 +01:00
_args = stack_extract( %i[any] * args[0][:value] )
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# drop all stack entries
2022-02-10 14:33:09 +01:00
def del
@stack = []
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# rotate 3 first stack entries
2022-02-10 14:33:09 +01:00
def rot
args = stack_extract( %i[any any any] )
2022-02-10 14:33:09 +01:00
@stack << args[1] << args[0] << args[2]
2021-12-07 15:50:58 +01:00
end
2021-12-07 15:50:58 +01:00
# duplicate n first stack entries
2022-02-10 14:33:09 +01:00
def dupn
args = stack_extract( [%i[numeric]] )
2021-12-08 13:14:42 +01:00
n = args[0][:value].to_i
2022-02-10 14:33:09 +01:00
args = stack_extract( %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|
2022-02-10 14:33:09 +01:00
@stack << Marshal.load(Marshal.dump( args[i] ))
2021-12-07 15:50:58 +01:00
end
end
end
2021-12-07 15:50:58 +01:00
# push a copy of the given stack level onto the stack
2022-02-10 14:33:09 +01:00
def pick
args = stack_extract( [%i[numeric]] )
2021-12-08 13:14:42 +01:00
n = args[0][:value].to_i
2022-02-10 14:33:09 +01:00
args = stack_extract( %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|
2022-02-10 14:33:09 +01:00
@stack << args[ i ]
2021-12-07 15:50:58 +01:00
end
2022-02-10 14:33:09 +01:00
@stack << args[0]
end
2021-12-07 15:50:58 +01:00
# give stack depth
2022-02-10 14:33:09 +01:00
def depth
@stack << { type: :numeric, base: 10, value: stack.size }
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
2022-02-10 14:33:09 +01:00
def roll
args = stack_extract( [%i[numeric]] )
2021-12-07 15:50:58 +01:00
n = args[0][:value]
2022-02-10 14:33:09 +01:00
args = stack_extract( %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|
2022-02-10 14:33:09 +01:00
@stack << args[ i ]
2021-12-07 15:50:58 +01:00
end
2022-02-10 14:33:09 +01:00
@stack << args[0]
end
2021-12-07 15:50:58 +01:00
# move the element on top of the stack to a higher stack position
2022-02-10 14:33:09 +01:00
def rolld
args = stack_extract( [%i[numeric]] )
2021-12-07 15:50:58 +01:00
n = args[0][:value]
2022-02-10 14:33:09 +01:00
args = stack_extract( %i[any] * args[0][:value] )
2021-12-07 15:50:58 +01:00
args.reverse!
2022-02-10 14:33:09 +01:00
@stack << args[n - 1]
2021-12-07 15:50:58 +01:00
(0..(n - 2)).each do |i|
2022-02-10 14:33:09 +01:00
@stack << args[ i ]
2021-12-07 15:50:58 +01:00
end
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
2022-02-10 14:33:09 +01:00
def over
run( '2 pick' )
2021-12-08 13:15:33 +01:00
end
# drop first stack entry
2022-02-10 14:33:09 +01:00
def drop
run( '1 dropn' )
2021-12-08 13:15:33 +01:00
end
# drop 2 first stack entries
2022-02-10 14:33:09 +01:00
def drop2
run( '2 dropn' )
2021-12-08 13:15:33 +01:00
end
# duplicate first stack entry
2022-02-10 14:33:09 +01:00
def dup
run( '1 dupn' )
2021-12-08 13:15:33 +01:00
end
# duplicate 2 first stack entries
2022-02-10 14:33:09 +01:00
def dup2
run( '2 dupn' )
2021-12-07 15:50:58 +01:00
end
end
end
end