Пример #1
0
def prim_loop(compiler, src):
    if src[2] != lisp.Symbol("<-"):
        raise SyntaxError, src[:3]
    loop_binding = src[1]
    loop_init = src[3]
    loop_body = src[4:]

    loop_name = pycode.name("loop")
    context.curr().setdefault("LOOP_STACK", []).append(loop_name)

    tpl = (
        "%s = $#\n" % (loop_name,)
        + "while True:\n"
        + "  try:\n"
        + "    $#\n"
        + "  except _ME:\n"
        + "    break\n"
        + "  $#\n"
        + "  break\n"
        + loop_name
    )

    output_code = pycode.create(
        tpl,
        compiler.compile(loop_init),
        compiler.compile((lisp.Symbol("="), loop_binding, lisp.Symbol(loop_name))),
        compiler.compile_block(loop_body, loop_name),
    )
    context.curr()["LOOP_STACK"].pop()
    return output_code
Пример #2
0
def prim_loop(compiler, src):
    if src[2] != lisp.Symbol('<-'):
	raise SyntaxError, src[:3]
    loop_binding = src[1]
    loop_init = src[3]
    loop_body = src[4:]
    
    loop_name = pycode.name('loop')
    context.curr().setdefault('LOOP_STACK', []).append(loop_name)

    tpl = \
	    '%s = $#\n' % (loop_name,) + \
	    'while True:\n' + \
	    '  try:\n' + \
	    '    $#\n' + \
	    '  except _ME:\n' + \
	    '    break\n' + \
	    '  $#\n' + \
	    '  break\n' + \
	    loop_name

    output_code = pycode.create(
	    tpl,
	    compiler.compile(loop_init),
	    compiler.compile((lisp.Symbol('='), loop_binding, lisp.Symbol(loop_name))),
	    compiler.compile_block(loop_body, loop_name))
    context.curr()['LOOP_STACK'].pop()
    return output_code
Пример #3
0
def prim_for(compiler, src):
    if lisp.Symbol('<-') != src[2]:
        raise SyntaxError(src[:3])

    matcher = src[1]
    datasource = src[3]
    body = src[4:]

    queue_name = pycode.name('for_queue')
    context.curr().setdefault('FOR_STACK', []).append(queue_name)

    if type(matcher) is lisp.Symbol:
        tpl = '%s = []\nfor %s in $#:\n  %s.append($#)\n%s' % (
            queue_name, matcher.name, queue_name, queue_name)
        datasource_code = compiler.compile(datasource)
        if body:
            body_code = compiler.compile((lisp.Symbol('env'), matcher) + body)
        else:
            body_code = pycode.create(matcher.name)
        output_code = pycode.create(tpl, datasource_code, body_code)
    else:
        datasource_code = compiler.compile(datasource)
        if datasource_code.value == '_':
            datasource_code = datasource.asname(pycode.name())

        for_var = pycode.name('for_var')
        proc_compiler = proc.Compiler(compiler)
        matcher_code = proc_compiler.compile(for_var, matcher)

        tpl = \
         '%s = []\n' % (queue_name,) + \
         'for %s in $#:\n' % (for_var,) + \
         '  try:\n' + \
         '    $#\n' + \
         '  except _ME, e:\n' + \
         '    continue\n' + \
         '  %s.append($#)\n' % (queue_name,) + \
         queue_name

        if body:
            body_code = compiler.compile((lisp.Symbol('env'),
                                          lisp.Symbol(matcher_code.value)) +
                                         body)
        else:
            body_code = pycode.create(matcher_code.value)
        output_code = pycode.create(tpl, datasource_code, matcher_code,
                                    body_code)
    context.curr()['FOR_STACK'].pop()
    return output_code
Пример #4
0
def name(prefix = 'tmp'):
    """Assign name in current context"""
    nameidx = context.curr().setdefault('NAME_INDEX', {})
    idx = nameidx.setdefault(prefix, 0)
    name = '_%s_%d' % (prefix, idx)
    nameidx[prefix] = idx + 1
    return name
Пример #5
0
def prim_break(compiler, src):
    if len(src) == 1:
	return pycode.create('break\nNone')
    loop_name = context.curr()['LOOP_STACK'][-1]
    return pycode.create(
	    '%s = $#\nbreak\n%s' % (loop_name, loop_name),
	    compiler.compile(src[1]))
Пример #6
0
def name(prefix='tmp'):
    """Assign name in current context"""
    nameidx = context.curr().setdefault('NAME_INDEX', {})
    idx = nameidx.setdefault(prefix, 0)
    name = '_%s_%d' % (prefix, idx)
    nameidx[prefix] = idx + 1
    return name
