Skip to content

Commit b57c3bc

Browse files
committed
Add: structure detecting
1 parent 4470b0e commit b57c3bc

File tree

3 files changed

+56
-20
lines changed

3 files changed

+56
-20
lines changed

fastpy/parser/nodes.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@ class BaseNode(ABC):
77
@abstractmethod
88
def line(self) -> int: ...
99

10-
@abstractmethod
11-
def have_body(self) -> bool: ...
1210

11+
class NodeWithBody(BaseNode, ABC):
12+
_body = []
1313

14-
class BellyNode(BaseNode, ABC):
15-
def have_body(self) -> bool:
16-
return True
14+
def push_node_to_body(self, node: BaseNode):
15+
self._body.append(node)
1716

1817

19-
class ThinNode(BaseNode, ABC):
20-
def have_body(self) -> bool:
21-
return False
18+
class BasicNode(BaseNode, ABC):
19+
pass
2220

2321

2422
class PrintableNode(BaseNode, ABC):
@@ -30,23 +28,23 @@ def __repr__(self):
3028
return self.__class__.__name__ + text
3129

3230

33-
class VariableNode(ThinNode, PrintableNode):
31+
class VariableNode(BasicNode, PrintableNode):
3432
def __init__(self, identifier: BaseToken):
3533
self.identifier = identifier
3634

3735
def line(self) -> int:
3836
return self.identifier.line
3937

4038

41-
class ValueNode(ThinNode, PrintableNode):
39+
class ValueNode(BasicNode, PrintableNode):
4240
def __init__(self, value: BaseToken):
4341
self.value = value
4442

4543
def line(self) -> int:
4644
return self.value.line
4745

4846

49-
class AssignNode(ThinNode, PrintableNode):
47+
class AssignNode(BasicNode, PrintableNode):
5048
def __init__(self,
5149
identifier: BaseToken,
5250
value_type: BaseToken = None,
@@ -59,29 +57,29 @@ def line(self) -> int:
5957
return self.identifier.line
6058

6159

62-
class FuncNode(BellyNode, PrintableNode):
60+
class FuncNode(NodeWithBody, PrintableNode):
6361
def __init__(self,
6462
identifier: BaseToken,
6563
arguments: list[AssignNode] = None,
6664
body: list[BaseNode] = None,
6765
return_type: BaseToken = None):
6866
self.identifier = identifier
6967
self.arguments = arguments or []
70-
self.body = body or []
68+
self._body = body or []
7169
self.return_type = return_type
7270

7371
def line(self) -> int:
7472
return self.identifier.line
7573

7674

77-
class IfNode(BellyNode, PrintableNode):
75+
class IfNode(NodeWithBody, PrintableNode):
7876
def __init__(self,
7977
condition: list[BaseNode] = None,
8078
body: list[BaseNode] = None,
8179
elif_cases: list = None,
8280
else_body: list[BaseNode] = None):
8381
self.condition = condition
84-
self.body = body or []
82+
self._body = body or []
8583
self.elif_cases: list[IfNode.__init__] = elif_cases
8684
self.else_body = else_body
8785

@@ -91,7 +89,7 @@ def line(self) -> int:
9189
return self.condition[0].line
9290

9391

94-
class BinOpNode(ThinNode, PrintableNode):
92+
class BinOpNode(BasicNode, PrintableNode):
9593
def __init__(self,
9694
left_operand: BaseNode = None,
9795
right_operand: BaseNode = None,
@@ -116,14 +114,14 @@ def line(self) -> int:
116114
# pass
117115

118116

119-
class WhileNode(BellyNode, PrintableNode):
117+
class WhileNode(NodeWithBody, PrintableNode):
120118
def __init__(self,
121119
condition: list[BaseNode] = None,
122120
body: list[BaseNode] = None,
123121
else_body: list[BaseNode] = None):
124122
self.condition = condition
125-
self.body = body or []
126123
self.else_body = else_body or []
124+
self._body = body
127125

128126
def line(self) -> int:
129127
if not self.condition or len(self.condition) == 0:

fastpy/parser/parsers.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from .config import *
55
from ..import_tools import import_class
66
from ..log import Logger
7+
from .nodes import *
8+
from .structure import *
79

810

911
class BaseParser(ABC):
@@ -18,13 +20,36 @@ class Parser(BaseParser):
1820
def __init__(self, tokens: list[BaseToken]):
1921
self._tokens = tokens
2022
self._ast = create_ast()
23+
self._structures: list[Structure] = []
24+
self._current_structure: Structure | None = None
2125

22-
def _parse_node(self, tokens: list[BaseToken]):
26+
def _parse_node(self, tokens: list[BaseToken]) -> BaseNode | None:
2327
pass
2428

29+
def _detect_struct_start(self, node: BaseNode, level: int):
30+
if isinstance(node, NodeWithBody):
31+
self._current_structure = Structure(
32+
node=node,
33+
level=level
34+
)
35+
self._structures.append(self._current_structure)
36+
Logger.log_info('Structure detected:', node, ': level:', level)
37+
2538
@Logger.info_decorator(pattern='Parsing: {expr_tokens[0].line}: {expr_tokens}: level: {expr_level}')
2639
def _parse_expression(self, expr_tokens: list[BaseToken], expr_level: int):
27-
pass
40+
node = self._parse_node(expr_tokens)
41+
42+
if node:
43+
self._detect_struct_start(node=node, level=expr_level)
44+
if self._current_structure and self._current_structure.within_struct(expr_level):
45+
self._current_structure.push_node(node)
46+
else:
47+
if self._current_structure and len(self._structures) >= 2:
48+
self._structures.pop(-1)
49+
self._current_structure = self._structures[-1]
50+
else:
51+
self._current_structure = None
52+
self._structures.clear()
2853

2954
@Logger.info_decorator('Start parsing...', ending_message='Parsing completed in {time}')
3055
def parse(self) -> BaseAST:

fastpy/parser/structure.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from .nodes import *
2+
3+
4+
class Structure:
5+
def __init__(self, node, level: int):
6+
self._level = level
7+
self._node: NodeWithBody = node
8+
9+
def push_node(self, node: BaseNode):
10+
self._node.push_node_to_body(node=node)
11+
12+
def within_struct(self, level: int):
13+
return level == self._level

0 commit comments

Comments
 (0)