def eval_seq(ast, context): context.indent += 3 print ' ' * context.indent, '/----\\' for item in ast.data: send(item, 'eval', context) print ' ' * context.indent, '\\____/' context.indent -= 3
def bracket(context): send(context, 'addMethod', 'collecting', True) b = send(context, 'lookup', 'basket') f(context) if send(context, 'lookup', 'success'): send(context, 'push', post_process(''.join(b))) del b[:] send(context, 'addMethod', 'collecting', False)
def evaluate(ast, context): sname = name_of_symbol_of(ast) if sname == 'symbol': try: return send(context, 'lookup', ast.data) except: return str(ast.data) + '?' if sname == 'literal': return ast.data first, rest = ast.data[0], ast.data[1:] sname = name_of_symbol_of(first) if sname == 'symbol': if first.data == 'define': define(rest, context) return if first.data == 'lambda': return make_lambda_ast(rest, context) exp = tuple(evaluate(it, context) for it in ast.data) if callable(exp[0]): return exp[0](*exp[1:]) return exp
def advance(context): send(context, 'collect') stream = send(context, 'lookup', 'stream') try: char = stream.next() except StopIteration: if not send(context, 'lookup', 'success'): raise else: send(context, 'addMethod', 'current', '') else: send(context, 'addMethod', 'current', char)
def evaluate_list_(ast, context): first = ast.data[0] sname = name_of_symbol_of(first) if sname == 'symbol' and first.data in ('define', 'lambda'): return evaluate_special(ast, context) send(context, 'start_frame') for inner_ast in ast.data: send(inner_ast, 'eval', context) send(context, 'finish_frame') current_frame = send(context, 'lookup', 'current_frame') exp = current_frame.pop().data if callable(exp[0]): result = exp[0](*exp[1:]) else: result = exp current_frame.append(result)
if first.data == 'define': define(rest, context) return if first.data == 'lambda': return make_lambda_ast(rest, context) exp = tuple(evaluate(it, context) for it in ast.data) if callable(exp[0]): return exp[0](*exp[1:]) return exp def define((var, exp), context): send(context, 'addMethod', var.data, evaluate(exp, context)) return def make_lambda_ast((variables, exp), context): variables = tuple(v.data for v in variables.data) exp = list_(*exp.data) def inner(*args): new_context = send(context, 'delegated') for k, v in zip(variables, args): send(new_context, 'addMethod', k, v) return evaluate(exp, new_context) return inner
def Eval(tree, context): symbol = send(tree, 'typeOf') closure = send(symbol, 'transform', context) new_tree = closure(tree, context) if new_tree is not None: return send(new_tree, 'eval', context)
def prep_eval_context(context): send(context, 'addMethod', 'lambda', evaluate_lambda) send(context, 'addMethod', 'define', evaluate_define) send(context, 'addMethod', 'literal', evaluate_literal) send(context, 'addMethod', 'symbol', evaluate_symbol) send(context, 'addMethod', 'list', evaluate_list_)
def name_of_symbol_of(ast): return send(send(ast, 'typeOf'), 'getName') # Some AST symbol types. SYMBOL = make_kind('symbol')
def finish_frame(context): frame_stack = send(context, 'lookup', 'frame_stack') current_frame = send(context, 'lookup', 'current_frame') frame_stack[-1].append(list_(*current_frame)) send(context, 'addMethod', 'current_frame', frame_stack.pop())
def name_of_symbol_of(ast): return send(send(ast, 'typeOf'), 'getName')
def delegated(vt): return send(vt, 'delegated')
def finish_frame(context): send(context, 'finish_frame')
def push(context, term): send(context, 'lookup', 'current_frame').append(term)
def start_frame(context): frame_stack = send(context, 'lookup', 'frame_stack') current_frame = send(context, 'lookup', 'current_frame') frame_stack.append(current_frame) send(context, 'addMethod', 'current_frame', [])
def collect(context): if send(context, 'lookup', 'collecting'): basket = send(context, 'lookup', 'basket') current = send(context, 'lookup', 'current') basket.append(current)
def evaluate_symbol(ast, context): try: it = send(context, 'lookup', ast.data) except: it = str(ast.data) + '?' _append_result(context, it)
def prep_emit_context(context): send(context, 'addMethod', 'literal', emit_lit) send(context, 'addMethod', 'symbol', emit_word) send(context, 'addMethod', 'list', emit_seq) context.indent = 0
def allocate(vt): return send(vt, 'allocate')
def start_frame(context): send(context, 'start_frame')
def make_kind(kind): return send(allocate(symbol_vt), 'setName', kind)
def make_kind(kind): return send(allocate(symbol_vt), 'setName', kind) def make_ast(KIND, value): return send(allocate(ast_vt), 'init', KIND, value)
def init_ast(ast, symbol, value): ast.data = value send(symbol, 'setSymbol', ast) return ast
def _append_result(context, result): current_frame = send(context, 'lookup', 'current_frame') current_frame.append(result)
from co import bootstrap, send from la import setUpTransformEngine object_vt, vtvt = bootstrap() symbol_vt, ast_vt = setUpTransformEngine(object_vt, vtvt) def p(*a): print a context_vt = send(vtvt, 'delegated') send(context_vt, 'addMethod', 'bil', lambda *args: p(args[0] is c)) c = send(context_vt, 'allocate') send(c, 'bil') ##send(i, 'bil') ''' [context addMethod [[context allocate] makekind 'symbol'] 'SYMBOL'] [[context allocate] makeast [context lookup 'SYMBOL'] 'Barry'] [ context addMethod 'twentythree' 23 ] ( twentythree ) ( ooo [ context addMethod 'g' [context lookup 'twentythree'] ]) (define p (divide 1 1000000000))
def transform(symbol, context): return send(context, 'lookup', send(symbol, 'getName'))
def evaluate_define(ast, context): var, exp = ast.data send(exp, 'eval', context) current_frame = send(context, 'lookup', 'current_frame') send(context, 'addMethod', var.data, current_frame.pop())
def setUpTransformEngine(object_vt, vtvt): # Create a Symbol object type. symbol_vt = send(vtvt, 'delegated') # Create ast object type. ast_vt = send(object_vt, 'delegated') send(object_vt, 'addMethod', 'eval', Eval) send(object_vt, 'addMethod', 'transform', Eval) send(object_vt, 'addMethod', 'typeOf', getSymbol) send(symbol_vt, 'addMethod', 'setName', setName) send(symbol_vt, 'addMethod', 'getName', getName) send(symbol_vt, 'addMethod', 'setSymbol', setSymbol) send(symbol_vt, 'addMethod', 'transform', transform) send(ast_vt, 'addMethod', 'init', init_ast) return symbol_vt, ast_vt
def make_ast(KIND, value): return send(allocate(ast_vt), 'init', KIND, value)
def inner(*args): new_context = send(context, 'delegated') for k, v in zip(variables, args): send(new_context, 'addMethod', k, v) return evaluate(exp, new_context)
def kst(context): while send(context, 'lookup', 'success'): term(context) send(context, 'addMethod', 'success', True)
def OR(context): if send(context, 'lookup', 'success'): raise PopFrame send(context, 'addMethod', 'success', True)
def allocate(vt): return send(vt, 'allocate') def make_kind(kind): return send(allocate(symbol_vt), 'setName', kind)
def make_ast(KIND, value): return send(allocate(ast_vt), 'init', KIND, value) def name_of_symbol_of(ast): return send(send(ast, 'typeOf'), 'getName')
def tok(context): if start <= send(context, 'lookup', 'current') <= stop: send(context, 'advance') else: send(context, 'addMethod', 'success', False)