def expand(self, element: Element, EC: ExpansionContext): acode = element.code for import_element in acode[1:]: if is_identifier(import_element): to_import_name = import_element.code.full_name try: module = importlib.import_module(to_import_name) macros = module.__macros__ EC.macros.update(macros) id_macros = module.__id_macros__ EC.id_macros.update(id_macros) special_forms = module.__special_forms__ EC.special_forms.update(special_forms) except Exception as e: traceback.print_exc() raise CodeGenerationError( import_element.range, "Failed to meta-import module `%s`." % to_import_name) else: raise CodeGenerationError( import_element.range, "Special form `meta-import` expected a module pathbut found `%s`." % succinct_lisp_printer(import_element)) return
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 _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 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
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 _get_name(element:Element): if not is_identifier(element): raise SyntaxError(element.range, "Expected a module name , but found `%s`." % succinct_lisp_printer(element)) return element.code.full_name
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 expand(self, element:Element, EC:ExpansionContext): acode = element.code for import_element in acode[1:]: if is_identifier(import_element): to_import_name = import_element.code.full_name try: module = importlib.import_module(to_import_name) macros = module.__macros__ EC.macros.update(macros) id_macros = module.__id_macros__ EC.id_macros.update(id_macros) special_forms = module.__special_forms__ EC.special_forms.update(special_forms) except Exception as e: traceback.print_exc() raise CodeGenerationError(import_element.range, "Failed to meta-import module `%s`." % to_import_name) else: raise CodeGenerationError(import_element.range, "Special form `meta-import` expected a module pathbut found `%s`." % succinct_lisp_printer( import_element)) return
def _get_name(element: Element): if not is_identifier(element): raise SyntaxError( element.range, "Expected a module name , but found `%s`." % succinct_lisp_printer(element)) return element.code.full_name
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