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
|
||||
* REPL:
|
||||
* autosave/autoload stack and vars from ~/.rplenv on start/exit
|
||||
. autoload is just « '~/.rplenv' feval »
|
||||
. autosave on exit overwrites
|
||||
* Language:
|
||||
* pseudo filesystem: subdir/namespace for variables
|
||||
. 'a dir' crdir 'a dir' cd vars
|
||||
|
|
32
bin/rpl
32
bin/rpl
|
@ -8,9 +8,7 @@ require 'readline'
|
|||
require 'rpl'
|
||||
|
||||
class RplRepl
|
||||
def initialize( interpreter )
|
||||
interpreter ||= Rpl.new
|
||||
|
||||
def initialize( interpreter: Rpl.new )
|
||||
@interpreter = interpreter
|
||||
end
|
||||
|
||||
|
@ -51,11 +49,25 @@ class RplRepl
|
|||
end
|
||||
|
||||
options = { run_REPL: ARGV.empty?,
|
||||
persistence_filename: File.expand_path( '~/.local/state/rpl.rb/machine' ),
|
||||
live_persistence: true,
|
||||
files: [],
|
||||
programs: [] }
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -69,7 +81,8 @@ OptionParser.new do |opts|
|
|||
end.parse!
|
||||
|
||||
# Instantiate interpreter
|
||||
interpreter = Rpl.new
|
||||
interpreter = Rpl.new( persistence_filename: options[:persistence_filename],
|
||||
live_persistence: options[:live_persistence] )
|
||||
|
||||
# first run provided files if any
|
||||
options[:files].each do |filename|
|
||||
|
@ -82,7 +95,8 @@ options[:programs].each do |program|
|
|||
end
|
||||
|
||||
# third launch REPL if (explicitely or implicitely) asked
|
||||
RplRepl.new( interpreter ).run if options[:run_REPL]
|
||||
|
||||
# last print defined vars and resulting stack on exit (formatted so that it can be fed back later to interpreter)
|
||||
pp "#{interpreter.export_vars} #{interpreter.export_stack}"
|
||||
if options[:run_REPL]
|
||||
RplRepl.new( interpreter: interpreter ).run
|
||||
else
|
||||
interpreter.persist_state
|
||||
end
|
||||
|
|
39
lib/rpl.rb
39
lib/rpl.rb
|
@ -7,10 +7,45 @@ require 'rpl/words'
|
|||
class Rpl < Interpreter
|
||||
include Types
|
||||
|
||||
def initialize( stack = [], dictionary = Dictionary.new )
|
||||
super
|
||||
attr_accessor :live_persistence
|
||||
|
||||
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?
|
||||
|
||||
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
|
||||
|
||||
prepend RplLang::Words::Branch
|
||||
|
|
|
@ -36,7 +36,7 @@ class Interpreter
|
|||
|
||||
attr_accessor :precision
|
||||
|
||||
def initialize( stack = [], dictionary = Rpl::Lang::Dictionary.new )
|
||||
def initialize( stack: [], dictionary: Dictionary.new )
|
||||
@version = 0.91
|
||||
|
||||
@dictionary = dictionary
|
||||
|
@ -100,12 +100,19 @@ class Interpreter
|
|||
end
|
||||
|
||||
def export_vars
|
||||
@dictionary.vars
|
||||
.map { |name, value| "#{value} '#{name}' sto" }
|
||||
.join(' ')
|
||||
vars_as_string = "@ variables:\n"
|
||||
vars_as_string += @dictionary.vars
|
||||
.map { |name, value| "#{value}\n'#{name}' sto\n" }
|
||||
.join("\n")
|
||||
|
||||
vars_as_string
|
||||
end
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue