コード例 #1
0
ファイル: lisp_loop.py プロジェクト: kuangyh/chord
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]))
コード例 #2
0
ファイル: lisp_for.py プロジェクト: kuangyh/chord
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
コード例 #3
0
ファイル: proc.py プロジェクト: kuangyh/chord
    def compile_test(self, *exprs):
	proc_var = lisp.env_curr()
	tpl = 'if not ($#):\n  raise _ME()\n%s' % (proc_var,) 
	source = (_S('and'),) + tuple(exprs)
	test_code = self.compile_lisp(source)
	return pycode.create(
		tpl, test_code, shortcut_guards = list(exprs))
コード例 #4
0
ファイル: lisp_loop.py プロジェクト: kuangyh/chord
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
コード例 #5
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
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))
コード例 #6
0
ファイル: lisp_class.py プロジェクト: kuangyh/chord
def prim_class(compiler, source):
    class_name = source[1].name
    if len(source) > 2 and lisp.getop(source[2]) == ':':
	extends = [x.name for x in source[2][1:]]
	block = source[3:]
    else:
	extends = ['object']
	block = source[2:]

    tpl = 'class %s(%s):\n' % (class_name, ','.join(extends))
    if block:
	tpl += '  $#\n' + class_name
	return pycode.create(tpl, compiler.compile_block(block))
    else:
	tpl += '  pass\n' + class_name
	return pycode.create(tpl)
コード例 #7
0
ファイル: lisp_loop.py プロジェクト: kuangyh/chord
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
コード例 #8
0
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)
コード例 #9
0
ファイル: lisp_class.py プロジェクト: kuangyh/chord
def prim_class(compiler, source):
    class_name = source[1].name
    if len(source) > 2 and lisp.getop(source[2]) == ':':
        extends = [x.name for x in source[2][1:]]
        block = source[3:]
    else:
        extends = ['object']
        block = source[2:]

    tpl = 'class %s(%s):\n' % (class_name, ','.join(extends))
    if block:
        tpl += '  $#\n' + class_name
        return pycode.create(tpl, compiler.compile_block(block))
    else:
        tpl += '  pass\n' + class_name
        return pycode.create(tpl)
コード例 #10
0
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)
コード例 #11
0
ファイル: lisp_for.py プロジェクト: kuangyh/chord
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
コード例 #12
0
def compile_struct(compiler, data):
    if type(data) in (tuple, list):
        elements = map(compiler.compile, data)
        if type(data) is tuple:
            tpl = '(' + '$#,' * len(elements) + ')'
        else:
            tpl = '[' + '$#,' * len(elements) + ']'
        return pycode.create(tpl, *elements)
    elif type(data) is KVStream:
        element_codes = [
                pycode.create(
                        '$#:$#', compiler.compile(x[0]), compiler.compile(x[1]))
                for x in data]
        tpl = '{' + '$#,' * len(element_codes) + '}'
        return pycode.create(tpl, *element_codes)
    else:
        return pycode.create('$#', data)
コード例 #13
0
ファイル: proc.py プロジェクト: kuangyh/chord
    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))
コード例 #14
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_infix(compiler, src):
    op_name = src[0].name
    if op_name != '-':
        op_name = op_name.replace('-', ' ')
    op_name = OP_MAPPING.get(op_name, op_name)

    tpl = '(' + (') %s (' % (op_name, )).join(['$#'] * (len(src) - 1)) + ')'
    codes = map(compiler.compile, src[1:])
    return pycode.create(tpl, *codes)
コード例 #15
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_infix(compiler, src):
    op_name = src[0].name
    if op_name != '-':
	op_name = op_name.replace('-', ' ')
    op_name = OP_MAPPING.get(op_name, op_name)

    tpl = '(' + (') %s (' % (op_name,)).join(['$#'] * (len(src) - 1)) + ')'
    codes = map(compiler.compile, src[1:])
    return pycode.create(tpl, *codes)
