Completed
Push — master ( 59f318...e377b7 )
by Wilfred
01:02
created

entry_point()   F

Complexity

Conditions 13

Size

Total Lines 76

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 13
dl 0
loc 76
rs 2.1875

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like entry_point() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# Copyright 2014 Wilfred Hughes. See docs/Licensing.md.
2
#
3
# Licensed under the Apache Licence, Version 2.0 <Licence-Apache.txt or
4
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT licence
5
# <Licence-MIT.txt or http://opensource.org/licenses/MIT>, at your
6
# option. This file may not be copied, modified, or distributed
7
# except according to those terms.
8
9
import sys
10
import os
11
12
from rpython.rtyper.module.ll_os_environ import getenv_llimpl
13
14
from interpreter.lexer import lex
15
from interpreter.trifle_parser import parse
16
from interpreter.evaluator import evaluate_all, is_thrown_exception
17
from interpreter.environment import fresh_environment
18
from interpreter.errors import error
19
20
21
def get_contents(filename):
22
    """Return the contents of this filename, as a unicode object. Assumes
23
    the file is UTF-8 encoded.
24
25
    """
26
    fp = os.open(filename, os.O_RDONLY, 0777)
27
28
    program_contents = ""
29
    while True:
30
        read = os.read(fp, 4096)
31
        if len(read) == 0:
32
            break
33
        program_contents += read
34
    os.close(fp)
35
36
    return program_contents.decode('utf-8')
37
38
39
def env_with_prelude():
40
    """Return a fresh environment where the prelude has already been
41
    evaluated.
42
43
    """
44
    # todo: document TRIFLEPATH
45
    # todo: should we inline the prelude, so changing TRIFLEPATH doens't break this?
46
    trifle_path = getenv_llimpl("TRIFLEPATH") or "."
47
    prelude_path = os.path.join(trifle_path, "prelude.tfl")
48
    
49
    # Trifle equivalent of PYTHONPATH.
50
    try:
51
        code = get_contents(prelude_path)
52
    except OSError:
53
        # TODO: work out which error occurred (not found/wrong
54
        # permissions/other) and be more helpful.
55
        print "Could not find prelude.tfl. Have you set TRIFLEPATH?"
56
        raise
57
58
    # TODO: either of these could return errors, and we should handle that.
59
    lexed_tokens = lex(code)
60
    parse_tree = parse(lexed_tokens)
61
62
    env = fresh_environment()
63
    result = evaluate_all(parse_tree, env)
64
65
    assert not is_thrown_exception(result, error), "Error when evaluating prelude: %s" % result
66
67
    return env
68
69
70
USAGE = """Usage:
71
./trifle -i <code snippet>
72
./trifle <path to script>"""
73
74
75
def entry_point(argv):
76
    """Either a file name:
77
    $ ./trifle ~/files/foo.tfl
78
79
    A code snippet:
80
    $ ./trifle -i '1 2'
81
82
    """
83
    if len(argv) == 2:
84
        # open the file
85
        filename = argv[1]
86
87
        if not os.path.exists(filename):
88
            print 'No such file: %s' % filename
89
            return 2
90
91
        try:
92
            env = env_with_prelude()
93
        except OSError:
94
            return 2
95
        code = get_contents(filename)
96
        lexed_tokens = lex(code)
97
98
        if is_thrown_exception(lexed_tokens, error):
99
            print u'Uncaught error: %s: %s' % (
100
                lexed_tokens.exception_type.name,
101
                lexed_tokens.message)
102
            return 1
103
104
        parse_tree = parse(lexed_tokens)
105
        try:
106
            result = evaluate_all(parse_tree, env)
107
108
            if is_thrown_exception(result, error):
109
                # TODO: a proper stack trace.
110
                print u'Uncaught error: %s: %s' % (result.exception_type.name,
111
                                          result.message)
112
                return 1
113
        except SystemExit:
114
            return 0
115
        return 0
116
    
117
    elif len(argv) == 3:
118
        if argv[1] == '-i':
119
            try:
120
                env = env_with_prelude()
121
            except OSError:
122
                return 2
123
            code_snippet = argv[2].decode('utf-8')
124
            lexed_tokens = lex(code_snippet)
125
126
            if is_thrown_exception(lexed_tokens, error):
127
                print u'Uncaught error: %s: %s' % (
128
                    lexed_tokens.exception_type.name,
129
                    lexed_tokens.message)
130
                return 1
131
            
132
            parse_tree = parse(lexed_tokens)
133
134
            try:
135
                result = evaluate_all(parse_tree, env)
136
137
                if is_thrown_exception(result, error):
138
                    # TODO: a proper stack trace.
139
                    print u'Uncaught error: %s: %s' % (result.exception_type.name,
140
                                              result.message)
141
                    return 1
142
                else:
143
                    print result.repr().encode('utf-8')
144
                
145
            except SystemExit:
146
                return 0
147
            return 0
148
            
149
    print USAGE
150
    return 1
151
152
153
def target(*args):
154
    return entry_point, None
155
156
157
if __name__ == '__main__':
158
    entry_point(sys.argv)
159