Persist stack and variable in ~/.local/state/rpl.rb/machine
This commit is contained in:
parent
dfac755ce5
commit
4dfe9554cb
4 changed files with 72 additions and 20 deletions
|
@ -12,10 +12,6 @@ To build gem: `rake gem`
|
||||||
-
|
-
|
||||||
|
|
||||||
# TODO-list
|
# TODO-list
|
||||||
* REPL:
|
|
||||||
* autosave/autoload stack and vars from ~/.rplenv on start/exit
|
|
||||||
. autoload is just « '~/.rplenv' feval »
|
|
||||||
. autosave on exit overwrites
|
|
||||||
* Language:
|
* Language:
|
||||||
* pseudo filesystem: subdir/namespace for variables
|
* pseudo filesystem: subdir/namespace for variables
|
||||||
. 'a dir' crdir 'a dir' cd vars
|
. 'a dir' crdir 'a dir' cd vars
|
||||||
|
|
32
bin/rpl
32
bin/rpl
|
@ -8,9 +8,7 @@ require 'readline'
|
||||||
require 'rpl'
|
require 'rpl'
|
||||||
|
|
||||||
class RplRepl
|
class RplRepl
|
||||||
def initialize( interpreter )
|
def initialize( interpreter: Rpl.new )
|
||||||
interpreter ||= Rpl.new
|
|
||||||
|
|
||||||
@interpreter = interpreter
|
@interpreter = interpreter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,11 +49,25 @@ class RplRepl
|
||||||
end
|
end
|
||||||
|
|
||||||
options = { run_REPL: ARGV.empty?,
|
options = { run_REPL: ARGV.empty?,
|
||||||
|
persistence_filename: File.expand_path( '~/.local/state/rpl.rb/machine' ),
|
||||||
|
live_persistence: true,
|
||||||
files: [],
|
files: [],
|
||||||
programs: [] }
|
programs: [] }
|
||||||
|
|
||||||
OptionParser.new do |opts|
|
OptionParser.new do |opts|
|
||||||
opts.on('-c', '--code "program"', ' ') do |program|
|
opts.on('-s', "--state filename", "persist state in filename (default: #{options[:persistence_filename]}) (will be created if needed)") do |filename|
|
||||||
|
options[:persistence_filename] = File.expand_path( filename )
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-q', '--no-state', 'Do not load persisted state') do
|
||||||
|
options[:persistence_filename] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-d', '--no-persist', 'Do not persist state') do
|
||||||
|
options[:live_persistence] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-c', '--code "program"', 'run provided "program"') do |program|
|
||||||
options[:programs] << program
|
options[:programs] << program
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,7 +81,8 @@ OptionParser.new do |opts|
|
||||||
end.parse!
|
end.parse!
|
||||||
|
|
||||||
# Instantiate interpreter
|
# Instantiate interpreter
|
||||||
interpreter = Rpl.new
|
interpreter = Rpl.new( persistence_filename: options[:persistence_filename],
|
||||||
|
live_persistence: options[:live_persistence] )
|
||||||
|
|
||||||
# first run provided files if any
|
# first run provided files if any
|
||||||
options[:files].each do |filename|
|
options[:files].each do |filename|
|
||||||
|
@ -82,7 +95,8 @@ options[:programs].each do |program|
|
||||||
end
|
end
|
||||||
|
|
||||||
# third launch REPL if (explicitely or implicitely) asked
|
# third launch REPL if (explicitely or implicitely) asked
|
||||||
RplRepl.new( interpreter ).run if options[:run_REPL]
|
if options[:run_REPL]
|
||||||
|
RplRepl.new( interpreter: interpreter ).run
|
||||||
# last print defined vars and resulting stack on exit (formatted so that it can be fed back later to interpreter)
|
else
|
||||||
pp "#{interpreter.export_vars} #{interpreter.export_stack}"
|
interpreter.persist_state
|
||||||
|
end
|
||||||
|
|
39
lib/rpl.rb
39
lib/rpl.rb
|
@ -7,10 +7,45 @@ require 'rpl/words'
|
||||||
class Rpl < Interpreter
|
class Rpl < Interpreter
|
||||||
include Types
|
include Types
|
||||||
|
|
||||||
def initialize( stack = [], dictionary = Dictionary.new )
|
attr_accessor :live_persistence
|
||||||
super
|
|
||||||
|
def initialize( stack: [],
|
||||||
|
dictionary: Dictionary.new,
|
||||||
|
persistence_filename: nil,
|
||||||
|
live_persistence: true )
|
||||||
|
super( stack: stack, dictionary: dictionary )
|
||||||
|
|
||||||
|
@persistence_filename = persistence_filename
|
||||||
|
@live_persistence = live_persistence
|
||||||
|
|
||||||
populate_dictionary if @dictionary.words.empty?
|
populate_dictionary if @dictionary.words.empty?
|
||||||
|
|
||||||
|
load_persisted_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_persisted_state
|
||||||
|
return if @persistence_filename.nil?
|
||||||
|
|
||||||
|
FileUtils.mkdir_p( File.dirname( @persistence_filename ) )
|
||||||
|
FileUtils.touch( @persistence_filename )
|
||||||
|
|
||||||
|
run "\"#{@persistence_filename}\" feval"
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_state
|
||||||
|
return if @persistence_filename.nil?
|
||||||
|
|
||||||
|
File.open( @persistence_filename, 'w' ) do |persistence_file|
|
||||||
|
persistence_file.write "#{export_vars}\n#{export_stack}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run( input )
|
||||||
|
stack = super
|
||||||
|
|
||||||
|
persist_state if @live_persistence
|
||||||
|
|
||||||
|
stack
|
||||||
end
|
end
|
||||||
|
|
||||||
prepend RplLang::Words::Branch
|
prepend RplLang::Words::Branch
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Interpreter
|
||||||
|
|
||||||
attr_accessor :precision
|
attr_accessor :precision
|
||||||
|
|
||||||
def initialize( stack = [], dictionary = Rpl::Lang::Dictionary.new )
|
def initialize( stack: [], dictionary: Dictionary.new )
|
||||||
@version = 0.91
|
@version = 0.91
|
||||||
|
|
||||||
@dictionary = dictionary
|
@dictionary = dictionary
|
||||||
|
@ -100,12 +100,19 @@ class Interpreter
|
||||||
end
|
end
|
||||||
|
|
||||||
def export_vars
|
def export_vars
|
||||||
@dictionary.vars
|
vars_as_string = "@ variables:\n"
|
||||||
.map { |name, value| "#{value} '#{name}' sto" }
|
vars_as_string += @dictionary.vars
|
||||||
.join(' ')
|
.map { |name, value| "#{value}\n'#{name}' sto\n" }
|
||||||
|
.join("\n")
|
||||||
|
|
||||||
|
vars_as_string
|
||||||
end
|
end
|
||||||
|
|
||||||
def export_stack
|
def export_stack
|
||||||
@stack.map(&:to_s).join(' ')
|
stack_as_string = "@ stack:\n"
|
||||||
|
stack_as_string += @stack.map(&:to_s)
|
||||||
|
.join("\n")
|
||||||
|
|
||||||
|
stack_as_string
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue