Exemple #1
0
    def make_adts(self, typedefs):
        adts = CodeSection("algebraic data types")

        adt_names = set()
        for typedef in typedefs:
            adt = typedef.typ
            adt_names.add(adt.type_name)

            # If true, this ADT contains a function type somewhere, and
            # therefore cannot derive Show or Eq.
            has_function = False

            ind = 0
            for i, constructor in enumerate(adt.constructors):

                params = []
                for p in constructor.parameters:
                    pstring = self.funky_type_to_haskell(p, adt_names)
                    if "->" in pstring: has_function = True
                    params.append(pstring)
                params = " ".join(params)

                if i == 0:
                    definition = "data {}{}".format(self.ADT_PREFIX,
                                                    adt.type_name)
                    ind = len(definition) + 1
                    line = "{} = {}{} {}".format(definition, self.ADT_PREFIX,
                                                 constructor.identifier,
                                                 params)
                    adts.emit(line)
                else:
                    line = "| {}{} {}".format(self.ADT_PREFIX,
                                              constructor.identifier, params)
                    adts.emit(line, d=ind)
                self.constructor_names.add(constructor.identifier)

            if not has_function:
                adts.emit("deriving (Show, Eq)", d=ind)

            adts.newline()

        return adts
Exemple #2
0
 def make_core_section(self, core_tree):
     core_section = CodeSection("core section")
     for bind in core_tree.binds:
         compiled_bind = self.hs_compile(bind)
         core_section.emit(compiled_bind)
     core_section.newline()
     return core_section
Exemple #3
0
    def do_generate_code(self, core_tree, typedefs):
        """Generates Python code from the core tree and type definitions.

        :param core_tree: the type-checked core tree from the desugarer
        :param typedefs:  the typedefs from the desugarer
        :return:          the generated Python code as a string
        :rtype:           str
        """
        super().do_generate_code(core_tree, typedefs)

        log.info("Generating {} code...".format(self.lang_name))
        self.program.reset()
        self.runtime.reset()

        header_section = self.code_header()
        base_runtime_section = self.make_base_runtime()

        log.info("Creating user-defined data structres...")
        adts_section = self.make_adts(typedefs)
        log.info("Done.")
        log.info("Compiling core tree...")
        core_section = CodeSection("core code")
        main = self.py_compile(core_tree, core_section,  0)
        log.info("Done.")

        log.info("Creating main method...")
        main_section = self.make_main(main)
        log.info("Done.")

        log.info("Creating used runtime section...")
        used_runtime_section = self.make_used_runtime()
        log.info("Done.")

        for i, section in enumerate([header_section, base_runtime_section,
                                     used_runtime_section, adts_section,
                                     core_section, main_section]):
            self.program.add_section(section, i)

        log.info("Done generating {} code.".format(self.lang_name))
        return self.program.get_code()
Exemple #4
0
 def get_runtime(self):
     runtime_section = CodeSection("runtime")
     for method_code in self.used_runtime_methods:
         runtime_section.emit(method_code)
         runtime_section.newline()
     return runtime_section
Exemple #5
0
 def make_main_section(self, expr):
     main_section = CodeSection("main")
     main_section.emit("main = do")
     main_section.emit("       print ({})".format(self.hs_compile(expr)))
     return main_section
Exemple #6
0
 def make_base_runtime(self):
     runtime_section = CodeSection("base runtime")
     runtime_section.emit(base_runtime)
     runtime_section.newline()
     return runtime_section
Exemple #7
0
    def make_main(self, main):
        main_section = CodeSection("main method")

        main_section.emit("def result():")
        main_section.emit("return {}".format(main), d=4)
        main_section.emit("")

        main_section.emit("def main():")

        # are we in the REPL?  if so, we want to show the representation of an
        # object.  this has the nice benefit of wrapping it in quotes, etc, if
        # need be
        if funky.globals.CURRENT_MODE == funky.globals.Mode.REPL:
            main_section.emit("print(repr(result()))", d=4)
        else:
            main_section.emit("print(result())", d=4)

        main_section.newline()
        main_section.emit("if __name__ == \"__main__\":")
        main_section.emit("    main()")

        return main_section
Exemple #8
0
    def make_adts(self, typedefs):
        adts = CodeSection("algebraic data types")
        for typedef in typedefs:
            adt = typedef.typ
            superclass_name = "ADT{}".format(adt.type_name)
            adts.emit("class {}(ADT):".format(superclass_name))
            adts.emit("    pass")
            adts.newline()

            for constructor in adt.constructors:
                constructor_name = "ADT{}".format(constructor.identifier)
                adts.emit("class {}({}):".format(constructor_name,
                                                 superclass_name))
                varnames = ["v{}".format(i)
                            for i, _ in enumerate(constructor.parameters)]

                adts.newline()
                if varnames:
                    adts.emit("    def __init__(self, {}):".format(", ".join(varnames)))
                    adts.emit("        super().__init__([{}])".format(", ".join(v for v in varnames)))
                else:
                    adts.emit("    def __init__(self):".format(", ".join(varnames)))
                    adts.emit("        super().__init__([])")

                adts.newline()

                s = ""
                for var in varnames:
                    s += "lambda {}: ".format(var)

                if constructor.identifier in kwlist:
                    py_name = "__{}".format(constructor.identifier)
                else:
                    py_name = constructor.identifier
                adts.emit("{} = {}{}({})".format(py_name,
                                                 s,
                                                 constructor_name,
                                                 ", ".join(varnames)))
                adts.newline()

        return adts