コード例 #1
0
    def read_expression(tokenizer):
        if vector_length_token.match(tokenizer.file.read_character()) == None:
            raise SyntaxException(
                self,
                "Vector length expression syntax error: no double |'s found")

        expression = VectorLengthExpression(tokenizer=tokenizer)
        tokenizer.tokenize(stop_ats=[vector_length_token], tree=expression)

        if vector_length_token.match(tokenizer.file.read_character()) == None:
            raise SyntaxException(
                self,
                "Vector length expression syntax error: no double |'s found")

        return expression
コード例 #2
0
	def to_script(self):
		value = ""
		for expression in self.expressions:
			value = value + expression.to_script()

		if value == "":
			raise SyntaxException(self, f"Variable assignment syntax error: could not find right hand side value '{self.left_hand_expression}'")

		return f"{self.left_hand_expression.to_script()}{self.assignment_operator.to_script()}{value}{self.handle_semicolon()}" 
コード例 #3
0
    def to_script(self):
        value = ""
        for expression in self.expressions:
            value = value + expression.to_script()

        if value == "":
            raise SyntaxException(
                self, "Parentheses syntax error: empty expression")

        return f"({value})"
コード例 #4
0
		def create_method(chain, buffer):
			if buffer == "xyz":
				return chain
			elif buffer == "_":
				return Literal("0")
			elif buffer in VectorExpression.component_table:
				method_data = VectorExpression.component_table[buffer]
				replacement_expression = MethodExpression(method_data[0], tokenizer=expression.tokenizer)
				for index in range(1, len(method_data)):
					element = method_data[index]
					if element == None:
						replacement_expression.expressions.append(chain)
					else:
						replacement_expression.expressions.append(Literal(element))
					replacement_expression.convert_expressions_to_arguments()
				return replacement_expression
			else:
				raise SyntaxException(self, f"Component access '{buffer}' not in component table")
コード例 #5
0
	def replace_modifier_operation_with_call(self, index_of_left, left_vector, operator, expression=None):
		if expression == None:
			expression = self
		
		del expression.expressions[index_of_left:index_of_left + 1]

		if operator.operator not in VectorExpression.modifier_operator_table:
			raise SyntaxException(self, f"Vector syntax error: {operator.operator} is invalid modifier operator")

		modifier_method = VectorExpression.modifier_operator_table[operator.operator]

		expression.expressions[index_of_left] = MethodExpression(modifier_method[0], current_line_index=self.current_line_index, current_index=self.current_index, current_file_name=self.current_file_name)
		expression.expressions[index_of_left].parent = expression

		for index in range(1, len(modifier_method)):
			if modifier_method[index] == None:
				expression.expressions[index_of_left].expressions.append(left_vector)
				expression.expressions[index_of_left].convert_expressions_to_arguments()
				left_vector.parent = expression.expressions[index_of_left]
			else:
				expression.expressions[index_of_left].expressions.append(Literal(modifier_method[index]))
				expression.expressions[index_of_left].convert_expressions_to_arguments()
コード例 #6
0
    def to_script(self):
        if len(self.expressions) == 0:
            raise SyntaxException(self,
                                  "Vector length exception: empty expression")

        if (len(self.expressions) == 1
                and type(self.expressions[0]) == MethodExpression
                and self.expressions[0].method_symbol.name == "vectorSub"):
            # change name of the expression
            self.expressions[0].method_symbol = Symbol("vectorDist")
            return self.expressions[0].to_script()
        else:
            method_expression = MethodExpression(
                Symbol("vectorLen"),
                current_line_index=self.current_line_index,
                current_index=self.current_index,
                current_file_name=self.current_file_name)
            method_expression.parent = self.parent

            method_expression.expressions = self.expressions
            method_expression.convert_expressions_to_arguments()

            return method_expression.to_script()