コード例 #16
0
ファイル: proc.py プロジェクト: kuangyh/chord
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]))
コード例 #17
0
ファイル: proc.py プロジェクト: kuangyh/chord
    def compile_pattern_element(self, element):
	proc_var = lisp.env_curr()

	# '_' is a blank space holder that do nothing
	if element == _S('_'):
	    return pycode.create(proc_var, shortcut_nop = True)

	# Name binding
	bind_to, may_raise = Compiler.get_binding(element)
	if bind_to is not None:
	    return pycode.create(
		    '%s=%s\n%s' % (bind_to, proc_var, proc_var),
		    shortcut_bind = [bind_to],
		    raise_random = may_raise)

	opname = lisp.getop(element)
	# Force equal testing
	if opname == '\'':
	    return self.compile_equal(element[1])

	# Type checking
	if opname == ':':
	    # NOTE: infact, type checking expression could throw exception
	    return self.compile_test((_S('isinstance'), _S('_'), element[1]))

	if opname == '?':
	    return self.compile_test(*element[1:]).add_meta(raise_random = True)

	# Expanded matchings
	if opname in self.EXTS:
	    return self.EXTS[opname](self, element)

	# Extractor
	if type(element) is tuple and len(element) > 0:
	    return self.compile_call(
		    (_S('#'),) + element[1:],
		    (element[0], _S('_'))).add_meta(raise_random = True)
	# Now all come to the structual matching
	return self.compile_pattern_struct(element)
コード例 #18
0
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]))
コード例 #19
0
    def compile(self, proc_var, src):
        chain = Compiler.construct_chain(src)
        if not chain:
            return pycode.create(proc_var)
        if len(chain) == 1:
            return self.compile_section(proc_var, chain[0], True)

        tpl = 'try:\n  $#\n'
        indent = ''
        for i in xrange(len(chain) - 2):
            tpl += indent + 'except _ME:\n'
            tpl += indent + '  try:\n'
            tpl += indent + '    $#\n'
            indent += pycode.TAB
        tpl += indent + 'except _ME:\n'
        tpl += indent + '  $#\n'
        tpl += proc_var
        section_codes = [self.compile_section(proc_var, chain[0], False)]
        section_codes.extend(
            [self.compile_section(proc_var, x, False) for x in chain[1:-1]])
        section_codes.append(self.compile_section(proc_var, chain[-1], True))
        return pycode.create(tpl, *section_codes)
コード例 #20
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
コード例 #21
0
    def compile_pattern_element(self, element):
        proc_var = lisp.env_curr()

        # '_' is a blank space holder that do nothing
        if element == _S('_'):
            return pycode.create(proc_var, shortcut_nop=True)

        # Name binding
        bind_to, may_raise = Compiler.get_binding(element)
        if bind_to is not None:
            return pycode.create('%s=%s\n%s' % (bind_to, proc_var, proc_var),
                                 shortcut_bind=[bind_to],
                                 raise_random=may_raise)

        opname = lisp.getop(element)
        # Force equal testing
        if opname == '\'':
            return self.compile_equal(element[1])

        # Type checking
        if opname == ':':
            # NOTE: infact, type checking expression could throw exception
            return self.compile_test((_S('isinstance'), _S('_'), element[1]))

        if opname == '?':
            return self.compile_test(*element[1:]).add_meta(raise_random=True)

        # Expanded matchings
        if opname in self.EXTS:
            return self.EXTS[opname](self, element)

        # Extractor
        if type(element) is tuple and len(element) > 0:
            return self.compile_call(
                (_S('#'), ) + element[1:],
                (element[0], _S('_'))).add_meta(raise_random=True)
        # Now all come to the structual matching
        return self.compile_pattern_struct(element)
コード例 #22
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
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]))
コード例 #23
0
ファイル: proc.py プロジェクト: kuangyh/chord
    def compile(self, proc_var, src):
        chain = Compiler.construct_chain(src)
        if not chain:
            return pycode.create(proc_var)
	if len(chain) == 1:
	    return self.compile_section(proc_var, chain[0], True)

        tpl = 'try:\n  $#\n'
	indent = ''
        for i in xrange(len(chain) - 2):
	    tpl += indent + 'except _ME:\n'
	    tpl += indent + '  try:\n'
	    tpl += indent + '    $#\n'
	    indent += pycode.TAB
	tpl += indent + 'except _ME:\n'
	tpl += indent + '  $#\n'
	tpl += proc_var
	section_codes = [self.compile_section(proc_var,  chain[0], False)]
	section_codes.extend([
	    self.compile_section(proc_var, x, False)
	    for x in chain[1:-1]])
	section_codes.append(self.compile_section(proc_var, chain[-1], True))
	return pycode.create(tpl, *section_codes)
コード例 #24
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
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]))
コード例 #25
0
ファイル: proc.py プロジェクト: kuangyh/chord
    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
