Class: Emfrp::Interpreter
- Inherits:
-
Object
- Object
- Emfrp::Interpreter
show all
- Defined in:
- lib/emfrp/interpreter/evaluater.rb,
lib/emfrp/interpreter/interpreter.rb,
lib/emfrp/interpreter/command_manager.rb
Defined Under Namespace
Modules: Evaluater
Classes: CommandManager, InterpreterError
Instance Method Summary
collapse
-
#append_def(uniq_id, def_str) ⇒ Object
-
#close ⇒ Object
-
#command_exec(command_name, arg, readline_id) ⇒ Object
-
#compile(c_output_io, h_output_io, main_output_io, name, print_log = false) ⇒ Object
-
#compile_default(gen_cpp = false, gen_main = true) ⇒ Object
-
#completion_proc ⇒ Object
-
#current_readline_id ⇒ Object
-
#disable_io(&block) ⇒ Object
-
#exec_embedded_commands(only_on_main_path = false) ⇒ Object
-> true-like(abnormal-term) / false-like(normal-term).
-
#initialize(include_dirs, output_io, main_path) ⇒ Interpreter
constructor
A new instance of Interpreter.
-
#lexical_tokens ⇒ Object
-
#pp(obj) ⇒ Object
-
#proceed_readline_id ⇒ Object
-
#process_repl_line(line) ⇒ Object
-> true-like(abnormal-term) / false-like(normal-term).
-
#puts(str) ⇒ Object
-
#str_to_exp(exp_str, type = nil) ⇒ Object
-> parsed-expression or nil(fail).
Constructor Details
#initialize(include_dirs, output_io, main_path) ⇒ Interpreter
Returns a new instance of Interpreter.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# 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
|
Instance Method Details
#append_def(uniq_id, def_str) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# 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 ⇒ Object
163
164
165
|
# File 'lib/emfrp/interpreter/interpreter.rb', line 163
def close
puts ""
end
|
#command_exec(command_name, arg, readline_id) ⇒ Object
146
147
148
149
150
151
152
153
|
# 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) ⇒ Object
37
38
39
|
# 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) ⇒ Object
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# 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 ⇒ Object
175
176
177
178
179
180
181
182
|
# 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 ⇒ Object
171
172
173
|
# File 'lib/emfrp/interpreter/interpreter.rb', line 171
def current_readline_id
"%03d" % @readline_nums.first
end
|
#disable_io(&block) ⇒ Object
155
156
157
158
159
160
161
|
# 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) ⇒ Object
-> true-like(abnormal-term) / false-like(normal-term)
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
# 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 ⇒ Object
184
185
186
187
188
189
190
|
# 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) ⇒ Object
192
193
194
|
# File 'lib/emfrp/interpreter/interpreter.rb', line 192
def pp(obj)
PP.pp(obj, @output_io)
end
|
#proceed_readline_id ⇒ Object
167
168
169
|
# File 'lib/emfrp/interpreter/interpreter.rb', line 167
def proceed_readline_id
"%03d" % @readline_nums.shift
end
|
#process_repl_line(line) ⇒ Object
-> true-like(abnormal-term) / false-like(normal-term)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# 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) ⇒ Object
196
197
198
|
# File 'lib/emfrp/interpreter/interpreter.rb', line 196
def puts(str)
@output_io.puts(str)
end
|
#str_to_exp(exp_str, type = nil) ⇒ Object
-> parsed-expression or nil(fail)
88
89
90
91
92
93
94
95
96
97
|
# 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
|