예제 #1
0
파일: def.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):


        acode = element.code

        func_specs = acode[1].code

        assert isinstance(func_specs[0].code, Identifier)

        function_name = func_specs[0].code.full_name

        arguments = self.generate_arguments(*func_specs[1:], GC=GC)

        body_elements = acode[2:]

        body_code = []
        with GC.let(domain=SDom):
            for body_element in body_elements:
                extend_body(body_code, GC.generate(body_element))

        decorators_code = []

        returns_code = None

        return ast.FunctionDef(function_name, arguments, body_code,
                               decorators_code, returns_code)
예제 #2
0
    def generate(self, element: Element, GC: GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        target_iter_element = acode[1]
        target_element = target_iter_element.code[0]
        iter_element = target_iter_element.code[1]

        with GC.let(domain=LValueDomain):
            target_code = GC.generate(target_element)

        with GC.let(domain=ExpressionDomain):
            iter_code = GC.generate(iter_element)

        if is_form(acode.last, "else"):
            raise NotImplementedError()

        body_codes = []
        for e in acode[2:]:
            extend_body(body_codes, GC.generate(e))

        return ast.For(
            target=target_code,
            iter=iter_code,
            body=body_codes,
            orelse=[],
        )
예제 #3
0
파일: for.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        target_iter_element = acode[1]
        target_element = target_iter_element.code[0]
        iter_element = target_iter_element.code[1]

        with GC.let(domain=LValueDomain):
            target_code = GC.generate(target_element)

        with GC.let(domain=ExpressionDomain):
            iter_code = GC.generate(iter_element)

        if is_form(acode.last, "else"):
            raise NotImplementedError()

        body_codes = []
        for e in acode[2:]:
            extend_body(body_codes, GC.generate(e))


        return ast.For(target=target_code,
                      iter=iter_code,
                      body=body_codes,
                      orelse=[],
                      )
예제 #4
0
파일: quote.py 프로젝트: bloff/rmtc-parsing
    def generate_quote_ast(element:Element, GC:GenerationContext):

        # allow passing code instead of element?

        acode = element.code


        if isinstance(acode, Form) and is_identifier(acode[0], "~"):

            assert len(acode) == 2

            with GC.let(domain=ExpressionDomain):
                literal_value = GC.generate(acode[1])

            a = ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                            attr="force_literal",
                                            ctx=ast.Load()),
                         args=[literal_value],
                         keywords=[])

            return a


        elif isinstance(acode, Form) or isinstance(acode, Seq):

            #return __aky__.Form(*[akycode_to_ast(e) for e in acode])

            children_ast = [Quote.generate_quote_ast(e, GC) for e in acode]

            a = ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                            attr="Form" if isinstance(acode, Form) else "Seq",
                                            ctx=ast.Load()),
                         args=children_ast,
                         keywords=[])

            return a


        elif isinstance(acode, Identifier):

            return ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                            attr="Identifier", ctx=ast.Load()),
                            args=[ast.Str(acode.full_name)],
                            keywords=[])

        else:

            assert isinstance(acode, Literal)

            if acode.type is str:
                value_code = ast.Str(acode.value)
            else:
                assert acode.type in [int, float]
                value_code = ast.Num(acode.value)

            return ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                            attr="Literal", ctx=ast.Load()),
                            args=[value_code,
                                  ast.Name(id=acode.type.__name__, ctx=ast.Load())],
                            keywords=[])
예제 #5
0
    def generate(self, element:Element, GC:GenerationContext):

        assert GC.domain == ExDom

        acode = element.code
        #assert len(acode) == 3

        with GC.let(domain=ExDom):
            expression_code = GC.generate(acode[2])


        # INCOMPLETE:
        # vararg, kwarg, defaults, kw_defaults
        #
        # - This whole arg section might be way off-track
        # - since anything could be an argument, we might need to check
        #   when generating any expression if we actually need to return an ast.arg object
        #   ..or, could we convert everything (e.g. ast.Name, ast.BoolOp, anything)
        #   to an ast.arg after it's been generated

        args_codes = []
        #with GC.let(domain=ArgDom):
            # for a in acode[1]:
            #     # args_code should be a list of ast.arg objects!
            #     args_codes.append(GC.generate(a))




        arguments_code = ast.arguments(args_codes, )


        return ast.Lambda(arguments_code, expression_code)
예제 #6
0
파일: class.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code


        #name
        spec = acode[1]
        if isinstance(spec.code, Form):
            assert is_identifier(spec.code[0])
            class_name = spec.code[0].code.full_name

            with GC.let(domain=ExDom):
                base_classes_codes = []

                for base_class in spec.code[1:]:
                    extend_body(base_classes_codes, GC.generate(base_class))

        elif isinstance(spec.code, Identifier):
            class_name = spec.code.full_name
            base_classes_codes = []

        #keywords

        # "class keyword(arg, value)
        #  A keyword argument to a function call or class definition.
        #  arg is a raw string of the parameter name, value is a node to pass in."

        #starargs

        #kwargs


        body_elements = acode[3:]

        assert len(body_elements) > 0

        body_codes = []

        with GC.let(domain=StatementDomain):
            for body_statement in body_elements:
                extend_body(body_codes, GC.generate(body_statement))







        return ast.ClassDef(name=class_name,
                            bases=base_classes_codes,
                            keywords=[],
                            #starargs
                            #kwargs
                            body=body_codes,
                            decorator_list=[]
                            )
예제 #7
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        operand_element = acode[1]

        with GC.let(domain=ExDom):
            operand_code = GC.generate(operand_element)

        return expr_wrap(ast.UnaryOp(self.OP(), operand_code), GC)
예제 #8
0
    def generate_as_expressions(GC:GenerationContext, *args:Element):

        expr_codes = []

        with GC.let(domain=ExDom):

            for arg_element in args:
                expr_codes.append(GC.generate(arg_element))

        return expr_codes
예제 #9
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        operand_element = acode[1]

        with GC.let(domain=ExDom):
            operand_code = GC.generate(operand_element)

        return expr_wrap(ast.UnaryOp(self.OP(), operand_code), GC)
예제 #10
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        left_element, right_element = acode[1], acode[2]

        with GC.let(domain=ExDom):
            left_code = GC.generate(left_element)
            right_code = GC.generate(right_element)

        return expr_wrap(ast.BinOp(left_code, self.OP(), right_code), GC)
예제 #11
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        left_element, right_element = acode[1], acode[2]

        with GC.let(domain=ExDom):
            left_code = GC.generate(left_element)
            right_code = GC.generate(right_element)

        return expr_wrap(ast.BinOp(left_code, self.OP(), right_code), GC)
예제 #12
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code
        #assert isinstance(acode, Form)

        if len(acode) > 1:
            with GC.let(domain=ExDom):
                exception_obj_code = GC.generate(acode[1])

            return ast.Raise(exception_obj_code, None) # Fix none to allow raise x from y syntax

        else:
            assert len(acode) == 1
            return ast.Raise()
