Beispiel #1
0
        def quote(module, contents):
            clc = module.clc
            quotation = Quote(clc)
            quote_expr = quotation.eval(contents)
            quote_scope: Scope = quotation.clc.scope
            sym_arg = quote_scope.enter(".external")
            name_var = new_var(clc, name="external")
            tenv[sym_arg] = name_var

            record_fields = []
            for attr_name, each in quote_scope.freevars.items():
                record_fields.append((each, attr_name, tenv[each]))

            rho_group = types.ForallScope(clc.location, filename=clc.filename)
            rho = te.Bound('ρ', rho_group)
            type_arg = te.Record(
                te.row_from_list([(attr, t) for _, attr, t in record_fields],
                                 te.RowPoly(rho)))
            tc_state.unify(name_var, type_arg)
            exp_arg = ir.Expr(type=tc_state.infer(type_arg), expr=sym_arg)
            block = [
                ignore(
                    ir.Set(
                        each,
                        ir.Expr(type=t, expr=ir.Field(base=exp_arg,
                                                      attr=attr))))
                for each, attr, t in record_fields
            ]
            block.append(quote_expr)
            ret_expr = ir.Fun(
                "<quote>", clc.filename, sym_arg,
                ir.Expr(expr=ir.Block(block), type=quote_expr.type))
            ret_type = te.Arrow(type_arg, quote_expr.type)
            ret_type = te.Forall(rho_group, (rho, ), ret_type)
            return ir.Expr(expr=ret_expr, type=ret_type)
Beispiel #2
0
        def imp(module, qualname: typing.List[str], *, backend=backend):
            clc = module.clc
            name = qualname[-1]
            sym = clc.scope.enter(name)
            module_finder = backend.search_module(qualname)
            if module_finder.exist:
                sym_mod = module_finder.exist
                type_mod = type_of_value(sym_mod)
                exp_mod = ir.Expr(expr=sym_mod, type=type_mod)
                return ignore(ir.Set(module_finder.exist, exp_mod))

            filename, get_code = module_finder.filename, module_finder.get_code
            path = '.'.join(qualname)
            new_modular = Modular(
                CompilerLocalContext(scope=backend.mk_top_scope(),
                                     filename=filename,
                                     path=path))

            ast_mod = parse(get_code(), filename)
            exp_mod = new_modular.eval(ast_mod)
            tenv[sym] = exp_mod.type
            backend.remember_module(path, sym)
            return ignore(ir.Set(sym, exp_mod))
Beispiel #3
0
        def define(self, is_rec, name, annotated, bound):
            module = Express(self.clc)
            loc, name = sexpr.unloc(name)
            clc = self.clc
            outer_scope = clc.scope

            if is_rec:
                sym_def = outer_scope.require(name)
            else:
                sym_def = outer_scope.shadow(name)  # may shadow

            with clc.resume_scope():
                inner_scope = outer_scope.sub_scope()

                clc.scope = inner_scope
                if annotated:
                    t1 = infer(Typing(clc).eval(annotated))
                    if sym_def in tenv:
                        unify(inst(tenv[sym_def])[1], inst(t1)[1])
                    else:
                        tenv[sym_def] = t1
                else:
                    if sym_def in tenv:
                        t1 = infer(tenv[sym_def])
                    else:
                        new_var = tc_state.new_var(Var=types.Var,
                                                   loc=loc,
                                                   filename=clc.filename,
                                                   name=sym_def.name)
                        tenv[sym_def] = t1 = new_var

                level = tc_state.push_level()
                bound: ir.Expr = module.eval(bound)

                t1_inst = te.fresh(tc_state.new_var, infer(t1))
                t1_inst = inst(t1_inst, rigid=True)[1]

                t2_inst = bound.type = inst(infer(bound.type))[1]
                resolve_instance_(outer_scope, bound)
                unify(t1_inst, t2_inst)
                bound.type = generalise_type(tc_state,
                                             t2_inst,
                                             loc=loc,
                                             filename=clc.filename,
                                             level=level)

            unify(bound.type, t1)

            exp_def = ir.Set(sym_def, bound)
            return ignore(exp_def)
