Ejemplo n.º 1
0
    def desugar_equation(self, params, param_types, result_type, equation):
        position = equation.position
        patterns = equation.lhs.application_args()
        body = equation.rhs
        if len(patterns) != len(params):
            self.fail('equations-arity-mismatch', name=name, position=position)
        self._env.open_scope()  # Equation scope
        fvs = set()
        for var in syntax.free_variables_list(patterns):
            if not self._env.is_defined(var):
                fvs.add(var)
                self._env.define(var,
                                 syntax.Metavar(prefix="t", position=position))

        # TODO: allow forced binding by prefixing a variable with "."

        if len(equation.where) == 0:
            d_type, d_body = self.check_expr(body)
        else:
            d_type, d_body = self.check_let(
                syntax.Let(declarations=equation.where,
                           body=body,
                           position=position))
        self.unify_types(d_type, result_type)

        unif_goals = []
        for param, pattern, t_param in zip(params, patterns, param_types):
            t_pattern, e_pattern = self.check_expr(pattern)
            self.unify_types(t_param, t_pattern)
            unif_goals.append(syntax.unify(param, e_pattern))

        alternative = syntax.fresh_many(
            fvs, syntax.sequence_many1(unif_goals, d_body))
        self._env.close_scope()  # Equation scope
        return alternative
Ejemplo n.º 2
0
 def check_application(self, expr):
     t_fun, e_fun = self.check_expr(expr.fun)
     t_arg, e_arg = self.check_expr(expr.arg)
     t_res = syntax.Metavar(prefix='t', position=expr.position)
     self.unify_types(t_fun, syntax.function(t_arg, t_res))
     return (t_res,
             syntax.Application(fun=e_fun, arg=e_arg,
                                position=expr.position))
Ejemplo n.º 3
0
 def check_fresh(self, expr):
     self._env.open_scope()
     self._env.define(expr.var, syntax.Metavar(prefix='t',
                                               position=expr.position))
     t_body, e_body = self.check_expr(expr.body)
     self._env.close_scope()
     return (t_body,
             syntax.Fresh(var=expr.var, body=e_body,
                          position=expr.position))
Ejemplo n.º 4
0
    def desugar_definition(self, name, equations):
        position = equations[0].position
        alternatives = []

        patterns_0 = equations[0].lhs.application_args()
        params = [syntax.fresh_variable(position=position)
                    for pat in patterns_0]

        definition_type = self._env.value(name)

        self._env.open_scope() # Definition scope

        param_types = []
        for param in params:
            param_type = syntax.Metavar(prefix='t', position=position)
            self._env.define(param, param_type)
            param_types.append(param_type)
        result_type = syntax.Metavar(prefix='t', position=position)

        self.unify_types(
          definition_type,
          syntax.function_many(param_types, result_type)
        )

        for equation in equations:
            alternatives.append(
              self.desugar_equation(params, param_types, result_type, equation)
            )

        rhs = syntax.lambda_many(
                [param.name for param in params],
                syntax.alternative_many(alternatives, position=position),
                position=position,
              )
        self._env.close_scope() # Definition scope
        return syntax.Definition(
                 lhs=syntax.Variable(name=name,
                                     position=position),
                 rhs=rhs,
                 where=[],
                 position=position)
Ejemplo n.º 5
0
    def check_let(self, expr):
        # Check kinds and extend environment
        # to allow for recursive definitions.

        definitions, definition_keys, type_declarations = \
            self.check_let_declarations_well_formed(expr)

        # TODO: Dependency graph
        graph = self.dependency_graph(definitions)
        partition = dependencies.partition_dependencies(graph)

        desugared_declarations = []
        for part in partition:

            part_definitions = {}
            part_type_declarations = {}
            for x in part:
                part_definitions[x] = definitions[x]
                if x in type_declarations:
                    part_type_declarations[x] = type_declarations[x]
            part_definition_keys = []
            for k in definition_keys:
                if k in part_definitions:
                    part_definition_keys.append(k)

            self._env.open_scope()
            for name, defs in part_definitions.items():
                self._env.define(name,
                                 syntax.Metavar(prefix='t',
                                                position=defs[0].position))

            e_decls = []
            for name in part_definition_keys:
                e_decls.append(
                  self.desugar_definition(name, part_definitions[name])
                )

            self.generalize_types_in_current_scope()
            self.check_declared_instantiate_real(part_type_declarations) 

            # To reconstruct the final AST
            ds = []
            for e_decl in e_decls:
                t_decl = syntax.TypeDeclaration(
                             name=e_decl.lhs.name,
                             type=self._env.value(e_decl.lhs.name),
                             position=e_decl.position
                         )
                ds.append(t_decl)
                ds.append(e_decl)
            desugared_declarations.append(ds)

        t_body, e_body = self.check_expr(expr.body)
        for part in reversed(partition):
            self._env.close_scope()
            e_body = syntax.Let(
                       declarations=desugared_declarations.pop(),
                       body=e_body,
                       position=expr.position)

        return t_body, e_body
Ejemplo n.º 6
0
    def check_let(self, expr):
        # Check kinds and extend environment
        # to allow for recursive definitions.
        declared_names = set()
        definitions = {}
        definition_keys = []
        self._env.open_scope()
        type_declarations = []
        for decl in expr.declarations:
            if decl.is_type_declaration():
                decl = self.check_type_declaration(decl)
                declared_names.add(decl.name)
                type_declarations.append(decl)
            elif decl.is_definition():
                head = decl.lhs.application_head()
                if not head.is_variable():
                    self.fail('declaration-head-is-not-variable',
                              head=head,
                              position=decl.position)
                declared_names.add(head.name)
                if head.name not in definitions:
                    definition_keys.append(head.name)
                    definitions[head.name] = []
                definitions[head.name].append(decl)
                if not self._env.is_locally_defined(head.name):
                    self._env.define(
                        head.name,
                        syntax.Metavar(prefix='t', position=decl.position))
            else:
                raise Exception('Check for declaration not implemented.')

        defined_names = set(definitions.keys())
        if declared_names != defined_names:
            missing = declared_names - defined_names
            self.fail('name-declared-but-not-defined',
                      name=missing.pop(),
                      position=expr.position)

        e_decls = []
        for name in definition_keys:
            e_decls.append(self.desugar_definition(name, definitions[name]))

        self.generalize_types_in_current_scope()
        self.check_declared_instantiate_real(type_declarations)

        body_type, desugared_body = self.check_expr(expr.body)

        # To reconstruct the final AST
        desugared_declarations = []
        for e_decl in e_decls:
            t_decl = syntax.TypeDeclaration(name=e_decl.lhs.name,
                                            type=self._env.value(
                                                e_decl.lhs.name),
                                            position=e_decl.position)
            desugared_declarations.append(t_decl)
            desugared_declarations.append(e_decl)

        self._env.close_scope()
        return (body_type,
                syntax.Let(declarations=desugared_declarations,
                           body=desugared_body,
                           position=expr.position))