예제 #13
0
파일: yield.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):
        self.precheck(element, GC)

        acode = element.code

        if len(acode) == 1:
            return ast.Return(None)
        else:
            assert len(acode) == 2
            # TODO: return a, b, c => tuple

            with GC.let(domain=ExpressionDomain):
                expression_code = GC.generate(acode[1])

            return expr_wrap(ast.Yield(expression_code), GC)
예제 #14
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        #name
        spec = acode[1]
        if isinstance(spec.code, Form):
            assert is_identifier(spec.code[0])
            class_name = spec.code[0].code.full_name

            with GC.let(domain=ExDom):
                base_classes_codes = []

                for base_class in spec.code[1:]:
                    extend_body(base_classes_codes, GC.generate(base_class))

        elif isinstance(spec.code, Identifier):
            class_name = spec.code.full_name
            base_classes_codes = []

        #keywords

        # "class keyword(arg, value)
        #  A keyword argument to a function call or class definition.
        #  arg is a raw string of the parameter name, value is a node to pass in."

        #starargs

        #kwargs

        body_elements = acode[3:]

        assert len(body_elements) > 0

        body_codes = []

        with GC.let(domain=StatementDomain):
            for body_statement in body_elements:
                extend_body(body_codes, GC.generate(body_statement))

        return ast.ClassDef(
            name=class_name,
            bases=base_classes_codes,
            keywords=[],
            #starargs
            #kwargs
            body=body_codes,
            decorator_list=[])
예제 #15
0
    def generate(self, element: Element, GC: GenerationContext):

        assert GC.domain == SDom

        acode = element.code

        if len(acode) == 1:
            return ast.Return(None)
        else:
            assert len(acode) == 2
            # TODO: return a, b, c => tuple

            with GC.let(domain=ExpressionDomain):
                expression_code = GC.generate(acode[1])

            return ast.Return(expression_code)
예제 #16
0
    def generate(self, element:Element, GC:GenerationContext):

        assert GC.domain == SDom

        acode = element.code

        if len(acode) == 1:
            return ast.Return(None)
        else:
            assert len(acode) == 2
            # TODO: return a, b, c => tuple

            with GC.let(domain=ExpressionDomain):
                expression_code = GC.generate(acode[1])

            return ast.Return(expression_code)
예제 #17
0
    def begin(self, interactive=False, **kwargs) -> (GenerationContext, list):
        from anoky.generation.default_special_forms_table import default_special_forms_table
        context_root_bindings = Record(
            default_generator=self,
            generator=self,
            domain=SDom,
            special_forms=default_special_forms_table(),
            macros=default_macro_table(),
            id_macros=default_id_macro_table(),
            interactive=interactive)
        context_root_bindings.update(kwargs)

        GC = GenerationContext(**context_root_bindings.__dict__)
        initialization_nodes = []

        # Prepend anoky unit initialization code
        # Something like:
        # import anoky.importer as __akyimp__
        # import anoky.module as __aky__
        # __macros__ = {}
        # __id_macros__ = {}
        # __special_forms__ = {}

        from anoky.generation.stubs import akyimport_init_code as aic
        from anoky.generation.stubs import macrostore_init_code as mic
        initialization_nodes.extend(aic)
        initialization_nodes.extend(mic)

        return GC, initialization_nodes
예제 #18
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        with GC.let(domain=ExDom):
            base_object_code = GC.generate(acode[1])

        att_name = acode[2].code.full_name

        if GC.domain == LValueDomain:
            return ast.Attribute(base_object_code, att_name, ast.Store())

        elif GC.domain == DeletionDomain:
            return ast.Attribute(base_object_code, att_name, ast.Del())

        else:
            return expr_wrap(ast.Attribute(base_object_code, att_name, ast.Load()), GC)
예제 #19
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code
        #assert isinstance(acode, Form)

        # if acode[0].code.full_name == "and":
        #     op = ast.And()
        # else:
        #     assert acode[0].code.full_name == "or"
        #     op = ast.Or()

        juncts_code = []

        with GC.let(domain=ExDom):
            for e in acode[1:]:
                juncts_code.append(GC.generate(e))

        return expr_wrap(ast.BoolOp(self.OP(), juncts_code), GC)
예제 #20
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        with GC.let(domain=ExDom):
            base_object_code = GC.generate(acode[1])

        att_name = acode[2].code.full_name

        if GC.domain == LValueDomain:
            return ast.Attribute(base_object_code, att_name, ast.Store())

        elif GC.domain == DeletionDomain:
            return ast.Attribute(base_object_code, att_name, ast.Del())

        else:
            return expr_wrap(
                ast.Attribute(base_object_code, att_name, ast.Load()), GC)