コード例 #7
0
	def handle_order_of_operations(self, offset=0, min_precedence=0, expression=None):
		def is_maybe_scalar_expression(expression):
			# checking to see if this expression is a scalar expression
			if (
				type(expression) == VectorEscapeExpression
				or (
					type(expression) == MethodExpression
					and expression.method_symbol.name == "vectorDot"
					and expression.method_symbol.name == "vectorLen"
				)
				or (
					type(expression) == Literal
					and expression.is_number()
				)
			):
				return True
			else:
				return False
		
		if expression == None:
			expression = self
		
		# fetch operand
		left_vector = expression.safe_get_index(0 + offset)
		if hasattr(left_vector, "operator"): # handling special cases where operators are used to modify a vector (-, ^)
			self.replace_modifier_operation_with_call(offset, expression.safe_get_index(1 + offset), left_vector, expression=expression)
			left_vector = expression.safe_get_index(0 + offset)

		# fetch operator
		operator = expression.safe_get_index(1 + offset)

		# fetch operand
		right_vector = expression.safe_get_index(2 + offset)
		if hasattr(right_vector, "operator"): # handling special cases where operators are used to modify a vector (-, ^)
			self.replace_modifier_operation_with_call(2 + offset, expression.safe_get_index(3 + offset), right_vector)
			right_vector = expression.safe_get_index(2 + offset)

		# fetch operator
		next_operator = expression.safe_get_index(3 + offset)

		# if we hit an operator that isn't anything, then we've probably reached the end of our expression. quit
		if operator == None:
			return
		elif (
			left_vector == None
			or (left_vector != None and operator != None and right_vector == None)
		):
			raise SyntaxException(self, "Vector expression syntax error: couldn't find operands")
		elif operator != None and operator.operator not in VectorExpression.operator_table:
			raise SyntaxException(self, f"Vector expression syntax error: invalid operator {operator.operator}")
		elif next_operator != None and next_operator.operator not in VectorExpression.operator_table:
			raise SyntaxException(self, f"Vector expression syntax error: invalid operator {next_operator.operator}")
		
		# check for type errors
		if (
			VectorExpression.operator_allows_scalars[operator.operator] == OperatorScalarOption.NO_SCALARS
		):
			if (
				(
					is_maybe_scalar_expression(left_vector) == True
					and is_maybe_scalar_expression(right_vector) == False
				)
				or (
					is_maybe_scalar_expression(left_vector) == False
					and is_maybe_scalar_expression(right_vector) == True
				)
			):
				raise SyntaxException(self, f"Vector expression syntax error: cannot mix scalars and vectors for operator {operator.operator} at {left_vector.to_script()} {operator.operator} {right_vector.to_script()}")
			elif (
				is_maybe_scalar_expression(left_vector) == True
				and is_maybe_scalar_expression(right_vector) == True
			):
				raise SyntaxException(self, f"Vector expression syntax error: only vector operations are allowed inside backticks, not {left_vector.to_script()} {operator.operator} {right_vector.to_script()}. To escape, use the vector escape syntax " + "{}")
		elif (
			VectorExpression.operator_allows_scalars[operator.operator] == OperatorScalarOption.RIGHT_OR_LEFT_SCALAR
			or VectorExpression.operator_allows_scalars[operator.operator] == OperatorScalarOption.ONLY_RIGHT_SCALAR
		):
			if VectorExpression.operator_allows_scalars[operator.operator] == OperatorScalarOption.ONLY_RIGHT_SCALAR and is_maybe_scalar_expression(left_vector) == True:
				raise SyntaxException(self, f"Vector expression syntax error: the {operator.operator} operator does not support left-handed scalar operations at {left_vector.to_script()} {operator.operator} {right_vector.to_script()}")
			elif (
				is_maybe_scalar_expression(left_vector) == False
				and is_maybe_scalar_expression(right_vector) == False
			):
				warn(self, f"Vector expression syntax warning: implicit usage of scalars for operator {operator.operator} at {left_vector.to_script()} {operator.operator} {right_vector.to_script()}. Will only work at run-time if right-hand side is a scalar")
			elif (
				is_maybe_scalar_expression(left_vector) == True
				and is_maybe_scalar_expression(right_vector) == True
			):
				raise SyntaxException(self, f"Vector expression syntax error: only vector operations are allowed inside backticks, not {left_vector.to_script()} {operator.operator} {right_vector.to_script()}. To escape, use the vector escape syntax " + "{}")
		# done with syntax errors

		# do precedence rules
		if next_operator != None:
			if OperatorExpression.operator_precedence[operator.operator] >= min_precedence and OperatorExpression.operator_precedence[operator.operator] < OperatorExpression.operator_precedence[next_operator.operator]:
				self.handle_order_of_operations(offset=offset + 2, min_precedence=OperatorExpression.operator_precedence[next_operator.operator], expression=expression)
		
		# these operands may have changed due to precedence rules. re-fetch
		left_vector = expression.safe_get_index(0 + offset)
		right_vector = expression.safe_get_index(2 + offset)

		# determine which vector is a scalar and if we need to flip the sides
		if (
			VectorExpression.operator_allows_scalars[operator.operator] == 1
			and is_maybe_scalar_expression(left_vector)
		):
			right_vector = expression.safe_get_index(0 + offset)
			left_vector = expression.safe_get_index(2 + offset)

		self.replace_operation_with_call(offset, left_vector, operator, right_vector, expression=expression)
		self.handle_order_of_operations(offset=offset, expression=expression)