[an error occurred while processing this directive]

cs150: Notes 29

Assignments Due

Core Evaluator

def meval(expr, env):
    if isPrimitive(expr):
       return evalPrimitive(expr)
    elif isConditional(expr):
       return evalConditional(expr, env)
    elif isLambda(expr):
       return evalLambda(expr, env)
    elif isDefinition(expr):                
       evalDefinition(expr, env)
    elif isName(expr):
       return evalName(expr, env)
    elif isApplication(expr):
       return evalApplication(expr, env)
    else:
       evalError ("Unknown expression type: " + str(expr))

Primitives

def isNumber(expr):
    return isinstance(expr, str) and expr.isdigit()

def isPrimitiveProcedure(expr):
    return callable(expr)

def isPrimitive(expr):
    return (isNumber(expr) or isPrimitiveProcedure(expr))

def evalPrimitive(expr):
    # A primitive evaluates to its pre-defined value
    if isNumber(expr):
        return int(expr)
    else:

        __________________

Example Primitive Procedure

def primitivePlus (operands):
    if (len(operands) == 0):
       return 0
    else:
       return operands[0] + primitivePlus (operands[1:])


def initializeGlobalEnvironment():
   ...
   globalEnvironment.addVariable('+', primitivePlus)
   ...

Conditionals

def isSpecialForm(expr, keyword):
    return isinstance(expr, list) \
           and len(expr) > 0 and expr[0] == keyword

def isConditional(expr):
    return isSpecialForm(expr, 'cond')

def evalConditional(expr, env):
    assert isConditional(expr)
    if len(expr) <= 2:
        evalError ("Bad conditional expression: %s" % str(expr))
    for clause in expr[1:]:
        if len(clause) != 2:
            evalError ("Bad conditional clause: %s" % str(clause))
        predicate = _____________

        result = ____________________
        if not result == False:

            return _________________________

    evalError ("No conditional predicate evaluates to non-false value: %s"
               % (expr))
    return None

Environments, Definitions, and Names

class Environment:
    def __init__(self, parent):
        self._parent = parent
        self._frame = { }
    def addVariable(self, name, value):
        # add a new name, or replace old value
        self._frame[name] = value
    def lookupVariable(self, name):
        if self._frame.has_key(name):
            return self._frame[name]
        
        ____________________:    

            return ____________________________
        else:
            evalError("Undefined name: %s" % (name))
    def toString(self):
        return "" % (str(self._frame), str(self._parent))

def isDefinition(expr):
    return isSpecialForm(expr, 'define')

def evalDefinition(expr, env):
    assert isDefinition(expr)
    if len(expr) != 3:
        evalError ("Bad definition: %s" % str(expr))
    name = expr[1]
    if isinstance(name, str):

        _____________________________        

        _____________________________

    elif isinstance(name, list):
        evalError ("Procedure definition syntax not implemented")
    else:
        evalError ("Bad definition: %s" % str(expr))

def isName(expr):
    return isinstance(expr, str)

def evalName(expr, env):
    # To evaluate a name, lookup the value of the name in the environment
    assert isName(expr)
    return env.lookupVariable(expr)

Procedures and Applications


class Procedure:
    def __init__(self, params, body, env):
        self._params = params
        self._body = body
        self._env = env
    def getParams(self):
        return self._params
    def getBody(self):
        return self._body
    def getEnvironment(self):
        return self._env        
    def toString(self):
        return "" % (str(self._params), str(self._body))

def isLambda(expr):
    return isSpecialForm(expr, 'lambda')

def evalLambda(expr,env):
    assert isLambda(expr)
    if len(expr) != 3:
        evalError ("Bad lambda expression: %s" % str(expr))

    return __________________________
                      
def isApplication(expr):
    # Applications are lists [proc, oper, oper]
    # Assumes expr is not a special form (must check special forms first)
    return isinstance(expr, list)
   
def evalApplication(expr, env):
    # To evaluate an application, evaluate all the subexpressions

    subexprvals = map (____________________________, expr)

    return mapply(________________, ________________)

def mapply(proc, operands):
    if (isPrimitiveProcedure(proc)):
        return ____________________
    elif isinstance(proc, Procedure):
        params = proc.getParams()

        newenv = _____________________
        if len(params) != len(operands):
            evalError ("Parameter length mismatch: %s given operands %s" \
                       % (proc.toString(), str(operands)))
        for i in range(0, len(params)):
            newenv.addVariable(params[i], operands[i])        

        return _______________________
    else:
        evalError("Application of non-procedure: %s" % (proc))