Exemple #1
0
def run_code(env, code):
    code = preprocessor.remove_comments(code)
    lexed = desugarizer.desugar(lexer.lex(code))
    nodes = [parser.parse(tree) for tree in lexed]
    for node in nodes:
        value = env.eval(node)
    return value
Exemple #2
0
    def eval(self, program):
        """Evaluate this program in a fresh environment with the prelude
        already included. Returns the result of the last expression.

        """
        # Fresh copy of the environment so tests don't interfere with one another.
        env = Environment([Scope({})])
        global_scope = self.env.scopes[0]
        for key, value in global_scope.bindings.iteritems():
            # We do a deep copy of mutable values.
            if isinstance(value, List):
                env.set(key, deepcopy(value))
            elif isinstance(value, String):
                env.set(key, deepcopy(value))
            elif isinstance(value, Bytestring):
                env.set(key, deepcopy(value))
            else:
                env.set(key, value)

        parse_tree = parse(lex(program))
        if isinstance(parse_tree, TrifleExceptionInstance):
            self.fail("Parse error on: %r" % program)

        result = NULL
        for expression in parse_tree.values:
            result = evaluate(expression, env)

            if is_thrown_exception(result, error):
                return result

        return result
Exemple #3
0
def env_with_prelude():
    """Return a fresh environment where the prelude has already been
    evaluated.

    """
    # todo: document TRIFLEPATH
    # todo: should we inline the prelude, so changing TRIFLEPATH doens't break this?
    trifle_path = getenv_llimpl("TRIFLEPATH") or "."
    prelude_path = os.path.join(trifle_path, "prelude.tfl")
    
    # Trifle equivalent of PYTHONPATH.
    try:
        code = get_contents(prelude_path)
    except OSError:
        # TODO: work out which error occurred (not found/wrong
        # permissions/other) and be more helpful.
        print "Could not find prelude.tfl. Have you set TRIFLEPATH?"
        raise

    # TODO: either of these could return errors, and we should handle that.
    lexed_tokens = lex(code)
    parse_tree = parse(lexed_tokens)

    env = fresh_environment()
    result = evaluate_all(parse_tree, env)

    assert not is_thrown_exception(result, error), "Error when evaluating prelude: %s" % result

    return env
Exemple #4
0
 def test_rest_bytestring(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(rest #bytes("abc"))'))),
         Bytestring([ord(c) for c in b"bc"]))
Exemple #5
0
 def test_push_returns_null(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(
             u"(push! (quote ()) 1)"))),
         NULL)
Exemple #6
0
 def test_last_string(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(last "abc")'))),
         Character(u'c'))
Exemple #7
0
 def test_last_bytestring(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(last #bytes("abc"))'))),
         Integer.fromint(99))
Exemple #8
0
def test_desugar(test_case, expected):
    lexed = lex(test_case)
    actual = desugar(lexed)
    assert actual == expected
Exemple #9
0
 def test_second_string(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(second "abc")'))),
         Character(u'b'))
Exemple #10
0
 def test_map_string(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(filter (lambda (x) (equal? x \'b\')) "abc")'))),
         String(list(u"b")))
Exemple #11
0
 def test_map_bytestring(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(filter (lambda (x) (equal? x 98)) #bytes("abc"))'))),
         Bytestring([ord("b")]))
Exemple #12
0
 def test_map_string(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(map (lambda (x) \'z\') "abc")'))),
         String(list(u"zzz")))
Exemple #13
0
 def test_map_bytestring(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(map (lambda (x) (+ x 1)) #bytes("abc"))'))),
         Bytestring([ord(c) for c in "bcd"]))
Exemple #14
0
 def test_for_each(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u"""(let (total 0 numbers (list 1 2 3 4))
         (for-each number numbers (set! total (+ total number)))
         total)"""))),
         Integer.fromint(10))
Exemple #15
0
 def test_rest_string(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(rest "abc")'))),
         String(list(u"bc")))
Exemple #16
0
 def test_fifth_bytestring(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(fifth #bytes("abcde"))'))),
         Integer.fromint(101))
Exemple #17
0
 def test_fifth_string(self):
     self.assertEqual(
         evaluate_with_prelude(parse_one(lex(u'(fifth "abcde")'))),
         Character(u'e'))
Exemple #18
0
def entry_point(argv):
    """Either a file name:
    $ ./trifle ~/files/foo.tfl

    A code snippet:
    $ ./trifle -i '1 2'

    """
    if len(argv) == 2:
        # open the file
        filename = argv[1]

        if not os.path.exists(filename):
            print 'No such file: %s' % filename
            return 2

        try:
            env = env_with_prelude()
        except OSError:
            return 2
        code = get_contents(filename)
        lexed_tokens = lex(code)

        if is_thrown_exception(lexed_tokens, error):
            print u'Uncaught error: %s: %s' % (
                lexed_tokens.exception_type.name,
                lexed_tokens.message)
            return 1

        parse_tree = parse(lexed_tokens)
        try:
            result = evaluate_all(parse_tree, env)

            if is_thrown_exception(result, error):
                # TODO: a proper stack trace.
                print u'Uncaught error: %s: %s' % (result.exception_type.name,
                                          result.message)
                return 1
        except SystemExit:
            return 0
        return 0
    
    elif len(argv) == 3:
        if argv[1] == '-i':
            try:
                env = env_with_prelude()
            except OSError:
                return 2
            code_snippet = argv[2].decode('utf-8')
            lexed_tokens = lex(code_snippet)

            if is_thrown_exception(lexed_tokens, error):
                print u'Uncaught error: %s: %s' % (
                    lexed_tokens.exception_type.name,
                    lexed_tokens.message)
                return 1
            
            parse_tree = parse(lexed_tokens)

            try:
                result = evaluate_all(parse_tree, env)

                if is_thrown_exception(result, error):
                    # TODO: a proper stack trace.
                    print u'Uncaught error: %s: %s' % (result.exception_type.name,
                                              result.message)
                    return 1
                else:
                    print result.repr().encode('utf-8')
                
            except SystemExit:
                return 0
            return 0
            
    print USAGE
    return 1
Exemple #19
0
def test_lexer(test_case, expected):
    actual = lex(test_case)
    assert actual == expected