diff --git a/src/astx/__init__.py b/src/astx/__init__.py index cda7a3a..89bd5c3 100644 --- a/src/astx/__init__.py +++ b/src/astx/__init__.py @@ -39,6 +39,7 @@ LambdaExpr, ) from astx.datatypes import ( + AnyType, Boolean, Complex, Complex32, @@ -237,6 +238,7 @@ def get_version() -> str: "LiteralUTF8String", "UTF8Char", "UTF8String", + "AnyType", ] diff --git a/src/astx/base.py b/src/astx/base.py index 4b0bd66..ce93e86 100644 --- a/src/astx/base.py +++ b/src/astx/base.py @@ -130,6 +130,7 @@ class ASTKind(Enum): Decimal256DTKind = -621 UTF8CharDTKind = -622 UTF8StringDTKind = -623 + AnyDTKind = -627 # imports(packages) ImportStmtKind = -700 diff --git a/src/astx/datatypes.py b/src/astx/datatypes.py index 9012d55..dc9b6fd 100644 --- a/src/astx/datatypes.py +++ b/src/astx/datatypes.py @@ -783,3 +783,27 @@ def get_struct(self, simplified: bool = False) -> ReprStruct: key = f"LiteralUTF8Char: {self.value}" value = self.value return self._prepare_struct(key, value, simplified) + + +@public +@typechecked +class AnyType(DataTypeOps): + """Class representing the 'Any' data type, used generically.""" + + def __init__(self, loc: SourceLocation = NO_SOURCE_LOCATION) -> None: + """Initialize the Any type with a source location.""" + super().__init__() + self.loc = loc + self.kind = ASTKind.AnyDTKind + self.value = None + + def __str__(self) -> str: + """Return a simplified string representation for Any.""" + return "Any" + + def get_struct(self, simplified: bool = False) -> dict[str, str]: + """Return the AST structure of the AnyType object.""" + if simplified: + return {"key": "Any"} + else: + return {"type": "Any", "value": repr(self.value)} diff --git a/src/astx/transpilers/python.py b/src/astx/transpilers/python.py index d781fb0..4de5f72 100644 --- a/src/astx/transpilers/python.py +++ b/src/astx/transpilers/python.py @@ -346,3 +346,8 @@ def visit(self, node: astx.WhileStmt) -> str: condition = self.visit(node.condition) body = self._generate_block(node.body) return f"while {condition}:\n{body}" + + @dispatch # type: ignore[no-redef] + def visit(self, node: astx.AnyType) -> str: + """Handle AnyType nodes.""" + return repr(node.value) diff --git a/tests/test_datatype_any.py b/tests/test_datatype_any.py new file mode 100644 index 0000000..688cf3f --- /dev/null +++ b/tests/test_datatype_any.py @@ -0,0 +1,26 @@ +"""Tests for Any data type.""" + +from astx.base import ASTKind +from astx.datatypes import AnyType + + +def test_any_type_creation() -> None: + """Test basic creation of AnyType.""" + any_type = AnyType() + assert isinstance(any_type, AnyType) + assert any_type.kind == ASTKind.AnyDTKind + + +def test_any_type_str_representation() -> None: + """Test string representation of AnyType.""" + any_type = AnyType() + assert str(any_type) == "Any" + + +def test_any_type_equality() -> None: + """Test equality comparison between AnyType instances.""" + any_type1 = AnyType() + any_type2 = AnyType() + + # Same types should be equal + assert any_type1 == any_type2 diff --git a/tests/transpilers/test_python.py b/tests/transpilers/test_python.py index b2cee87..8ed1ef5 100644 --- a/tests/transpilers/test_python.py +++ b/tests/transpilers/test_python.py @@ -753,3 +753,24 @@ def test_transpiler_ifstmt_without_else() -> None: assert ( generated_code == expected_code ), f"Expected '{expected_code}', but got '{generated_code}'" + + +def test_transpiler_any_type() -> None: + """Test the transpiler's handling of AnyType.""" + # Create an AnyType instance + any_type_value = astx.AnyType() + any_type_value.value = None # The default value + + # Initialize the transpiler + generator = astx2py.ASTxPythonTranspiler() + + # Generate Python code + generated_code = generator.visit(any_type_value) + + # Expected code + expected_code = repr(None) # Should be 'None' + + # Assert that the generated code matches the expected output + assert ( + generated_code == expected_code + ), f"Generated code '{generated_code}' but expected '{expected_code}'"