예제 #21
0
    def generate(self, element: Element, GC: GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        test_element = acode[1]

        with GC.let(domain=ExDom):

            test_code = GC.generate(test_element)

            msg_code = None
            if len(acode) > 2:
                msg_element = acode[2]
                msg_code = GC.generate(msg_element)

        return ast.Assert(test=test_code, msg=msg_code)
예제 #22
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code
        #assert isinstance(acode, Form)

        # if acode[0].code.full_name == "and":
        #     op = ast.And()
        # else:
        #     assert acode[0].code.full_name == "or"
        #     op = ast.Or()

        juncts_code = []

        with GC.let(domain=ExDom):
            for e in acode[1:]:
                juncts_code.append(GC.generate(e))

        return expr_wrap(ast.BoolOp(self.OP(), juncts_code), GC)
예제 #23
0
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        test_element = acode[1]

        with GC.let(domain=ExDom):

            test_code = GC.generate(test_element)

            msg_code = None
            if len(acode) > 2:
                msg_element = acode[2]
                msg_code = GC.generate(msg_element)


        return ast.Assert(test=test_code, msg=msg_code)
예제 #24
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        assert len(acode) == 3
        # target_element = acode[1]
        # augvalue_element = acode[2]

        with GC.let(domain=LVDom):
            # "target can be Name, Subscript or Attribute,
            #  but not a Tuple or List (unlike the targets of Assign)."

            target_code = GC.generate(acode[1])

        with GC.let(domain=ExDom):
            augvalue_code = GC.generate(acode[2])


        return ast.AugAssign(target_code, type(self).OP(), augvalue_code)
예제 #25
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        with GC.let(domain=ExDom):
            base_object_code = GC.generate(acode[1])


        # (.. )
        if is_form(acode[2], ".."):
            #slice
            raise NotImplementedError()

        #if isinstance(acode[2].code, Literal):
        else:
            with GC.let(domain=ExDom):
                index_code = GC.generate(acode[2])

            return expr_wrap(ast.Subscript(base_object_code,
                                 ast.Index(index_code),
                                 ast.Store() if GC.domain == LVDom else ast.Load()), GC)
예제 #26
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        if len(acode) == 2:
            arg = acode[1]

            with GC.let(domain=ExDom):
                arg_code = GC.generate(arg)

            return expr_wrap(ast.UnaryOp(op=ast.USub(), operand=arg_code), GC)

        else:
            assert len(acode) == 3

            left_element, right_element = acode[1], acode[2]

            with GC.let(domain=ExDom):
                left_code = GC.generate(left_element)
                right_code = GC.generate(right_element)

            return expr_wrap(ast.BinOp(left_code, ast.Sub(), right_code), GC)
예제 #27
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        if len(acode) == 2:
            arg = acode[1]

            with GC.let(domain=ExDom):
                arg_code = GC.generate(arg)

            return expr_wrap(ast.UnaryOp(op=ast.USub(), operand=arg_code), GC)

        else:
            assert len(acode) == 3

            left_element, right_element = acode[1], acode[2]

            with GC.let(domain=ExDom):
                left_code = GC.generate(left_element)
                right_code = GC.generate(right_element)

            return expr_wrap(ast.BinOp(left_code, ast.Sub(), right_code), GC)
예제 #28
0
파일: while.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        testexpr_element = acode[1]

        with GC.let(domain=ExpressionDomain):

            testexpr_code = GC.generate(testexpr_element)

        if is_form(element.next, "else"):
            raise NotImplementedError()

        body_codes = []
        for e in acode[2:]:
            extend_body(body_codes, GC.generate(e))

        return ast.While(test=testexpr_code,
                         body=body_codes,
                         orelse=[])
예제 #29
0
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        operands_seq = acode.last.code

        first_operand = operands_seq[0]

        with GC.let(domain = ExpressionDomain):
            first_operand_gen = GC.generate(first_operand)

            ops = [self.OPERAND_DICT[e.code.name]() for e in acode[1:-1]]
            comparators = [GC.generate(operand) for operand in operands_seq.iterate_from(1)]

        return expr_wrap(
            ast.Compare(
                left = first_operand_gen,
                ops = ops,
                comparators = comparators
            ), GC)
예제 #30
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        imports_list = []
        import_statements = []

        with GC.let(domain=ExDom):

            for import_element in acode[1:]:

                if _is_module_path(import_element):
                    to_import_name = _get_module_path(import_element)
                    imports_list.append(ast.alias(name=to_import_name, asname=None))

                elif is_form(import_element.code, "as"):
                    to_import_name = _get_module_path(import_element.code[1])
                    to_import_asname = _get_name(import_element.code[2])

                    imports_list.append(ast.alias(name=to_import_name,
                                                  asname=to_import_asname))
                elif is_form(import_element.code) or is_seq(import_element.code):
                    to_import_module_name = _get_module_path(import_element.code[0])
                    imported_names_from_module = []

                    for to_import_item_element in import_element.code[1:]:

                        if is_identifier(to_import_item_element):
                            to_import_name = _get_name(to_import_item_element)
                            imported_names_from_module.append(ast.alias(name=to_import_name, asname=None))

                        elif is_form(to_import_item_element.code, "as"):
                            to_import_name = _get_name(to_import_item_element.code[1])
                            to_import_asname = _get_name(to_import_item_element.code[2])
                            imported_names_from_module.append(ast.alias(name=to_import_name,
                                                          asname=to_import_asname))
                    import_statements.append(ast.ImportFrom(to_import_module_name, imported_names_from_module, 0))
                else:
                    raise CodeGenerationError(import_element.range, "Special form `import` expected an import specifier but found `%s`."
                                                                    "For example:"
                                                                    "```"
                                                                    "import"
                                                                    "   a.b.c"
                                                                    "   x.y.z as name"
                                                                    "   u.v.w( var1, var2 as v )"
                                                                    "```" % succinct_lisp_printer(import_element))

        if len(imports_list) > 0:
            import_statements.append(ast.Import(imports_list))
        return import_statements
예제 #31
0
    def generate(self, element: Element, GC: GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        operands_seq = acode.last.code

        first_operand = operands_seq[0]

        with GC.let(domain=ExpressionDomain):
            first_operand_gen = GC.generate(first_operand)

            ops = [self.OPERAND_DICT[e.code.name]() for e in acode[1:-1]]
            comparators = [
                GC.generate(operand)
                for operand in operands_seq.iterate_from(1)
            ]

        return expr_wrap(
            ast.Compare(left=first_operand_gen,
                        ops=ops,
                        comparators=comparators), GC)
예제 #32
0
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        targets_element = acode[1]
        value_element = acode.last


        # if not isinstance(targets, Seq):
        #     # targets is only one target
        #
        #     with GC.let(domain=LVDom):
        #         target_code = GC.generate(targets)

        with GC.let(domain=LVDom):
            targets_code = GC.generate(targets_element)

        with GC.let(domain=ExDom):
            value_code = GC.generate(value_element)


        return ast.Assign(targets=[targets_code], value=value_code)
예제 #33
0
    def generate(self, element:Element, GC:GenerationContext):


        acode = element.code

        if len(acode) is 2 and is_form(acode[1], "for"):

            for_form = acode[1].code

            # list comprehension

            # («[]» (for (in i lst) (f i))) # list compr

            in_el = for_form[1]
            in_el_code = in_el.code

            #with GC.let(domain=ExDom):

            assert is_identifier(in_el, "in")

            target_element = in_el_code[1]
            iter_element = in_el_code[2]

            with GC.let(domain=LVDom):
                target_code = GC.generate(target_element)

            with GC.let(domain=ExDom):
                iter_code = GC.generate(iter_element)



            generators = [ ast.comprehension(target=target_code,
                                             iter=iter_code,
                                             ifs=[]) ]


            to_evaluate_element = for_form[2]

            with GC.let(domain=ExDom):

                to_evaluate_code = GC.generate(to_evaluate_element)


            return ast.ListComp(to_evaluate_code, generators)


        else:

            els = self.generate_as_expressions(GC, *acode[1:])

            if GC.domain == LVDom:
                return ast.List(els, ast.Store())
            return expr_wrap(ast.List(els, ast.Load()), GC)
예제 #34
0
파일: with.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        context_element = acode[1]
        context_element_code = context_element.code
        assert len(context_element_code) > 0

        with_items = []

        with GC.let(domain=ExpressionDomain):

            for ctxel in context_element_code:


                if is_form(ctxel.code, "as"):

                    ctxelcode = ctxel.code

                    assert len(ctxel) == 3
                    ctx_expr = GC.generate(ctxelcode[1])

                    opt_var = GC.generate(ctxelcode[2])

                    with_items.append(ast.withitem(context_expr=ctx_expr,
                                                   optional_vars=opt_var))

                else:

                    ctx_expr = GC.generate(ctxel)

                    with_items.append(ast.withitem(context_expr=ctx_expr,
                                                   optional_vars=None))

            body_items = []

            with GC.let(domain=SDom):

                for bodyel in acode[2:]:
                    extend_body(body_items, GC.generate(bodyel))


        return ast.With(items=with_items,
                        body=body_items)
예제 #35
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        context_element = acode[1]
        context_element_code = context_element.code
        assert len(context_element_code) > 0

        with_items = []

        with GC.let(domain=ExpressionDomain):

            for ctxel in context_element_code:

                if is_form(ctxel.code, "as"):

                    ctxelcode = ctxel.code

                    assert len(ctxel) == 3
                    ctx_expr = GC.generate(ctxelcode[1])

                    opt_var = GC.generate(ctxelcode[2])

                    with_items.append(
                        ast.withitem(context_expr=ctx_expr,
                                     optional_vars=opt_var))

                else:

                    ctx_expr = GC.generate(ctxel)

                    with_items.append(
                        ast.withitem(context_expr=ctx_expr,
                                     optional_vars=None))

            body_items = []

            with GC.let(domain=SDom):

                for bodyel in acode[2:]:
                    extend_body(body_items, GC.generate(bodyel))

        return ast.With(items=with_items, body=body_items)
예제 #36
0
파일: quote.py 프로젝트: bloff/rmtc-parsing
    def generate_quote_ast(element: Element, GC: GenerationContext):

        # allow passing code instead of element?

        acode = element.code

        if isinstance(acode, Form) and is_identifier(acode[0], "~"):

            assert len(acode) == 2

            with GC.let(domain=ExpressionDomain):
                literal_value = GC.generate(acode[1])

            a = ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__",
                                                           ctx=ast.Load()),
                                            attr="force_literal",
                                            ctx=ast.Load()),
                         args=[literal_value],
                         keywords=[])

            return a

        elif isinstance(acode, Form) or isinstance(acode, Seq):

            #return __aky__.Form(*[akycode_to_ast(e) for e in acode])

            children_ast = [Quote.generate_quote_ast(e, GC) for e in acode]

            a = ast.Call(func=ast.Attribute(
                value=ast.Name(id="__aky__", ctx=ast.Load()),
                attr="Form" if isinstance(acode, Form) else "Seq",
                ctx=ast.Load()),
                         args=children_ast,
                         keywords=[])

            return a

        elif isinstance(acode, Identifier):

            return ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__",
                                                              ctx=ast.Load()),
                                               attr="Identifier",
                                               ctx=ast.Load()),
                            args=[ast.Str(acode.full_name)],
                            keywords=[])

        else:

            assert isinstance(acode, Literal)

            if acode.type is str:
                value_code = ast.Str(acode.value)
            else:
                assert acode.type in [int, float]
                value_code = ast.Num(acode.value)

            return ast.Call(func=ast.Attribute(value=ast.Name(id="__aky__",
                                                              ctx=ast.Load()),
                                               attr="Literal",
                                               ctx=ast.Load()),
                            args=[
                                value_code,
                                ast.Name(id=acode.type.__name__,
                                         ctx=ast.Load())
                            ],
                            keywords=[])
