def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder, eval_operands=True): verify_exact_callable_length(self, 1, len(operands)) if eval_operands: operands = evaluate_all(operands, frame, gui_holder.expression.children[1:]) if (not isinstance(operands[0], Symbol)): raise OperandDeduceError(''.join([ 'Load expected a Symbol, received ', '{}'.format(operands[0]), '.' ])) if logger.fragile: raise IrreversibleOperationError() try: with open(''.join(['{}'.format(operands[0].value), '.scm'])) as file: code = (('(begin' + '\n'.join(file.readlines())) + '\n)') buffer = TokenBuffer([code]) expr = get_expression(buffer) gui_holder.expression.set_entries([ VisualExpression(expr, gui_holder.expression.display_value) ]) gui_holder.apply() return evaluate(expr, frame, gui_holder.expression.children[0], True) except OSError as e: raise LoadError(e)
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder, eval_operands=True): verify_exact_callable_length(self, 1, len(operands)) if eval_operands: operands = evaluate_all(operands, frame, gui_holder.expression.children[1:]) if not isinstance(operands[0], Symbol): raise OperandDeduceError( f"Load expected a Symbol, received {operands[0]}.") if logger.fragile: raise IrreversibleOperationError() try: with open(f"{operands[0].value}.scm") as file: code = "(begin-noexcept" + "\n".join(file.readlines()) + "\n)" buffer = TokenBuffer([code]) expr = get_expression(buffer) gui_holder.expression.set_entries([ VisualExpression(expr, gui_holder.expression.display_value) ]) gui_holder.apply() return evaluate(expr, frame, gui_holder.expression.children[0], True) except OSError as e: raise LoadError(e)
def get_expression(buffer: TokenBuffer) -> Union[(Expression, None)]: token = buffer.pop_next_token() if (token is None): return None elif (token in ('(', '[')): return get_rest_of_list(buffer, (')' if (token == '(') else ']')) elif (token == "'"): return make_list([Symbol('quote'), get_expression(buffer)]) elif (token == ','): if (buffer.get_next_token() == '@'): buffer.pop_next_token() return make_list( [Symbol('unquote-splicing'), get_expression(buffer)]) else: return make_list([Symbol('unquote'), get_expression(buffer)]) elif (token == '`'): return make_list([Symbol('quasiquote'), get_expression(buffer)]) elif (token == '.'): if logger.dotted: raise ParseError(''.join( ["Unexpected token: '", '{}'.format(token), "'"])) else: return make_list([Symbol('variadic'), get_expression(buffer)]) elif (token == '"'): return get_string(buffer) elif (token in SPECIALS): raise ParseError(''.join( ["Unexpected token: '", '{}'.format(token), "'"])) elif is_number(token.value): try: return Number(int(token.value)) except ValueError: return Number(float(token.value)) elif ((token == '#t') or (token.value.lower() == 'true')): return SingletonTrue elif ((token == '#f') or (token.value.lower() == 'false')): return SingletonFalse elif (token == 'nil'): return Nil elif is_str(token.value): return Symbol(token.value.lower()) else: raise ParseError(''.join( ["Unexpected token: '", '{}'.format(token), "'"]))
def get_string(buffer: TokenBuffer) -> String: out = [] string = buffer.pop_next_token() escaping = False for char in string.value: if escaping: if (char == 'n'): out.append('\n') else: out.append(char) escaping = False elif (char == '\\'): escaping = True else: out.append(char) if (buffer.pop_next_token() != '"'): raise ParseError('String not terminated correctly!') return String(''.join(out))
def get_string(buffer: TokenBuffer) -> String: out = [] string = buffer.pop_next_token() escaping = False for char in string.value: if escaping: if char == "n": out.append("\n") else: out.append(char) escaping = False elif char == "\\": escaping = True else: out.append(char) if buffer.pop_next_token() != "\"": raise ParseError("String not terminated correctly!") return String("".join(out))
def get_expression(buffer: TokenBuffer) -> Union[Expression, None]: token = buffer.pop_next_token() if token is None: return None elif token in ("(", "["): return get_rest_of_list(buffer, ")" if token == "(" else "]") elif token == "'": return make_list([Symbol("quote"), get_expression(buffer)]) elif token == ",": if buffer.get_next_token() == "@": buffer.pop_next_token() return make_list( [Symbol("unquote-splicing"), get_expression(buffer)]) else: return make_list([Symbol("unquote"), get_expression(buffer)]) elif token == "`": return make_list([Symbol("quasiquote"), get_expression(buffer)]) elif token == ".": if logger.dotted: raise ParseError(f"Unexpected token: '{token}'") else: return make_list([Symbol("variadic"), get_expression(buffer)]) elif token == "\"": return get_string(buffer) elif token in SPECIALS: raise ParseError(f"Unexpected token: '{token}'") elif is_number(token.value): try: return Number(int(token.value)) except ValueError: return Number(float(token.value)) elif token == "#t" or token.value.lower() == "true": return SingletonTrue elif token == "#f" or token.value.lower() == "false": return SingletonFalse elif token == "nil": return Nil elif is_str(token.value): return Symbol(token.value.lower()) else: raise ParseError(f"Unexpected token: '{token}'")
def strip_comments(code): try: out = '' for string in code: if (not string.strip()): continue buff = TokenBuffer([string]) while (not buff.done): out += str(get_expression(buff)) return out except ParseError: return str(code)
def get_rest_of_list(buffer: TokenBuffer, end_paren: str): out = [] last = None while ((buffer.get_next_token() != end_paren) and (buffer.get_next_token() != '.')): out.append(get_expression(buffer)) if (buffer.get_next_token() == '.'): buffer.pop_next_token() last = get_expression(buffer) if (buffer.get_next_token() != end_paren): raise ParseError( 'Only one expression may follow a dot in a dotted list.') buffer.pop_next_token() return FormatList(out, last, [], end_paren, True)
def get_rest_of_list(buffer: TokenBuffer, end_paren: str) -> Expression: out = [] last = Nil while True: next = buffer.get_next_token() if next == end_paren: buffer.pop_next_token() break elif logger.dotted and next == ".": buffer.pop_next_token() last = get_expression(buffer) if buffer.pop_next_token() != end_paren: raise ParseError( f"Only one expression may follow a dot in a dotted list.") break expr = get_expression(buffer) out.append(expr) out = make_list(out, last) return out
def get_rest_of_list(buffer: TokenBuffer, end_paren: str): out = [] while (buffer.get_next_token() != end_paren): out.append(get_expression(buffer)) buffer.pop_next_token() return FormatList(out, end_paren)
def get_expression(buffer: TokenBuffer) -> Formatted: token = buffer.pop_next_token() if isinstance(token, Comment): return FormatComment(token.value, (not token.first_in_line)) elif ((token == '#') and (not buffer.done) and (buffer.get_next_token() == '[')): buffer.pop_next_token() out = FormatAtom((('#[' + buffer.pop_next_token().value) + ']')) buffer.pop_next_token() elif (token in SPECIALS): if (token in ('(', '[')): out = get_rest_of_list(buffer, (')' if (token == '(') else ']')) elif (token in ("'", '`')): out = get_expression(buffer) out.prefix = token.value elif (token == ','): if (buffer.get_next_token() == '@'): buffer.pop_next_token() out = get_expression(buffer) out.prefix = ',@' else: out = get_expression(buffer) out.prefix = token.value elif (token == '"'): out = FormatAtom((('"' + buffer.pop_next_token().value) + '"')) buffer.pop_next_token() else: raise ParseError(''.join( ["Unexpected token: '", '{}'.format(token), "'"])) else: if (token.value.lower() == 'true'): token.value = '#t' elif (token.value.lower() == 'false'): token.value = '#f' out = FormatAtom(token.value) return out
def string_exec(strings, out, visualize_tail_calls, global_frame=None): import log empty = False if global_frame is None: empty = True from environment import build_global_frame log.logger.f_delta -= 1 global_frame = build_global_frame() log.logger.active_frames.pop(0) # clear builtin frame log.logger.f_delta += 1 log.logger.global_frame = log.logger.frame_lookup[id(global_frame)] log.logger.graphics_lookup[id(global_frame)] = Canvas() log.logger.export_states = [] log.logger.roots = [] log.logger.frame_updates = [] log.logger._out = [] log.logger.visualize_tail_calls(visualize_tail_calls) for i, string in enumerate(strings): try: if not string.strip(): continue buff = TokenBuffer([string]) while not buff.done: expr = get_expression(buff) if expr is None: continue empty = False log.logger.new_expr() holder = Holder(expr, None) Root.setroot(holder) res = evaluate(expr, global_frame, holder) if res is not Undefined: out(res) if not log.logger.fragile and log.logger.autodraw: try: log.logger.raw_out("AUTODRAW" + json.dumps([log.logger.i, log.logger.heap.record(res)]) + "\n") except RecursionError: pass except (SchemeError, ZeroDivisionError, RecursionError, ValueError) as e: if isinstance(e, ParseError): log.logger.new_expr() raise if not log.logger.fragile: log.logger.raw_out("Traceback (most recent call last)\n") for j, expr in enumerate(log.logger.eval_stack[:MAX_TRACEBACK_LENGTH - 1]): log.logger.raw_out(str(j).ljust(3) + " " + expr + "\n") truncated = len(log.logger.eval_stack) - MAX_TRACEBACK_LENGTH if len(log.logger.eval_stack) > MAX_TRACEBACK_LENGTH: log.logger.raw_out(f"[{truncated} lines omitted from traceback]\n") log.logger.raw_out( str(len(log.logger.eval_stack) - 1).ljust(3) + " " + log.logger.eval_stack[-1] + "\n" ) log.logger.out(e) except TimeLimitException: if not log.logger.fragile: log.logger.out("Time limit exceeded.") log.logger.new_expr() if empty: log.logger.new_expr() holder = Holder(Undefined, None) Root.setroot(holder) evaluate(Undefined, global_frame, holder) log.logger.new_expr()
def get_expression(buffer: TokenBuffer) -> Formatted: token = buffer.pop_next_token() if isinstance(token, Comment): return FormatComment(token.value, not token.first_in_line) elif token == "#" and not buffer.done and buffer.get_next_token() == "[": buffer.pop_next_token() out = FormatAtom("#[" + buffer.pop_next_token().value + "]") buffer.pop_next_token() elif token in SPECIALS: if token in ("(", "["): out = get_rest_of_list(buffer, ")" if token == "(" else "]") elif token in ("'", "`"): out = get_expression(buffer) out.prefix = token.value + out.prefix elif token == ",": if buffer.get_next_token() == "@": buffer.pop_next_token() out = get_expression(buffer) out.prefix = ",@" + out.prefix else: out = get_expression(buffer) out.prefix = token.value + out.prefix elif token == "\"": out = FormatAtom('"' + buffer.pop_next_token().value + '"') buffer.pop_next_token() else: raise ParseError(f"Unexpected token: '{token}'") else: if token.value.lower() == "true": token.value = "#t" elif token.value.lower() == "false": token.value = "#f" out = FormatAtom(token.value) return out
def get_expression(buffer: TokenBuffer) -> Formatted: token = buffer.pop_next_token() comments = [] if ((token == '#') and (not buffer.done) and (buffer.get_next_token() == '[')): buffer.pop_next_token() out = FormatAtom((('#[' + buffer.pop_next_token().value) + ']')) buffer.pop_next_token() elif (token in SPECIALS): comments = token.comments if (token in ('(', '[')): out = get_rest_of_list(buffer, (')' if (token == '(') else ']')) elif (token in ("'", '`')): out = get_expression(buffer) out.prefix = token.value elif (token == ','): if (buffer.get_next_token() == '@'): buffer.pop_next_token() out = get_expression(buffer) out.prefix = ',@' else: out = get_expression(buffer) out.prefix = token.value elif (token == '"'): out = FormatAtom((('"' + buffer.pop_next_token().value) + '"')) buffer.pop_next_token() else: raise ParseError(''.join( ["Unexpected token: '", '{}'.format(token), "'"])) else: if (token.value.lower() == 'true'): token.value = '#t' elif (token.value.lower() == 'false'): token.value = '#f' out = FormatAtom(token.value) out.comments = (comments + buffer.tokens[(buffer.i - 1)].comments) out.allow_inline = (token.comments_inline and buffer.tokens[(buffer.i - 1)].comments_inline) return out
def string_exec(strings, out, global_frame=None): import log empty = False if (global_frame is None): empty = True from environment import build_global_frame log.logger.f_delta -= 1 global_frame = build_global_frame() log.logger.active_frames.pop(0) log.logger.f_delta += 1 log.logger.global_frame = log.logger.frame_lookup[id(global_frame)] log.logger.graphics_lookup[id(global_frame)] = Canvas() log.logger.export_states = [] log.logger.roots = [] log.logger.frame_updates = [] log.logger._out = [] for (i, string) in enumerate(strings): try: if (not string.strip()): continue buff = TokenBuffer([string]) while (not buff.done): expr = get_expression(buff) if (expr is None): continue empty = False log.logger.new_expr() holder = Holder(expr, None) Root.setroot(holder) res = evaluate(expr, global_frame, holder) if (res is not Undefined): out(res) if ((not log.logger.fragile) and log.logger.autodraw and isinstance(res, Pair)): log.logger.raw_out((('AUTODRAW' + json.dumps( [log.logger.i, log.logger.heap.record(res)])) + '\n')) except (SchemeError, ZeroDivisionError, RecursionError, ValueError) as e: if isinstance(e, ParseError): log.logger.new_expr() raise if (not log.logger.fragile): log.logger.raw_out('Traceback (most recent call last)\n') for (j, expr) in enumerate( log.logger.eval_stack[:(MAX_TRACEBACK_LENGTH - 1)]): log.logger.raw_out( (((str(j).ljust(3) + ' ') + expr) + '\n')) truncated = (len(log.logger.eval_stack) - MAX_TRACEBACK_LENGTH) if (len(log.logger.eval_stack) > MAX_TRACEBACK_LENGTH): log.logger.raw_out(''.join([ '[', '{}'.format(truncated), ' lines omitted from traceback]\n' ])) log.logger.raw_out((((str( (len(log.logger.eval_stack) - 1)).ljust(3) + ' ') + log.logger.eval_stack[(-1)]) + '\n')) log.logger.out(e) except TimeLimitException: if (not log.logger.fragile): log.logger.out('Time limit exceeded.') log.logger.new_expr() if empty: log.logger.new_expr() holder = Holder(Undefined, None) Root.setroot(holder) evaluate(Undefined, global_frame, holder) log.logger.new_expr()