示例#1
0
    def execute_run(self, exec_ctx):
        fn = exec_ctx.symbol_table.get("fn")

        if not isinstance(fn, String):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        "First argument must be string", exec_ctx))

        fn = fn.value

        try:
            with open(fn, "r") as f:
                if os.path.splitext(f.name)[1] == ".ds":
                    script = f.read()
                else:
                    return RTResult().failure(
                        InvalidSyntaxError(self.pos_start, self.pos_end,
                                           f"{f.name} is not a valid file!"))
        except Exception as e:
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        f"Failed to load script \"{fn}\"\n" + str(e),
                        exec_ctx))

        _, error = run(fn, script)

        if error:
            return RTResult().failure(
                RTError(
                    self.pos_start, self.pos_end,
                    f"Failed to finish executing script \"{fn}\"\n" +
                    error.as_string(), exec_ctx))

        return RTResult().success(Number.null)
示例#2
0
 def execute_lower(self, exec_ctx):
     value = exec_ctx.symbol_table.get("value")
     if isinstance(value, String):
         lower = value.value.lower()
     else:
         return RTResult().failure(
             RTError(self.pos_start, self.pos_end, "Value is not a String",
                     exec_ctx))
     return RTResult().success(String(lower))
示例#3
0
    def execute_split(self, exec_ctx):
        value = exec_ctx.symbol_table.get("value")

        if not isinstance(value1, String):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end, "Value is not a String",
                        exec_ctx))

        return RTResult().success(String(value.value.split()))
示例#4
0
    def visit_VarAssignNode(self, node, context):
        res = RTResult()
        var_name = node.var_name_tok.value
        value = res.register(self.visit(node.value_node, context))
        if res.should_return():
            return res

        context.symbol_table.set(var_name, value)
        return res.success(value)
示例#5
0
 def execute_len(self, exec_ctx):
     value = exec_ctx.symbol_table.get("value")
     if isinstance(value, String):
         length = len(value.value)
     elif isinstance(value, List):
         length = len(value.value)
     else:
         return RTResult().failure(
             RTError(self.pos_start, self.pos_end, "Value is not String",
                     exec_ctx))
     return RTResult().success(Number(length))
示例#6
0
    def execute_ord(self, exec_ctx):
        value = exec_ctx.symbol_table.get("value")

        if isinstance(value, String):
            uni = ord(value.value[0])
        else:
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end, f"Value is not String",
                        exec_ctx))

        return RTResult().success(Number(uni))
示例#7
0
    def visit_ReturnNode(self, node, context):
        res = RTResult()

        if node.node_to_return:
            value = res.register(self.visit(node.node_to_return, context))
            if res.should_return():
                return res
        else:
            value = Number.null

        return res.success_return(value)
示例#8
0
    def execute_append(self, exec_ctx):
        list_ = exec_ctx.symbol_table.get("list")
        value = exec_ctx.symbol_table.get("value")

        if not isinstance(list_, List):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        "First argument must be list", exec_ctx))

        list_.elements.append(value)
        return RTResult().success(Number.null)
示例#9
0
    def execute_py_eval(self, exec_ctx):
        code = exec_ctx.symbol_table.get("code").value

        try:
            res = exec(code)
        except BaseException as e:
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        f"A error has occured when executing!\nError: {e}",
                        exec_ctx))

        return RTResult().success(String(res) if res else Number.null)
示例#10
0
    def execute_bin(self, exec_ctx):
        value = exec_ctx.symbol_table.get("value")

        if isinstance(value, Number):
            binop = bin(value.value)

        else:
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end, f"Value is not a Number",
                        exec_ctx))

        return RTResult().success(Number(int(binop[2:])))
示例#11
0
    def visit_DictNode(self, node, context):
        res = RTResult()
        elements = []

        for element_node in node.element_nodes:
            elements.append(res.register(self.visit(element_node, context)))
            if res.should_return():
                return res

        return res.success(
            Dictionary(elements).set_context(context).set_pos(
                node.pos_start, node.pos_end)
        )
示例#12
0
    def visit_FuncDefNode(self, node, context):
        res = RTResult()

        func_name = node.var_name_tok.value if node.var_name_tok else None
        body_node = node.body_node
        arg_names = [arg_name.value for arg_name in node.arg_name_toks]
        func_value = Function(func_name, body_node, arg_names, node.should_auto_return).set_context(
            context).set_pos(node.pos_start, node.pos_end)

        if node.var_name_tok:
            context.symbol_table.set(func_name, func_value)

        return res.success(func_value)
