コード例 #1
0
ファイル: compiler.py プロジェクト: pjhades/Tabris
    def compile_namedlet(self, exp, env, cont, istail=False):
        """Compile a named let form. At runtime a new frame will
        be created and the closure will be defined in such frame
        and applied to the arguments listed in the bindings.
        """
        def got_define(define_code):
            nonlocal compiled_define_code
            compiled_define_code = define_code
            apply_form = cons(proc_name, from_python_list(vall))
            return bounce(self.compile_call, apply_form, newenv, got_apply, istail=istail)
    
        def got_apply(apply_code):
            code = [
                (inst_extenv,),
            ] + compiled_define_code + \
                apply_code + [
                (inst_killenv,),
            ]
            return bounce(cont, code)
    
        proc_name = cadr(exp)
        varl = let_vars(caddr(exp))
        vall = let_vals(caddr(exp))
    
        lambda_form = lib_append(
                        lib_list(
                            tsym('lambda'), from_python_list(varl)), 
                        cdddr(exp))
        define_form = lib_list(tsym('define'), proc_name, lambda_form)
    
        newenv = Frame([proc_name], outer=env)
        compiled_define_code = None

        return bounce(self.compile_define, define_form, newenv, got_define)
コード例 #2
0
ファイル: compiler.py プロジェクト: pjhades/Tabris
        def got_test(test_code):
            nonlocal compiled_test_code
            compiled_test_code = test_code
            if cadar(clauses) is tsym('=>'):
                # current clause is in arrow form (foo => proc)
                proc = caddar(clauses)
                return bounce(self.dispatch_exp, proc, env, got_proc, 
                              istail=istail)

            # normal cond clause ((foo x) (bar))
            seq = cdar(clauses)
            defs = define_dumb(seq, env)

            return bounce(self.compile_sequence, seq, defs, env, got_action, 
                          istail=istail)
コード例 #3
0
ファイル: compiler.py プロジェクト: pjhades/Tabris
    def compile_define(self, exp, env, cont, istail=False):
        def got_val(val_code):
            if var not in env.binds:
                env.binds.append(var)
            code = val_code + [
                (inst_bindvar, env.get_lexaddr(var)),
            ]
            return bounce(cont, code)
    
        var, val = cadr(exp), cddr(exp)
        if lib_issymbol(var):
            return bounce(self.dispatch_exp, car(val), env, got_val)

        lambda_form = lib_append(lib_list(tsym('lambda'), cdr(var)), val)
        var = car(var)
        return bounce(self.compile_lambda, lambda_form, env, got_val)
コード例 #4
0
ファイル: parser.py プロジェクト: pjhades/Tabris
    def parse_lexeme_datum(self, tokens, cont):
        token = tokens[0]
        token_type = token[1]

        if token_type == TOKEN_TYPE_BOOLEAN:
            self.consume(tokens, TOKEN_TYPE_BOOLEAN)
            if token[0] == '#t':
                return bounce(cont, True)
            else:
                return bounce(cont, False)

        elif token_type == TOKEN_TYPE_STRING:
            self.consume(tokens, TOKEN_TYPE_STRING)
            return bounce(cont, token[0][1:-1])

        elif token_type == TOKEN_TYPE_SYMBOL:
            self.consume(tokens, TOKEN_TYPE_SYMBOL)
            return bounce(cont, tsym(token[0]))

        elif token_type == TOKEN_TYPE_INTEGER:
            self.consume(tokens, TOKEN_TYPE_INTEGER)
            return bounce(cont, int(token[0]))

        elif token_type == TOKEN_TYPE_FLOAT:
            self.consume(tokens, TOKEN_TYPE_FLOAT)
            return bounce(cont, float(token[0]))

        elif token_type == TOKEN_TYPE_FRACTION:
            self.consume(tokens, TOKEN_TYPE_FRACTION)
            numer, denom = token[0].split('/')
            return bounce(cont, float(numer) / float(denom))

        elif token_type == TOKEN_TYPE_COMPLEX:
            self.consume(tokens, TOKEN_TYPE_COMPLEX)
            return bounce(cont, complex(token[0].replace('i', 'j')))
    
        else:
            raise SchemeError(token, 'is not a lexeme datum')
