def repl(prompt='>'): global Tokens, res # print "\n" print 'Pyscheme REPL Ver:', repl_VER s_time = 0 cc = 0 GL['PROMPT'] = prompt while True: prompt = GL['PROMPT'] if isa(prompt, String): prompt = prompt.tostring() cc += 1 try: s = read("", 'In [' + str(cc) + ']' if isa(prompt, int) else prompt) # S式を入手 #s=expand(s,True) # 文法チェック&前処理 if GL['%timeit'] == True: s_time = time.time() #expr = compile(s) # コンパイル(case of python list) #expr = compile(toLlist(s)) # コンパイル(case of Linked list) du = GL['%debug-vm'] GL['%debug-vm'] = False if EXPAND_FLG: tt = expand(toLlist(s), None) # expand syntax-rules else: tt = toLlist(s) # expand syntax-rules GL['%debug-vm'] = du expr = compile(tt) # コンパイル #GL['%debug-vm'] = du res = vm(None, None, expr, None) # VM実行 GL['_' + str(cc)] = res # _番号 で以前の値を参照可能 GL['___'] = GL['__'] GL['__'] = GL['_'] GL['_'] = res # 直前の結果が_で参照できる # outputの処理 if isa(prompt, int): print 'Out[' + str(cc) + ']:', # python like prompt # 以下VMの出力をデータタイプ別にわかりやすく表示 # 本来ならデータタイプごとにclass化してそこで__repr__にて規定すべき if isa(res, Vector) and res == []: print(to_string(res)) elif isa(res, Values): res = tolist_(res.data) for r in res: print to_string(r) elif res != [] and isa(res, list): if isa(s, list): s = "" if res[0] == "closue": print '#<user-function> ' + s + ' ' elif res[0] == "continuation": print '#<continuation-function> ' + s + ' ' elif res[0] == "macro": print '#<macro-function> ' + s + ' ' elif res[0] == "primitive": print '#<primitive-function> ' + s + ' ' else: print(to_string(tolist(res))) else: print(to_string(tolist(res))) if GL['%timeit'] == True: e_time = time.time() - s_time print("elapsed time:{0}".format(e_time))
def __repr__(self): #return Symbol('#<values> ') + to_string(tolist(self.data)) s = Symbol('#<values:') L = self.data while isa(L, list): s = s + ' ' + to_string(tolist(L[0])) L = L[1] return s + Symbol('>')
def load(file_name, silent=True): """ schemeプログラムを読み込みコンパイル、実行する """ global DBG if DBG is True: silent = False f = open(file_name) while True: s = read(f, '') if s == EOF: break # EOFが返るのはファイルから読み込んだ場合のみ #s=expand(s) # 文法チェック&構文拡張 if EXPAND_FLG: expr = compile(expand(toLlist(s), None)) else: expr = compile(toLlist(s)) if silent: vm(None, None, expr, None) else: print(to_string(tolist(vm(None, None, expr, None)))) f.close() return
def repl_dbg(prompt='dbg>'): #print "\n" print 'Pyscheme REPL (debug version) Ver:', repl_VER s_time = 0 cc = 0 GL['PROMPT'] = prompt while True: prompt = GL['PROMPT'] if isa(prompt, String): prompt = prompt.tostring() cc += 1 s = read("", 'In [' + str(cc) + ']' if isa(prompt, int) else prompt) # S式を入手 #s=expand(s,True) # 文法チェック&前処理 if GL['%timeit'] == True: s_time = time.time() #expr = compile(s) # コンパイル(case of python list) #expr = compile(toLlist(s)) # コンパイル(case of Linked list) if EXPAND_FLG: expr = compile(expand(toLlist(s), None)) # コンパイル(case of Linked list) else: expr = compile(toLlist(s)) # コンパイル(case of Linked list) res = vm(None, None, expr, None) # VM実行 GL['_' + str(cc)] = res GL['___'] = GL['__'] GL['__'] = GL['_'] GL['_'] = res # 直前の結果が_で参照できる # outputの処理 if isa(prompt, int): print 'Out[' + str(cc) + ']:', # python like prompt print(to_string(tolist(res))) # 結果を加工しないで出力 print if GL['%timeit'] == True: e_time = time.time() - s_time print("elapsed time:{0}".format(e_time)) pass
def require(x, predicate, msg="wrong length"): "Signal a syntax error if predicate is false." if not predicate: raise SyntaxError(to_string(tolist(x)) + ': ' + msg)
def comp(expr, env, code, tail, LL): global COUNT # for dbug if GL['%debug-cp']: print "\ncount", COUNT, print "\nexp :", to_string(tolist(expr)), "\nenv :", to_string(tolist(env)), \ "\ncod :", to_string(tolist(code)) # COUNT += 1 #for debug if is_self_eval(expr): # number, string, #t, #f, vector return cons_star(LDC, expr, code) elif isSymbol(expr): pos = location(expr, env) if pos == Nil: #if ismacro_value(expr): # return compile(cdr(GL[expr])) return cons_star(LDG, expr, code) return cons_star(LD, pos, code) # op = car(expr) if op == 'quote': require(expr, Llen(expr) == 2) return cons_star(LDC, cadr(expr), code) elif op == 'if': require(expr, Llen(expr) == 3 or Llen(expr) == 4) if tail: # tail t_clause = comp(caddr(expr), env, [RTN, None], True, LL) if cdddr(expr) == None: f_clause = Llist(LDC, Symbol('*undef*'), RTN) else: f_clause = comp(cadddr(expr), env, [RTN, None], True, LL) return comp(cadr(expr), env, cons_star(SELR, t_clause, f_clause, cdr(code)), False, LL) t_clause = comp(caddr(expr), env, [JOIN, None], False, LL) if cdddr(expr) == None: f_clause = Llist(LDC, Symbol('*undef*'), JOIN) else: f_clause = comp(cadddr(expr), env, [JOIN, None], False, LL) return comp(cadr(expr), env, cons_star(SEL, t_clause, f_clause, code), False, LL) elif op == 'begin': if cdr(expr) is None: # (begin)は'*undef*と展開する body = comp([Symbol('quote'), [Symbol('*undef*'), None]], env, code, False, LL) else: body = comp_body(cdr(expr), env, code, LL, True) return body elif op == '_lambda': body = comp_body(cddr(expr), cons(cadr(expr), env), [RTN, None], LL, False) return cons_star(LDF, body, code) elif op == '_define': require(expr, Llen(expr) == 3) require(expr, isa(cadr(expr), Symbol), "can define only a symbol") #return comp(caddr(expr), env, cons_star(DEF_, cadr(expr), code), False,LL) new_code = cons_star(DEF_, cadr(expr), code) new_code[1].append(expr) return comp(caddr(expr), env, new_code, False, LL) elif op == '_define-macro': require(expr, Llen(expr) == 3) require(expr, isa(cadr(expr), Symbol), "can define-macro only a symbol") return comp(caddr(expr), env, cons_star(DEFM, cadr(expr), code), False, LL) elif op == 'let-macro': #require(expr, Llen(expr) == 3) # local macroをLLに登録して L = {} defs, does = cadr(expr), cddr(expr) #print does while isa(defs, list): _def_ = car(defs) _name_, m_body = car(_def_), cadr(_def_) L[_name_] = Llist('macro', 'clouse', cadr(comp(m_body, env, code, False, LL))) defs = cdr(defs) # LLの環境内で式を評価する LL.append(L) new_expr = Llist(cons_star('lambda', None, does)) return comp(new_expr, env, code, False, LL) elif op == 'set!' or op == '_set!': require(expr, Llen(expr) == 3) require(expr, isa(cadr(expr), Symbol), "can set! only a symbol") pos = location(cadr(expr), env) if pos != Nil: return comp(caddr(expr), env, cons_star(LSET, pos, code), False, LL) return comp(caddr(expr), env, cons_star(GSET, cadr(expr), code), False, LL) elif islocalmacro(op, LL): new_expr = vm(None, [cdr(expr), None], get_localmacro_code(car(expr), LL), [Llist(None, None, [STOP, None]), None]) return comp(new_expr, env, code, False, LL) elif ismacro(op): #print op new_expr = vm(None, [cdr(expr), None], get_macro_code(car(expr)), [Llist(None, None, [STOP, None]), None]) return comp(new_expr, env, code, False, LL) #elif (op == 'call/cc') or (op == 'call-with-current-continuation'):# TODO:第1引数が関数であることをチェックする elif op == '_call/cc': return cons_star(LDCT, code, ARGS, 1, comp(expr[1][0], env, cons(APP, code), False, LL)) elif op == 'apply': # TODO:第1引数が関数であることをチェックする return complis( cddr(expr), env, cons_star(ARGSAP, Llen(expr[1][1]), comp(expr[1][0], env, [APP, code], False, LL)), LL) #elif op == 'applycc': # TODO:第1引数が関数であることをチェックする # return complis(cddr(expr), env, cons_star(ARGSAP, Llen(expr[1][1]), comp(expr[1][0], env, [APPCC, code], False,LL)),LL) # optional VM OP-code # 高速化のためよく使う命令をVMのOP-codeに設定している # 通常は args <n>, ldg <func name>, appと3命令かかるところ1命令で済む # ただしVM OP-codeは高階関数の因数には使用できないので注意 # (同じ名前の関数をグローバル環境に登録しておくこと) elif (op == '+' and Llen(cdr(expr)) == 2) or op == ':+': return complis(cdr(expr), env, [ADD, code], LL) elif (op == '-' and Llen(cdr(expr)) == 2) or op == ':-': return complis(cdr(expr), env, [SUB, code], LL) elif (op == '=' and Llen(cdr(expr)) == 2) or op == ':=': return complis(cdr(expr), env, [EQ, code], LL) elif (op == '!=' and Llen(cdr(expr)) == 2) or op == ':!=': return complis(cdr(expr), env, [NEQ, code], LL) elif (op == '<=' and Llen(cdr(expr)) == 2) or op == ':<=': return complis(cdr(expr), env, [SEQ, code], LL) elif (op == '>=' and Llen(cdr(expr)) == 2) or op == ':>=': return complis(cdr(expr), env, [GEQ, code], LL) elif (op == '<' and Llen(cdr(expr)) == 2) or op == ':<': return complis(cdr(expr), env, [ST, code], LL) elif (op == '>' and Llen(cdr(expr)) == 2) or op == ':>': return complis(cdr(expr), env, [GT, code], LL) elif (op == '*' and Llen(cdr(expr)) == 2) or op == ':*': return complis(cdr(expr), env, [MUL, code], LL) elif (op == '/' and Llen(cdr(expr)) == 2) or op == ':/': return complis(cdr(expr), env, [DIV, code], LL) elif op == '1+': return complis(cdr(expr), env, [INC, code], LL) elif op == '1-': return complis(cdr(expr), env, [DEC, code], LL) elif op == '2*': return complis(cdr(expr), env, [_2TIMES, code], LL) elif op == 'zero?': return complis(cdr(expr), env, [ZEQ, code], LL) elif op == 'car': return complis(cdr(expr), env, [_CAR, code], LL) elif op == 'cdr': return complis(cdr(expr), env, [_CDR, code], LL) elif op == 'cons': return complis(cdr(expr), env, [_CONS, code], LL) elif op == 'pair?': return complis(cdr(expr), env, [ISPAIR, code], LL) elif op == 'null?': return complis(cdr(expr), env, [NULL_, code], LL) elif tail: c_ = cons_star(ARGS, Llen(cdr(expr)), comp(car(expr), env, cons(TAPP, code), False, LL)) #print p_, c_ if c_[1][1][0] == LDG and c_[1][1][1][1][0] == TAPP: if c_[1][1][1][0] in GL and isa( GL[c_[1][1][1][0]], list) and GL[c_[1][1][1][0]][0] == 'primitive': return complis( cdr(expr), env, [CALLP, [c_[1][0], [GL[c_[1][1][1][0]][1][0], code]]], LL) else: return complis(cdr(expr), env, [TCALLG, [c_[1][0], [c_[1][1][1][0], code]]], LL) elif c_[1][1][0] == LD and c_[1][1][1][1][0] == TAPP: return complis(cdr(expr), env, [TCALL, [c_[1][0], [c_[1][1][1][0], code]]], LL) elif c_[1][1][0] == LDF and c_[1][1][1][1][0] == TAPP: return complis(cdr(expr), env, [TCALLF, [c_[1][0], [c_[1][1][1][0], code]]], LL) else: return complis(cdr(expr), env, c_, LL) #return complis(cdr(expr), env, c_, LL) else: c_ = cons_star(ARGS, Llen(cdr(expr)), comp(car(expr), env, cons(APP, code), False, LL)) #print p_, c_ if c_[1][1][0] == LDG and c_[1][1][1][1][0] == APP: if c_[1][1][1][0] in GL and isa( GL[c_[1][1][1][0]], list) and GL[c_[1][1][1][0]][0] == 'primitive': #print GL[c_[1][1][1][0]],c_[1][1][1][0] return complis( cdr(expr), env, [CALLP, [c_[1][0], [GL[c_[1][1][1][0]][1][0], code]]], LL) else: return complis(cdr(expr), env, [CALLG, [c_[1][0], [c_[1][1][1][0], code]]], LL) #return complis(cdr(expr), env, [CALLG, [c_[1][0], [c_[1][1][1][0], code]]], LL) elif c_[1][1][0] == LD and c_[1][1][1][1][0] == APP: return complis(cdr(expr), env, [CALL, [c_[1][0], [c_[1][1][1][0], code]]], LL) elif c_[1][1][0] == LDF and c_[1][1][1][1][0] == APP: return complis(cdr(expr), env, [CALLF, [c_[1][0], [c_[1][1][1][0], code]]], LL) else: return complis(cdr(expr), env, c_, LL)