def m_let(block, args): if not isinstance(args[0], tuple): raise NoodleSyntaxError("bad let call; first arg must be tuple") if len(args) < 1: raise NoodleSyntaxError("empty let call") translator = block.push_var_translator() mynumber = unique_name() for vardef in args[0]: if not isinstance(vardef, tuple): raise NoodleSyntaxError( "bad let call; variable binding must be tuple" ) if len(vardef) != 2 or not isinstance(vardef[0], Symbol): raise NoodleSyntaxError( "bad let call; variable binding must be (identifier value)" ) name = vardef[0].name mungedname = mynumber + name translator[name] = mungedname for varname, varvalue in args[0]: block.compile_piece(varvalue) block.emit_store_name(varname.name, dup=False) begin(block, args[1:]) if block.pop_var_translator() is not translator: raise NoodleCompilerError("Unexpected var translator popped") return NoCompilation
def force_add_local(self, varname=None): if varname is None: varname = unique_name() varlist = self.loadscopes['local'][1] varlist.append(varname) return varname
def define_lambda(block, args, steps, codename='*lambda*'): given_posargs, func_defaultargs, func_vararg, func_kwarg = \ decode_function_arguments(args) func_posargs = [] codetuple = [Symbol('begin')] for element in given_posargs: if isinstance(element, tuple): specialname = Symbol(unique_name()) func_posargs.append(specialname) codetuple.append((Symbol('='), element, specialname)) else: if not isinstance(element, Symbol): raise NoodleSyntaxError( "Defined arguments to a function must be symbols" ) func_posargs.append(element) arglist = list([pos.name for pos in func_posargs]) codeflags = 0 for name, val in func_defaultargs: arglist.append(name.name) block.compile_piece(val) if func_vararg: arglist.append(func_vararg.name) codeflags |= 0x4 # uses *args syntax if func_kwarg: arglist.append(func_kwarg.name) codeflags |= 0x8 # uses **kwargs syntax # (final) stack changes to result from this MAKE_FUNCTION call. # Doesn't yet take into account free variables to be loaded and # consumed. block.stackmove(-len(func_defaultargs)) # docstring docstring = None if len(steps) > 0 and isinstance(steps[0], str): docstring = steps[0] steps = steps[1:] block.code.append(CreateSubBlock( block.subfunc( tuple(codetuple) + tuple(steps), firstlineno=block.curlineno, varnames=arglist, argcount=(len(func_posargs) + len(func_defaultargs)), codename=codename, codeflags=codeflags, docstring=docstring, nopassmacros={ codename: make_recursive_apply( codename, [n.name for n in func_posargs] + [p[0].name for p in tuple(func_defaultargs)] ), 'return': m_return, 'yield': m_yield } ), block, len(func_defaultargs) )) block.stackmove(1)
def m_gensym(block, args): return (Symbol('mksymbol'), unique_name())