# 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()