示例#1
0
	def execute_findIndex(self, exec_ctx):
		string = exec_ctx.symbol_table.get('string')
		char = exec_ctx.symbol_table.get('char')
		if not isinstance(string, String):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"First argument must be a string",
				exec_ctx
			))
		if not isinstance(char, String):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Second argument must be a string",
				exec_ctx
			))
		if len(list(char.value)) > 1:
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Second argument must be a single character string",
				exec_ctx
			))

		res_index = string.value.find(char.value)
		
		return RTResult().success(Number(res_index))
示例#2
0
	def execute_insert(self, exec_ctx):
		list_ = exec_ctx.symbol_table.get('list')
		index = exec_ctx.symbol_table.get('index')
		char = exec_ctx.symbol_table.get('char')
		if not isinstance(list_, List):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"First argument must be a list",
				exec_ctx
			))
		if not isinstance(index, Number):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Second argument must be a number",
				exec_ctx
			))
		if index.value > len(list_.elements):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Second argument must be less than length of list",
				exec_ctx
			))

		list_.elements.insert(index.value, char.value)
		
		return RTResult().success(Number.null)
示例#3
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(errors.RTError(
				self.pos_start, self.pos_end,
				"First argument must be a list",
				exec_ctx
			))

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

		try:
			element = list_.elements.pop(index.value)
		except:
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Element at this index could not be removed from the list because the index is out of bounds",
				exec_ctx
			))

		return RTResult().success(element)
示例#4
0
	def visit_VarAccessNode(self, node, context):
		res = RTResult()
		var_name = node.var_name_tok.value
		var_module_name = node.module_tok.value if node.module_tok else None

		if var_module_name:
			symbol_table = find_symbol_table(var_module_name)

			if not symbol_table:
				return res.failure(errors.RTError(
					node.pos_start, node.pos_end,
					f"'{var_module_name}' module is not defined",
					context
				))

			value = symbol_table.get(var_name)
		else:
			value = context.symbol_table.get(var_name)

		if not value:
			return res.failure(errors.RTError(
				node.pos_start, node.pos_end,
				f"'{var_name}' is not defined",
				context
			))
		# print(type(value))
		value = value.copy().set_pos(node.pos_start, node.pos_end).set_context(context)
		return res.success(value)
示例#5
0
    def execute_concat(self, exec_ctx):
        str1 = exec_ctx.symbol_table.get('string1')
        str2 = exec_ctx.symbol_table.get('string2')
        if not isinstance(str1, String):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               "First argument must be a string", exec_ctx))
        if not isinstance(str2, String):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               "Second argument must be a string", exec_ctx))
        res_str = str1.value + str2.value

        return RTResult().success(String(res_str))
示例#6
0
	def execute_run(self, exec_ctx, importFile=False, module_name=""):
		global global_symbol_table

		if not importFile:
			global_symbol_table = reset_global_symbol_table()
		else:
			new_symbol_table = SymbolTable(parent=None, name = module_name)
			modules_symbol_table.append(new_symbol_table)

		fn = exec_ctx.symbol_table.get('fn')

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

		a = fn.value.split('.')

		if a[len(a)-1] != "kode":
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"File extension must be .kode",
				exec_ctx
			))

		fn = fn.value

		try:
			with open(fn, "r") as f:
				script = f.read()
		except Exception as e:
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				f"Failed to load the file \"{fn}\"\n" + str(e),
				exec_ctx
			))

		_, error = run(fn, script, module_name)

		if error:
			return RTResult().failure(errors.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)
