def execute_evaluated(self, operands: List[Expression], frame: Frame): verify_exact_callable_length(self, 2, len(operands)) for operand in operands: if (not isinstance(operand, Number)): raise OperandDeduceError( ''.join(['Expected operand to be Number, not ', '{}'.format(operand)])) log.logger.get_canvas().move(operands[0].value, (- operands[1].value)) return Undefined
def pair_to_list(pos: Pair) -> List[Expression]: out = [] while pos is not Nil: if not isinstance(pos, Pair): raise OperandDeduceError(f"List terminated with '{pos}', not nil") out.append(pos.first) pos = pos.rest return out
def execute_simple(self, operand: Expression) -> Expression: if isinstance(operand, Pair): return operand.rest else: raise OperandDeduceError(''.join([ 'Unable to extract second element, as ', '{}'.format(operand), ' is not a Pair.' ]))
def execute_evaluated(self, operands: List[Expression], frame: Frame): verify_exact_callable_length(self, 2, len(operands)) for operand in operands: if not isinstance(operand, Number): raise OperandDeduceError( f"Expected operand to be Number, not {operand}") log.logger.get_canvas().move(operands[0].value, -operands[1].value) return Undefined
def pair_to_list(pos: Pair) -> List[Expression]: out = [] while (pos is not Nil): if (not isinstance(pos, Pair)): raise OperandDeduceError( ''.join(["List terminated with '", '{}'.format(pos), "', not nil"])) out.append(pos.first) pos = pos.rest return out
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: verify_exact_callable_length(self, 3, len(operands)) (x, y, c) = operands for v in (x, y): if (not isinstance(v, Number)): raise OperandDeduceError( ''.join(['Expected operand to be Number, not ', '{}'.format(v)])) log.logger.get_canvas().pixel(x.value, y.value, make_color(c)) return Undefined
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder): verify_min_callable_length(self, 2, len(operands)) bindings = operands[0] if ((not isinstance(bindings, Pair)) and (bindings is not Nil)): raise OperandDeduceError(''.join([ 'Expected first argument of let to be a Pair, not ', '{}'.format(bindings), '.' ])) new_frame = Frame('anonymous let', frame) gui_holder.expression.children[1].link_visual( VisualExpression(bindings)) bindings_holder = gui_holder.expression.children[1] bindings = pair_to_list(bindings) for (i, binding) in enumerate(bindings): if (not isinstance(binding, Pair)): raise OperandDeduceError(''.join([ 'Expected binding to be a Pair, not ', '{}'.format(binding), '.' ])) binding_holder = bindings_holder.expression.children[i] binding_holder.link_visual(VisualExpression(binding)) binding = pair_to_list(binding) if (len(binding) != 2): raise OperandDeduceError(''.join([ 'Expected binding to be of length 2, not ', '{}'.format(len(binding)), '.' ])) (name, expr) = binding if (not isinstance(name, Symbol)): raise OperandDeduceError(''.join([ 'Expected first element of binding to be a Symbol, not ', '{}'.format(name), '.' ])) new_frame.assign( name, evaluate(expr, frame, binding_holder.expression.children[1])) value = None for (i, (operand, holder)) in enumerate( zip(operands[1:], gui_holder.expression.children[2:])): value = evaluate(operand, new_frame, holder, (i == (len(operands) - 2))) new_frame.assign(return_symbol, value) return value
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: verify_exact_callable_length(self, 2, len(operands)) if log.logger.fragile: raise IrreversibleOperationError() pair, val = operands if not isinstance(pair, Pair): raise OperandDeduceError(f"set-car! expected a Pair, received {pair}.") pair.first = val log.logger.raw_out("WARNING: Mutation operations on pairs are not yet supported by the debugger.") return Undefined
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: verify_exact_callable_length(self, 3, len(operands)) x, y, c, = operands for v in x, y: if not isinstance(v, Number): raise OperandDeduceError( f"Expected operand to be Number, not {v}") log.logger.get_canvas().pixel(x.value, y.value, make_color(c)) return Undefined
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: for operand in operands: if not isinstance(operand, Number): raise MathError() try: return Number(self.func(*(operand.value for operand in operands))) except TypeError: raise OperandDeduceError( f"Incorrect number of arguments for #[{self.name}].")
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder): verify_min_callable_length(self, 2, len(operands)) bindings = operands[0] if not isinstance(bindings, Pair) and bindings is not Nil: raise OperandDeduceError( f"Expected first argument of let to be a Pair, not {bindings}." ) new_frame = Frame("anonymous let", frame) bindings_holder = gui_holder.expression.children[1] bindings = pair_to_list(bindings) for i, binding in enumerate(bindings): if not isinstance(binding, Pair): raise OperandDeduceError( f"Expected binding to be a Pair, not {binding}.") binding_holder = bindings_holder.expression.children[i] binding = pair_to_list(binding) if len(binding) != 2: raise OperandDeduceError( f"Expected binding to be of length 2, not {len(binding)}.") name, expr = binding if not isinstance(name, Symbol): raise OperandDeduceError( f"Expected first element of binding to be a Symbol, not {name}." ) new_frame.assign( name, evaluate(expr, frame, binding_holder.expression.children[1])) value = None for i, (operand, holder) in enumerate( zip(operands[1:], gui_holder.expression.children[2:])): value = evaluate(operand, new_frame, holder, i == len(operands) - 2) new_frame.assign(return_symbol, value) return value
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: verify_exact_callable_length(self, 2, len(operands)) if log.logger.fragile: raise IrreversibleOperationError() (pair, val) = operands if (not isinstance(pair, Pair)): raise OperandDeduceError(''.join([ 'set-cdr! expected a Pair, received ', '{}'.format(pair), '.' ])) if (not isinstance(val, (Pair, Promise, NilType))): raise OperandDeduceError(''.join([ 'Unable to assign ', '{}'.format(val), ' to cdr, expected a Pair, Nil, or Promise.' ])) pair.rest = val log.logger.raw_out( 'WARNING: Mutation operations on pairs are not yet supported by the debugger.' ) return Undefined
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder): verify_exact_callable_length(self, 2, len(operands)) name = operands[0] if not isinstance(name, Symbol): raise OperandDeduceError( f"Expected a Symbol, not {name}, as the first operand of set!") frame.mutate( name, evaluate(operands[1], frame, gui_holder.expression.children[2])) return Undefined
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder, eval_operands=True): verify_exact_callable_length(self, 2, len(operands)) if eval_operands: operands = evaluate_all(operands, frame, gui_holder.expression.children[1:]) func, args = operands if not isinstance(func, Applicable): raise OperandDeduceError(f"Unable to apply {func}.") gui_holder.expression.set_entries([VisualExpression(Pair(func, args), gui_holder.expression.display_value)]) gui_holder.expression.children[0].expression.children = [] gui_holder.apply() args = pair_to_list(args) return func.execute(args, frame, gui_holder.expression.children[0], False)
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: for operand in operands: if (not isinstance(operand, Number)): raise MathError() try: return Number(self.func(*(operand.value for operand in operands))) except TypeError: raise OperandDeduceError(''.join([ 'Incorrect number of arguments for #[', '{}'.format(self.name), '].' ]))
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: if len(operands) == 0: return Nil exprs = [] for operand in operands[:-1]: if not isinstance(operand, Pair) and operand is not Nil: raise OperandDeduceError(f"Expected operand to be valid list, not {operand}") exprs.extend(pair_to_list(operand)) out = operands[-1] for expr in reversed(exprs): out = Pair(expr, out) return out
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder, name: str = "lambda"): verify_min_callable_length(self, 2, len(operands)) params = operands[0] if not logger.dotted and not isinstance(params, (Pair, NilType)): raise OperandDeduceError(f"Expected Pair as parameter list, received {params}.") params, var_param = dotted_pair_to_list(params) for i, param in enumerate(params): if (logger.dotted or i != len(params) - 1) and not isinstance(param, Symbol): raise OperandDeduceError(f"Expected Symbol in parameter list, received {param}.") if isinstance(param, Pair): param_vals = pair_to_list(param) if len(param_vals) != 2 or \ not isinstance(param_vals[0], Symbol) or \ not isinstance(param_vals[1], Symbol) or \ param_vals[0].value != "variadic": raise OperandDeduceError(f"Each member of a parameter list must be a Symbol or a variadic " f"parameter, not {param}.") var_param = param_vals[1] params.pop() return self.procedure(params, var_param, operands[1:], frame, name)
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: if (len(operands) == 0): return Nil exprs = [] for operand in operands[:(- 1)]: if ((not isinstance(operand, Pair)) and (operand is not Nil)): raise OperandDeduceError( ''.join(['Expected operand to be valid list, not ', '{}'.format(operand)])) exprs.extend(pair_to_list(operand)) out = operands[(- 1)] for expr in reversed(exprs): out = Pair(expr, out) return out
def execute_evaluated(self, operands: List[Expression], frame: Frame) -> Expression: if (len(operands) == 0): return Nil out = [] for operand in operands[:(-1)]: if ((not isinstance(operand, Pair)) and (operand is not Nil)): raise OperandDeduceError(''.join([ 'Expected operand to be valid list, not ', '{}'.format(operand) ])) out.extend(pair_to_list(operand)) try: last = operands[(-1)] if (not isinstance(last, Pair)): raise OperandDeduceError() last = pair_to_list(last) except OperandDeduceError: return make_list(out, operands[(-1)]) else: out.extend(last) return make_list(out)
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder): verify_min_callable_length(self, 2, len(operands)) params = operands[0] if isinstance(params, Symbol): verify_exact_callable_length(self, 2, len(operands)) frame.assign( params, evaluate(operands[1], frame, gui_holder.expression.children[2])) return params elif isinstance(params, Pair): name = params.first operands[0] = params.rest if not isinstance(name, Symbol): raise OperandDeduceError(f"Expected a Symbol, not {name}.") frame.assign( name, Lambda().execute(operands, frame, gui_holder, name.value)) return name else: raise OperandDeduceError( f"Expected a Pair, not {params}, as the first operand of define-macro." )
def execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder): verify_min_callable_length(self, 1, len(operands)) for cond_i, cond in enumerate(operands): if not isinstance(cond, Pair): raise OperandDeduceError(f"Unable to evaluate clause of cond, as {cond} is not a Pair.") expanded = pair_to_list(cond) cond_holder = gui_holder.expression.children[cond_i + 1] eval_condition = SingletonTrue if not isinstance(expanded[0], Symbol) or expanded[0].value != "else": eval_condition = evaluate(expanded[0], frame, cond_holder.expression.children[0]) if (isinstance(expanded[0], Symbol) and expanded[0].value == "else") \ or eval_condition is not SingletonFalse: out = eval_condition for i, expr in enumerate(expanded[1:]): out = evaluate(expr, frame, cond_holder.expression.children[i + 1], i == len(expanded) - 2) return out return Undefined
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 execute(self, operands: List[Expression], frame: Frame, gui_holder: Holder, eval_operands=True): verify_exact_callable_length(self, 1, len(operands)) operand = operands[0] if eval_operands: operand = evaluate_all(operands, frame, gui_holder.expression.children[1:])[0] if not isinstance(operand, Promise): raise OperandDeduceError(f"Force expected a Promise, received {operand}") if operand.forced: return operand.expr if logger.fragile: raise IrreversibleOperationError() gui_holder.expression.set_entries([VisualExpression(operand.expr, gui_holder.expression.display_value)]) gui_holder.apply() evaluated = evaluate(operand.expr, operand.frame, gui_holder.expression.children[0]) if not logger.dotted and not isinstance(evaluated, (Pair, NilType)): raise TypeMismatchError( f"Unable to force a Promise evaluating to {operand.expr}, expected another Pair or Nil") operand.expr = evaluated operand.force() return operand.expr
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], String): raise OperandDeduceError(f"Load expected a String, received {operands[0]}.") if logger.fragile: raise IrreversibleOperationError() from os import listdir from os.path import join directory = operands[0].value try: targets = sorted(listdir(directory)) targets = [join(directory, target) for target in targets if target.endswith(".scm")] exprs = [make_list([Symbol("load"), make_list([Symbol("quote"), Symbol(x[:-4])])]) for x in targets] equiv = make_list([Symbol("begin-noexcept")] + exprs) gui_holder.expression.set_entries([equiv]) gui_holder.apply() return evaluate(equiv, frame, gui_holder.expression.children[0], True) except Exception as e: raise SchemeError(e)
def execute_simple(self, operand: Expression) -> Expression: if (not isinstance(operand, Number)): raise OperandDeduceError( ''.join(['Expected operand to be Number, not ', '{}'.format(operand)])) return Undefined
def quasiquote_evaluate(cls, expr: Expression, frame: Frame, gui_holder: Holder, splicing=False): is_well_formed = False if isinstance(expr, Pair): try: lst = pair_to_list(expr) except OperandDeduceError: pass else: is_well_formed = not any( map( lambda x: isinstance(x, Symbol) and x.value in ["unquote", "quasiquote", "unquote-splicing"], lst)) visual_expression = gui_holder.expression if not is_well_formed: visual_expression.children[2:] = [] if isinstance(expr, Pair): if isinstance(expr.first, Symbol) and expr.first.value in ("unquote", "unquote-splicing"): if expr.first.value == "unquote-splicing" and not splicing: raise OperandDeduceError( "Unquote-splicing must be in list template.") gui_holder.evaluate() verify_exact_callable_length(expr.first, 1, len(pair_to_list(expr)) - 1) out = evaluate(expr.rest.first, frame, visual_expression.children[1]) visual_expression.value = out gui_holder.complete() return out elif isinstance(expr.first, Symbol) and expr.first.value == "quasiquote": visual_expression.value = expr gui_holder.complete() return expr else: if is_well_formed: out = [] for sub_expr, holder in zip(pair_to_list(expr), visual_expression.children): splicing = isinstance(sub_expr, Pair) and isinstance(sub_expr.first, Symbol) \ and sub_expr.first.value == "unquote-splicing" evaluated = Quasiquote.quasiquote_evaluate( sub_expr, frame, holder, splicing) if splicing: if not isinstance(evaluated, (Pair, NilType)): raise TypeMismatchError( f"Can only splice lists, not {evaluated}.") out.extend(pair_to_list(evaluated)) else: out.append(evaluated) out = make_list(out) else: if not logger.dotted: raise OperandDeduceError( f"{expr} is an ill-formed quasiquotation.") out = Pair( Quasiquote.quasiquote_evaluate( expr.first, frame, visual_expression.children[0]), Quasiquote.quasiquote_evaluate( expr.rest, frame, visual_expression.children[1])) visual_expression.value = out gui_holder.complete() return out else: visual_expression.value = expr gui_holder.complete() return expr
def execute_simple(self, operand: Expression) -> Expression: if not isinstance(operand, Number): raise OperandDeduceError( f"Expected operand to be Number, not {operand}") return Undefined
def execute_simple(self, operand: Expression) -> Expression: if not isinstance(operand, Number): raise OperandDeduceError( f"Expected operand to be Number, not {operand}") log.logger.get_canvas().abs_rotate(90 - operand.value) return Undefined
def quasiquote_evaluate(cls, expr: Expression, frame: Frame, gui_holder: Holder, splicing=False): is_well_formed = False if isinstance(expr, Pair): try: lst = pair_to_list(expr) except OperandDeduceError: pass else: is_well_formed = (not any( map((lambda x: (isinstance(x, Symbol) and (x.value in ['unquote', 'quasiquote', 'unquote-splicing']))), lst))) visual_expression = VisualExpression(expr) gui_holder.link_visual(visual_expression) if (not is_well_formed): visual_expression.children[2:] = [] if isinstance(expr, Pair): if (isinstance(expr.first, Symbol) and (expr.first.value in ('unquote', 'unquote-splicing'))): if ((expr.first.value == 'unquote-splicing') and (not splicing)): raise OperandDeduceError( 'Unquote-splicing must be in list template.') gui_holder.evaluate() verify_exact_callable_length(expr.first, 1, (len(pair_to_list(expr)) - 1)) out = evaluate(expr.rest.first, frame, visual_expression.children[1]) visual_expression.value = out gui_holder.complete() return out elif (isinstance(expr.first, Symbol) and (expr.first.value == 'quasiquote')): visual_expression.value = expr gui_holder.complete() return expr else: if is_well_formed: out = [] for (sub_expr, holder) in zip(pair_to_list(expr), visual_expression.children): splicing = (isinstance(sub_expr, Pair) and isinstance(sub_expr.first, Symbol) and (sub_expr.first.value == 'unquote-splicing')) evaluated = Quasiquote.quasiquote_evaluate( sub_expr, frame, holder, splicing) if splicing: if (not isinstance(evaluated, (Pair, NilType))): raise TypeMismatchError(''.join([ 'Can only splice lists, not ', '{}'.format(evaluated), '.' ])) out.extend(pair_to_list(evaluated)) else: out.append(evaluated) out = make_list(out) else: if (not logger.dotted): raise OperandDeduceError(''.join([ '{}'.format(expr), ' is an ill-formed quasiquotation.' ])) out = Pair( Quasiquote.quasiquote_evaluate( expr.first, frame, visual_expression.children[0]), Quasiquote.quasiquote_evaluate( expr.rest, frame, visual_expression.children[1])) visual_expression.value = out gui_holder.complete() return out else: visual_expression.value = expr gui_holder.complete() return expr
def execute_simple(self, operand: Expression) -> Expression: if (not isinstance(operand, Number)): raise OperandDeduceError( ''.join(['Expected operand to be Number, not ', '{}'.format(operand)])) log.logger.get_canvas().abs_rotate((90 - operand.value)) return Undefined