Пример #7
0
def prim_for(compiler, src):
    if lisp.Symbol('<-') != src[2]:
	raise SyntaxError(src[:3])

    matcher = src[1]
    datasource = src[3]
    body = src[4:]

    queue_name = pycode.name('for_queue')
    context.curr().setdefault('FOR_STACK', []).append(queue_name)

    if type(matcher) is lisp.Symbol:
	tpl = '%s = []\nfor %s in $#:\n  %s.append($#)\n%s' % (
		queue_name, matcher.name, queue_name, queue_name)
	datasource_code = compiler.compile(datasource)
	if body:
	    body_code = compiler.compile((lisp.Symbol('env'), matcher) + body)
	else:
	    body_code = pycode.create(matcher.name)
	output_code = pycode.create(tpl, datasource_code, body_code)
    else:
	datasource_code = compiler.compile(datasource)
	if datasource_code.value == '_':
	    datasource_code = datasource.asname(pycode.name())
	
	for_var = pycode.name('for_var')
	proc_compiler = proc.Compiler(compiler)
	matcher_code = proc_compiler.compile(for_var, matcher)

	tpl = \
		'%s = []\n' % (queue_name,) + \
		'for %s in $#:\n' % (for_var,) + \
		'  try:\n' + \
		'    $#\n' + \
		'  except _ME, e:\n' + \
		'    continue\n' + \
		'  %s.append($#)\n' % (queue_name,) + \
		queue_name

	if body:
	    body_code = compiler.compile(
		    (lisp.Symbol('env'), lisp.Symbol(matcher_code.value)) + body)
	else:
	    body_code = pycode.create(matcher_code.value)
	output_code = pycode.create(tpl, datasource_code, matcher_code, body_code)
    context.curr()['FOR_STACK'].pop()
    return output_code
Пример #8
0
    def compile_section(self, proc_var, section, is_last):
        pattern_part, body_part = section
        proc_stack = context.curr().setdefault('PROC_STACK', [])
        lisp.env_push(proc_var)

        if pattern_part:
            proc_stack.append('#')
            pattern_code = self.compile_pattern(pattern_part)

            if pattern_code.meta.get('raise_random', False) and (
                (not is_last) or
                (len(proc_stack) < 2 or proc_stack[-2] != '#')):
                # When compiled pattern code may raise random exception
                # And it's not the last one of matching chain or
                # The caller is call directely in a LISP environment (not in pattern matching)
                # It's the pattern matching code's responsibility to catch all exception
                # and turn it to _ME
                wrap_tpl = 'try:\n  $#\nexcept:\n  raise _ME(%s)\n%s' % (
                    proc_var, proc_var)
                pattern_code = pycode.create(wrap_tpl, pattern_code)
            proc_stack.pop()
        else:
            pattern_code = pycode.create(proc_var, shortcut_nop=True)

        if body_part is None:
            return pattern_code

        proc_stack.append('=>')
        body_code = pycode.create(proc_var + ' = $#\n' + proc_var,
                                  self.lisp_compiler.compile_block(body_part))
        proc_stack.pop()
        lisp.env_pop()

        if not is_last:
            body_tpl = 'try:\n  $#\nexcept _ME, e:\n  raise _UME(%s)\n%s' % (
                proc_var, proc_var)
            body_code = pycode.create(body_tpl, body_code)
        return pattern_code + body_code
Пример #9
0
    def compile_section(self, proc_var, section, is_last):
	pattern_part, body_part = section
	proc_stack = context.curr().setdefault('PROC_STACK', [])
	lisp.env_push(proc_var)
    
	if pattern_part:
	    proc_stack.append('#')
	    pattern_code = self.compile_pattern(pattern_part)
            
	    if pattern_code.meta.get('raise_random', False) and (
                (not is_last) or (len(proc_stack) < 2 or proc_stack[-2] != '#')):
                # When compiled pattern code may raise random exception
                # And it's not the last one of matching chain or
                # The caller is call directely in a LISP environment (not in pattern matching)
                # It's the pattern matching code's responsibility to catch all exception
                # and turn it to _ME
		wrap_tpl = 'try:\n  $#\nexcept:\n  raise _ME(%s)\n%s' % (proc_var, proc_var)
		pattern_code = pycode.create(wrap_tpl, pattern_code)
	    proc_stack.pop()
	else:
	    pattern_code = pycode.create(proc_var, shortcut_nop = True)

	if body_part is None:
	    return pattern_code

	proc_stack.append('=>')
	body_code = pycode.create(
		proc_var + ' = $#\n' + proc_var,
		self.lisp_compiler.compile_block(body_part))
	proc_stack.pop()
	lisp.env_pop()

	if not is_last:
	   body_tpl = 'try:\n  $#\nexcept _ME, e:\n  raise _UME(%s)\n%s' % (
		   proc_var, proc_var)
	   body_code = pycode.create(body_tpl, body_code)
	return pattern_code + body_code
Пример #10
0
def prim_emit_many(compiler, src):
    queue_name = context.curr()['FOR_STACK'][-1]
    return pycode.create('%s.extend($#)\nNone' % (queue_name,), compiler.compile(src[1]))
Пример #11
0
 def __call__(self, value):
     curr = context.curr()
     if curr is not None:
         curr[self.name] = value
     return value
Пример #12
0
def prim_emit_many(compiler, src):
    queue_name = context.curr()['FOR_STACK'][-1]
    return pycode.create('%s.extend($#)\nNone' % (queue_name, ),
                         compiler.compile(src[1]))
Пример #13
0
def env_curr():
    return context.curr()['ENV_STACK'][-1]
Пример #14
0
def prim_break(compiler, src):
    if len(src) == 1:
        return pycode.create("break\nNone")
    loop_name = context.curr()["LOOP_STACK"][-1]
    return pycode.create("%s = $#\nbreak\n%s" % (loop_name, loop_name), compiler.compile(src[1]))
Пример #15
0
 def __call__(self, value):
     curr = context.curr()
     if curr is not None:
         curr[self.name] = value
     return value
Пример #16
0
def env_pop():
    context.curr()['ENV_STACK'].pop()
Пример #17
0
def env_push(name):
    context.curr().setdefault('ENV_STACK', []).append(name)