示例#7
0
    def execute_max(self, exec_ctx):
        a = exec_ctx.symbol_table.get('b')
        b = exec_ctx.symbol_table.get('a')

        if not isinstance(a, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument must be a number", exec_ctx))

        if not isinstance(b, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument must be a number", exec_ctx))

        return RTResult().success(Number(max(a.value, b.value)))
示例#8
0
    def execute_min(self, exec_ctx):
        numberA = exec_ctx.symbol_table.get('numberA')
        numberB = exec_ctx.symbol_table.get('numberB')

        if not isinstance(numberA, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument must be a number", exec_ctx))

        if not isinstance(numberB, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument must be a number", exec_ctx))

        return RTResult().success(Number(min(numberA.value, numberB.value)))
示例#9
0
	def illegal_operation(self, other=None):
		if not other: other = self
		return errors.RTError(
			self.pos_start, other.pos_end,
			'Illegal operation',
			self.context
		)
示例#10
0
	def visit_FunctionDefNode(self, node, context):
		res = RTResult()

		func_name = node.var_name_tok.value if node.var_name_tok else None

		if func_name in global_symbol_table.symbols:
			return res.failure(errors.RTError(
				node.pos_start, node.pos_end,
				f"There is a function called '{func_name}' already defined",
				context
			))

		body_node = node.body_node
		arg_names = [arg_name.value for arg_name in node.arg_name_toks]
		optional_arg_names = [optional_arg.value for optional_arg in node.optional_arg_names]
		optional_arg_values = []

		for i in node.optional_arg_values:
			optional_arg_values.append(res.register(self.visit(i, context)))
			if res.error: return res
		
		module = node.module

		func_value = Function(func_name, body_node, arg_names, optional_arg_names, optional_arg_values, node.should_auto_return, module).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)
示例#11
0
	def visit_CallNode(self, node, context):
		res = RTResult()
		args = []
		optional_arg_names = []
		optional_arg_values = []

		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

		optional_names = value_to_call.optional_arg_names
		for i in range(len(node.optional_arg_names)):
			if node.optional_arg_names[i].value not in optional_names:
				return res.failure(errors.RTError(
					node.pos_start, node.pos_end,
					f"There is no argument named {node.optional_arg_names[i].var_name_tok.value}",
					context
				))
			optional_arg_names.append(node.optional_arg_names[i].value)
			optional_arg_values.append(res.register(self.visit(node.optional_arg_values[i], context)))

		return_value = res.register(value_to_call.execute(args, optional_arg_names, optional_arg_values))
		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)
示例#12
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(
                errors.RTError(self.pos_start, self.pos_end,
                               "First argument must be a list", exec_ctx))

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

        listA.elements.extend(listB.elements)
        return RTResult().success(Number.null)
示例#13
0
	def check_args(self, arg_names, args):
		res = RTResult()
		if len(args) > len(arg_names):
			return res.failure(errors.RTError(
				self.pos_start, self.pos_end,
				f"{len(args) - len(arg_names)} too many args passed into '{self.name}'",
				self.context
			))
		
		if len(args) < len(arg_names):
			return res.failure(errors.RTError(
				self.pos_start, self.pos_end,
				f"{len(arg_names) - len(args)} too few args passed into '{self.name}'",
				self.context
			))
		
		return res.success(None)
示例#14
0
	def execute_set(self, exec_ctx):
		list_ = exec_ctx.symbol_table.get('list')
		index = exec_ctx.symbol_table.get('index')
		value = exec_ctx.symbol_table.get('value')

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

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

			try:
				list_.elements[index.value] = value
			except:
				return RTResult().failure(errors.RTError(
					self.pos_start, self.pos_end,
					"Could not set that value to the list because the index is out of bounds",
					exec_ctx
				))

			return RTResult().success(Number.null)

		if not isinstance(index, String):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Second argument must be a string",
				exec_ctx
			))

		for k in list_.elements:
			if index.value == k.value:
				list_.elements[k] = value
				return RTResult().success(Number.null)
		
		list_.elements[index] = value

		return RTResult().success(Number.null)
示例#15
0
    def execute_to_str(self, exec_ctx):
        value = exec_ctx.symbol_table.get('value')

        if isinstance(value, BaseFunction):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Cannot convert Function to String", exec_ctx))

        return RTResult().success(String(str(value)))
示例#16
0
    def execute_abs(self, exec_ctx):
        number = exec_ctx.symbol_table.get('number')

        if not isinstance(number, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument must be a number", exec_ctx))

        return RTResult().success(Number(abs(number.value)))
示例#17
0
    def execute_len(self, exec_ctx):
        list_ = exec_ctx.symbol_table.get('list')

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

        return RTResult().success(Number(len(list_.elements)))
示例#18
0
	def execute_get(self, exec_ctx):
		list_ = exec_ctx.symbol_table.get('list')
		index = exec_ctx.symbol_table.get('index')

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

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

			try:
				return RTResult().success(list_.elements[index.value])
			except:
				return RTResult().failure(errors.RTError(
					self.pos_start, self.pos_end,
					"Element at this index could not be retrieved because the index is out of bounds",
					exec_ctx
				))

		if not isinstance(index, String):
				return RTResult().failure(errors.RTError(
					self.pos_start, self.pos_end,
					"Second argument must be a string",
					exec_ctx
				))

		for k in list_.elements:
			if index.value == k.value:
				return RTResult().success(list_.elements[k])

		return RTResult().failure(errors.RTError(
			self.pos_start, self.pos_end,
			"Could not get any value because that key doesn't exist",
			exec_ctx
		))
示例#19
0
    def remainder_of(self, other):
        if isinstance(other, Number):
            if other.value == 0:
                return None, errors.RTError(other.pos_start, other.pos_end,
                                            'Division by zero', self.context)

            return Number(self.value % other.value).set_context(
                self.context), None
        else:
            return None, Value.illegal_operation(self, other)
示例#20
0
    def execute_has_key(self, exec_ctx):
        d = exec_ctx.symbol_table.get('d')
        key = exec_ctx.symbol_table.get('key')

        if not isinstance(d, Dict):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"First argument must be a dictionary",
                               exec_ctx))

        if not isinstance(key, String):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Second argument must be a string", exec_ctx))

        for k in d.elements:
            if key.value == k.value:
                return RTResult().success(Number.true)
        return RTResult().success(Number.false)