コード例 #5
0
ファイル: test_parser.py プロジェクト: pjhades/Tabris
    def testLexemeParsing(self):
        """Test parsing lexemes.
        """
        self.tokenizer.tokenize_piece("aaa" + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], tsym("aaa"))

        self.tokenizer.tokenize_piece("#t" + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], True)

        self.tokenizer.tokenize_piece('"helloworld"' + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], "helloworld")

        self.tokenizer.tokenize_piece('123' + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], 123)

        self.tokenizer.tokenize_piece('-4/6' + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], -2.0/3.0)

        self.tokenizer.tokenize_piece('.0' + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], 0.0)

        self.tokenizer.tokenize_piece('+i' + "\n")
        obj = self.parser.parse(self.tokenizer.get_tokens())
        self.assertEqual(len(obj), 1)
        self.assertEqual(obj[0], 1j)
コード例 #6
0
ファイル: compiler.py プロジェクト: pjhades/Tabris
 def got_action(action_code):
     nonlocal code
     if test is tsym('else'):
         code += action_code + [
             label_after,
         ]
         return bounce(cont, resolve_label(code))
     elif lib_isnull(cdr(clauses)):
         code += compiled_test_code + [
             (inst_jf, label_after),
         ] + action_code + [
             label_after,
         ]
         return bounce(cont, resolve_label(code))
     else:
         label_next = label()
         code += compiled_test_code + [
             (inst_jf, label_next),
         ] + action_code + [
             (inst_j, label_after),
             label_next,
         ]
         return bounce(self.compile_clauses, cdr(clauses), code, label_after, 
                       env, cont, istail=istail)
コード例 #7
0
ファイル: parser.py プロジェクト: pjhades/Tabris
 def make_quote(word):
     return bounce(cont, lib_list(tsym('quote'), word))
コード例 #8
0
ファイル: compiler.py プロジェクト: pjhades/Tabris
    def compile_clauses(self, clauses, code, label_after, env, cont, istail=False):
        """Compile clauses of a cond form. Decide if each clause
        is a normal clause or an arrow clause. If the clause is a
        normal one, the last expression in the action part of the
        chosen clause will be in tail position if the whole cond is
        in tail position; if the clause is an arrow clause, the call
        will be a tail call.
        """
        def got_test(test_code):
            nonlocal compiled_test_code
            compiled_test_code = test_code
            if cadar(clauses) is tsym('=>'):
                # current clause is in arrow form (foo => proc)
                proc = caddar(clauses)
                return bounce(self.dispatch_exp, proc, env, got_proc, 
                              istail=istail)

            # normal cond clause ((foo x) (bar))
            seq = cdar(clauses)
            defs = define_dumb(seq, env)

            return bounce(self.compile_sequence, seq, defs, env, got_action, 
                          istail=istail)
    
        def got_proc(proc_code):
            nonlocal code
            if lib_isnull(cdr(clauses)):
                if istail:
                    code += compiled_test_code + [
                        (inst_jf, label_after),
                        (inst_clrargs,),
                        (inst_addarg,),
                    ] + proc_code + [
                        (inst_tailcall,),
                        label_after,
                    ]
                else:
                    code += compiled_test_code + [
                        (inst_jf, label_after),
                        (inst_pushr, VM.REG_ARGS),
                        (inst_clrargs,),
                        (inst_addarg,),
                    ] + proc_code + [
                        (inst_call,),
                        (inst_pop, VM.REG_ARGS),
                        label_after,
                    ]
                return bounce(cont, resolve_label(code))
            else:
                label_next = label()
                code += compiled_test_code + [
                    (inst_jf, label_next),
                    (inst_pushr, VM.REG_ARGS),
                    (inst_clrargs,),
                    (inst_addarg,),
                ] + proc_code + [
                    (inst_call,),
                    (inst_pop, VM.REG_ARGS),
                    (inst_j, label_after),
                    label_next,
                ]
                return bounce(self.compile_clauses, cdr(clauses), code, 
                              label_after, env, cont, istail=istail)
    
        def got_action(action_code):
            nonlocal code
            if test is tsym('else'):
                code += action_code + [
                    label_after,
                ]
                return bounce(cont, resolve_label(code))
            elif lib_isnull(cdr(clauses)):
                code += compiled_test_code + [
                    (inst_jf, label_after),
                ] + action_code + [
                    label_after,
                ]
                return bounce(cont, resolve_label(code))
            else:
                label_next = label()
                code += compiled_test_code + [
                    (inst_jf, label_next),
                ] + action_code + [
                    (inst_j, label_after),
                    label_next,
                ]
                return bounce(self.compile_clauses, cdr(clauses), code, label_after, 
                              env, cont, istail=istail)
    
        compiled_test_code = None
        test = caar(clauses)
        if test is tsym('else'):
            defs = define_dumb(cdar(clauses), env)
            return bounce(self.compile_sequence, cdar(clauses), defs, env, got_action, 
                          istail=istail)
        return bounce(self.dispatch_exp, test, env, got_test)
