Example #1
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
Example #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
Example #3
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