예제 #37
0
파일: if.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        # "Check that form is as above"
        #assert


        if GC.domain == ExDom:
            astIf = ast.IfExp
            if len(acode) > 3 and not (is_form(acode[3], 'elif') or is_form(acode[3], 'else')):
                raise CodeGenerationError(acode.range, "If expression must only have a single sub-expression (for now).")
        else:
            astIf = ast.If



        def gen_elif_elses(elif_else_elm):
            my_code = elif_else_elm.code
            if is_form(elif_else_elm, 'elif'):
                with GC.let(domain=ExDom):
                    my_condition_gen = GC.generate(my_code[1])

                my_body_gens = []
                for body_elm in my_code.iterate_from(2):
                    extend_body(my_body_gens, GC.generate(body_elm))

                if elif_else_elm.next is None:
                    return [astIf(my_condition_gen, my_body_gens, [])]
                else:
                    else_code = gen_elif_elses(elif_else_elm.next)
                    return [astIf(my_condition_gen, my_body_gens, else_code)]
            elif is_form(elif_else_elm, 'else'):
                my_body_gens = []
                for body_elm in my_code.iterate_from(1):
                    extend_body(my_body_gens, GC.generate(body_elm))
                return my_body_gens
            else:
                raise CodeGenerationError(elif_else_elm.range,
                                          "Unexpected element `%s` after first `elif` or `else` form within `if` form." % (
                                          succinct_lisp_printer(elif_else_elm)))

        with GC.let(domain=ExDom):
            condition_gen = GC.generate(acode[1])
        body_gens = []
        else_code = []

        for body_elm in acode.iterate_from(2):
            if is_form(body_elm, 'elif') or is_form(body_elm, 'else'):
                else_code = gen_elif_elses(body_elm)
                break
            else:
                body_gen = GC.generate(body_elm)
                extend_body(body_gens, body_gen)

        if len(body_gens) == 0: body_gens.append(ast.Pass())


        if GC.domain == ExDom:
            return ast.IfExp(condition_gen, body_gens[0], else_code[0] if len(else_code) > 0 else ast.NameConstant(None))
        else:
            return ast.If(condition_gen, body_gens, else_code)
예제 #38
0
파일: def.py 프로젝트: bloff/rmtc-parsing
    def generate_arguments(self, *params, GC:GenerationContext):

        poststar = False

        argslist = []
        kwonlyargslist = []
        vararg = None
        kwarg = None
        defaults = []
        kw_defaults = []

        for param_element in params:

            param_code = param_element.code

            if isinstance(param_code, Identifier) and param_code.full_name == '*':

                poststar = True


            elif isinstance(param_code, Identifier):
                # arg

                arg_object = ast.arg(arg=param_code.full_name, annotation=None)

                #if self.vararg is not None or self.kwarg is not None:
                if poststar:
                    # argument is keyword-only

                    kwonlyargslist.append(arg_object)

                else:

                    assert not poststar

                    argslist.append(arg_object)



            elif isinstance(param_code, Form):

                #assert isinstance(param_code[0].code, Identifier) and
                if param_code[0].code.full_name == '=':
                    # (= arg initializer)

                    assert len(param_code) == 3

                    with GC.let(domain=ExDom):
                        initializer_code = GC.generate(param_code[2])

                    assert isinstance(param_code[1].code, Identifier)
                    arg_object = ast.arg(arg=param_code[1].code.full_name, annotation=None)

                    if poststar:

                        kwonlyargslist.append(arg_object)
                        kw_defaults.append(initializer_code)

                    else:

                        argslist.append(arg_object)
                        defaults.append(initializer_code)


                elif param_code[0].code.full_name == '*':
                    # (* arg)

                    #assert isinstance(param_code[1].code, Identifier)

                    starg = ast.arg(arg=param_code[1].code.full_name, annotation=None)

                    assert vararg is None

                    vararg = starg

                    poststar = True




                else:
                    assert param_code[0].code.full_name == '**'
                    # (** arg)

                    #assert isinstance(param_code[1].code, Identifier)

                    dblstarg = ast.arg(arg=param_code[1].code.full_name, annotation=None)

                    assert kwarg is None

                    kwarg = dblstarg

                    poststar = True





            else:
                # (type, arg)
                # (type, (= arg initializer))
                # (type, (* arg))
                # (type, (** arg))

                #assert isinstance(param_code, Seq)

                annotation_element = param_code[0]

                # if isinstance(annotation_code, Identifier):
                #     annotation = ast.Name(id=annotation_code.full_name, ctx=ast.Load())
                #
                # elif isinstance(annotation_code, Literal):
                #     annotation =

                with GC.let(domain=ExDom):
                    annotation_code = GC.generate(annotation_element)

                # and now the arg itself..

                param_code = param_code[1].code

                if isinstance(param_code, Identifier):

                    #assert param_code.full_name != '*'

                    arg_object = ast.arg(arg=param_code.full_name, annotation=annotation_code)

                    if poststar:

                        kwonlyargslist.append(arg_object)

                    else:

                        argslist.append(arg_object)


                else:

                    assert isinstance(param_code, Form)

                    #assert isinstance(param_code[0].code, Identifier) and
                    if param_code[0].code.full_name == '=':
                        # (= arg initializer)

                        assert len(param_code) == 3

                        with GC.let(domain=ExDom):
                            initializer_code = GC.generate(param_code[2])

                        assert isinstance(param_code[1].code, Identifier)
                        arg_object = ast.arg(arg=param_code[1].full_name, annotation=annotation_code)

                        if poststar:

                            kwonlyargslist.append(arg_object)
                            kw_defaults.append(initializer_code)

                        else:

                            argslist.append(arg_object)
                            defaults.append(initializer_code)





                    elif param_code[0].code.full_name == '*':
                        # (* arg)

                        #assert isinstance(param_code[1].code, Identifier)

                        starg = ast.arg(arg=param_code[1].code.full_name, annotation=annotation_code)

                        assert vararg is None

                        vararg = starg

                        poststar = True




                    else:
                        assert param_code[0].code.full_name == '**'
                        # (** arg)

                        #assert isinstance(param_code[1].code, Identifier)

                        dblstarg = ast.arg(arg=param_code[1].code.full_name, annotation=annotation_code)

                        assert kwarg is None

                        kwarg = dblstarg

                        poststar = True





        return ast.arguments(args=argslist, vararg=vararg, kwonlyargs=kwonlyargslist,
                             kwarg=kwarg, defaults=defaults, kw_defaults=kw_defaults)
