Esempio n. 1
0
    def testTrampoline(self):
        # trampolined factorial
        def fact(n, ans, cont):
            if n < 2:
                return bounce(cont, ans)
            else:
                return bounce(fact, n-1, n*ans, cont)

        ans = pogo_stick(bounce(fact, 5, 1, lambda d:d))
        self.assertEqual(ans, 120)

        ans = pogo_stick(bounce(fact, 1, 1, lambda d:d))
        self.assertEqual(ans, 1)


        # member search
        def memq(target, lst, cont):
            if lst == []:
                return bounce(cont, False)
            elif target == lst[0]:
                return bounce(cont, True)
            else:
                return bounce(memq, target, lst[1:], cont)

        ans = pogo_stick(bounce(memq, 3, [1, 2, 3, 4, 5], lambda d:d))
        self.assertEqual(ans, True)

        ans = pogo_stick(bounce(memq, 3, [1, 2, 4, 5, 6], lambda d:d))
        self.assertEqual(ans, False)
Esempio n. 2
0
    def parse_sexp(self, tokens, cont):
        """Parse a single S-expression.
        """
        token_type = tokens[0][1]
        if token_type in (TOKEN_TYPE_BOOLEAN, 
                          TOKEN_TYPE_INTEGER, 
                          TOKEN_TYPE_FLOAT, 
                          TOKEN_TYPE_FRACTION, 
                          TOKEN_TYPE_COMPLEX, 
                          TOKEN_TYPE_STRING, 
                          TOKEN_TYPE_SYMBOL,):
            return bounce(self.parse_lexeme_datum, tokens, cont)

        elif token_type == TOKEN_TYPE_SINGLE_QUOTE:
            def make_quote(word):
                return bounce(cont, lib_list(tsym('quote'), word))

            self.consume(tokens, TOKEN_TYPE_SINGLE_QUOTE)
            return bounce(self.parse_sexp, tokens, make_quote)

        elif token_type == TOKEN_TYPE_LPAREN:
            return bounce(self.parse_list, tokens, cont)

        else:
            raise SchemeError('bad expression syntax')
Esempio n. 3
0
 def memq(target, lst, cont):
     if lst == []:
         return bounce(cont, False)
     elif target == lst[0]:
         return bounce(cont, True)
     else:
         return bounce(memq, target, lst[1:], cont)
Esempio n. 4
0
 def done_rest(rest):
     if rest[0] == '(':
         if rest[1:-1] == '':
             return bounce(cont, '(' + first + ')')
         else:
             return bounce(cont, '(' + first + ' ' + rest[1:-1] + ')')
     else:
         return bounce(cont, '(' + first + ' . ' + rest + ')')
Esempio n. 5
0
def _to_python_list(scmlist, pylist, cont):
    """Convert a Scheme list into a Python list.
    """
    def got_first(first):
        nonlocal pylist
        pylist.append(first)
        return bounce(_to_python_list, scmlist[1], pylist, cont)

    if scmlist.isnil:
        return bounce(cont, pylist)

    if isinstance(scmlist[0], Pair):
        return bounce(_to_python_list, scmlist[0], [], got_first)

    pylist.append(scmlist[0])
    return bounce(_to_python_list, scmlist[1], pylist, cont)
Esempio n. 6
0
def _from_python_list(pylist, scmlist, cont):
    """Produce a Scheme list from a Python list.
    """
    def got_first(first):
        nonlocal scmlist
        scmlist = Pair([first, scmlist])
        return bounce(_from_python_list, pylist[1:], scmlist, cont)

    if pylist == []:
        return bounce(cont, scmlist)

    if isinstance(pylist[0], list):
        return bounce(_from_python_list, list(reversed(pylist[0])), NIL, got_first)

    scmlist = Pair([pylist[0], scmlist])
    return bounce(_from_python_list, pylist[1:], scmlist, cont)
Esempio n. 7
0
    def parse_list(self, tokens, cont):
        """Parse a Scheme list.
        """
        def done_rest(rest):
            self.consume(tokens, TOKEN_TYPE_RPAREN)
            return bounce(cont, rest)

        self.consume(tokens, TOKEN_TYPE_LPAREN)
        return bounce(self.parse_rest_sexps, tokens, done_rest)