Beispiel #4
0
        def let(module, is_rec, seq, body):
            clc = module.clc
            with clc.resume_scope():
                outer_scope = clc.scope = clc.scope.sub_scope()
                types = []
                for loc, name, annotation, _ in seq:
                    if annotation:
                        type_bind = Typing(clc).eval(annotation)
                    else:
                        type_bind = new_var(clc, name)
                    types.append(type_bind)
                    if is_rec:
                        _, name = sexpr.unloc(name)
                        sym_bind = outer_scope.enter(name)
                        tenv[sym_bind] = type_bind

                block = []
                syms = []
                for (loc, name, annotation,
                     bound), sym_type in zip(seq, types):
                    _, name = sexpr.unloc(name)
                    level = tc_state.push_level()
                    inner_scope = clc.scope = outer_scope.sub_scope()
                    if is_rec:
                        sym_bind = inner_scope.require(name)
                    else:
                        sym_bind = inner_scope.enter(name)
                        tenv[sym_bind] = sym_type
                    syms.append(sym_bind)
                    t_inst = te.fresh(tc_state.new_var, sym_type)
                    t_inst = inst(t_inst, rigid=True)[1]
                    bound = module.eval_with_implicit(bound)
                    tc_state.unify(t_inst, bound.type)
                    gen_type = generalise_type(tc_state,
                                               t_inst,
                                               loc=loc,
                                               filename=clc.filename,
                                               level=level)
                    bound.type = gen_type

                    unify(gen_type, sym_type)
                    block.append(ignore(ir.Set(sym_bind, bound)))

                # level = tc_state.push_level()
                clc.scope = inner_scope.sub_scope()
                body = module.eval(body)
                # block.append(body)
                # body.type = generalise_type(tc_state, body.type, loc=clc.location, filename=clc.filename, level=level)
                return ir.Expr(type=body.type, expr=ir.Block(block))
Beispiel #5
0
        def type(module, typename, typedef):
            clc = module.clc
            path = clc.path
            loc, typename = sexpr.unloc(typename)
            qual_typename = '{}.{}'.format(path, typename)
            sym_typename = clc.scope.enter(typename)
            if typedef:
                # type alias
                nom_type = tc_state.infer(Typing(clc).eval(typedef))
            else:
                nom_type = types.Nom(qual_typename,
                                     loc=loc,
                                     filename=clc.filename)
            tenv[sym_typename] = te.App(types.type_type, nom_type)

            return wrap_loc(
                loc,
                ignore(
                    ir.Set(sym_typename,
                           ir.Expr(type=nom_type, expr=ir.Const(nom_type)))))
Beispiel #6
0
        def module(module_eval, is_rec, name, stmts, loc=None):
            loc, name = sexpr.unloc(name)
            clc = module_eval.clc
            scope = clc.scope
            filename = clc.filename
            path = clc.path = '.'.join(
                (*filter(None, clc.path.split('.')), name))

            # only for recursive modules.
            sym_mod: typing.Optional[Sym] = None

            # generated ir outside module;
            # only for recursive modules.
            outer_stmts: typing.List[ir.Expr] = []
            # generated ir for module itself
            inner_stmts: typing.List[ir.Expr] = []

            # type of module. will be a non-extensible record.
            type_mod = None

            # recursive module.
            if is_rec:
                sym_mod = scope.enter(name)
                new_var = tc_state.new_var(Var=types.Var,
                                           loc=loc,
                                           filename=filename,
                                           name=path)
                type_mod = tenv[sym_mod] = new_var
                outer_stmts.append(
                    ignore(ir.Set(sym_mod, ignore(ir.Const(())))))

            # for preprocessing
            # 1. recursive functions and
            # 2. type definitions.
            filter_stmts = []
            for stmt in stmts:
                _, stmt_unloc = sexpr.unloc(stmt)

                # type definition
                if stmt_unloc[0] is sexpr.type_k:
                    inner_stmts.append(module_eval.eval(stmt))
                    continue

                filter_stmts.append(stmt)
                if stmt_unloc[0] is sexpr.def_k:
                    if stmt_unloc[1]:
                        # Recursive definition. It's guaranteed to
                        # be a function in syntax level.
                        loc, n = sexpr.unloc(stmt_unloc[2])
                        sym = scope.enter(n)
                        tenv[sym] = tc_state.new_var(Var=types.Var,
                                                     loc=loc,
                                                     filename=filename,
                                                     name=n)

            for stmt in filter_stmts:
                inner_stmts.append(module_eval.eval(stmt))

            syms = [
                sym for sym in scope.get_newest_bounds() if sym is not sym_mod
            ]

            row_mod = te.row_from_list([(s.name, tenv[s]) for s in syms],
                                       te.empty_row)
            if type_mod:
                # recursive module
                tc_state.unify(type_mod, te.Record(row_mod))
            else:
                type_mod = te.Record(row_mod)

            elts_mod = [ir.Expr(type=tenv[sym], expr=sym) for sym in syms]
            elts_mod.sort(key=_sort_sym)

            val_mod = ir.Expr(type=type_mod,
                              expr=ir.Tuple([
                                  anyway(ir.Tuple(elts_mod)),
                                  anyway(ir.Tuple([]))
                              ]))
            inner_stmts.append(val_mod)

            exp_mod = ir.Expr(type=type_mod, expr=ir.Block(inner_stmts))

            if not is_rec:
                return exp_mod

            outer_stmts.append(ignore(ir.Set(sym_mod, exp_mod)))
            outer_stmts.append(ir.Expr(type=type_mod, expr=sym_mod))
            return ir.Expr(type=type_mod, expr=ir.Block(outer_stmts))