示例#13
0
    def visit_VarAccessNode(self, node, context):
        res = RTResult()
        var_name = node.var_name_tok.value
        value = context.symbol_table.get(var_name)

        if not value:
            return res.failure(RTError(
                node.pos_start, node.pos_end,
                f"'{var_name}' is not defined",
                context
            ))

        value = value.copy().set_pos(node.pos_start, node.pos_end).set_context(context)
        return res.success(value)
示例#14
0
    def execute_reverse(self, exec_ctx):
        value = exec_ctx.symbol_table.get("value")

        if isinstance(value, List):
            value.elements.reverse()
            return RTResult().success(List(value.elements))
        elif isinstance(value, String):
            return RTResult().success(String(value.value[::-1]))
        elif isinstance(value, Number):
            return RTResult().success(Number(int(str(value.value)[::-1])))

        return RTResult().failure(
            RTError(self.pos_start, self.pos_end,
                    "Value is not string, number, or list", exec_ctx))
示例#15
0
    def execute_random(self, exec_ctx):
        value1 = exec_ctx.symbol_table.get("value1")
        value2 = exec_ctx.symbol_table.get("value2")

        if not isinstance(value1, Number):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end, "Value1 is not a Number",
                        exec_ctx))

        if not isinstance(value2, Number):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end, "Value2 is not a Number",
                        exec_ctx))

        return RTResult().success(
            Number(random.randint(value1.value, value2.value)))
示例#16
0
    def execute_extend(self, exec_ctx):
        listA = exec_ctx.symbol_table.get("listA")
        listB = exec_ctx.symbol_table.get("listB")

        if not isinstance(listA, List):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        "First argument must be list", exec_ctx))

        if not isinstance(listB, List):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        "Second argument must be list", exec_ctx))

        listA.elements.extend(listB.elements)
        return RTResult().success(Number.null)
示例#17
0
    def visit_WhileNode(self, node, context):
        res = RTResult()
        elements = []

        while True:
            condition = res.register(self.visit(node.condition_node, context))
            if res.should_return():
                return res

            if not condition.is_true():
                break

            value = res.register(self.visit(node.body_node, context))
            if res.should_return() and res.loop_should_continue == False and res.loop_should_break == False:
                return res

            if res.loop_should_continue:
                continue

            if res.loop_should_break:
                break

            elements.append(value)

        return res.success(
            Number.null if node.should_return_null else
            List(elements).set_context(context).set_pos(
                node.pos_start, node.pos_end)
        )
示例#18
0
    def check_args(self, arg_names, args):
        res = RTResult()

        if len(args) > len(arg_names):
            return res.failure(
                RTError(
                    self.pos_start, self.pos_end,
                    f"{len(args) - len(arg_names)} too many args passed into {self}",
                    self.context))

        if len(args) < len(arg_names):
            return res.failure(
                RTError(
                    self.pos_start, self.pos_end,
                    f"{len(arg_names) - len(args)} too few args passed into {self}",
                    self.context))

        return res.success(None)
示例#19
0
 def execute_input_int(self, exec_ctx):
     while True:
         text = input()
         try:
             number = int(text)
             break
         except ValueError:
             print(f"'{text}' must be an integer. Try again!")
     return RTResult().success(Number(number))
示例#20
0
 def check_and_populate_args(self, arg_names, args, exec_ctx):
     res = RTResult()
     res.register(self.check_args(arg_names, args))
     if res.should_return():
         return res
     self.populate_args(arg_names, args, exec_ctx)
     return res.success(None)
示例#21
0
    def execute(self, args):
        res = RTResult()
        exec_ctx = self.generate_new_context()

        method_name = f'execute_{self.name}'
        method = getattr(self, method_name, self.no_visit_method)

        res.register(
            self.check_and_populate_args(method.arg_names, args, exec_ctx))
        if res.should_return():
            return res

        return_value = res.register(method(exec_ctx))
        if res.should_return():
            return res
        return res.success(return_value)