예제 #39
0
    def generate(self, element:Element, GC:GenerationContext):


        acode = element.code

        head = acode[0].code
        assert isinstance(head, Identifier)
        headtext = head.full_name


        if len(acode) is 2 and is_form(acode[1].code, "for"):


            ccode = acode[1].code
            assert len(ccode) == 3

            target_iter_element = ccode[1]
            expr_element = ccode[2]

            with GC.let(domain=LVDom):
                target_code = GC.generate(target_iter_element.code[1])

            with GC.let(domain=ExDom):
                iter_code = GC.generate(target_iter_element.code[2])

                comp_code = ast.comprehension(target=target_code,
                                              iter=iter_code,
                                              ifs=[])

                if is_form(expr_element.code, "="):
                    # dict comp
                    key_code = GC.generate(expr_element.code[1])
                    value_code = GC.generate(expr_element.code[2])

                    return ast.DictComp(key=key_code, value=value_code,
                                        generators=[comp_code])

                else:
                    # set comp
                    elt_code = GC.generate(expr_element)

                    return ast.SetComp(elt=elt_code, generators=[comp_code])


        else:

            if len(acode) is 1:

                return ast.Dict([], [])


            if all([is_form(i.code, "=") for i in acode[1:]]):

                #dict

                keys = []
                values = []

                with GC.let(domain=ExDom):

                    for kvpair_el in acode[1:]:

                        kvpair = kvpair_el.code

                        key_code = GC.generate(kvpair[1])
                        value_code = GC.generate(kvpair[2])

                        keys.append(key_code)
                        values.append(value_code)

                return expr_wrap(ast.Dict(keys, values), GC)

            else:

                #set

                el_codes = self.generate_as_expressions(GC, *acode[1:])

                return expr_wrap(ast.Set(el_codes), GC)
