Skip to content

Commit

Permalink
Move helper method into semantic error checker
Browse files Browse the repository at this point in the history
- Enable plugins to overload this method
  • Loading branch information
OliverStolzBO committed Feb 16, 2024
1 parent e48e0be commit 68809a0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 28 deletions.
23 changes: 1 addition & 22 deletions pfdl_scheduler/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,14 @@
"""Helper functions used in the project (especially in the SemanticErrorChecker)."""

# standard libraries
from typing import Any, Dict, List, Union
from typing import Dict, List, Union
import operator

# local sources
from pfdl_scheduler.model.struct import Struct
from pfdl_scheduler.model.task import Task


def check_type_of_value(value: Any, value_type: str) -> bool:
"""Checks if the given value is the given type in the DSL.
Returns:
True if the value is from the given value type.
"""
if value_type == "number":
# bool is a subclass of int so check it before
if isinstance(value, bool):
return False
return isinstance(value, (int, float))
if value_type == "boolean":
return isinstance(value, bool)
if value_type == "string":
return isinstance(value, str)
if isinstance(value, Struct):
return value.name == value_type
# value was a string
return True


def get_type_of_variable_list(
var_list: List[str], task: Task, struct_definitions: Dict[str, Struct]
) -> str:
Expand Down
35 changes: 29 additions & 6 deletions pfdl_scheduler/validation/semantic_error_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""Contains the SemanticErrorChecker class."""

# standard libraries
from typing import Dict, List, Union
from typing import Dict, List, Union, Any

# 3rd party libraries
from antlr4.ParserRuleContext import ParserRuleContext
Expand All @@ -29,7 +29,7 @@
from pfdl_scheduler.utils import helpers

# global defines
from pfdl_scheduler.parser.pfdl_tree_visitor import PRIMITIVE_DATATYPES, IN_KEY, OUT_KEY, START_TASK
from pfdl_scheduler.parser.pfdl_tree_visitor import IN_KEY, OUT_KEY, START_TASK


class SemanticErrorChecker:
Expand Down Expand Up @@ -602,7 +602,6 @@ def check_for_wrong_attribute_type_in_struct(

if isinstance(correct_attribute_type, str):
if correct_attribute_type in self.structs:

# check for structs which has structs as attribute
if isinstance(attribute, Struct):
attribute.name = correct_attribute_type
Expand All @@ -621,7 +620,7 @@ def check_for_wrong_attribute_type_in_struct(
)
self.error_handler.print_error(error_msg, context=struct_instance.context)
return False
if not helpers.check_type_of_value(attribute, correct_attribute_type):
if not self.check_type_of_value(attribute, correct_attribute_type):
error_msg = (
f"Attribute '{identifier}' has the wrong type in the instantiated"
f" Struct '{struct_instance.name}', expected '{correct_attribute_type}'"
Expand Down Expand Up @@ -656,7 +655,7 @@ def check_array(self, instantiated_array: Array, array_definition: Array) -> boo
value.name = array_definition.type_of_elements
if not self.check_instantiated_struct_attributes(value):
return False
if not helpers.check_type_of_value(value, element_type):
if not self.check_type_of_value(value, element_type):
error_msg = (
f"Array has elements that does not match "
f"with the defined type '{element_type}'"
Expand Down Expand Up @@ -773,6 +772,7 @@ def check_single_expression(
if not self.check_attribute_access(expression, context, task):
return False

# only numbers and booleans are allowed, so check the variable type
variable_type = helpers.get_type_of_variable_list(expression, task, self.structs)
if not (isinstance(variable_type, str) and variable_type in ["number", "boolean"]):
msg = "The given attribute can not be resolved to a boolean expression"
Expand Down Expand Up @@ -806,7 +806,10 @@ def check_binary_operation(self, expression, context: ParserRuleContext, task: T
if self.expression_is_string(left, task) and self.expression_is_string(right, task):
return True

msg = "Types of Right and left side of the comparison dont match"
msg = (
"Types of right and left side of the comparison dont match. "
"This might be caused by some of the Rule parameters that are not initialised."
)
self.error_handler.print_error(msg, context=context)
return False
if expression["binOp"] in ["*", "/", "+", "-"]:
Expand Down Expand Up @@ -911,6 +914,26 @@ def variable_type_exists(self, variable_type: str) -> bool:
return False
return True

def check_type_of_value(self, value: Any, value_type: str) -> bool:
"""Checks if the given value is the given type in the DSL.
Returns:
True if the value is from the given value type.
"""
if value_type == "number":
# bool is a subclass of int so check it before
if isinstance(value, bool):
return False
return isinstance(value, (int, float))
if value_type == "boolean":
return isinstance(value, bool)
if value_type == "string":
return isinstance(value, str)
if isinstance(value, Struct):
return value.name == value_type
# value was a string
return True

def instantiated_array_length_correct(
self, instantiated_array: Array, array_definition: Array
) -> bool:
Expand Down

0 comments on commit 68809a0

Please sign in to comment.