コード例 #26
0
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]))
コード例 #27
0
ファイル: proc.py プロジェクト: kuangyh/chord
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]))
コード例 #28
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
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])
コード例 #29
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
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])
コード例 #30
0
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)
コード例 #31
0
    def compile_pattern(self, pattern):
        proc_var = lisp.env_curr()

        # Combine effect of each pattern element
        # Count metadata for caller
        shortcuts = []
        is_raise_random = False

        output = pycode.create(proc_var)
        for element in pattern:
            code = self.compile_pattern_element(element)
            if code.meta.get('shortcut_nop', False):
                continue
            output += code

            is_raise_random = is_raise_random or code.meta.get(
                'raise_random', False)
            if 'shortcut_equal' in code.meta:
                shortcut = ('equal', code.meta['shortcut_equal'])
            elif 'shortcut_bind' in code.meta:
                shortcut = ('bind', code.meta['shortcut_bind'])
            else:
                shortcut = (None, None)
            shortcuts.append(shortcut)

        if len(shortcuts) == 0:
            return output.add_meta(shortcut_nop=True)

        equals = [x[1] for x in shortcuts if x[0] == 'equal']
        if len(equals) == len(shortcuts):
            return output.add_meta(shortcut_equal=equals[0])

        binds = [x[1] for x in shortcuts if x[0] == 'bind']
        if len(binds) == len(shortcuts):
            join_binds = []
            for item in binds:
                join_binds.extend(item)
            return output.add_meta(shortcut_bind=join_binds,
                                   raise_random=is_raise_random)
        return output.add_meta(raise_random=is_raise_random)
コード例 #32
0
ファイル: proc.py プロジェクト: kuangyh/chord
    def compile_pattern(self, pattern):
	proc_var = lisp.env_curr()

	# Combine effect of each pattern element
	# Count metadata for caller
	shortcuts = []
	is_raise_random = False

	output = pycode.create(proc_var)
	for element in pattern:
	    code = self.compile_pattern_element(element)
	    if code.meta.get('shortcut_nop', False):
		continue
	    output += code

	    is_raise_random = is_raise_random or code.meta.get('raise_random', False)
	    if 'shortcut_equal' in code.meta:
		shortcut = ('equal', code.meta['shortcut_equal'])
	    elif 'shortcut_bind' in code.meta:
		shortcut = ('bind', code.meta['shortcut_bind'])
	    else:
		shortcut = (None, None)
	    shortcuts.append(shortcut)

	if len(shortcuts) == 0:
	    return output.add_meta(shortcut_nop = True)
 
	equals = [x[1] for x in shortcuts if x[0] == 'equal']
	if len(equals) == len(shortcuts):
	    return output.add_meta(shortcut_equal = equals[0])

	binds = [x[1] for x in shortcuts if x[0] == 'bind']
	if len(binds) == len(shortcuts):
	    join_binds = []
	    for item in binds:
		join_binds.extend(item)
	    return output.add_meta(shortcut_bind = join_binds, raise_random = is_raise_random)
	return output.add_meta(raise_random = is_raise_random) 
コード例 #33
0
ファイル: lisp_if.py プロジェクト: kuangyh/chord
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)
コード例 #34
0
 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))
コード例 #35
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_quote(compiler, src):
    return pycode.create('$#', src[1])
