def invoke(self, args, *_): acc = "" for w_arg in args: if isinstance(w_arg, space.W_String): acc += w_arg.val else: acc += w_arg.to_str() return space.wrap(acc)
def invoke(ip, env, code, r1, stack, sp, ctx): ip += 1 sp = jit.promote(sp) argc = jit.promote(get_op(code, ip)) assert argc >= 0 fn = jit.promote(r1) if isinstance(fn, space.W_Fun): arg_ids_len = const_len(fn.arg_ids) if fn.env.on_stack: new_env = Env([], fn.env) else: new_env = fn.env try: new_env.mark_used() if (argc < arg_ids_len or (argc > arg_ids_len and not fn.got_rest_args())): raise space.ArityException(argc, arg_ids_len) if argc > arg_ids_len and fn.got_rest_args(): new_sp = sp - (argc - arg_ids_len) assert new_sp >= 0 rest_args = [space.w_nil for _ in range(argc - arg_ids_len)] for i in range(new_sp, sp): rest_args[i - new_sp] = stack[jit.promote(i)] sp = new_sp new_env.set(fn.rest_args_id, space.wrap(rest_args)) elif fn.got_rest_args(): new_env.set(fn.rest_args_id, space.w_empty_list) sp -= arg_ids_len idx = 0 for arg_id in fn.arg_ids: new_env.set(arg_id, stack[jit.promote(idx + sp)]) idx += 1 return eval(ctx, new_env, fn.code) finally: new_env.mark_free() else: new_sp = sp - argc assert new_sp >= 0 args = [space.w_nil for _ in range(argc)] for i in range(new_sp, sp): args[i - new_sp] = stack[i] ret = fn.invoke(args, ctx) if ret is None: ret = space.w_nil return ret
def invoke_fn(w_fn, args_w, ctx): w_fn = space.cast(w_fn, space.W_Fun) argc = len(args_w) arg_ids_len = len(w_fn.arg_ids) rest_args = space.w_empty_list if argc > arg_ids_len and w_fn.got_rest_args(): rest_args = [args_w.pop() for _ in range(argc - arg_ids_len)] rest_args.reverse() rest_args = space.wrap(rest_args) args = [args_w.pop() for _ in range(arg_ids_len)] idx = 0 env = Env([], w_fn.env) for arg_id in reversed(w_fn.arg_ids): env.set(arg_id, args[idx]) idx += 1 if w_fn.got_rest_args(): env.set(w_fn.rest_args_id, rest_args) return eval(ctx, env, w_fn.code)
def apply(ip, env, code, r1, stack, sp, ctx): ip += 1 assert code[ip] == 2 new_sp = sp - 2 assert new_sp >= 0 (fn, w_args) = stack[new_sp : sp] sp = new_sp args = space.unwrap(w_args) argc = len(args) if isinstance(fn, space.W_Fun): arg_ids_len = len(fn.arg_ids) if fn.env.on_stack: new_env = Env([], fn.env) else: new_env = fn.env try: new_env.mark_used() if (argc < arg_ids_len or (argc > arg_ids_len and not fn.got_rest_args())): raise space.ArityException(argc, arg_ids_len) if argc > arg_ids_len and fn.got_rest_args(): rest_args = [args.pop() for _ in range(argc - arg_ids_len)] rest_args.reverse() new_env.set(fn.rest_args_id, space.wrap(rest_args)) elif fn.got_rest_args(): new_env.set(fn.rest_args_id, space.w_empty_list) idx = 0 for arg_id in fn.arg_ids: new_env.set(arg_id, args[idx]) idx += 1 return eval(ctx, new_env, fn.code) finally: new_env.mark_free() else: ret = fn.invoke(args, ctx) if ret is None: ret = space.w_nil return ret
def lambda_expr(sexpr): return wrap([W_Sym('#'), sexpr])
def unquote(sexpr): return wrap([W_Sym('~'), sexpr])
def quasiquote(sexpr): return wrap([W_Sym('qquote'), sexpr])
def eval(ctx, env, code): ip = 0 stack = empty_stack sp = 0 r1 = space.w_nil while ip < const_len(code): jitdriver.jit_merge_point( ip=ip, sp=sp, stack=stack, ctx=ctx, env=env, code=code, r1=r1, ) assert r1 is not None assert sp >= 0 op = get_op(code, ip) if op == ops.IF: ip += 1 if not space.is_true(r1): ip += get_op(code, ip) elif op == ops.SYM: ip += 1 r1 = lookup(env, ctx, get_op(code, ip)) elif op == ops.KEYWORD: ip += 1 r1 = space.W_Keyword(ctx.st().get_sym(get_op(code, ip))) elif op == ops.STRING: ip += 1 r1 = space.W_String(ctx.st().get_sym(get_op(code, ip))) elif op == ops.INT: ip += 1 r1 = space.W_Int(get_op(code, ip)) elif op == ops.PUSH_ENV: ip += 1 env = Env([(get_op(code, ip), r1)], env) elif op == ops.POP_ENV: env = env.parent elif op == ops.QUOTE: ip += 1 r1 = space.W_Sym(ctx.st().get_sym(get_op(code, ip))) elif op == ops.RELJMP: ip += get_op(code, ip + 1) + 1 elif op == ops.FN: ip += 1 r1 = ctx.st().get_fn(get_op(code, ip)).with_env(env) elif op == ops.PUSH: if stack is empty_stack: stack = [None for _ in range(stack_size)] stack[jit.promote(sp)] = r1 sp += 1 elif op == ops.DEF: ip += 1 ctx.bindings().set(get_op(code, ip), r1) elif op == ops.RECUR: ip += 1 argc = jit.promote(get_op(code, ip)) sp -= argc idx = argc - 1 while idx >= 0: ip += 1 env.set(get_op(code, ip), stack[jit.promote(idx + sp)]) idx -= 1 ip = -1 elif op == ops.INVOKE: r1 = invoke(ip, env, code, r1, stack, sp, ctx) ip += 1 sp -= get_op(code, ip) elif op == ops.APPLY: r1 = apply(ip, env, code, r1, stack, sp, ctx) ip += 1 sp -= 2 elif op == ops.TRY: try: assert isinstance(r1, space.W_Fun) r1 = eval(ctx, env, r1.code) ip += code[ip + 1] except space.SpaceException as ex: if stack is empty_stack: stack = [None for _ in range(stack_size)] stack[jit.promote(sp)] = space.wrap(ex.reason()) sp += 1 ip += 1 elif op == ops.CHAR: ip += 1 r1 = space.W_Char(get_op(code, ip)) else: raise Exception("Unknown code: %s, ip %s, code %s" % (str(op), ip, str(code))) ip += 1 assert sp == 0 return r1
def invoke(self, args, *_): return space.wrap(args)
def invoke(self, args, *_): a = space.cast(args[0], space.W_Int) b = space.cast(args[1], space.W_Int) return space.wrap(a.val < b.val)
def invoke(self, *_): return space.wrap(str(stdin.get().readline()))
def f(self, args, *_): arg = args[0] return space.wrap(isinstance(arg, type))