def compile(self, source, filepath, initial_lineno=1, symtable=None): if symtable is None: symtable = SymbolTable() astnode = self.parse(source, initial_lineno=initial_lineno, symtable=symtable) ctx = CompilerContext(self, "<main>", symtable, filepath) with ctx.set_lineno(initial_lineno): astnode.compile(ctx) return ctx.create_bytecode([], [], None, None)
def compile(self, source, filepath, initial_lineno=1, symtable=None): if symtable is None: symtable = SymbolTable() astnode = self.parse( source, initial_lineno=initial_lineno, symtable=symtable) ctx = CompilerContext(self, "<main>", symtable, filepath) with ctx.set_lineno(initial_lineno): try: astnode.compile(ctx) except CompilerError as e: raise self.error(self.w_SyntaxError, "%s" % e.msg) return ctx.create_bytecode(initial_lineno, [], [], None, None)
def compile(self, ctx): blockname = "block in %s" % ctx.code_name block_ctx = ctx.get_subctx(blockname, self) for cellname, kind in block_ctx.symtable.cells.iteritems(): if kind == block_ctx.symtable.CELLVAR: block_ctx.symtable.get_cell_num(cellname) block_args = [] defaults = [] for arg in self.block_args: assert isinstance(arg, Argument) block_args.append(arg.name) block_ctx.symtable.get_cell_num(arg.name) if arg.defl is not None: arg_ctx = CompilerContext(ctx.space, blockname, block_ctx.symtable, ctx.filepath) arg.defl.compile(arg_ctx) arg_ctx.emit(consts.RETURN) bc = arg_ctx.create_bytecode([], [], None, None) defaults.append(bc) if self.splat_arg is not None: block_ctx.symtable.get_cell_num(self.splat_arg) if self.block_arg is not None: block_ctx.symtable.get_cell_num(self.block_arg) for name in ctx.symtable.cells: if (name not in block_ctx.symtable.cell_numbers and name not in block_ctx.symtable.cells): block_ctx.symtable.cells[name] = block_ctx.symtable.FREEVAR self.block.compile(block_ctx) block_ctx.emit(consts.RETURN) bc = block_ctx.create_bytecode(block_args, defaults, self.splat_arg, self.block_arg) ctx.emit(consts.LOAD_CONST, ctx.create_const(bc)) cells = [None] * len(block_ctx.symtable.cell_numbers) for name, pos in block_ctx.symtable.cell_numbers.iteritems(): cells[pos] = name num_cells = 0 for i in xrange(len(cells) - 1, -1, -1): name = cells[i] if block_ctx.symtable.cells[name] == block_ctx.symtable.FREEVAR: ctx.emit(consts.LOAD_CLOSURE, ctx.symtable.get_cell_num(name)) num_cells += 1 ctx.emit(consts.BUILD_BLOCK, num_cells)
def compile(self, ctx): function_ctx = ctx.get_subctx(self.name, self) defaults = [] arg_names = [] for arg in self.args: assert isinstance(arg, Argument) arg_names.append(arg.name) function_ctx.symtable.get_cell_num(arg.name) arg_ctx = CompilerContext(ctx.space, self.name, function_ctx.symtable, ctx.filepath) if arg.defl is not None: arg.defl.compile(arg_ctx) arg_ctx.emit(consts.RETURN) bc = arg_ctx.create_bytecode([], [], None, None) defaults.append(bc) if self.splat_arg is not None: function_ctx.symtable.get_cell_num(self.splat_arg) if self.block_arg is not None: function_ctx.symtable.get_cell_num(self.block_arg) self.body.compile(function_ctx) function_ctx.emit(consts.RETURN) bytecode = function_ctx.create_bytecode(arg_names, defaults, self.splat_arg, self.block_arg) if self.parent is None: ctx.emit(consts.LOAD_SCOPE) else: self.parent.compile(ctx) ctx.emit(consts.LOAD_CONST, ctx.create_symbol_const(self.name)) ctx.emit(consts.LOAD_CONST, ctx.create_symbol_const(self.name)) ctx.emit(consts.LOAD_CONST, ctx.create_const(bytecode)) ctx.emit(consts.BUILD_FUNCTION) if self.parent is None: ctx.emit(consts.DEFINE_FUNCTION) else: ctx.emit(consts.ATTACH_FUNCTION)
def compile(self, ctx): function_ctx = ctx.get_subctx(self.name, self) defaults = [] arg_names = [] for arg in self.args: assert isinstance(arg, Argument) arg_names.append(arg.name) function_ctx.symtable.get_cell_num(arg.name) arg_ctx = CompilerContext(ctx.space, self.name, function_ctx.symtable, ctx.filepath) if arg.defl is not None: arg.defl.compile(arg_ctx) arg_ctx.emit(consts.RETURN) bc = arg_ctx.create_bytecode([], [], None, None) defaults.append(bc) if self.splat_arg is not None: function_ctx.symtable.get_cell_num(self.splat_arg) if self.block_arg is not None: function_ctx.symtable.get_cell_num(self.block_arg) self.body.compile(function_ctx) function_ctx.emit(consts.RETURN) bytecode = function_ctx.create_bytecode( arg_names, defaults, self.splat_arg, self.block_arg ) if self.parent is None: ctx.emit(consts.LOAD_SCOPE) else: self.parent.compile(ctx) ctx.emit(consts.LOAD_CONST, ctx.create_symbol_const(self.name)) ctx.emit(consts.LOAD_CONST, ctx.create_symbol_const(self.name)) ctx.emit(consts.LOAD_CONST, ctx.create_const(bytecode)) ctx.emit(consts.BUILD_FUNCTION) if self.parent is None: ctx.emit(consts.DEFINE_FUNCTION) else: ctx.emit(consts.ATTACH_FUNCTION)
def compile_bytecode(self, ctx, code_ctx, args, splat_arg, post_args, kwargs, kwrest_arg, block_arg, body): ctxname = self.get_code_name(ctx) arg_names = [] arg_defaults = [] kw_arg_names = [] kw_defaults = [] first_default_arg = None for arg in args: assert isinstance(arg, Argument) if arg.defl is None: arg_names.append(arg.name) code_ctx.symtable.get_cell_num(arg.name) for arg in args: assert isinstance(arg, Argument) if arg.defl is not None: arg_names.append(arg.name) code_ctx.symtable.get_cell_num(arg.name) if first_default_arg is None: first_default_arg = arg.name arg_ctx = CompilerContext(ctx.space, ctxname, code_ctx.symtable, ctx.filepath) arg.defl.compile(arg_ctx) arg_ctx.emit(consts.RETURN) bc = arg_ctx.create_bytecode() arg_defaults.append(bc) if splat_arg is not None: code_ctx.symtable.get_cell_num(splat_arg) for arg in post_args: assert isinstance(arg, Argument) arg_names.append(arg.name) code_ctx.symtable.get_cell_num(arg.name) assert arg.defl is None # this sorting of kwargs with defaults first is important for arg # handling in frame.py for arg in kwargs: assert isinstance(arg, Argument) if arg.defl is not None: code_ctx.symtable.get_cell_num(arg.name) arg_ctx = CompilerContext(ctx.space, ctxname, code_ctx.symtable, ctx.filepath) arg.defl.compile(arg_ctx) arg_ctx.emit(consts.RETURN) bc = arg_ctx.create_bytecode() kw_defaults.append(bc) for arg in kwargs: assert isinstance(arg, Argument) code_ctx.symtable.get_cell_num(arg.name) kw_arg_names.append(arg.name) if kwrest_arg is not None: code_ctx.symtable.get_cell_num(kwrest_arg) if block_arg is not None: code_ctx.symtable.get_cell_num(block_arg) self.post_process_ctx(ctx, code_ctx) body.compile(code_ctx) code_ctx.emit(consts.RETURN) return code_ctx.create_bytecode( lineno=self.lineno, args=arg_names, defaults=arg_defaults, first_default_arg=first_default_arg, splat_arg=splat_arg, kwargs=kw_arg_names, kw_defaults=kw_defaults, kwrest_arg=kwrest_arg, block_arg=block_arg, )