Example #1
0
        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)))
Example #2
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
Example #3
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=[],
        )
Example #4
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=[],
                      )
Example #5
0
def _get_module_path(element:Element) -> str:
    if not _is_module_path(element):
            raise CodeGenerationError(element.range, "Expected a module path (`a.b.c`) , but found `%s`." % succinct_lisp_printer(element))
    elif is_identifier(element):
        return element.code.full_name # TODO: name mangling?
    elif is_form(element, '.'):
        return _get_module_path(element.code[1]) + "." + _get_module_path(element.code[2])
 def applies(self, element:Element):
     #  p [ + ] n
     return (is_identifier(element.code) and
             identifier_in(element.code, self.sym_vals) and
             not element.is_first() and
             not element.is_last() and
             not is_form(element.parent, self.head_symbol_name))
 def applies(self, element:Element):
     next = element.next
     return (
         next is not None and
         (not (element.is_first() and is_form(element.parent)) or not next.is_last()) and
         is_identifier(element) and
         element.code.name in self.token_vals and
         is_not_none(element, ".range.position_after.index", next, ".range.first_position.index") and
         element.code.range.position_after.index == next.code.range.first_position.index
     )
 def applies(self, element: Element):
     next = element.next
     return (next is not None
             and (not (element.is_first() and is_form(element.parent))
                  or not next.is_last()) and is_identifier(element)
             and element.code.name in self.token_vals
             and is_not_none(element, ".range.position_after.index", next,
                             ".range.first_position.index")
             and element.code.range.position_after.index
             == next.code.range.first_position.index)
Example #9
0
    def expand_inner_escapes(element: Element, EC: ExpansionContext):
        aquote = element.code
        # If we have a quote escape, expand sub-elements
        if is_form(aquote, "~"):
            assert len(aquote) == 2
            EC.expand(aquote[1])

        # otherwise, recurse on nodes, ignore the rest
        elif isinstance(aquote, Node):
            for e in aquote:
                Quote.expand_inner_escapes(e, EC)
Example #10
0
def _get_module_path(element: Element) -> str:
    if not _is_module_path(element):
        raise CodeGenerationError(
            element.range,
            "Expected a module path (`a.b.c`) , but found `%s`." %
            succinct_lisp_printer(element))
    elif is_identifier(element):
        return element.code.full_name  # TODO: name mangling?
    elif is_form(element, '.'):
        return _get_module_path(element.code[1]) + "." + _get_module_path(
            element.code[2])
Example #11
0
    def expand_inner_escapes(element:Element, EC:ExpansionContext):
        aquote = element.code
        # If we have a quote escape, expand sub-elements
        if is_form(aquote, "~"):
            assert len(aquote) == 2
            EC.expand(aquote[1])

        # otherwise, recurse on nodes, ignore the rest
        elif isinstance(aquote, Node):
            for e in aquote:
                Quote.expand_inner_escapes(e, EC)
Example #12
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)
    def generate(self, element:Element, GC:GenerationContext):

        self.precheck(element, GC)
        head_name = element.code[0].code.name

        if not is_form(element.prev) or not identifier_in(element.prev.code[0], self.expected_names):
            raise CodeGenerationError(element.code[0].range, "`%s` form must appear after %s." % (head_name, self.expected_names))

        if GC.domain == ExpressionDomain:
            return expr_wrap(ast.NameConstant(None), GC)
        else:
            return []
Example #14
0
    def apply(self, element:Element):
        form = element.parent
        next_form_element = element.next
        while next_form_element is not None:
            interesting_form = any( is_form(next_form_element, form_head) for form_head in self.following_names)
            if not interesting_form: break
            form.remove(next_form_element)
            element.code.append(next_form_element)
            next_form_element = element.next


        return element.next
Example #15
0
    def apply(self, element: Element):
        form = element.parent
        next_form_element = element.next
        while next_form_element is not None:
            interesting_form = any(
                is_form(next_form_element, form_head)
                for form_head in self.following_names)
            if not interesting_form: break
            form.remove(next_form_element)
            element.code.append(next_form_element)
            next_form_element = element.next

        return element.next
    def generate(self, element: Element, GC: GenerationContext):

        self.precheck(element, GC)
        head_name = element.code[0].code.name

        if not is_form(element.prev) or not identifier_in(
                element.prev.code[0], self.expected_names):
            raise CodeGenerationError(
                element.code[0].range, "`%s` form must appear after %s." %
                (head_name, self.expected_names))

        if GC.domain == ExpressionDomain:
            return expr_wrap(ast.NameConstant(None), GC)
        else:
            return []
