Skip to content

Commit

Permalink
feat: add TypeCastExpr class (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
apkrelling authored Nov 1, 2024
1 parent 7b8f52d commit 3a18439
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 212 deletions.
16 changes: 9 additions & 7 deletions .makim.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
version: 1.0
groups:
clean:
tasks:
tmp:
help: remove build artifacts, compiled files, and cache
shell: bash
backend: bash
run: |
find . -name '*.egg-info' -exec rm -rf {} +
find . -name '*.egg' -exec rm -f {} +
Expand All @@ -18,6 +17,8 @@ groups:
rm -f .coverage
rm -rf htmlcov/
rm -rf .pytest_cache
rm -rf .ruff_cache
rm -rf .mypy_cache
tests:
tasks:
Expand All @@ -38,7 +39,7 @@ groups:
help: Specify parameters to be used for tests
type: string
default: "-vv"
shell: bash
backend: bash
run: |
pytest \
--cov=astx \
Expand All @@ -52,10 +53,11 @@ groups:

ci:
help: run the sames tests executed on CI
dependencies:
- task: tests.unit
- task: tests.notebooks
- task: tests.linter
hooks:
pre-run:
- task: tests.unit
- task: tests.notebooks
- task: tests.linter

docs:
tasks:
Expand Down
416 changes: 212 additions & 204 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mkdocs-macros-plugin = ">=0.7.0,<1"
mkdocs-material = ">=9.1.15"
mkdocstrings = {version=">=0.24.3", extras=["python"]}
jupyterlab = ">=4.0.5"
makim = "1.18.1"
makim = "1.19.0"
umlizer = ">=0.1.0"
nbmake = ">=1.4.6"
mkdocs-gen-files = ">=0.5.0"
Expand Down
4 changes: 4 additions & 0 deletions src/astx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@
Program,
Target,
)
from astx.types import (
TypeCastExpr,
)
from astx.variables import (
InlineVariableDeclaration,
Variable,
Expand Down Expand Up @@ -207,6 +210,7 @@ def get_version() -> str:
"StatementType",
"symbol_table",
"Target",
"TypeCastExpr",
"UnaryOp",
"Undefined",
"VariableAssignment",
Expand Down
1 change: 1 addition & 0 deletions src/astx/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class ASTKind(Enum):
ImportFromExprKind = -801

LambdaExprKind = -807
TypeCastExprKind = -809


class ASTMeta(type):
Expand Down
7 changes: 7 additions & 0 deletions src/astx/transpilers/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ def visit(self, node: astx.LambdaExpr) -> str:
params_str = ", ".join(param.name for param in node.params)
return f"lambda {params_str}: {self.visit(node.body)}"

@dispatch # type: ignore[no-redef]
def visit(self, node: astx.TypeCastExpr) -> str:
"""Handle TypeCastExpr nodes."""
return (
f"cast({self.visit(node.target_type.__class__)}, {node.expr.name})"
)

@dispatch # type: ignore[no-redef]
def visit(self, node: astx.UnaryOp) -> str:
"""Handle UnaryOp nodes."""
Expand Down
50 changes: 50 additions & 0 deletions src/astx/types.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
"""AST types module."""

from __future__ import annotations

from typing import Optional

from public import public
from typeguard import typechecked

from astx.base import (
NO_SOURCE_LOCATION,
ASTKind,
ASTNodes,
DataType,
Expr,
ReprStruct,
SourceLocation,
)


@public
@typechecked
class TypeCastExpr(Expr):
"""AST class for type casting expressions."""

expr: Expr
target_type: DataType

def __init__(
self,
expr: Expr,
target_type: DataType,
loc: SourceLocation = NO_SOURCE_LOCATION,
parent: Optional[ASTNodes] = None,
) -> None:
super().__init__(loc=loc, parent=parent)
self.expr = expr
self.target_type = target_type
self.kind = ASTKind.TypeCastExprKind

def __str__(self) -> str:
"""Return a string representation of the TypeCast expression."""
return f"TypeCastExpr ({self.expr}, {self.target_type})"

def get_struct(self, simplified: bool = False) -> ReprStruct:
"""Return the AST structure of the TypeCast expression."""
key = "TypeCastExpr"
value: ReprStruct = {
"expression": self.expr.get_struct(simplified),
"target_type": self.target_type.get_struct(simplified),
}

return self._prepare_struct(key, value, simplified)
26 changes: 26 additions & 0 deletions tests/test_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Tests for classes in types.py."""

from __future__ import annotations

from astx.datatypes import Int32
from astx.types import TypeCastExpr
from astx.variables import Variable
from astx.viz import visualize


def test_typecastexpr() -> None:
"""Test TypeCastExpr."""
# Expression to cast
expr = Variable(name="x")

# Target type for casting
target_type = Int32()

# Create the TypeCastExpr
cast_expr = TypeCastExpr(expr=expr, target_type=target_type)

assert str(cast_expr)
assert cast_expr.get_struct()
assert cast_expr.get_struct(simplified=True)

visualize(cast_expr.get_struct())
19 changes: 19 additions & 0 deletions tests/transpilers/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,25 @@ def test_literal_complex64() -> None:
), f"Expected '{expected_code}', but got '{generated_code}'"


def test_transpiler_typecastexpr() -> None:
"""Test astx.TypeCastExpr."""
# Expression to cast
expr = astx.Variable(name="x")
# Target type for casting
target_type = astx.Int32()
# Create the TypeCastExpr
cast_expr = astx.TypeCastExpr(expr=expr, target_type=target_type)

# Initialize the generator
generator = astx2py.ASTxPythonTranspiler()

generated_code = generator.visit(cast_expr)
expected_code = "cast(int, x)"

assert (
generated_code == expected_code
), f"Expected '{expected_code}', but got '{generated_code}'"

def test_transpiler_utf8_char() -> None:
"""Test astx.Utf8Char."""
# Create a Utf8Char node
Expand Down

0 comments on commit 3a18439

Please sign in to comment.