示例#22
0
    def execute_pop(self, exec_ctx):
        list_ = exec_ctx.symbol_table.get("list")
        index = exec_ctx.symbol_table.get("index")

        if not isinstance(list_, List):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        "First argument must be list", exec_ctx))

        if not isinstance(index, Number):
            return RTResult().failure(
                RTError(self.pos_start, self.pos_end,
                        "Second argument must be number", exec_ctx))

        try:
            element = list_.elements.pop(index.value)
        except:
            return RTResult().failure(
                RTError(
                    self.pos_start, self.pos_end,
                    'Element at this index could not be removed from list because index is out of bounds',
                    exec_ctx))
        return RTResult().success(element)
示例#23
0
    def visit_CallNode(self, node, context):
        res = RTResult()
        args = []

        value_to_call = res.register(self.visit(node.node_to_call, context))
        if res.should_return():
            return res
        value_to_call = value_to_call.copy().set_pos(node.pos_start, node.pos_end)

        for arg_node in node.arg_nodes:
            args.append(res.register(self.visit(arg_node, context)))
            if res.should_return():
                return res

        return_value = res.register(value_to_call.execute(args))
        if res.should_return():
            return res
        return_value = return_value.copy().set_pos(
            node.pos_start, node.pos_end).set_context(context)
        return res.success(return_value)
示例#24
0
    def execute(self, args):
        res = RTResult()
        interpreter = Interpreter()
        exec_ctx = self.generate_new_context()

        res.register(
            self.check_and_populate_args(self.arg_names, args, exec_ctx))
        if res.should_return():
            return res

        value = res.register(interpreter.visit(self.body_node, exec_ctx))
        if res.should_return() and res.func_return_value == None:
            return res

        ret_value = (value if self.should_auto_return else
                     None) or res.func_return_value or Number.null
        return res.success(ret_value)
示例#25
0
    def visit_BinOpNode(self, node, context):
        res = RTResult()
        left = res.register(self.visit(node.left_node, context))
        if res.should_return():
            return res
        right = res.register(self.visit(node.right_node, context))
        if res.should_return():
            return res

        if node.op_tok.type == TT_PLUS:
            result, error = left.added_to(right)
        elif node.op_tok.type == TT_MINUS:
            result, error = left.subbed_by(right)
        elif node.op_tok.type == TT_MUL:
            result, error = left.multed_by(right)
        elif node.op_tok.type == TT_DIV:
            result, error = left.dived_by(right)
        elif node.op_tok.type == TT_POW:
            result, error = left.powed_by(right)
        elif node.op_tok.type == TT_EE:
            result, error = left.get_comparison_eq(right)
        elif node.op_tok.type == TT_NE:
            result, error = left.get_comparison_ne(right)
        elif node.op_tok.type == TT_LT:
            result, error = left.get_comparison_lt(right)
        elif node.op_tok.type == TT_GT:
            result, error = left.get_comparison_gt(right)
        elif node.op_tok.type == TT_LTE:
            result, error = left.get_comparison_lte(right)
        elif node.op_tok.type == TT_GTE:
            result, error = left.get_comparison_gte(right)
        elif node.op_tok.matches(TT_KEYWORD, 'and'):
            result, error = left.anded_by(right)
        elif node.op_tok.matches(TT_KEYWORD, 'or'):
            result, error = left.ored_by(right)

        if error:
            return res.failure(error)
        else:
            return res.success(result.set_pos(node.pos_start, node.pos_end))
示例#26
0
    def visit_UnaryOpNode(self, node, context):
        res = RTResult()
        number = res.register(self.visit(node.node, context))
        if res.should_return():
            return res

        error = None

        if node.op_tok.type == TT_MINUS:
            number, error = number.multed_by(Number(-1))
        elif node.op_tok.matches(TT_KEYWORD, 'not'):
            number, error = number.notted()

        if error:
            return res.failure(error)
        else:
            return res.success(number.set_pos(node.pos_start, node.pos_end))
示例#27
0
    def execute_global(self, exec_ctx):
        _vars = []
        for x in exec_ctx.symbol_table.parent.symbols:
            _vars.append(x)

        return RTResult().success(List(_vars))
示例#28
0
 def execute_lag(self, exec_ctx):
     return RTResult().success(String("LanguageArtsGrade"))
示例#29
0
 def execute_murgn(self, exec_ctx):
     return RTResult().success(String("is gay."))
示例#30
0
    def execute_getch(self, exec_ctx):
        value = getch().decode("utf-8")

        return RTResult().success(String(value))