{% skip_file if flag?(:without_interpreter) %} require "./spec_helper" require "../loader/spec_helper" require "../../support/env" private def ldflags {% if flag?(:msvc) %} "/LIBPATH:#{SPEC_CRYSTAL_LOADER_LIB_PATH} sum.lib" {% else %} "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -lsum" {% end %} end private def ldflags_with_backtick {% if flag?(:msvc) %} "/LIBPATH:#{SPEC_CRYSTAL_LOADER_LIB_PATH} `powershell.exe -C Write-Host -NoNewline sum.lib`" {% else %} "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -l`echo sum`" {% end %} end describe Crystal::Repl::Interpreter do around_all do |example| FileUtils.mkdir_p(SPEC_CRYSTAL_LOADER_LIB_PATH) build_c_dynlib(compiler_datapath("interpreter", "sum.c")) {% if flag?(:win32) %} with_env({"PATH" => "#{SPEC_CRYSTAL_LOADER_LIB_PATH}#{Process::PATH_DELIMITER}#{ENV["PATH"]}"}) do example.run end {% else %} example.run {% end %} FileUtils.rm_rf(SPEC_CRYSTAL_LOADER_LIB_PATH) end context "variadic calls" do it "promotes float" do interpret(<<-CRYSTAL).should eq 3.5 @[Link(ldflags: #{ldflags.inspect})] lib LibSum fun sum_float(count : Int32, ...) : Float32 end LibSum.sum_float(2, 1.2_f32, 2.3_f32) CRYSTAL end it "promotes int" do interpret(<<-CRYSTAL).should eq 5 @[Link(ldflags: #{ldflags.inspect})] lib LibSum fun sum_int(count : Int32, ...) : Int32 end LibSum.sum_int(2, 1_u8, 4_i16) CRYSTAL end it "promotes enum" do interpret(<<-CRYSTAL).should eq 5 @[Link(ldflags: #{ldflags.inspect})] lib LibSum fun sum_int(count : Int32, ...) : Int32 end enum E : Int8 ONE = 1 end enum F : UInt16 FOUR = 4 end LibSum.sum_int(2, E::ONE, F::FOUR) CRYSTAL end end context "command expansion" do it "expands ldflags" do interpret(<<-CRYSTAL).should eq 4 @[Link(ldflags: #{ldflags_with_backtick.inspect})] lib LibSum fun simple_sum_int(a : Int32, b : Int32) : Int32 end LibSum.simple_sum_int(2, 2) CRYSTAL end end context "proc pointer" do it "calls extern fun" do interpret(<<-CRYSTAL).should eq 6 @[Link(ldflags: #{ldflags_with_backtick.inspect})] lib LibSum fun simple_sum_int(a : Int32, b : Int32) : Int32 end class Foo def initialize(@method : Proc(Int32, Int32, Int32)) end def call(a, b) @method.call(a, b) end end foo = Foo.new(->LibSum.simple_sum_int) foo.call(1, 5) CRYSTAL end end end