class Emfrp::Interpreter
Public Class Methods
new(include_dirs, output_io, main_path)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 18 def initialize(include_dirs, output_io, main_path) @file_loader = FileLoader.new(include_dirs) @main_path = main_path @output_io = output_io @readline_nums = (1..1000).to_a @command_manager = CommandManager.make(self) @top = Parser.parse_input(main_path, @file_loader, Parser.module_or_material_file) @infix_parser = Parser.from_infixes_to_parser(@top[:infixes]) @top = Parser.infix_convert(@top, @infix_parser) PreConvert.convert(@top) Typing.typing(@top) rescue Parser::ParsingError => err err.print_error(@output_io) raise InterpreterError.new(err.code) rescue CompileError => err err.print_error(@output_io, @file_loader) raise InterpreterError.new(err.code) end
Public Instance Methods
append_def(uniq_id, def_str)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 65 def append_def(uniq_id, def_str) file_name = "command-line-#{uniq_id}" @file_loader.add_to_loaded(file_name, def_str) ds = Parser.parse(def_str, file_name, Parser.oneline_file) ds.map!{|d| Parser.infix_convert(d, @infix_parser)} ds.each do |d| PreConvert.additional_convert(@top, d) Typing.additional_typing(@top, d) @top.add(d) end return nil rescue Parser::ParsingError => err err.print_error(@output_io) return err.code rescue CompileError => err err.print_error(@output_io, @file_loader) ds.each do |d| PreConvert.cancel(@top, d) end return err.code end
close()
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 163 def close puts "" end
command_exec(command_name, arg, readline_id)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 146 def command_exec(command_name, arg, readline_id) res = @command_manager.exec(command_name, arg, readline_id) if res == :command_format_error puts "Error: command_format_error" @command_manager.print_usage(command_name, @output_io) end return res end
compile(c_output_io, h_output_io, main_output_io, name, print_log=false)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 37 def compile(c_output_io, h_output_io, main_output_io, name, print_log=false) Emfrp::Codegen.codegen(@top, c_output_io, h_output_io, main_output_io, name) end
compile_default(gen_cpp = false, gen_main = true)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 41 def compile_default(gen_cpp = false, gen_main = true) filename = @top[:module_name][:desc] c_output_file = filename + (gen_cpp ? ".cpp" : ".c") h_output_file = filename + ".h" main_output_file = filename + "Main" + ".c" File.open(c_output_file, 'w') do |c_file| File.open(h_output_file, 'w') do |h_file| main_output_file += ".gen" if File.exist?(main_output_file) if gen_main File.open(main_output_file, 'w') do |main_file| compile(c_file, h_file, main_file, filename) end else require "stringio" compile(c_file, h_file, StringIO.new, filename) end return nil end end rescue SystemCallError => err puts err.inspect return :file_write_error end
completion_proc()
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 175 def completion_proc command_comp = @command_manager.completion_proc proc do |s| token_candidates = lexical_tokens.select{|x| x.index(s) == 0} command_candidates = command_comp.call(s) token_candidates + command_candidates end end
current_readline_id()
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 171 def current_readline_id "%03d" % @readline_nums.first end
disable_io(&block)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 155 def disable_io(&block) output_io = @output_io @output_io = StringIO.new block.call ensure @output_io = output_io end
exec_embedded_commands(only_on_main_path=false)
click to toggle source
-> true-like(abnormal-term) / false-like(normal-term)
# File lib/emfrp/interpreter/interpreter.rb, line 100 def exec_embedded_commands(only_on_main_path=false) # @top[:commands].any? do |com| if !only_on_main_path || com[:file_name] == @file_loader.loaded_full_path(@main_path) unless process_repl_line(com[:command_str]) nil else puts "Embedded command on #{com[:file_name]}:#{com[:line_number]}\n" true end else nil end end end
lexical_tokens()
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 184 def lexical_tokens res = [] res += @top[:dict][:const_space].keys res += @top[:dict][:data_space].keys res += @top[:dict][:func_space].keys return res end
pp(obj)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 192 def pp(obj) PP.pp(obj, @output_io) end
proceed_readline_id()
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 167 def proceed_readline_id "%03d" % @readline_nums.shift end
process_repl_line(line)
click to toggle source
-> true-like(abnormal-term) / false-like(normal-term)
# File lib/emfrp/interpreter/interpreter.rb, line 116 def process_repl_line(line) readline_id = proceed_readline_id() @last_status = case line when /^\s*(data|func|type)\s(.*)$/ append_def(readline_id, line) when /^[a-z][a-zA-Z0-9]*\s*=(.*)$/ append_def(readline_id, "data #{line}") when /^\s*\:([a-z\-]+)\s*(.*)$/ @last_command = $1 command_exec($1, $2, readline_id) when /^\s*\:\s+(.*)$/ if @last_command command_exec(@last_command, $1, readline_id) else puts "Error: there isn't a last-executed command" :recall_last_executed_error end when "" nil else if exp = str_to_exp(line) val = Evaluater.eval_exp(@top, exp) puts "#{Evaluater.value_to_s(val)} : #{exp[:typing].inspect.colorize(:green)}" nil else :eval_error end end end
puts(str)
click to toggle source
# File lib/emfrp/interpreter/interpreter.rb, line 196 def puts(str) @output_io.puts(str) end
str_to_exp(exp_str, type=nil)
click to toggle source
-> parsed-expression or nil(fail)
# File lib/emfrp/interpreter/interpreter.rb, line 88 def str_to_exp(exp_str, type=nil) @eval_serial ||= (0..1000).to_a uname = "tmp%03d" % @eval_serial.shift type_ano = type ? " : #{type}" : "" unless append_def(uname, "data #{uname}#{type_ano} = #{exp_str}") @top[:datas].last[:exp] else nil end end