From 947e9f0149862d5051e99268ae6497c4a32088e3 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Sat, 13 Jun 2026 18:44:19 +0200 Subject: [PATCH] feat(parser): add subscript expressions --- gen/python.py | 5 +++++ midas/ast/printer.py | 12 +++++++++++- midas/ast/python.py | 12 ++++++++++++ midas/cli/highlighter.py | 4 ++++ midas/parser/python.py | 8 ++++++++ tests/serializer/python.py | 8 ++++++++ 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/gen/python.py b/gen/python.py index 79ba8b0..b7c38ec 100644 --- a/gen/python.py +++ b/gen/python.py @@ -143,4 +143,9 @@ class ListExpr: items: list[Expr] +class SubscriptExpr: + object: Expr + index: Expr + + ###< diff --git a/midas/ast/printer.py b/midas/ast/printer.py index 2124778..3495883 100644 --- a/midas/ast/printer.py +++ b/midas/ast/printer.py @@ -664,7 +664,7 @@ class PythonAstPrinter( def visit_literal_expr(self, expr: p.LiteralExpr) -> None: self._write_line("LiteralExpr") with self._child_level(single=True): - self._write_line(f"value: {expr.value}") + self._write_line(f"value: {expr.value!r}") def visit_variable_expr(self, expr: p.VariableExpr) -> None: self._write_line("VariableExpr") @@ -719,3 +719,13 @@ class PythonAstPrinter( if i == len(expr.items) - 1: self._mark_last() item.accept(self) + + def visit_subscript_expr(self, expr: p.SubscriptExpr) -> None: + self._write_line("SubscriptExpr") + with self._child_level(): + self._write_line("object") + with self._child_level(single=True): + expr.object.accept(self) + self._write_line("index", last=True) + with self._child_level(single=True): + expr.index.accept(self) diff --git a/midas/ast/python.py b/midas/ast/python.py index 350dbb1..a199b89 100644 --- a/midas/ast/python.py +++ b/midas/ast/python.py @@ -224,6 +224,9 @@ class Expr(ABC): @abstractmethod def visit_list_expr(self, expr: ListExpr) -> T: ... + @abstractmethod + def visit_subscript_expr(self, expr: SubscriptExpr) -> T: ... + @dataclass(frozen=True) class BinaryExpr(Expr): @@ -324,3 +327,12 @@ class ListExpr(Expr): def accept(self, visitor: Expr.Visitor[T]) -> T: return visitor.visit_list_expr(self) + + +@dataclass(frozen=True) +class SubscriptExpr(Expr): + object: Expr + index: Expr + + def accept(self, visitor: Expr.Visitor[T]) -> T: + return visitor.visit_subscript_expr(self) diff --git a/midas/cli/highlighter.py b/midas/cli/highlighter.py index 00c8dcf..3c3f07e 100644 --- a/midas/cli/highlighter.py +++ b/midas/cli/highlighter.py @@ -218,6 +218,10 @@ class PythonHighlighter( for item in expr.items: item.accept(self) + def visit_subscript_expr(self, expr: p.SubscriptExpr) -> None: + expr.object.accept(self) + expr.index.accept(self) + class MidasHighlighter( Highlighter, m.Stmt.Visitor[None], m.Expr.Visitor[None], m.Type.Visitor[None] diff --git a/midas/parser/python.py b/midas/parser/python.py index bbe23c8..8c1f5a7 100644 --- a/midas/parser/python.py +++ b/midas/parser/python.py @@ -23,6 +23,7 @@ from midas.ast.python import ( MidasType, ReturnStmt, Stmt, + SubscriptExpr, TernaryExpr, TypeAssign, UnaryExpr, @@ -423,6 +424,13 @@ class PythonParser: items=[self.parse_expr(item) for item in items], ) + case ast.Subscript(value=value, slice=index): + return SubscriptExpr( + location=location, + object=self.parse_expr(value), + index=self.parse_expr(index), + ) + case _: raise UnsupportedSyntaxError(node) diff --git a/tests/serializer/python.py b/tests/serializer/python.py index 833d4e4..73b8b84 100644 --- a/tests/serializer/python.py +++ b/tests/serializer/python.py @@ -22,6 +22,7 @@ from midas.ast.python import ( MidasType, ReturnStmt, Stmt, + SubscriptExpr, TernaryExpr, TypeAssign, UnaryExpr, @@ -252,3 +253,10 @@ class PythonAstJsonSerializer( "_type": "ListExpr", "items": [item.accept(self) for item in expr.items], } + + def visit_subscript_expr(self, expr: SubscriptExpr) -> dict: + return { + "_type": "SubscriptExpr", + "object": expr.object.accept(self), + "index": expr.index.accept(self), + }