Пример #1
0
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))
Пример #2
0
 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('>')
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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)
Пример #6
0
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)