1 # frozen_string_literal: true
2
3 require "test_helper"
4
5
6 module Umu
7
8 module Test
9
10 module Grammar
11
12 module CoreLanguage
13
14 module Declaration
15
16 class RecursiveTest < Minitest::Test
17 =begin
18 <recursive-declaration> ::=
19 FUN REC <pattern> "=" <binding> { AND <binding> } ;
20
21 <binding> ::= ID "=" <function-body> ;
22
23 /* <function-body> ::= ... ; See FunctionTest */
24 =end
25 def setup
26 @interp = Api.setup_interpreter
27 end
28
29
30 def test_recursive
31 interp = Api.eval_decls @interp, <<-EOS
32 fun rec fact = x ->
33 if x <= 1 then
34 1
35 else
36 x * fact (x - 1)
37 EOS
38
39 value = Api.eval_expr interp, "fact 1"
40 assert_instance_of VCAN::Int, value
41 assert_equal 1, value.val
42
43 value = Api.eval_expr interp, "fact 3"
44 assert_instance_of VCAN::Int, value
45 assert_equal 6, value.val
46 end
47
48
49 def test_mutual_recursive
50 interp = Api.eval_decls @interp, <<-EOS
51 fun rec even? = x -> if x == 0 then TRUE else odd? (x - 1)
52 and odd? = x -> if x == 0 then FALSE else even? (x - 1)
53 EOS
54
55 value = Api.eval_expr interp, "even? 2"
56 assert_instance_of VCA::Bool, value
57 assert_equal true, value.val
58
59 value = Api.eval_expr interp, "even? 3"
60 assert_instance_of VCA::Bool, value
61 assert_equal false, value.val
62
63 value = Api.eval_expr interp, "odd? 2"
64 assert_instance_of VCA::Bool, value
65 assert_equal false, value.val
66
67 value = Api.eval_expr interp, "odd? 3"
68 assert_instance_of VCA::Bool, value
69 assert_equal true, value.val
70 end
71
72
73 def test_should_not_be_duplicated_function_names
74 assert_raises(X::SyntaxError) do
75 Api.eval_decls @interp, <<-EOS
76 fun rec f = x -> f 3
77 and f = x -> f 4
78 EOS
79 end
80 end
81 end
82
83 end # Umu::Test::Grammar::CoreLanguage::Declaration
84
85 end # Umu::Test::Grammar::CoreLanguage
86
87 end # Umu::Test::Grammar
88
89 end # Umu::Test
90
91 end # Umu