# File: sifflet.py
# Python definitions for built-in Sifflet functions
# The variable "undefined" (sifflet.undefined) is reserved for Sifflet,
# representing an undefined variable.
# Identifiers containing any of the substrings _QUESTION_, _CHR0_,
# _CHR1_, ... _CHR255_ are reserved for Sifflet.
# For example: "zero_QUESTION_", "zero_CHR33_".
def add1 (n):
return n + 1
def sub1 (n):
return n - 1
def eqZero (n):
return (n == 0)
def gtZero (n):
return (n > 0)
def ltZero (n):
return (n < 0)
def null (xs):
return xs.null()
def head (xs):
return xs.head()
def tail (xs):
return xs.tail()
def cons (x, xs):
return Cons(x, xs)
# The List data type
# These could use some methods to implement operations,
# like __eq__ and __repr__
# List delimiters
ListBegin = "li("
ListEnd = ")"
class List:
pass
class Null (List):
def __repr__ (self): return ListBegin + ListEnd
def __repr2__ (self, _): return ListEnd
def null(self): return True
def head(self): error("head: empty list")
def tail(self): error("tail: empty list")
class Cons (List):
def __init__ (self, h, t):
self.__head = h
self.__tail = t
def __repr__ (self):
return self.__repr2__(ListBegin)
def __repr2__ (self, prefix):
return prefix + repr(self.__head) + self.__tail.__repr2__(", ")
def null (self): return False
def head (self): return self.__head
def tail (self): return self.__tail
## Create a List (linked list) from any number of arguments,
## using the same notation as when Lists are converted to string reprs:
def li (*args): return al_to_ll(args)
# Convert between our List type and Python's built-in list type.
# Axioms:
# I. If alist is a Python list, then ll_to_al(al_to_ll(alist)) == alist
# II. If llist is a List, then al_to_ll(ll_to_al(llist)) == llist
## al_to_ll: convert Python list to our List type (linked list)
def al_to_ll (alist):
node = Null()
n = len(alist)
for i in range(n - 1, -1, -1):
node = cons(alist[i], node)
return node
## ll_to_al: convert our List type to Python list (array list)
def ll_to_al (llist):
alist = []
while not null(llist):
alist.append(head(llist))
llist = tail(llist)
return alist
# Handy
empty = Null()