コード例 #36
0
    def compile_pattern_struct(self, source):
        proc_var = lisp.env_curr()

        if type(source) is not list or len(source) < 1:
            return self.compile_equal(source)

        if len(source) >= 2 and source[-2] == _S('.'):
            car_part = source[:-2]
            cdr_part = source[-1]
        else:
            car_part = source
            cdr_part = _S('_')
        if not car_part:
            return self.compile(cdr_part)

        # Compile each element, do special handling with equal and bind shortcuts
        equal_elements = []
        bind_elements = []
        custom_elements = []
        is_need_wrap = [False]

        def handle_element_code(idx_expr, src_var, element_code):
            is_need_wrap[0] = is_need_wrap[0] or \
             element_code.meta.get('raise_random', False)
            if 'shortcut_nop' in element_code.meta:
                pass
            elif 'shortcut_equal' in element_code.meta:
                equal_elements.append((idx_expr, element_code))
            elif 'shortcut_bind' in element_code.meta:
                bind_elements.append((idx_expr, element_code))
            else:
                custom_elements.append((idx_expr, src_var, element_code))

        for element_idx in xrange(len(car_part)):
            idx_expr = '%s[%d]' % (
                proc_var,
                element_idx,
            )
            src_var = '%s_%d' % (proc_var, element_idx)
            element_code = self.compile(src_var, car_part[element_idx])
            handle_element_code(idx_expr, src_var, element_code)
        # Handle cdr_expr as the same
        if len(car_part) < len(source):
            cdr_expr = '%s[%d:]' % (
                proc_var,
                len(car_part),
            )
            src_var = proc_var + '_cdr'
            cdr_code = self.compile(src_var, cdr_part)
            handle_element_code(cdr_expr, src_var, cdr_code)

        # Shortcut: if all element is equal check
        # Treat as a equal check of whole
        if len(equal_elements) == len(source):
            return self.compile_equal(source)

        code = pycode.create(proc_var).add_meta(shortcut_nop=True)
        # Compile equal_elemens and length check
        if equal_elements:
            fetch_part = '(' + ','.join([x[0] for x in equal_elements]) + ',)'
            equal_data = tuple(x[1].meta['shortcut_equal']
                               for x in equal_elements)
            if len(car_part) == len(source):
                tpl = 'if len(%s) != %d or $# != $#:\n  raise _ME(%s)\n%s' % (
                    proc_var, len(car_part), proc_var, proc_var)
            else:
                tpl = 'if len(%s) < %d or $# != $#:\n  raise _ME(%s)\n%s' % (
                    proc_var, len(car_part), proc_var, proc_var)
            code += pycode.create(tpl, equal_data, pycode.create(fetch_part))
        elif len(car_part) == len(source):
            code += pycode.create(
                'if len(%s) != %d:\n  raise _ME(%s)\n%s' %
                (proc_var, len(car_part), proc_var, proc_var))
        else:
            code += pycode.create(
                'if len(%s) < %d:\n  raise _ME(%s)\n%s' %
                (proc_var, len(car_part), proc_var, proc_var))

        for bind_idx, bind_code in bind_elements:
            code += pycode.create('%s=%s\n%s' % ('='.join(
                bind_code.meta['shortcut_bind']), bind_idx, proc_var))

        if custom_elements:
            for source_idx, src_var, element_code in custom_elements:
                code += pycode.create('%s = %s\n%s' %
                                      (src_var, source_idx, src_var))
                code += element_code
        return code.add_meta(raise_random=is_need_wrap[0])
コード例 #37
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_quote(compiler, src):
    return pycode.create('$#', src[1])
コード例 #38
0
 def compile_test(self, *exprs):
     proc_var = lisp.env_curr()
     tpl = 'if not ($#):\n  raise _ME()\n%s' % (proc_var, )
     source = (_S('and'), ) + tuple(exprs)
     test_code = self.compile_lisp(source)
     return pycode.create(tpl, test_code, shortcut_guards=list(exprs))
コード例 #39
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_global(compiler, src):
    return pycode.create('global ' + ','.join([x.name
                                               for x in src[1:]]) + '\nNone')
コード例 #40
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_import(compiler, src):
    if isinstance(src[1], lisp.Symbol):
        import_expr = src[1].name
    else:
        import_expr = str(src[1])
    return pycode.create('import %s\nNone' % (import_expr, ))
コード例 #41
0
ファイル: lisp_for.py プロジェクト: kuangyh/chord
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]))
コード例 #42
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_print(compiler, src):
    return pycode.create('print $#\nNone', compiler.compile(src[1]))
コード例 #43
0
ファイル: lisp_loop.py プロジェクト: kuangyh/chord
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]))
コード例 #44
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_import(compiler, src):
    if isinstance(src[1], lisp.Symbol):
	import_expr = src[1].name
    else:
	import_expr = str(src[1])
    return pycode.create('import %s\nNone' % (import_expr,))
コード例 #45
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_print(compiler, src):
    return pycode.create('print $#\nNone', compiler.compile(src[1]))
