text: """This module implements the primitives of the Scheme language."""
  
  import math
  import operator
  import sys
  from scheme_reader import Pair, nil
  
  try:
      import turtle
  except:
      print("warning: could not import the turtle module.", file=sys.stderr)
  
  class SchemeError(Exception):
      """Exception indicating an error in a Scheme program."""
  
  class okay(object):
      """Signifies an undefined value."""
      def __repr__(self):
          return "okay"
  
  okay = okay() # Assignment hides the okay class; there is only one instance
  
  ########################
  # Primitive Operations #
  ########################
  
  class PrimitiveProcedure:
      """A Scheme procedure defined as a Python function."""
  
      def __init__(self, fn, use_env=False):
          self.fn = fn
          self.use_env = use_env
  
      def __str__(self):
          return '#[primitive]'
  
  _PRIMITIVES = []
  
  def primitive(*names):
      """An annotation to convert a Python function into a PrimitiveProcedure."""
      def add(fn):
          proc = PrimitiveProcedure(fn)
          for name in names:
              _PRIMITIVES.append((name,proc))
          return fn
      return add
  
  def add_primitives(frame):
      """Enter bindings in _PRIMITIVES into FRAME, an environment frame."""
      for name, proc in _PRIMITIVES:
          frame.define(name, proc)
  
  def check_type(val, predicate, k, name):
      """Returns VAL.  Raises a SchemeError if not PREDICATE(VAL)
      using "argument K of NAME" to describe the offending value."""
      if not predicate(val):
          msg = "argument {0} of {1} has wrong type ({2})"
          raise SchemeError(msg.format(k, name, type(val).__name__))
      return val
  
  @primitive("boolean?")
  def scheme_booleanp(x):
      return x is True or x is False
  
  def scheme_true(val):
      """All values in Scheme are true except False."""
      return val is not False
  
  def scheme_false(val):
      """Only False is false in Scheme."""
      return val is False
  
  @primitive("not")
  def scheme_not(x):
      return not scheme_true(x)
  
  @primitive("eq?", "equal?")
  def scheme_eqp(x, y):
      return x == y
  
  @primitive("pair?")
  def scheme_pairp(x):
      return isinstance(x, Pair)
  
  @primitive("null?")
  def scheme_nullp(x):
      return x is nil
  
  @primitive("list?")
  def scheme_listp(x):
      """Return whether x is a well-formed list. Assumes no cycles."""
      while x is not nil:
          if not isinstance(x, Pair):
              return False
          x = x.second
      return True
  
  @primitive("length")
  def scheme_length(x):
      if x is nil:
          return 0
      check_type(x, scheme_listp, 0, 'length')
      return len(x)
  
  @primitive("cons")
  def scheme_cons(x, y):
      return Pair(x, y)
  
  @primitive("car")
  def scheme_car(x):
      check_type(x, scheme_pairp, 0, 'car')
      return x.first
  
  @primitive("cdr")
  def scheme_cdr(x):
      check_type(x, scheme_pairp, 0, 'cdr')
      return x.second
  
  
  @primitive("list")
  def scheme_list(*vals):
      result = nil
      for i in range(len(vals)-1, -1, -1):
          result = Pair(vals[i], result)
      return result
  
  @primitive("append")
  def scheme_append(*vals):
      if len(vals) == 0:
          return nil
      result = vals[-1]
      for i in range(len(vals)-2, -1, -1):
          v = vals[i]
          if v is not nil:
              check_type(v, scheme_pairp, i, "append")
              r = p = Pair(v.first, result)
              v = v.second
              while scheme_pairp(v):
                  p.second = Pair(v.first, result)
                  p = p.second
                  v = v.second
              result = r
      return result
  
  @primitive("string?")
  def scheme_stringp(x):
      return isinstance(x, str) and x.startswith('"')
  
  @primitive("symbol?")
  def scheme_symbolp(x):
      return isinstance(x, str) and not scheme_stringp(x)
  
  @primitive("number?")
  def scheme_numberp(x):
      return isinstance(x, int) or isinstance(x, float)
  
  @primitive("integer?")
  def scheme_integerp(x):
      return isinstance(x, int) or (scheme_numberp(x) and round(x) == x)
  
  def _check_nums(*vals):
      """Check that all arguments in VALS are numbers."""
      for i, v in enumerate(vals):
          if not scheme_numberp(v):
              msg = "operand {0} ({1}) is not a number"
              raise SchemeError(msg.format(i, v))
  
  def _arith(fn, init, vals):
      """Perform the fn fneration on the number values of VALS, with INIT as
      the value when VALS is empty. Returns the result as a Scheme value."""
      _check_nums(*vals)
      s = init
      for val in vals:
          s = fn(s, val)
      if round(s) == s:
          s = round(s)
      return s
  
  @primitive("+")
  def scheme_add(*vals):
      return _arith(operator.add, 0, vals)
  
  @primitive("-")
  def scheme_sub(val0, *vals):
      if len(vals) == 0:
          return -val0
      return _arith(operator.sub, val0, vals)
  
  @primitive("*")
  def scheme_mul(*vals):
      return _arith(operator.mul, 1, vals)
  
  @primitive("/")
  def scheme_div(val0, val1):
      try:
          return _arith(operator.truediv, val0, [val1])
      except ZeroDivisionError as err:
          raise SchemeError(err)
  
  @primitive("quotient")
  def scheme_quo(val0, val1):
      try:
          return _arith(operator.floordiv, val0, [val1])
      except ZeroDivisionError as err:
          raise SchemeError(err)
  
  @primitive("modulo", "remainder")
  def scheme_modulo(val0, val1):
      try:
          return _arith(operator.mod, val0, [val1])
      except ZeroDivisionError as err:
          raise SchemeError(err)
  
  @primitive("floor")
  def scheme_floor(val):
      _check_nums(val)
      return math.floor(val)
  
  @primitive("ceil")
  def scheme_ceil(val):
      _check_nums(val)
      return math.ceil(val)
  
  def _numcomp(op, x, y):
      _check_nums(x, y)
      return op(x, y)
  
  @primitive("=")
  def scheme_eq(x, y):
      return _numcomp(operator.eq, x, y)
  
  @primitive("<")
  def scheme_lt(x, y):
      return _numcomp(operator.lt, x, y)
  
  @primitive(">")
  def scheme_gt(x, y):
      return _numcomp(operator.gt, x, y)
  
  @primitive("<=")
  def scheme_le(x, y):
      return _numcomp(operator.le, x, y)
  
  @primitive(">=")
  def scheme_ge(x, y):
      return _numcomp(operator.ge, x, y)
  
  @primitive("even?")
  def scheme_evenp(x):
      _check_nums(x)
      return x % 2 == 0
  
  @primitive("odd?")
  def scheme_oddp(x):
      _check_nums(x)
      return x % 2 == 1
  
  @primitive("zero?")
  def scheme_zerop(x):
      _check_nums(x)
      return x == 0
  
  ##
  ## Other operations
  ##
  
  @primitive("atom?")
  def scheme_atomp(x):
      if scheme_booleanp(x):
          return True
      if scheme_numberp(x):
          return True
      if scheme_symbolp(x):
          return True
      if scheme_nullp(x):
          return True
      return False
  
  @primitive("display")
  def scheme_display(val):
      if scheme_stringp(val):
          val = eval(val)
      print(str(val), end="")
      return okay
  
  @primitive("print")
  def scheme_print(val):
      print(str(val))
      return okay
  
  @primitive("newline")
  def scheme_newline():
      print()
      sys.stdout.flush()
      return okay
  
  @primitive("error")
  def scheme_error(msg = None):
      msg = "" if msg is None else str(msg)
      raise SchemeError(msg)
  
  @primitive("exit")
  def scheme_exit():
      raise EOFError
  
  ##
  ## Turtle graphics (non-standard)
  ##
  
  _turtle_screen_on = False
  
  def turtle_screen_on():
      return _turtle_screen_on
  
  def _tscheme_prep():
      global _turtle_screen_on
      if not _turtle_screen_on:
          _turtle_screen_on = True
          turtle.title("Scheme Turtles")
          turtle.mode('logo')
  
  @primitive("forward", "fd")
  def tscheme_forward(n):
      """Move the turtle forward a distance N units on the current heading."""
      _check_nums(n)
      _tscheme_prep()
      turtle.forward(n)
      return okay
  
  @primitive("backward", "back", "bk")
  def tscheme_backward(n):
      """Move the turtle backward a distance N units on the current heading,
      without changing direction."""
      _check_nums(n)
      _tscheme_prep()
      turtle.backward(n)
      return okay
  
  @primitive("left", "lt")
  def tscheme_left(n):
      """Rotate the turtle's heading N degrees counterclockwise."""
      _check_nums(n)
      _tscheme_prep()
      turtle.left(n)
      return okay
  
  @primitive("right", "rt")
  def tscheme_right(n):
      """Rotate the turtle's heading N degrees clockwise."""
      _check_nums(n)
      _tscheme_prep()
      turtle.right(n)
      return okay
  
  @primitive("circle")
  def tscheme_circle(r, extent = None):
      """Draw a circle with center R units to the left of the turtle (i.e.,
      right if N is negative.  If EXTENT is not None, then draw EXTENT degrees
      of the circle only.  Draws in the clockwise direction if R is negative,
      and otherwise counterclockwise, leaving the turtle facing along the
      arc at its end."""
      if extent is None:
          _check_nums(r)
      else:
          _check_nums(r, extent)
      _tscheme_prep()
      turtle.circle(r, extent and extent)
      return okay
  
  @primitive("setposition", "setpos", "goto")
  def tscheme_setposition(x, y):
      """Set turtle's position to (X,Y), heading unchanged."""
      _check_nums(x, y)
      _tscheme_prep()
      turtle.setposition(x, y)
      return okay
  
  @primitive("setheading", "seth")
  def tscheme_setheading(h):
      """Set the turtle's heading H degrees clockwise from north (up)."""
      _check_nums(h)
      _tscheme_prep()
      turtle.setheading(h)
      return okay
  
  @primitive("penup", "pu")
  def tscheme_penup():
      """Raise the pen, so that the turtle does not draw."""
      _tscheme_prep()
      turtle.penup()
      return okay
  
  @primitive("pendown", "pd")
  def tscheme_pendown():
      """Lower the pen, so that the turtle starts drawing."""
      _tscheme_prep()
      turtle.pendown()
      return okay
  
  @primitive("showturtle", "st")
  def tscheme_showturtle():
      """Make turtle visible."""
      _tscheme_prep()
      turtle.showturtle()
      return okay
  
  @primitive("hideturtle", "ht")
  def tscheme_hideturtle():
      """Make turtle visible."""
      _tscheme_prep()
      turtle.hideturtle()
      return okay
  
  @primitive("clear")
  def tscheme_clear():
      """Clear the drawing, leaving the turtle unchanged."""
      _tscheme_prep()
      turtle.clear()
      return okay
  
  @primitive("color")
  def tscheme_color(c):
      """Set the color to C, a string such as '"red"' or '"#ffc0c0"' (representing
      hexadecimal red, green, and blue values."""
      _tscheme_prep()
      check_type(c, scheme_stringp, 0, "color")
      turtle.color(eval(c))
      return okay
  
  @primitive("begin_fill")
  def tscheme_begin_fill():
      """Start a sequence of moves that outline a shape to be filled."""
      _tscheme_prep()
      turtle.begin_fill()
      return okay
  
  @primitive("end_fill")
  def tscheme_end_fill():
      """Fill in shape drawn since last begin_fill."""
      _tscheme_prep()
      turtle.end_fill()
      return okay
  
  @primitive("exitonclick")
  def tscheme_exitonclick():
      """Wait for a click on the turtle window, and then close it."""
      global _turtle_screen_on
      if _turtle_screen_on:
          print("Close or click on turtle window to complete exit")
          turtle.exitonclick()
          _turtle_screen_on = False
      return okay
  
  @primitive("speed")
  def tscheme_speed(s):
      """Set the turtle's animation speed as indicated by S (an integer in
      0-10, with 0 indicating no animation (lines draw instantly), and 1-10
      indicating faster and faster movement."""
      check_type(s, scheme_integerp, 0, "speed")
      _tscheme_prep()
      turtle.speed(s)
      return okay
  