def scheme_read(src): """Read the next expression from SRC, a Buffer of tokens. >>> lines = ["(+ 1 ", "(+ 23 4)) ("] >>> src = Buffer(tokenize_lines(lines)) >>> print(scheme_read(src)) (+ 1 (+ 23 4)) >>> read_line("'hello") Pair('quote', Pair('hello', nil)) >>> print(read_line("(car '(1 2))")) (car (quote (1 2))) """ if src.current() is None: raise EOFError val = src.pop() if val == "nil": return nil elif type(val) is int or type(val) is float: return scnum(val) elif type(val) is bool: return scbool(val) elif val not in DELIMITERS: if val[0] == '"': return scstr(eval(val)) else: return intern(val) elif val == "'": return Pair(intern('quote'), Pair(scheme_read(src), nil)) elif val == "(": return read_tail(src) else: raise SyntaxError("unexpected token: {0}".format(val))
def read_tail(src): """Return the remainder of a list in SRC, starting before an element or ). >>> read_tail(Buffer(tokenize_lines([")"]))) nil >>> read_tail(Buffer(tokenize_lines(["2 3)"]))) Pair(2, Pair(3, nil)) >>> read_tail(Buffer(tokenize_lines(["2 (3 4))"]))) Pair(2, Pair(Pair(3, Pair(4, nil)), nil)) >>> read_line("(1 . 2)") Pair(1, 2) >>> read_line("(1 2 . 3)") Pair(1, Pair(2, 3)) >>> read_line("(1 . 2 3)") Traceback (most recent call last): ... SyntaxError: Expected one element after . >>> scheme_read(Buffer(tokenize_lines(["(1", "2 .", "'(3 4))", "4"]))) Pair(1, Pair(2, Pair('quote', Pair(Pair(3, Pair(4, nil)), nil)))) "'" """ try: if src.current() is None: raise SyntaxError("unexpected end of file") if src.current() == ")": src.pop() return nil "*** YOUR CODE HERE ***" first = scheme_read(src) rest = read_tail(src) return Pair(first, rest) except EOFError: raise SyntaxError("unexpected end of file")
def read_tail(src): """Return the remainder of a list in SRC, starting before an element or ). >>> read_tail(Buffer(tokenize_lines([")"]))) nil >>> read_tail(Buffer(tokenize_lines(["2 3)"]))) Pair(2, Pair(3, nil)) >>> read_tail(Buffer(tokenize_lines(["2 (3 4))"]))) Pair(2, Pair(Pair(3, Pair(4, nil)), nil)) >>> read_line("(1 . 2)") Pair(1, 2) >>> read_line("(1 . (2 3))") Pair(1, Pair(2, Pair(3, nil))) >>> read_line("(1 2 . 3)") Pair(1, Pair(2, 3)) >>> read_line("(1 . 2 3)") Traceback (most recent call last): ... SyntaxError: Expected one element after . >>> read_line("(2 (3 . 4) 5)") Pair(2, Pair(Pair(3, 4), Pair(5, nil))) >>> scheme_read(Buffer(tokenize_lines(["(1", "2 .", "'(3 4))", "4"]))) Pair(1, Pair(2, Pair('quote', Pair(Pair(3, Pair(4, nil)), nil)))) "'" """ try: if src.current() is None: raise SyntaxError("uexpected end of file") # base case for recursion on lists of Pairs. Last element is "nil" if src.current() == ")": src.pop() return nil "*** YOUR CODE HERE ***" if src.current() == ".": src.pop() # recursivly get second element second_element = scheme_read(src) # now we should be almost done if there is no third element but # the closing bracket if src.current() is not ')': raise SyntaxError("Expected one element after .") # "eat" the ')' src.pop() return second_element first = scheme_read(src) rest = read_tail(src) return Pair(first, rest) except EOFError: raise SyntaxError("unexpected end of file")
def scheme_read(src): # import pdb; pdb.set_trace() """Read the next expression from SRC, a Buffer of tokens. >>> lines = ["(+ 1 ", "(+ 23 4)) ("] >>> src = Buffer(tokenize_lines(lines)) >>> print(scheme_read(src)) (+ 1 (+ 23 4)) >>> read_line("(+ 1 2)") Pair('+', Pair(1, Pair(2, nil))) >>> read_line("'hello") Pair('quote', Pair('hello', nil)) >>> print(read_line("(car '(1 2))")) (car (quote (1 2))) """ if src.current() is None: raise EOFError val = src.pop() if val == "nil": return nil elif type(val) is int or type(val) is float: return scnum(val) elif type(val) is bool: return scbool(val) # self-evaluating elif val not in DELIMITERS: if val[0] == '"': return scstr(eval(val)) else: return intern(val) elif val == "'": "*** YOUR CODE HERE ***" # nested Pair eventually matches the required structure rest = scheme_read(src) return Pair("quote", Pair(rest, nil)) elif val == "(": return read_tail(src) else: raise SyntaxError("unexpected token: {0}".format(val))