コード例 #46
0
ファイル: proc.py プロジェクト: kuangyh/chord
    def compile_pattern_struct(self, source):
	proc_var = lisp.env_curr()

	if type(source) is not list or len(source) < 1:
	    return self.compile_equal(source)

	if len(source) >= 2 and source[-2] == _S('.'):
	    car_part = source[:-2]
	    cdr_part = source[-1]
	else:
	    car_part = source
	    cdr_part = _S('_')
	if not car_part:
	    return self.compile(cdr_part)

	# Compile each element, do special handling with equal and bind shortcuts
	equal_elements = []
	bind_elements = []
	custom_elements = []
	is_need_wrap = [False]

	def handle_element_code(idx_expr, src_var, element_code):
	    is_need_wrap[0] = is_need_wrap[0] or \
		    element_code.meta.get('raise_random', False)
	    if 'shortcut_nop' in element_code.meta:
		pass
	    elif 'shortcut_equal' in element_code.meta:
		equal_elements.append((idx_expr, element_code))
	    elif 'shortcut_bind' in element_code.meta:
		bind_elements.append((idx_expr, element_code))
	    else:
		custom_elements.append((idx_expr, src_var, element_code))

	for element_idx in xrange(len(car_part)):
	    idx_expr = '%s[%d]' % (proc_var, element_idx,)
	    src_var = '%s_%d' % (proc_var, element_idx)
	    element_code = self.compile(src_var, car_part[element_idx])
	    handle_element_code(idx_expr, src_var, element_code)
	# Handle cdr_expr as the same
	if len(car_part) < len(source):
	    cdr_expr = '%s[%d:]' % (proc_var, len(car_part),)
	    src_var = proc_var + '_cdr'
	    cdr_code = self.compile(src_var, cdr_part)
	    handle_element_code(cdr_expr, src_var, cdr_code)

	# Shortcut: if all element is equal check
	# Treat as a equal check of whole
	if len(equal_elements) == len(source):
	    return self.compile_equal(source)

	code = pycode.create(proc_var).add_meta(shortcut_nop = True)
	# Compile equal_elemens and length check
	if equal_elements:
	    fetch_part = '(' + ','.join([x[0] for x in equal_elements]) + ',)'
	    equal_data = tuple(x[1].meta['shortcut_equal'] for x in equal_elements)
	    if len(car_part) == len(source):
		tpl = 'if len(%s) != %d or $# != $#:\n  raise _ME(%s)\n%s' % (
			proc_var, len(car_part), proc_var, proc_var)
	    else:
		tpl = 'if len(%s) < %d or $# != $#:\n  raise _ME(%s)\n%s' % (
			proc_var, len(car_part), proc_var, proc_var)
	    code += pycode.create(tpl, equal_data, pycode.create(fetch_part))
	elif len(car_part) == len(source):
	    code += pycode.create('if len(%s) != %d:\n  raise _ME(%s)\n%s' % (
		proc_var, len(car_part), proc_var, proc_var))
	else:
	    code += pycode.create('if len(%s) < %d:\n  raise _ME(%s)\n%s' % (
		proc_var, len(car_part), proc_var, proc_var))
	    
	for bind_idx, bind_code in bind_elements:
	    code += pycode.create('%s=%s\n%s' %
		    ('='.join(bind_code.meta['shortcut_bind']), bind_idx, proc_var))

	if custom_elements:
	    for source_idx, src_var, element_code in custom_elements:
		code += pycode.create('%s = %s\n%s' % (src_var, source_idx, src_var))
		code += element_code
	return code.add_meta(raise_random = is_need_wrap[0])
コード例 #47
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
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))
コード例 #48
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_global(compiler, src):
    return pycode.create('global ' + ','.join([x.name for x in src[1:]]) + '\nNone')
コード例 #49
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_prefix(compiler, src):
    op_name = OP_MAPPING.get(src[0].name, src[0].name.replace('-', ' '))
    return pycode.create('%s($#)' % (op_name, ), compiler.compile(src[1]))
コード例 #50
0
ファイル: lisp_for.py プロジェクト: kuangyh/chord
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]))
コード例 #51
0
ファイル: proc.py プロジェクト: kuangyh/chord
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]))
コード例 #52
0
ファイル: lisp_prims.py プロジェクト: kuangyh/chord
def prim_prefix(compiler, src):
    op_name = OP_MAPPING.get(src[0].name, src[0].name.replace('-', ' '))
    return pycode.create('%s($#)' % (op_name,), compiler.compile(src[1]))
コード例 #53
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
def prim_return(compiler, source):
    return pycode.create('return $#\nNone', compiler.compile(source))
コード例 #54
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
def prim_return(compiler, source):
    return pycode.create('return $#\nNone', compiler.compile(source))
コード例 #55
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
def prim_yield(compiler, source):
    name = pycode.name('yield')
    return pycode.create('%s = yield $#\n%s' % (name, name),
                         compiler.compile(source[1]))
コード例 #56
0
ファイル: lisp_fn.py プロジェクト: kuangyh/chord
def prim_yield(compiler, source):
    name = pycode.name('yield')
    return pycode.create(
	    '%s = yield $#\n%s' % (name, name), compiler.compile(source[1]))
コード例 #57
0
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]))