예제 #40
0
    def generate(self, element: Element, GC: GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        # "Check that form is as above"
        #assert

        if GC.domain == ExDom:
            astIf = ast.IfExp
            if len(acode) > 3 and not (is_form(acode[3], 'elif')
                                       or is_form(acode[3], 'else')):
                raise CodeGenerationError(
                    acode.range,
                    "If expression must only have a single sub-expression (for now)."
                )
        else:
            astIf = ast.If

        def gen_elif_elses(elif_else_elm):
            my_code = elif_else_elm.code
            if is_form(elif_else_elm, 'elif'):
                with GC.let(domain=ExDom):
                    my_condition_gen = GC.generate(my_code[1])

                my_body_gens = []
                for body_elm in my_code.iterate_from(2):
                    extend_body(my_body_gens, GC.generate(body_elm))

                if elif_else_elm.next is None:
                    return [astIf(my_condition_gen, my_body_gens, [])]
                else:
                    else_code = gen_elif_elses(elif_else_elm.next)
                    return [astIf(my_condition_gen, my_body_gens, else_code)]
            elif is_form(elif_else_elm, 'else'):
                my_body_gens = []
                for body_elm in my_code.iterate_from(1):
                    extend_body(my_body_gens, GC.generate(body_elm))
                return my_body_gens
            else:
                raise CodeGenerationError(
                    elif_else_elm.range,
                    "Unexpected element `%s` after first `elif` or `else` form within `if` form."
                    % (succinct_lisp_printer(elif_else_elm)))

        with GC.let(domain=ExDom):
            condition_gen = GC.generate(acode[1])
        body_gens = []
        else_code = []

        for body_elm in acode.iterate_from(2):
            if is_form(body_elm, 'elif') or is_form(body_elm, 'else'):
                else_code = gen_elif_elses(body_elm)
                break
            else:
                body_gen = GC.generate(body_elm)
                extend_body(body_gens, body_gen)

        if len(body_gens) == 0: body_gens.append(ast.Pass())

        if GC.domain == ExDom:
            return ast.IfExp(
                condition_gen, body_gens[0],
                else_code[0] if len(else_code) > 0 else ast.NameConstant(None))
        else:
            return ast.If(condition_gen, body_gens, else_code)
예제 #41
0
파일: try.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element: Element, GC: GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        # "Check that form is as above"
        #assert

        def gen_except_handler(except_elm):
            my_code = except_elm.code
            exception_elm = my_code[1]
            name = None
            if is_form(exception_elm, 'as'):
                with GC.let(domain=ExpressionDomain):
                    my_exception_type = GC.generate(exception_elm.code[1])
                my_exception_name_id = exception_elm.code[2]
                if not is_identifier(my_exception_name_id):
                    raise CodeGenerationError(
                        my_exception_name_id.range,
                        "Expected an identifier as exception name of `except` clause in `try` special-form."
                    )
                name = my_exception_name_id.code.name
            else:
                with GC.let(domain=ExpressionDomain):
                    my_exception_type = GC.generate(exception_elm)

            body_gens = []
            for my_body_elm in my_code.iterate_from(2):
                extend_body(body_gens, GC.generate(my_body_elm))

            return ast.ExceptHandler(my_exception_type, name, body_gens)

        body_gens, handlers, or_else, finally_body = [], [], None, None
        stage = 0  # 0 = body, 1 = except, 2 = else, 3 = finally
        names = {1: "except", 2: "else", 3: "finally"}
        for body_elm in acode.iterate_from(1):
            if is_form(body_elm, 'except'):
                if stage > 1:
                    raise CodeGenerationError(
                        body_elm.range,
                        "Found `except` clause after first `%s` in `try` special form."
                        % names[stage])
                else:
                    stage = 1
                except_handler = gen_except_handler(body_elm)
                handlers.append(except_handler)
            elif is_form(body_elm, 'else'):
                if stage > 1:
                    raise CodeGenerationError(
                        body_elm.range,
                        "Found `except` clause after first `%s` in `try` special form."
                        % names[stage])
                else:
                    stage = 2
                or_else = [
                    GC.generate(my_body_elm)
                    for my_body_elm in body_elm.code.iterate_from(1)
                ]
            elif is_form(body_elm, 'finally'):
                if stage > 2:
                    raise CodeGenerationError(
                        body_elm.range,
                        "Found `except` clause after first `%s` in `try` special form."
                        % names[stage])
                else:
                    stage = 3
                finally_body = []
                for my_body_elm in body_elm.code.iterate_from(1):
                    extend_body(finally_body, GC.generate(my_body_elm))
            else:
                if stage > 0:
                    raise CodeGenerationError(
                        body_elm.range,
                        "Found body clause after first `%s` in `try` special form."
                        % names[stage])
                body_gen = GC.generate(body_elm)
                extend_body(body_gens, body_gen)

        return ast.Try(body_gens, handlers, or_else, finally_body)
예제 #42
0
    def generate(self, element, GC:GenerationContext):

        from anoky.generation.util import expr_wrap

        acode = element.code

        if isinstance(acode, Form):

            head = acode.first
            headcode = head.code

            if isinstance(headcode, Identifier) and headcode.full_name in GC.special_forms:

                    head.color = colors.SPECIAL_FORM

                    hcname = headcode.full_name

                    special_form = GC.special_forms[hcname]

                    generated_code = special_form.generate(element, GC)

                    return generated_code



            else:
                # function call
                # #(func arg1 arg2 arg3 ...)

                func_element = head
                #func_element_code = headcode

                with GC.let(domain=ExDom):
                    func_code = GC.generate(func_element)

                arg_elements = acode[1:]

                args = []
                keywords = []

                for arg_element in arg_elements:
                    arg_element_code = arg_element.code

                    if isinstance(arg_element_code, Form):
                        if is_form(arg_element_code, '='):
                            # keyword argument

                            kw_name = arg_element_code[1].code.full_name

                            with GC.let(domain=ExDom):
                                value_code = GC.generate(arg_element_code[2])

                            keywords.append(ast.keyword(kw_name, value_code))


                        elif is_form(arg_element_code, '*') and len(arg_element_code) == 2:
                            # stared argument - expand as list
                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element_code[1])
                            args.append(ast.Starred(arg_code, ast.Load()))

                        elif is_form(arg_element_code, '**') and len(arg_element_code) == 2:
                            # double starred argument - expand as kwlist

                            assert len(arg_element_code) == 2
                            # verify no other dblstars already?

                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element_code[1])

                            keywords.append(ast.keyword(None, arg_code))


                        else:
                            # positional argument

                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element)

                            args.append(arg_code)

                    else:
                        # arg_element_code not a Form
                        # then generate as expression

                        with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element)

                        args.append(arg_code)

                return expr_wrap(ast.Call(func_code, args, keywords), GC)



        if isinstance(acode, Seq):
            seq_codes = []
            with GC.let(domain=ExDom):
                for e in acode:
                    seq_codes.append(GC.generate(e))

            if GC.domain == LVDom:
                return ast.Tuple(seq_codes, ast.Store())
            elif GC.domain in [ExDom, SDom]:
                return expr_wrap(ast.Tuple(seq_codes, ast.Load()), GC)
            else:
                raise CodeGenerationError(acode.range, "Unexpected seq in domain `%s`." % str(GC.domain))



        if isinstance(acode, Literal):
            element.color = colors.LITERAL

            if acode.type is str:
                return expr_wrap(ast.Str(acode.value), GC)
            elif acode.type in [int, float]:
                return expr_wrap(ast.Num(acode.value), GC)
            else:
                assert False



        if isinstance(acode, Identifier):

            if acode.full_name == "True":
                return expr_wrap(ast.NameConstant(True), GC)

            elif acode.full_name == "False":
                return expr_wrap(ast.NameConstant(False), GC)

            elif acode.full_name == "None":
                return expr_wrap(ast.NameConstant(None), GC)

            elif acode.full_name in GC.special_forms:
                element.color = colors.SPECIAL_FORM
                raise CodeGenerationError(acode.range, "Refering to special form `%s` by name requires the use of `the`." % acode.full_name)
            # elif acode.full_name in GC.macros:
            #     raise CodeGenerationError(acode.range,
            #                               "Refering to macro `%s` by name requires the use of `the`." % acode.full_name)
            # elif acode.full_name in GC.id_macros:
            #     raise CodeGenerationError(acode.range,
            #                               "Refering to identifier macro `%s` by name requires the use of `the`." % acode.full_name)


            elif GC.domain == LVDom:
                return ast.Name(acode.full_name, ast.Store())

            elif GC.domain == DelDom:
                return ast.Name(acode.full_name, ast.Del())

            else:
                return expr_wrap(ast.Name(acode.full_name, ast.Load()), GC)