コード例 #9
0
ファイル: toplevel.py プロジェクト: pjhades/Tabris
from closure import Closure
from tsymbol import tsym
from scmlib import *
from prim import *


def init_compiletime_env():
    return Frame(list(top_bindings.keys()))


def init_runtime_env():
    return Frame(list(top_bindings.values()))


top_bindings = {
    tsym("+"): Closure((0, -1), prim_add, None, isprim=True),
    tsym("-"): Closure((1, -1), prim_sub, None, isprim=True),
    tsym("*"): Closure((0, -1), prim_mul, None, isprim=True),
    tsym("/"): Closure((1, -1), prim_div, None, isprim=True),
    tsym("="): Closure((2, -1), prim_eq, None, isprim=True),
    tsym(">"): Closure((2, -1), prim_gt, None, isprim=True),
    tsym("<"): Closure((2, -1), prim_lt, None, isprim=True),
    tsym(">="): Closure((2, -1), prim_ge, None, isprim=True),
    tsym("<="): Closure((2, -1), prim_le, None, isprim=True),
    tsym("or"): Closure((0, -1), prim_or, None, isprim=True),
    tsym("and"): Closure((0, -1), prim_and, None, isprim=True),
    tsym("not"): Closure((1, 1), prim_not, None, isprim=True),
    tsym("max"): Closure((1, -1), prim_max, None, isprim=True),
    tsym("min"): Closure((1, -1), prim_min, None, isprim=True),
    tsym("abs"): Closure((1, 1), prim_abs, None, isprim=True),
    tsym("gcd"): Closure((2, 2), prim_gcd, None, isprim=True),
コード例 #10
0
ファイル: test_parser.py プロジェクト: pjhades/Tabris
 def testSexpParsing(self):
     """Test parsing S-expressions.
     """
     cases = [("x", tsym("x")), \
              ("(x)", from_python_list([tsym("x")])), \
              ("(x y)", from_python_list([tsym("x"), tsym("y")])), \
              ("(x (y))", from_python_list([tsym("x"), [tsym("y")]])), \
              ("(x . y)", cons(tsym("x"), tsym("y"))), \
              ("(x y . z)", cons(tsym("x"), cons(tsym("y"), tsym("z")))), \
              ("(x (y . z) w)", cons(tsym("x"), 
                                    cons(cons(tsym("y"), tsym("z")),
                                        cons(tsym("w"), NIL))))]
     for case in cases:
         sexp = self.parser.parse(self.tokenizer.tokenize(case[0] + '\n'))[0]
         self.assertEqual(sexp, case[1])