示例#1
0
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
示例#2
0
 def force_add_local(self, varname=None):
     if varname is None:
         varname = unique_name()
     varlist = self.loadscopes['local'][1]
     varlist.append(varname)
     return varname
示例#3
0
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)
示例#4
0
def m_gensym(block, args):
    return (Symbol('mksymbol'), unique_name())