Esempio n. 8
0
 def parse(self, tokens):
     """The interface. Returns the list of S-expressions
     generated from the given token list.
     """
     self.sexps = []
     while True:
         if len(tokens) == 0:
             return self.sexps
         self.sexps.append(pogo_stick(bounce(self.parse_sexp, tokens, lambda d:d)))
Esempio n. 9
0
 def done_first(first):
     def done_rest(rest):
         if rest[0] == '(':
             if rest[1:-1] == '':
                 return bounce(cont, '(' + first + ')')
             else:
                 return bounce(cont, '(' + first + ' ' + rest[1:-1] + ')')
         else:
             return bounce(cont, '(' + first + ' . ' + rest + ')')
     return bounce(_to_str, p[1], done_rest)
Esempio n. 10
0
def _to_str(p, cont):
    """Give the neat string representation of a pair.
    """
    def done_first(first):
        def done_rest(rest):
            if rest[0] == '(':
                if rest[1:-1] == '':
                    return bounce(cont, '(' + first + ')')
                else:
                    return bounce(cont, '(' + first + ' ' + rest[1:-1] + ')')
            else:
                return bounce(cont, '(' + first + ' . ' + rest + ')')
        return bounce(_to_str, p[1], done_rest)

    if not isinstance(p, Pair):
        return bounce(cont, str(p))
    if p.isnil:
        return bounce(cont, '()')
    return bounce(_to_str, p[0], done_first)
Esempio n. 11
0
    def parse_rest_sexps(self, tokens, cont):
        """Parse the S-expressions in the list. The list may 
        be a Scheme list or a dotted partial list.
        """
        token_type = tokens[0][1]
        if token_type == TOKEN_TYPE_DOT:
            self.consume(tokens, TOKEN_TYPE_DOT)
            return bounce(self.parse_sexp, tokens, cont)

        elif token_type != TOKEN_TYPE_RPAREN:
            def done_first(first):
                nonlocal saved_first_exp
                saved_first_exp = first
                return bounce(self.parse_rest_sexps, tokens, done_rest)

            def done_rest(rest):
                return bounce(cont, cons(saved_first_exp, rest))

            saved_first_exp = None
            return bounce(self.parse_sexp, tokens, done_first)

        else:
            return bounce(cont, NIL)
Esempio n. 12
0
    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')
Esempio n. 13
0
 def fact(n, ans, cont):
     if n < 2:
         return bounce(cont, ans)
     else:
         return bounce(fact, n-1, n*ans, cont)
Esempio n. 14
0
 def done_first(first):
     nonlocal saved_first_exp
     saved_first_exp = first
     return bounce(self.parse_rest_sexps, tokens, done_rest)
Esempio n. 15
0
 def got_first(first):
     nonlocal scmlist
     scmlist = Pair([first, scmlist])
     return bounce(_from_python_list, pylist[1:], scmlist, cont)
Esempio n. 16
0
 def done_rest(rest):
     return bounce(cont, cons(saved_first_exp, rest))
Esempio n. 17
0
def to_python_list(scmlist):
    return pogo_stick(bounce(_to_python_list, scmlist, [], lambda d:d))
Esempio n. 18
0
 def got_first(first):
     nonlocal pylist
     pylist.append(first)
     return bounce(_to_python_list, scmlist[1], pylist, cont)
Esempio n. 19
0
 def done_rest(rest):
     self.consume(tokens, TOKEN_TYPE_RPAREN)
     return bounce(cont, rest)
Esempio n. 20
0
def to_str(p):
    return pogo_stick(bounce(_to_str, p, lambda d:d))
Esempio n. 21
0
 def make_quote(word):
     return bounce(cont, lib_list(tsym('quote'), word))
Esempio n. 22
0
def from_python_list(pylist):
    return pogo_stick(bounce(_from_python_list, list(reversed(pylist)), NIL, lambda d:d))