PageRenderTime 22ms CodeModel.GetById 10ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 1ms

/src/tools/interpreter/liberty_interpreter_debugger.e

http://github.com/tybor/Liberty
Specman e | 210 lines | 170 code | 21 blank | 19 comment | 8 complexity | b5ab9f4d91199f0729e78b0641e7f1d0 MD5 | raw file
  1-- This file is part of Liberty Eiffel.
  2--
  3-- Liberty Eiffel is free software: you can redistribute it and/or modify
  4-- it under the terms of the GNU General Public License as published by
  5-- the Free Software Foundation, version 3 of the License.
  6--
  7-- Liberty Eiffel is distributed in the hope that it will be useful,
  8-- but WITHOUT ANY WARRANTY; without even the implied warranty of
  9-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10-- GNU General Public License for more details.
 11--
 12-- You should have received a copy of the GNU General Public License
 13-- along with Liberty Eiffel.  If not, see <http://www.gnu.org/licenses/>.
 14--
 15class LIBERTY_INTERPRETER_DEBUGGER
 16
 17inherit
 18   LIBERTY_INTERPRETER_DEBUGGER_VISITOR
 19
 20create {LIBERTY_INTERPRETER}
 21   make
 22
 23feature {LIBERTY_INTERPRETER}
 24   steps: LIBERTY_INTERPRETER_DEBUGGER_STEPS
 25         -- The object to notify about the running program: entry and exit of functions, code stepping...
 26
 27   break (a_entry: like entry): BOOLEAN is
 28         -- `entry' is the debug instructions entered by the user.
 29         --
 30         -- Returns True if the program should continue running, False if the debugger should display the
 31         -- prompt again and wait for further instructions.
 32      require
 33         a_entry /= Void
 34      do
 35         entry.copy(a_entry)
 36         if not entry.is_empty then
 37            if entry.first = ':' then
 38               Result := debug_entry
 39            else
 40               execute
 41               check
 42                  not Result
 43               end
 44            end
 45         end
 46      end
 47
 48feature {}
 49   debug_entry: BOOLEAN is
 50      require
 51         entry.first = ':'
 52      local
 53         evaled: BOOLEAN
 54      do
 55         entry.remove_first
 56         if not entry.is_empty then
 57            parser_buffer.initialize_with(entry)
 58            debug_grammar.reset
 59            evaled := parser.eval(parser_buffer, debug_grammar.table, once "Entry")
 60            if not evaled then
 61               std_error.put_line(once "Incomplete command.")
 62            elseif parser.error /= Void then
 63               errors.emit_syntax_error(parser.error, entry, Void)
 64            else
 65               debug_grammar.root_node.accept(debug_visitor)
 66               Result := debug_visitor.should_continue
 67            end
 68         end
 69      end
 70
 71   execute is
 72      do
 73         check
 74            saved_errors.is_empty
 75         end
 76         if try_to_execute_expression then
 77         elseif try_to_execute_instruction then
 78         else
 79            print_saved_errors
 80         end
 81         saved_errors.clear_count
 82      end
 83
 84feature {}
 85   try_to_execute_expression: BOOLEAN is
 86      local
 87         ast: LIBERTY_AST_EXPRESSION; exp: LIBERTY_EXPRESSION
 88         actual_type: LIBERTY_ACTUAL_TYPE; done: BOOLEAN
 89      do
 90         error_saved := False
 91         from
 92         until
 93            done
 94         loop
 95            ast := interpreter.universe.parse_expression(entry, agent save_error)
 96            if ast /= Void then
 97               actual_type ::= interpreter.target.result_type.known_type
 98               exp := builder.expression(ast, actual_type)
 99               if exp.result_type /= Void then
100                  exp.accept(interpreter.expressions)
101                  interpreter.object_printer.print_object(std_output, interpreter.expressions.eval_memory, 0)
102                  Result := True
103                  done := True
104               end
105            elseif not error_saved then
106               readline.set_prompt(once " ... > ")
107               readline.read_line
108               entry.extend('%N')
109               entry.append(readline.last_string)
110            else
111               done := True
112            end
113         end
114      end
115
116   try_to_execute_instruction: BOOLEAN is
117      local
118         ast: LIBERTY_AST_INSTRUCTION; ins: LIBERTY_INSTRUCTION
119         actual_type: LIBERTY_ACTUAL_TYPE; done: BOOLEAN
120      do
121         error_saved := False
122         from
123         until
124            done
125         loop
126            ast := interpreter.universe.parse_instruction(entry, agent save_error)
127            if ast /= Void then
128               actual_type ::= interpreter.target.result_type.known_type
129               ins := builder.instruction(ast, actual_type)
130               ins.accept(interpreter.instructions)
131               Result := True
132               done := True
133            elseif not error_saved then
134               readline.set_prompt(once " ... > ")
135               readline.read_line
136               entry.extend('%N')
137               entry.append(readline.last_string)
138            else
139               done := True
140            end
141         end
142      end
143
144   entry: STRING is ""
145
146   saved_errors: FAST_ARRAY[PARSE_ERROR]
147   error_saved: BOOLEAN
148
149   save_error (parse_error: PARSE_ERROR) is
150      do
151         saved_errors.add_last(parse_error)
152         error_saved := True
153      end
154
155   print_saved_errors is
156      do
157         saved_errors.do_all(agent print_error)
158      end
159
160feature {}
161   print_error (a_error: PARSE_ERROR) is
162      require
163         a_error /= Void
164      do
165         std_error.put_line(a_error.message)
166      end
167
168   make (a_interpreter: like interpreter) is
169      require
170         a_interpreter /= Void
171      do
172         interpreter := a_interpreter
173         create steps.make(a_interpreter)
174         create debug_visitor.make(a_interpreter)
175         create builder.make(a_interpreter)
176         create saved_errors.with_capacity(2)
177      ensure
178         interpreter = a_interpreter
179      end
180
181   errors: LIBERTY_ERRORS
182   debug_visitor: LIBERTY_INTERPRETER_DEBUGGER_VISITOR_IMPL
183   interpreter: LIBERTY_INTERPRETER
184   builder: LIBERTY_INTERPRETER_DEBUGGER_SEMANTICS_BUILDER
185
186   debug_grammar: LIBERTY_INTERPRETER_DEBUGGER_GRAMMAR is
187      once
188         create Result.make(create {LIBERTY_INTERPRETER_DEBUGGER_FACTORY}.make)
189      end
190
191   parser_buffer: MINI_PARSER_BUFFER is
192      once
193         create Result
194      end
195
196   parser: DESCENDING_PARSER is
197      once
198         create Result.make
199      end
200
201   readline: READLINE_INPUT_STREAM is
202      once
203         create Result.make
204      end
205
206invariant
207   interpreter /= Void
208   saved_errors /= Void
209
210end -- class LIBERTY_INTERPRETER_DEBUGGER