예제 #43
0
    def generate(self, element, GC: GenerationContext):

        from anoky.generation.util import expr_wrap

        acode = element.code

        if isinstance(acode, Form):

            head = acode.first
            headcode = head.code

            if isinstance(
                    headcode,
                    Identifier) and headcode.full_name in GC.special_forms:

                head.color = colors.SPECIAL_FORM

                hcname = headcode.full_name

                special_form = GC.special_forms[hcname]

                generated_code = special_form.generate(element, GC)

                return generated_code

            else:
                # function call
                # #(func arg1 arg2 arg3 ...)

                func_element = head
                #func_element_code = headcode

                with GC.let(domain=ExDom):
                    func_code = GC.generate(func_element)

                arg_elements = acode[1:]

                args = []
                keywords = []

                for arg_element in arg_elements:
                    arg_element_code = arg_element.code

                    if isinstance(arg_element_code, Form):
                        if is_form(arg_element_code, '='):
                            # keyword argument

                            kw_name = arg_element_code[1].code.full_name

                            with GC.let(domain=ExDom):
                                value_code = GC.generate(arg_element_code[2])

                            keywords.append(ast.keyword(kw_name, value_code))

                        elif is_form(arg_element_code,
                                     '*') and len(arg_element_code) == 2:
                            # stared argument - expand as list
                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element_code[1])
                            args.append(ast.Starred(arg_code, ast.Load()))

                        elif is_form(arg_element_code,
                                     '**') and len(arg_element_code) == 2:
                            # double starred argument - expand as kwlist

                            assert len(arg_element_code) == 2
                            # verify no other dblstars already?

                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element_code[1])

                            keywords.append(ast.keyword(None, arg_code))

                        else:
                            # positional argument

                            with GC.let(domain=ExDom):
                                arg_code = GC.generate(arg_element)

                            args.append(arg_code)

                    else:
                        # arg_element_code not a Form
                        # then generate as expression

                        with GC.let(domain=ExDom):
                            arg_code = GC.generate(arg_element)

                        args.append(arg_code)

                return expr_wrap(ast.Call(func_code, args, keywords), GC)

        if isinstance(acode, Seq):
            seq_codes = []
            with GC.let(domain=ExDom):
                for e in acode:
                    seq_codes.append(GC.generate(e))

            if GC.domain == LVDom:
                return ast.Tuple(seq_codes, ast.Store())
            elif GC.domain in [ExDom, SDom]:
                return expr_wrap(ast.Tuple(seq_codes, ast.Load()), GC)
            else:
                raise CodeGenerationError(
                    acode.range,
                    "Unexpected seq in domain `%s`." % str(GC.domain))

        if isinstance(acode, Literal):
            element.color = colors.LITERAL

            if acode.type is str:
                return expr_wrap(ast.Str(acode.value), GC)
            elif acode.type in [int, float]:
                return expr_wrap(ast.Num(acode.value), GC)
            else:
                assert False

        if isinstance(acode, Identifier):

            if acode.full_name == "True":
                return expr_wrap(ast.NameConstant(True), GC)

            elif acode.full_name == "False":
                return expr_wrap(ast.NameConstant(False), GC)

            elif acode.full_name == "None":
                return expr_wrap(ast.NameConstant(None), GC)

            elif acode.full_name in GC.special_forms:
                element.color = colors.SPECIAL_FORM
                raise CodeGenerationError(
                    acode.range,
                    "Refering to special form `%s` by name requires the use of `the`."
                    % acode.full_name)
            # elif acode.full_name in GC.macros:
            #     raise CodeGenerationError(acode.range,
            #                               "Refering to macro `%s` by name requires the use of `the`." % acode.full_name)
            # elif acode.full_name in GC.id_macros:
            #     raise CodeGenerationError(acode.range,
            #                               "Refering to identifier macro `%s` by name requires the use of `the`." % acode.full_name)

            elif GC.domain == LVDom:
                return ast.Name(acode.full_name, ast.Store())

            elif GC.domain == DelDom:
                return ast.Name(acode.full_name, ast.Del())

            else:
                return expr_wrap(ast.Name(acode.full_name, ast.Load()), GC)
예제 #44
0
파일: try.py 프로젝트: bloff/rmtc-parsing
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)

        acode = element.code

        # "Check that form is as above"
        #assert





        def gen_except_handler(except_elm):
            my_code = except_elm.code
            exception_elm = my_code[1]
            name = None
            if is_form(exception_elm, 'as'):
                with GC.let(domain=ExpressionDomain):
                    my_exception_type = GC.generate(exception_elm.code[1])
                my_exception_name_id = exception_elm.code[2]
                if not is_identifier(my_exception_name_id):
                    raise CodeGenerationError(my_exception_name_id.range, "Expected an identifier as exception name of `except` clause in `try` special-form.")
                name = my_exception_name_id.code.name
            else:
                with GC.let(domain=ExpressionDomain):
                    my_exception_type = GC.generate(exception_elm)

            body_gens = []
            for my_body_elm in my_code.iterate_from(2):
                extend_body(body_gens, GC.generate(my_body_elm))

            return ast.ExceptHandler(my_exception_type, name, body_gens)





        body_gens, handlers, or_else, finally_body = [], [], None, None
        stage = 0 # 0 = body, 1 = except, 2 = else, 3 = finally
        names = {1: "except", 2: "else", 3: "finally"}
        for body_elm in acode.iterate_from(1):
            if is_form(body_elm, 'except'):
                if stage > 1: raise CodeGenerationError(body_elm.range, "Found `except` clause after first `%s` in `try` special form." % names[stage])
                else: stage = 1
                except_handler = gen_except_handler(body_elm)
                handlers.append(except_handler)
            elif is_form(body_elm, 'else'):
                if stage > 1: raise CodeGenerationError(body_elm.range, "Found `except` clause after first `%s` in `try` special form." % names[stage])
                else: stage = 2
                or_else = [GC.generate(my_body_elm) for my_body_elm in body_elm.code.iterate_from(1)]
            elif is_form(body_elm, 'finally'):
                if stage > 2: raise CodeGenerationError(body_elm.range, "Found `except` clause after first `%s` in `try` special form." % names[stage])
                else: stage = 3
                finally_body = []
                for my_body_elm in body_elm.code.iterate_from(1):
                    extend_body(finally_body, GC.generate(my_body_elm))
            else:
                if stage > 0: raise CodeGenerationError(body_elm.range, "Found body clause after first `%s` in `try` special form." % names[stage])
                body_gen = GC.generate(body_elm)
                extend_body(body_gens, body_gen)


        return ast.Try(body_gens, handlers, or_else, finally_body)
예제 #45
0
    def generate(self, element: Element, GC: GenerationContext):

        acode = element.code

        imports_list = []
        import_statements = []

        with GC.let(domain=ExDom):

            for import_element in acode[1:]:

                if _is_module_path(import_element):
                    to_import_name = _get_module_path(import_element)
                    imports_list.append(
                        ast.alias(name=to_import_name, asname=None))

                elif is_form(import_element.code, "as"):
                    to_import_name = _get_module_path(import_element.code[1])
                    to_import_asname = _get_name(import_element.code[2])

                    imports_list.append(
                        ast.alias(name=to_import_name,
                                  asname=to_import_asname))
                elif is_form(import_element.code) or is_seq(
                        import_element.code):
                    to_import_module_name = _get_module_path(
                        import_element.code[0])
                    imported_names_from_module = []

                    for to_import_item_element in import_element.code[1:]:

                        if is_identifier(to_import_item_element):
                            to_import_name = _get_name(to_import_item_element)
                            imported_names_from_module.append(
                                ast.alias(name=to_import_name, asname=None))

                        elif is_form(to_import_item_element.code, "as"):
                            to_import_name = _get_name(
                                to_import_item_element.code[1])
                            to_import_asname = _get_name(
                                to_import_item_element.code[2])
                            imported_names_from_module.append(
                                ast.alias(name=to_import_name,
                                          asname=to_import_asname))
                    import_statements.append(
                        ast.ImportFrom(to_import_module_name,
                                       imported_names_from_module, 0))
                else:
                    raise CodeGenerationError(
                        import_element.range,
                        "Special form `import` expected an import specifier but found `%s`."
                        "For example:"
                        "```"
                        "import"
                        "   a.b.c"
                        "   x.y.z as name"
                        "   u.v.w( var1, var2 as v )"
                        "```" % succinct_lisp_printer(import_element))

        if len(imports_list) > 0:
            import_statements.append(ast.Import(imports_list))
        return import_statements
