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
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
def prim_if(compiler, source): chain = _parse_if(source) if_var = pycode.name('if_var') tpl = 'if $#:\n %s = $#\n' % (if_var, ) codes = [ compiler.compile(chain[0][0]), compiler.compile_block(chain[0][1]) ] indent = '' for idx in xrange(1, len(chain)): curr_test, curr_body = chain[idx] if curr_test is None: tpl += indent + 'else:\n' tpl += indent + ' %s = $#\n' % (if_var, ) codes.append(compiler.compile_block(curr_body)) break else: tpl += indent + 'else:\n' tpl += indent + ' if $#:\n' tpl += indent + ' %s = $#\n' % (if_var, ) indent += pycode.TAB codes.extend([ compiler.compile(curr_test), compiler.compile_block(curr_body) ]) tpl += if_var return pycode.create(tpl, *codes)
def prim_env(compiler, src): env_name = pycode.name('env') env_code = compiler.compile(src[1]).asname(env_name) lisp.env_push(env_name) body_code = compiler.compile_block((lisp.Symbol('_'), ) + src[2:]) lisp.env_pop() return env_code + body_code
def prim_proc(compiler, source): proc_name = pycode.name('proc') tpl = 'def %s(%s_in):\n return $#\n%s' % (proc_name, proc_name, proc_name) with context.Context(): proc_compiler = proc.Compiler(compiler) return pycode.create(tpl, proc_compiler.compile(proc_name + '_in', source))
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
def prim_env(compiler, src): env_name = pycode.name('env') env_code = compiler.compile(src[1]).asname(env_name) lisp.env_push(env_name) body_code = compiler.compile_block((lisp.Symbol('_'),) + src[2:]) lisp.env_pop() return env_code + body_code
def compile_call(compiler, src): subject = src[0] tpl_lines = ['$#'] sum_codes = [compiler.compile(subject)] if len(src) > 1 and src[1] == Symbol('->'): # It's a selector chain op_sects = [] for selector in src[2:]: op_sects.extend(compile_select(compiler, selector)) else: op_sects = compile_call_args(compiler, src[1:]) # Create tpl tmp_name = None for item in op_sects: sect_tpl, sect_codes = item[0], item[1:] if len([x for x in sect_codes if x.is_expr()]) == len(sect_codes): # All section code is expr, save to directly join tpl_lines[-1] += sect_tpl else: if tmp_name is None: tmp_name = pycode.name() tpl_lines[-1] = '%s = %s' % (tmp_name, tpl_lines[-1]) tpl_lines.append(tmp_name + sect_tpl) sum_codes.extend(sect_codes) return pycode.create('\n'.join(tpl_lines), *sum_codes)
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
def pattern_ext_some(compiler, element): proc_var = lisp.env_curr() element_var = pycode.name('pattern_some') matched_var = pycode.name('switch') tpl = \ '%s = False\n' % (matched_var,) + \ 'for %s in %s\n' % (element_var, proc_var) + \ ' try:\n' + \ ' $#\n' + \ ' %s = True\n' % (matched_var,) + \ ' break\n' + \ ' except _ME:\n' + \ ' continue\n' + \ 'if not %s:\n' % (matched_var,) + \ ' raise _ME, %s\n' % (proc_var,) + \ proc_var return pycode.create(tpl, compiler.compile(element_var, element[1]))
def compile_call(self, proc_src, argument): if type(argument) is not pycode.Code: argument = self.compile_lisp(argument) proc_var = pycode.name('proc_var') return pycode.create( '%s = $#\n$#\n%s' % (proc_var, proc_var), argument, self.compile(proc_var, proc_src))
def pattern_ext_not(compiler, element): proc_var = lisp.env_curr() matched_var = pycode.name('switch') tpl = """\ try: $# %s = False except _ME: %s = True if not %s: raise _ME, %s %s""" % (matched_var, matched_var, matched_var, proc_var, proc_var) return pycode.create(tpl, compiler.compile(proc_var, element[1]))
def compile_fn(compiler, fn_name, arglist, body, compile_return = True): if fn_name is None: fn_name = pycode.name('fn') args, kwargs, kwargs_source = _parse_arglist(arglist) kwargs_codes = map(compiler.compile, kwargs_source) arglist_tpl = ','.join(list(args) + [x + '=$#' for x in kwargs]) if compile_return: tpl = 'def %s(%s):\n return $#\n%s' % (fn_name, arglist_tpl, fn_name) else: tpl = 'def %s(%s):\n $#\n%s' % (fn_name, arglist_tpl, fn_name) with context.Context(): body_code = compiler.compile_block(body) return pycode.create(tpl, *(kwargs_codes + [body_code]))
def compile_fn(compiler, fn_name, arglist, body, compile_return=True): if fn_name is None: fn_name = pycode.name('fn') args, kwargs, kwargs_source = _parse_arglist(arglist) kwargs_codes = map(compiler.compile, kwargs_source) arglist_tpl = ','.join(list(args) + [x + '=$#' for x in kwargs]) if compile_return: tpl = 'def %s(%s):\n return $#\n%s' % (fn_name, arglist_tpl, fn_name) else: tpl = 'def %s(%s):\n $#\n%s' % (fn_name, arglist_tpl, fn_name) with context.Context(): body_code = compiler.compile_block(body) return pycode.create(tpl, *(kwargs_codes + [body_code]))
def prim_assign(compiler, src): if type(src[1]) is lisp.Symbol: value_code = compiler.compile(src[2]) return pycode.create('%s=$#\n%s' % (src[1].name, src[1].name), value_code) elif is_prop_fetch(src[1]): value_code = compiler.compile(src[2]) if not pycode.Code.is_expr_pure(value_code.value): value_code = value_code.asname(pycode.name()) sym_code = compiler.compile(src[1]) # NOTE: Note that pycode tempalte dosen't work here # Because theres to code is not arguments to one expression stat_lines = (sym_code.stat, value_code.stat, '%s = %s' % (sym_code.value, value_code.value)) stat = '\n'.join([x for x in stat_lines if x]) return pycode.Code(stat, value_code.value) else: pattern_compiler = proc.Compiler(compiler) return pattern_compiler.compile_call(src[1], src[2])
def prim_try(compiler, source): curr_stat = 'try' # Step 1: Parse the list try_block = [] except_blocks = [] finally_block = [] try_var = pycode.name('try') for item in source[1:]: if lisp.getop(item) == 'except': if not type(item[1]) is tuple and len(item[1]) == 2 and ( type(item[1][0]) is lisp.Symbol and type(item[1][1]) is lisp.Symbol): raise SyntaxError, item curr_stat = 'except' (except_blocks.append((item[1][0].name, item[1][1].name, item[2:]))) elif lisp.getop(item) == 'finally': finally_block.extend(item[1:]) else: if curr_stat != 'try': raise SyntaxError, source try_block.append(item) if not except_blocks and not finally_block: raise SyntaxError, source # Try part output_tpl = 'try:\n %s = $#\n' % (try_var,) output_codes = [compiler.compile_block(try_block)] # Except part for type_sym, bind_sym, code in except_blocks: output_tpl += 'except %s, %s:\n %s = $#\n' % ( type_sym, bind_sym, try_var) output_codes.append(compiler.compile_block(code)) if finally_block: output_tpl += 'finally:\n $#\n' output_codes.append(compiler.compile_block(finally_block)) output_tpl += try_var return pycode.create(output_tpl, *output_codes)
def prim_if(compiler, source): chain = _parse_if(source) if_var = pycode.name('if_var') tpl = 'if $#:\n %s = $#\n' % (if_var,) codes = [compiler.compile(chain[0][0]), compiler.compile_block(chain[0][1])] indent = '' for idx in xrange(1, len(chain)): curr_test, curr_body = chain[idx] if curr_test is None: tpl += indent + 'else:\n' tpl += indent + ' %s = $#\n' % (if_var,) codes.append(compiler.compile_block(curr_body)) break else: tpl += indent + 'else:\n' tpl += indent + ' if $#:\n' tpl += indent + ' %s = $#\n' % (if_var,) indent += pycode.TAB codes.extend([compiler.compile(curr_test), compiler.compile_block(curr_body)]) tpl += if_var return pycode.create(tpl, *codes)
def pattern_ext_all(compiler, element): proc_var = lisp.env_curr() element_var = pycode.name('pattern_all') tpl = 'for %s in %s:\n $#\n%s' % (element_var, proc_var, proc_var) return pycode.create(tpl, compiler.compile(element_var, element[1]))
def prim_yield(compiler, source): name = pycode.name('yield') return pycode.create('%s = yield $#\n%s' % (name, name), compiler.compile(source[1]))
def prim_yield(compiler, source): name = pycode.name('yield') return pycode.create( '%s = yield $#\n%s' % (name, name), compiler.compile(source[1]))
def compile_call(self, proc_src, argument): if type(argument) is not pycode.Code: argument = self.compile_lisp(argument) proc_var = pycode.name('proc_var') return pycode.create('%s = $#\n$#\n%s' % (proc_var, proc_var), argument, self.compile(proc_var, proc_src))