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)))
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)
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=[], )
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=[], )
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=[] )
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=[])
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)
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)
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)
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 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)
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)))
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)
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
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
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)
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)
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)