typing: Added typing resolution for `ACallrefExpr`
[nit.git] / lib / functional / functional_gen.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2019 Louis-Vincent Boudreault <lv.boudreault95@gmail.com>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # This module is only used to generate `functional_types.nit`
18 module functional_gen
19
20 # Generates of an array of formal type as strings.
21 # The size of the array equals the arity of the class.
22 fun gen_generics(nargs: Int): Array[String]
23 do
24 var args = new Array[String]
25 for i in [0..nargs[ do
26 args.push("A" + i.to_s)
27 end
28 return args
29 end
30
31 class RoutineTemplate
32 var classkind: String
33 var classname: String
34 var nb_generics: Int
35 var supers: Array[String]
36 var has_return: Bool
37 var is_redef = false
38 var annotation = "is abstract"
39
40 fun callparams: Array[String]
41 do
42 var generics = gen_generics(nb_generics)
43 var params = new Array[String]
44 for g in generics do
45 if is_redef then
46 params.push(g.to_lower)
47 else
48 params.push(g.to_lower + ": " + g)
49 end
50 end
51 return params
52 end
53
54 fun classparams: Array[String]
55 do
56 var res = gen_generics(nb_generics)
57 if has_return then res.add("RESULT")
58 return res
59 end
60
61 redef fun to_s
62 do
63 var signature = ""
64 var callparams = self.callparams
65 var classparams = self.classparams
66
67 if callparams.length > 0 then signature = "({callparams.join(",")})"
68 if has_return then signature += ": RESULT"
69 var classdecl = "{classkind} {classname}"
70 if classparams.length > 0 then classdecl += "[{classparams.join(",")}]"
71 var superdecls = new Array[String]
72 for s in supers do superdecls.add("\tsuper {s}")
73
74 var classdef = new Array[String]
75 var redefkw = ""
76 if is_redef then redefkw = "redef "
77 classdef.add("{classdecl}")
78 classdef.add("{superdecls.join("\n")}")
79 classdef.add("\t{redefkw}fun call{signature} {annotation}")
80 classdef.add("end")
81 return classdef.join("\n")
82 end
83 end
84
85 # Writes all functional types
86 fun generate_functypes(n: Int, writer: Writer)
87 do
88 writer.write("""
89 # This file is part of NIT ( http://www.nitlanguage.org ).
90 #
91 # Licensed under the Apache License, Version 2.0 (the "License");
92 # you may not use this file except in compliance with the License.
93 # You may obtain a copy of the License at
94 #
95 # http://www.apache.org/licenses/LICENSE-2.0
96 #
97 # Unless required by applicable law or agreed to in writing, software
98 # distributed under the License is distributed on an "AS IS" BASIS,
99 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
100 # See the License for the specific language governing permissions and
101 # limitations under the License.
102
103 # This module provides functional type to represents various function forms.
104 # Function types can hold up to 20 arguments. The type `Fun` is for function
105 # (input and output) and `Proc` is for procedure (input but no output).
106 # This file is automatically generated, do not edit it manually.
107 module functional_types
108
109 interface Routine
110 end
111 interface Fun
112 super Routine
113 end
114 interface Proc
115 super Routine
116 end
117 """)
118 var templates = new Array[String]
119 var templates2 = new Array[String]
120 for i in [0..n[ do
121 var t1 = new RoutineTemplate("interface", "Fun{i}", i, ["Fun"], true)
122 var t2 = new RoutineTemplate("interface", "Proc{i}", i, ["Proc"], false)
123 templates.push(t1.to_s)
124 templates.push(t2.to_s)
125
126 # We want routine ref to be at the end of the file
127 var t3 = new RoutineTemplate("universal", "FunRef{i}", i, ["Fun{i}{t1.classparams}"], true)
128 var procsuper = "Proc{i}"
129 if i > 0 then procsuper = "Proc{i}{t2.classparams}"
130 var t4 = new RoutineTemplate("universal", "ProcRef{i}", i, [procsuper], false)
131 t3.annotation = "is intern"
132 t3.is_redef = true
133 t4.annotation = "is intern"
134 t4.is_redef = true
135 templates2.push(t3.to_s)
136 templates2.push(t4.to_s)
137 end
138 templates.add_all(templates2)
139 templates.add(
140 """
141 universal RoutineRef
142 end
143 """)
144 writer.write(templates.join("\n"))
145 end
146
147 var fw = new FileWriter.open("functional_types.nit")
148 generate_functypes(20, fw)