예제 #46
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code



        sf_name_element = acode[1]

        sf_name = sf_name_element.code.full_name
        sf_name_safe = "__specialform_"+sf_name+"__"



        rawexpand = acode[2].code

        rawexpand_header = rawexpand[0].code
        assert is_identifier(rawexpand_header[0], "expand")

        assert is_identifier(rawexpand_header[1])
        rawexpand_element_param = rawexpand_header[1].code.full_name

        assert is_identifier(rawexpand_header[2])
        rawexpand_context_param = rawexpand_header[2].code.full_name


        expand_body_elements = rawexpand[1:]
        expand_body_code = []
        for b in expand_body_elements:
            extend_body(expand_body_code, GC.generate(b))
        # The... second-to-last form? of the original element should be
        #  responsible for generating (i.e. should return) code that will
        #  complete the macro expansion;
        #  the final statement executed in an .expand method would actually
        #  be doing the replacing


        expand_args_code = ast.arguments(
            args=[ast.arg(arg="self"),
                  ast.arg(arg=rawexpand_element_param,
                          annotation=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="Element", ctx=ast.Load())),
                  ast.arg(arg=rawexpand_context_param,
                          annotation=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="ExpansionContext", ctx=ast.Load()))],
            kwonlyargs=[], defaults=[], kw_defaults=[]
        )



        expand_method_code = ast.FunctionDef(name="expand",
                                             args=expand_args_code,
                                             body=expand_body_code,
                                             decorator_list=[]
                                             )





        rawgenerate = acode[3].code

        rawgenerate_header = rawgenerate[0].code
        assert is_identifier(rawgenerate_header[0], "generate")

        assert is_identifier(rawgenerate_header[1])
        rawgenerate_element_param = rawgenerate_header[1].code.full_name

        assert is_identifier(rawgenerate_header[2])
        rawgenerate_context_param = rawgenerate_header[2].code.full_name

        generate_body_elements = rawgenerate[1:]

        generate_body_code = []
        for b in generate_body_elements:
            extend_body(generate_body_code, GC.generate(b))


        generate_args_code = ast.arguments(
            args=[ast.arg(arg="self"),
                  ast.arg(arg=rawgenerate_element_param,
                          annotation=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="Element", ctx=ast.Load())),
                  ast.arg(arg=rawgenerate_context_param,
                          annotation=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="GenerationContext", ctx=ast.Load()))],
            kwonlyargs=[], defaults=[], kw_defaults=[]
        )



        generate_method_code = ast.FunctionDef(name="generate",
                                             args=generate_args_code,
                                             body=generate_body_code,
                                             decorator_list=[]
                                             )


        class_body_code = []

        extend_body(class_body_code,ast.Import([ast.alias(name="anoky.module", asname="__aky__")]))

        extend_body(class_body_code, ast.Assign(targets=[ast.Name(id="HEADTEXT",
                                                            ctx=ast.Store())],
                                          value=ast.Str(sf_name)))

        extend_body(class_body_code, expand_method_code)
        extend_body(class_body_code, generate_method_code)




        classdef_code = ast.ClassDef(
                name=sf_name_safe,
                bases=[ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="SpecialForm", ctx=ast.Load())],
                keywords=[], decorator_list=[],
                body=class_body_code)


        # __specialform_sf_name__()
        instantiate_macro_code = ast.Call(func=ast.Name(id=sf_name_safe, ctx=ast.Load()),
                                          args=[], keywords=[])

        # EC.macro_table[sf_name]
        expansion_context_code = ast.Subscript(
                value=ast.Attribute(value=ast.Name(id="EC", ctx=ast.Load()),
                                    attr="macro_table", ctx=ast.Load()),
                slice=ast.Index(ast.Str(sf_name)), ctx=ast.Store())

        # GC.special_forms[sf_name]
        generation_context_code = ast.Subscript(
                value=ast.Attribute(value=ast.Name(id="GC", ctx=ast.Load()),
                                    attr="special_forms", ctx=ast.Load()),
                slice=ast.Index(ast.Str(sf_name)), ctx=ast.Store())


        # __special_forms__[sf_name] = EC.macro_table[sf_name] \
        #   = GC.special_forms[sf_name] = __specialform_sf_name__()
        register_macro_code = ast.Assign(targets=[
            ast.Subscript(value=ast.Name(id="__special_forms__", ctx=ast.Load()),
                          slice=ast.Index(ast.Str(sf_name)),
                          ctx=ast.Store()),
        #    expansion_context_code,
        #    generation_context_code
        ],
                                         value=instantiate_macro_code)


        generated_code = [classdef_code, register_macro_code]

        return generated_code
예제 #47
0
    def generate(self, element:Element, GC:GenerationContext):

        acode = element.code

        rawspecs = acode[1].code

        macro_name_element = rawspecs[0]

        macro_name = rawspecs[0].code.full_name
        macro_name_safe = "__macro_"+macro_name+"__"


        rawspec_element_param = rawspecs[1].code.full_name

        rawspec_context_param = rawspecs[2].code.full_name




        expand_body_elements = acode[2:]

        expand_body_code = []
        for b in expand_body_elements:
            extend_body(expand_body_code, GC.generate(b))
        # The... second-to-last form? of the original element should be
        #  responsible for generating (i.e. should return) code that will
        #  complete the macro expansion;
        #  the final statement executed in an .expand method would actually
        #  be doing the replacing
        #
        final_body_code = expand_body_code[-1]
        # element.replace(final_body_code)
        #ast.Call( ... )


        expand_args_code = ast.arguments(
            args=[ast.arg(arg="self"),
                  ast.arg(arg=rawspec_element_param,
                          annotation=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="Element", ctx=ast.Load())),
                  ast.arg(arg=rawspec_context_param,
                          annotation=ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="ExpansionContext", ctx=ast.Load()))],
            kwonlyargs=[], defaults=[], kw_defaults=[]
        )



        expand_method_code = ast.FunctionDef(name="expand",
                                             args=expand_args_code,
                                             body=expand_body_code,
                                             decorator_list=[]
                                             )



        class_body_code = []

        # extend_body(class_body_code, ast.Import([ast.alias(name="anoky.module", asname="__aky__")]))

        extend_body(class_body_code, ast.Assign(targets=[ast.Name(id="HEADTEXT",
                                                            ctx=ast.Store())],
                                          value=ast.Str(macro_name)))

        extend_body(class_body_code, expand_method_code)





        classdef_code = ast.ClassDef(
                name=macro_name_safe,
                bases=[ast.Attribute(value=ast.Name(id="__aky__", ctx=ast.Load()),
                                     attr="Macro", ctx=ast.Load())],
                keywords=[], decorator_list=[],
                body=class_body_code)


        # __macros_macro_name__()
        instantiate_macro_code = ast.Call(func=ast.Name(id=macro_name_safe, ctx=ast.Load()),
                                          args=[], keywords=[])

        # EC.macro_table[macro_name]
        context_code = ast.Subscript(
                value=ast.Attribute(value=ast.Name(id="EC", ctx=ast.Load()),
                                    attr="macro_table", ctx=ast.Load()),
                slice=ast.Index(ast.Str(macro_name)), ctx=ast.Store())


        # __macros__[macro_name] = EC.macro_table[macro_name] = __macros_macro_name__()
        register_macro_code = ast.Assign(targets=[
            ast.Subscript(value=ast.Name(id="__macros__", ctx=ast.Load()),
                          slice=ast.Index(ast.Str(macro_name)),
                          ctx=ast.Store()),
        #    context_code
        ],
                                         value=instantiate_macro_code)


        generated_code = [classdef_code, register_macro_code]

        return generated_code