def logo_if(val, exp, env): """Apply the "if" primitive, which takes a boolean and a list. ***YOUR DOCTEST HERE*** >>> val = 'equal? 1 difference 6 5' >>> exp = 'print word "snake "yes' >>> env = Environment() >>> logo_if(val, exp, env) 'print word "snake "yes' >>> val = 'True' >>> exp = ['print', '3'] >>> env = Environment() >>> logo_if(val, exp, env) 3 """ "*** YOUR CODE HERE ***" bool_val = eval_line(Buffer(parse_line(val)), env) if bool_val == 'True': if type(exp) == list: return eval_line(Buffer(exp), env) else: return exp elif bool_val == 'False': return None else: error('First argument to "if" is not Ture or False: ' + str(bool_val))
def eval_definition(line, env): """Evaluate a definition and return a corresponding procedure. line: The definition line, following "to", of the multi-line definition. Hint: create a user-defined Procedure object using Procedure(name, len(params), body, formal_params=params, needs_env=True) - name is a string defining the procedure name - body is a list of Buffer objects (one per line of source code) - params is a list of strings defining the name of each formal parameter - needs_env is always True >>> to_line = Buffer(parse_line('to double :n')) >>> body = ['output sum :n :n\\n', 'end'] >>> env = Environment(generate_lines(body, '>')) >>> eval_line(to_line, env) > output sum :n :n > end >>> print(env.procedures['double']) to double :n >>> env.procedures['double'].needs_env True >>> env.procedures['double'].body [['output', 'sum', ':n', ':n']] """ procedure_name = line.pop() params = [] while line.current != None: params.append(line.pop()[1:]) next_line = lambda: parse_line(env.get_continuation_line()) body = [] cur = next_line() while cur != parse_line("end"): body.append(cur) cur = next_line() proc = Procedure(procedure_name, len(params), body, formal_params=params, needs_env=True) env.procedures[procedure_name] = proc
def eval_definition(line, env): """Evaluate a definition and return a corresponding procedure. line: The definition line, following "to", of the multi-line definition. Hint: create a user-defined Procedure object using Procedure(name, len(params), body, formal_params=params, needs_env=True) - name is a string defining the procedure name - body is a list of Buffer objects (one per line of source code) - params is a list of strings defining the name of each formal parameter - needs_env is always True >>> to_line = Buffer(parse_line('to double :n')) >>> body = ['output sum :n :n\\n', 'end'] >>> env = Environment(generate_lines(body, '>')) >>> eval_line(to_line, env) > output sum :n :n > end >>> print(env.procedures['double']) to double :n >>> env.procedures['double'].needs_env True >>> env.procedures['double'].body [['output', 'sum', ':n', ':n']] """ procedure_name = line.pop() para_len = 0 params = [] while line.current: para_len += 1 params.append(line.pop()) next_line = lambda: parse_line(env.get_continuation_line()) body = [] new_line = next_line() while new_line != ['end']: body += new_line new_line = next_line() body = [body] new_proc = Procedure(procedure_name, para_len, body, isprimitive=False, needs_env=True, formal_params=params) env.procedures[procedure_name] = new_proc
def eval_definition(line, env): """Evaluate a definition and create a corresponding procedure. line: The definition line, following "to", of the multi-line definition. Hint: create a user-defined Procedure object using Procedure(name, len(formal_params), body, False, True, formal_params) - name is a string defining the procedure name - body is a list of lists representing Logo sentences (one per line) - False indicates that it is not a primitive procedure - True indicates that evaluation requires the environment - formal_params is a list of strings naming each formal parameter If you were to evaluate the following Logo definition, ? to double :n > output sum :n :n > end the Procedure object you would create should be equivalent to: Procedure('double', 1, [['output', 'sum', ':n', ':n']], False, True, ['n']) Note: The doctest for this function was removed because of cross-platform compatibility issues with the Python doctest module. (11/17 @ 3:15 PM) """ "*** YOUR CODE HERE ***" procedure_name = line.pop() formal_params = [] while line.current: formal_params.append(line.pop()) next_line = lambda: parse_line(env.get_continuation_line()) body = [] while True: a_line = next_line() if a_line == ['end']: break body.append(a_line) env.procedures[procedure_name] = Procedure(procedure_name, len(formal_params), body, False, True, formal_params) return
def logo_ifelse(val, true_exp, false_exp, env): """Apply the "ifelse" primitive, which takes a boolean and two lists. ***YOUR DOCTEST HERE*** """ "*** YOUR CODE HERE ***" bool_val = eval_line(Buffer(parse_line(val)), env) if bool_val == 'True': if type(true_exp) == list: return eval_line(Buffer(true_exp), env) else: return true_exp elif bool_val == 'False': if type(false_exp) == list: return eval_line(Buffer(false_exp), env) else: return false_exp else: error('First argument to "ifelse" is not Ture or False: ' + str(bool_val))
def eval_line(line, env): """Evaluate a line (buffer) of Logo. >>> line = Buffer(parse_line('1 2')) >>> eval_line(line, Environment()) '1' >>> line = Buffer(parse_line('print 1 2')) >>> eval_line(line, Environment()) 1 '2' """ "*** YOUR CODE HERE ***" try: line.contents[0] except IndexError as e: return eval_line(Buffer(parse_line(prompt_for_line())), env) result = logo_eval(line, env) if not result and line.current: return eval_line(line, env) return result
def eval_definition(line, env): """Evaluate a definition and create a corresponding procedure. line: The definition line, following "to", of the multi-line definition. Hint: create a user-defined Procedure object using Procedure(name, len(params), body, formal_params=params, needs_env=True) - name is a string defining the procedure name - body is a list of lists representing Logo sentences (one per line) - params is a list of strings naming each formal parameter - needs_env is always True >>> to_line = Buffer(parse_line('to double :n')) >>> body = ['output sum :n :n\\n', 'end'] >>> env = Environment(generate_lines(body, '>')) >>> eval_line(to_line, env) > output sum :n :n > end >>> print(env.procedures['double']) to double :n >>> env.procedures['double'].needs_env True >>> env.procedures['double'].body [['output', 'sum', ':n', ':n']] """ procedure_name = line.pop() next_line = lambda: parse_line(env.get_continuation_line()) # "*** YOUR CODE HERE ***" # DONE params = [] while line.current != None: params.append(line.pop().lstrip(':')) body = [] current_line = next_line() while current_line != ['end']: body.append(current_line) current_line = next_line() p = Procedure(procedure_name, len(params), body, formal_params=params, needs_env=True) env.procedures[procedure_name] = p
def eval_definition(line, env): """Evaluate a definition and create a corresponding procedure. line: The definition line, following "to", of the multi-line definition. Hint: create a user-defined Procedure object using Procedure(name, len(formal_params), body, False, True, formal_params) - name is a string defining the procedure name - body is a list of lists representing Logo sentences (one per line) - False indicates that it is not a primitive procedure - True indicates that evaluation requires the environment - formal_params is a list of strings naming each formal parameter If you were to evaluate the following Logo definition, ? to double :n > output sum :n :n > end the Procedure object you would create should be equivalent to: Procedure('double', 1, [['output', 'sum', ':n', ':n']], False, True, ['n']) Note: The doctest for this function was removed because of cross-platform compatibility issues with the Python doctest module. (11/17 @ 3:15 PM) """ procedure_name = line.pop() next_line = lambda: parse_line(env.get_continuation_line()) args, body = [], [] while line.current is not None: arg = line.pop() args.append(text_of_quotation(arg)) while True: line = next_line() if len(line) == 1 and line[0] == 'end': break body.append(line) proc = Procedure(procedure_name, len(args), body, False, True, args) #print(procedure_name, args, body) env.procedures[procedure_name] = proc
def interpret_line(line, env): """Interpret a single line in the read-eval loop.""" result = eval_line(Buffer(parse_line(line)), env) if result is not None: error('You do not say what to do with {0}.'.format(result))