Example #17
0
        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)))
Example #18
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)
Example #19
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)
Example #20
0
        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)
Example #21
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)
    def applies(self, element:Element):
        def _is_identifier_or_literal_immediately_after(next, element):
            return ((is_identifier(next) or is_literal(next)) and
                is_not_none(next, ".code.range.first_position.index") and
                element.code.range.position_after.index == next.code.range.first_position.index)

        def _is_begin_macro_token_immediately_after(next, element):
            return (is_token(next, Tokens.BEGIN_MACRO) and
                is_not_none(next, ".range.first_position.index") and
                element.code.range.position_after.index == next.range.first_position.index)

        next = element.next
        return (
            next is not None and
            (not (element.is_first() and is_form(element.parent)) or not next.is_last()) and
            is_identifier(element) and
            identifier_in(element.code, self.sym_vals) and
            is_not_none(element, ".code.range.position_after.index") and
            (_is_identifier_or_literal_immediately_after(next, element) or
             _is_begin_macro_token_immediately_after(next, element))
        )
Example #23
0
    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=[])
    def applies(self, element: Element):
        def _is_identifier_or_literal_immediately_after(next, element):
            return ((is_identifier(next) or is_literal(next))
                    and is_not_none(next, ".code.range.first_position.index")
                    and element.code.range.position_after.index
                    == next.code.range.first_position.index)

        def _is_begin_macro_token_immediately_after(next, element):
            return (is_token(next, Tokens.BEGIN_MACRO)
                    and is_not_none(next, ".range.first_position.index")
                    and element.code.range.position_after.index
                    == next.range.first_position.index)

        next = element.next
        return (next is not None
                and (not (element.is_first() and is_form(element.parent))
                     or not next.is_last()) and is_identifier(element)
                and identifier_in(element.code, self.sym_vals)
                and is_not_none(element, ".code.range.position_after.index")
                and
                (_is_identifier_or_literal_immediately_after(next, element)
                 or _is_begin_macro_token_immediately_after(next, element)))
Example #25
0
        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)
Example #26
0
 def apply(self, element):
     form = element.parent
     next = element.next  # this is 'b'
     prev = element.prev  # this is 'a'
     if is_identifier(next) or is_literal(next) or is_form(next):
         new_form_element = form.wrap(prev, next, Form)
     elif is_token(next, Tokens.BEGIN_MACRO):
         # a . BEGIN_MACRO something END_MACRO dont want => (. a BEGIN_MACRO) something END_MACRO
         # actually want
         # a . BEGIN_MACRO something END_MACRO => (. a BEGIN_MACRO something END_MACRO)
         new_form_element = form.wrap(prev, next.end, Form)
     else:
         raise ArrangementError(
             element.range.position_after,
             "Expected identifier, literal, form or begin-macro-token after '%s' in position %s."
             %
             (element.code.name, element.range.first_position.nameless_str))
     new_form = new_form_element.code
     # at this point new_form = ⦅a X b⦆
     new_form.remove(element)
     # at this point new_form = ⦅a b⦆
     new_form.prepend(element)
     # at this point new_form = ⦅X a b⦆
     return new_form_element.next  # return the next position to be read
Example #27
0
 def applies(self, element: Element):
     #  p [ + ] n
     return (is_identifier(element.code)
             and identifier_in(element.code, self.sym_vals)
             and not element.is_first() and not element.is_last()
             and not is_form(element.parent, self.head_symbol_name))
Example #28
0
def _is_module_path(element:Element) -> bool:
    return is_identifier(element) or \
               is_form(element, ".") and \
               len(element.code) == 3 and \
               _is_module_path(element.code[1]) and \
               is_identifier(element.code[2])
Example #29
0
 def applies(self, element: Element):
     return is_form(element.code) and is_identifier(element.code.head) and element.code.head.code.full_name in self.form_heads
Example #30
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)
Example #31
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)
Example #32
0
    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)
Example #33
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)
Example #34
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)
Example #35
0
def _is_module_path(element: Element) -> bool:
    return is_identifier(element) or \
               is_form(element, ".") and \
               len(element.code) == 3 and \
               _is_module_path(element.code[1]) and \
               is_identifier(element.code[2])
Example #36
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)
Example #37
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
Example #38
0
    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)
Example #39
0
 def applies(self, element: Element):
     return is_form(element.code, "for")