示例#1
0
 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)
示例#3
0
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), "'"]))
示例#4
0
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))
示例#5
0
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))
示例#6
0
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}'")
示例#7
0
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)
示例#8
0
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)
示例#9
0
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
示例#10
0
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)
示例#11
0
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
示例#12
0
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()
示例#13
0
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
示例#14
0
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
示例#15
0
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()