# This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2019 Louis-Vincent Boudreault # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This module is only used to generate `functional_types.nit` module functional_gen # Generates of an array of formal type as strings. # The size of the array equals the arity of the class. fun gen_generics(nargs: Int): Array[String] do var args = new Array[String] for i in [0..nargs[ do args.push("A" + i.to_s) end return args end class RoutineTemplate var classkind: String var classname: String var nb_generics: Int var supers: Array[String] var has_return: Bool var is_redef = false var annotation = "is abstract" fun callparams: Array[String] do var generics = gen_generics(nb_generics) var params = new Array[String] for g in generics do if is_redef then params.push(g.to_lower) else params.push(g.to_lower + ": " + g) end end return params end fun classparams: Array[String] do var res = gen_generics(nb_generics) if has_return then res.add("RESULT") return res end redef fun to_s do var signature = "" var callparams = self.callparams var classparams = self.classparams if callparams.length > 0 then signature = "({callparams.join(",")})" if has_return then signature += ": RESULT" var classdecl = "{classkind} {classname}" if classparams.length > 0 then classdecl += "[{classparams.join(",")}]" var superdecls = new Array[String] for s in supers do superdecls.add("\tsuper {s}") var classdef = new Array[String] var redefkw = "" if is_redef then redefkw = "redef " classdef.add("{classdecl}") classdef.add("{superdecls.join("\n")}") classdef.add("\t{redefkw}fun call{signature} {annotation}") classdef.add("end") return classdef.join("\n") end end # Writes all functional types fun generate_functypes(n: Int, writer: Writer) do writer.write(""" # This file is part of NIT ( http://www.nitlanguage.org ). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This module provides functional type to represents various function forms. # Function types can hold up to 20 arguments. The type `Fun` is for function # (input and output) and `Proc` is for procedure (input but no output). # This file is automatically generated, do not edit it manually. module functional_types interface Routine end interface Fun super Routine end interface Proc super Routine end """) var templates = new Array[String] var templates2 = new Array[String] for i in [0..n[ do var t1 = new RoutineTemplate("interface", "Fun{i}", i, ["Fun"], true) var t2 = new RoutineTemplate("interface", "Proc{i}", i, ["Proc"], false) templates.push(t1.to_s) templates.push(t2.to_s) # We want routine ref to be at the end of the file var t3 = new RoutineTemplate("universal", "FunRef{i}", i, ["Fun{i}{t1.classparams}"], true) var procsuper = "Proc{i}" if i > 0 then procsuper = "Proc{i}{t2.classparams}" var t4 = new RoutineTemplate("universal", "ProcRef{i}", i, [procsuper], false) t3.annotation = "is intern" t3.is_redef = true t4.annotation = "is intern" t4.is_redef = true templates2.push(t3.to_s) templates2.push(t4.to_s) end templates.add_all(templates2) templates.add( """ universal RoutineRef end """) writer.write(templates.join("\n")) end var fw = new FileWriter.open("functional_types.nit") generate_functypes(20, fw)