From 316422fb800826994c4623edb837f57b74f7a361 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 2 Jan 2024 10:34:25 -0300 Subject: [PATCH] Add Crystal::Repl#parse_and_interpret (#14138) * Add Crystal::Repl#parse_and_interpret * Use single EvalResult type * skip if without_interpreter --- spec/compiler/crystal/tools/repl_spec.cr | 20 ++++++++++++++++++++ src/compiler/crystal/interpreter/repl.cr | 24 +++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 spec/compiler/crystal/tools/repl_spec.cr diff --git a/spec/compiler/crystal/tools/repl_spec.cr b/spec/compiler/crystal/tools/repl_spec.cr new file mode 100644 index 000000000000..3a1e1275ef12 --- /dev/null +++ b/spec/compiler/crystal/tools/repl_spec.cr @@ -0,0 +1,20 @@ +{% skip_file if flag?(:without_interpreter) %} + +require "../../../spec_helper" + +private def success_value(result : Crystal::Repl::EvalResult) : Crystal::Repl::Value + result.warnings.infos.should be_empty + result.value.should_not be_nil +end + +describe Crystal::Repl do + it "can parse and evaluate snippets" do + repl = Crystal::Repl.new + repl.prelude = "primitives" + repl.load_prelude + + success_value(repl.parse_and_interpret("1 + 2")).value.should eq(3) + success_value(repl.parse_and_interpret("def foo; 1 + 2; end")).value.should eq(nil) + success_value(repl.parse_and_interpret("foo")).value.should eq(3) + end +end diff --git a/src/compiler/crystal/interpreter/repl.cr b/src/compiler/crystal/interpreter/repl.cr index 93b3a6cef65c..2c009a89e87d 100644 --- a/src/compiler/crystal/interpreter/repl.cr +++ b/src/compiler/crystal/interpreter/repl.cr @@ -22,15 +22,13 @@ class Crystal::Repl when "exit" break when .presence - parser = new_parser(expression) - parser.warnings.report(STDOUT) + result = parse_and_interpret(expression) + result.warnings.report(STDOUT) - node = parser.parse - next unless node + next unless result.value - value = interpret(node) print " => " - puts SyntaxHighlighter::Colorize.highlight!(value.to_s) + puts SyntaxHighlighter::Colorize.highlight!(result.value.to_s) end rescue ex : EscapingException print "Unhandled exception: " @@ -44,6 +42,18 @@ class Crystal::Repl end end + record EvalResult, value : Value?, warnings : WarningCollection + + def parse_and_interpret(expression : String) : EvalResult + parser = new_parser(expression) + + node = parser.parse + return EvalResult.new(value: nil, warnings: parser.warnings) unless node + + value = interpret(node) + return EvalResult.new(value: value, warnings: parser.warnings) + end + def run_file(filename, argv) @interpreter.argv = argv @@ -68,7 +78,7 @@ class Crystal::Repl interpret(exps) end - private def load_prelude + def load_prelude node = parse_prelude interpret_and_exit_on_error(node)