示例#21
0
    def execute_to_float(self, exec_ctx):
        number = exec_ctx.symbol_table.get('number')

        try:
            return RTResult().success(Number(float(number.value)))
        except:
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument can't be converted to Integer",
                               exec_ctx))
示例#22
0
    def execute_range(self, exec_ctx):
        begin = exec_ctx.symbol_table.get('begin')
        end = exec_ctx.symbol_table.get('end')

        if not isinstance(begin, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"First argument must be a number", exec_ctx))

        if not isinstance(end, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"First argument must be a number", exec_ctx))

        arr = []
        for i in range(begin.value, end.value):
            arr.append(Number(i))

        return RTResult().success(List(arr))
示例#23
0
 def dived_by(self, other):
     if isinstance(other, Number):
         try:
             return self.elements[other.value], None
         except:
             return None, errors.RTError(
                 other.pos_start, other.pos_end,
                 "Element at this index could not be retrieved form the list because the index is out of bounds",
                 self.context)
     else:
         return None, Value.illegal_operation(self, other)
示例#24
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(
                errors.RTError(self.pos_start, self.pos_end,
                               "First argument must be a list", exec_ctx))

        list_.elements.append(value)
        return RTResult().success(Number.null)
示例#25
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(
                errors.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)
示例#26
0
    def execute_imports(self, exec_ctx):
        path = exec_ctx.symbol_table.get('path')

        if not isinstance(path, String):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               "Argument must be a string", exec_ctx))

        exec_ctx.symbol_table.set('fn', path)
        self.execute_run(exec_ctx, importFile=True)

        return RTResult().success(Number.null)
示例#27
0
    def execute_fact(self, exec_ctx):
        number = exec_ctx.symbol_table.get('number')
        if not isinstance(number, Number):
            return RTResult().failure(
                errors.RTError(self.pos_start, self.pos_end,
                               f"Argument must be a number", exec_ctx))
        fact = 1
        for i in range(1, number.value + 1):
            fact = fact * i

        number.value = fact

        return RTResult().success(Number(number.value))
示例#28
0
	def execute_sort(self, exec_ctx):
		list_ = exec_ctx.symbol_table.get('list')
		if not isinstance(list_, List):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Argument must be a list",
				exec_ctx
			))

		length = len(list_.elements)
		arr = [list_.elements[i].value for i in range(0,length)]

		return RTResult().success((List(sorted(arr))))
示例#29
0
	def execute_importAs(self, exec_ctx):
		path = exec_ctx.symbol_table.get('path')
		name = exec_ctx.symbol_table.get('name')

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

		if not isinstance(name, String):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				"Second argument must be a string",
				exec_ctx
			))

		exec_ctx.symbol_table.set('fn', path)
		self.execute_run(exec_ctx, importFile=True, module_name = name.value)

		return RTResult().success(Number.null)
示例#30
0
	def execute_is_prime(self, exec_ctx):
		number = exec_ctx.symbol_table.get('number')

		if not isinstance(number, Number):
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				f"Argument must be a number",
				exec_ctx
			))
		elif number.value%1 != 0:
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				f"Argument must be a positive integer",
				exec_ctx
			))
		elif number.value <= 0:
			return RTResult().failure(errors.RTError(
				self.pos_start, self.pos_end,
				f"Argument must be a positive number",
				exec_ctx
			))

		is_prime = Number.true
		if number.value == 1:
			is_prime = Number.false
		elif number.value == 2 or number.value == 3:
			is_prime = Number.true
		elif number.value%2 == 0:
			is_prime = Number.false
		elif number.value%3 == 0:
			is_prime = Number.false
		else:
			for i in range(5, int(number.value**(1/2))+1, 6):
				if  number.value%i == 0 or number.value%(i+2) == 0:
					is_prime = number.false
					break

		return RTResult().success(is_prime)