Coverage for kye/parser/edges.py: 46%
48 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-01 14:46 -0700
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-01 14:46 -0700
1from __future__ import annotations
2from typing import Literal, Optional, TYPE_CHECKING
3from kye.parser.evaluate import evaluate
4from kye.parser.expressions import Expression
6if TYPE_CHECKING:
7 from kye.parser.environment import ChildEnvironment, Environment
8 import kye.parser.kye_ast as AST
10class Edges:
11 edges: dict[tuple[str, str], Edge]
13 def define(self,
14 env: ChildEnvironment,
15 name: str,
16 ast: Optional[AST.EdgeDefinition] = None,
17 returns: Optional[ChildEnvironment] = None,
18 parameters: list[ChildEnvironment] = [],
19 nullable: bool = False,
20 multiple: bool = False,
21 ):
23 self.edges[(env.global_name, name)] = Edge(
24 env=env,
25 name=name,
26 ast=ast,
27 returns=returns,
28 parameters=parameters,
29 nullable=nullable,
30 multiple=multiple,
31 )
33class Edge:
34 env: ChildEnvironment
35 name: str
36 ast: Optional[AST.EdgeDefinition]
37 returns: Optional[ChildEnvironment]
38 parameters: list[ChildEnvironment]
39 nullable: bool
40 multiple: bool
42 def __init__(self,
43 env: Environment,
44 name: str,
45 ast: Optional[AST.EdgeDefinition] = None,
46 returns: Optional[ChildEnvironment] = None,
47 parameters: list[ChildEnvironment] = [],
48 nullable = False,
49 multiple = False,
50 ):
51 self.env = env
52 self.name = name
53 self.ast = ast
54 self.returns = returns
55 self.parameters = parameters
56 self.nullable = nullable
57 self.multiple = multiple
60class ASTEdge(Edge):
61 ast: AST.EdgeDefinition
62 status: Literal['new', 'processing', 'done']
64 def __init__(self,
65 env: Environment,
66 name: str,
67 ast: AST.EdgeDefinition,
68 status: Literal['new', 'processing', 'done']):
69 self.env = env
70 self.name = name
71 self.ast = ast
72 self.status = status
74 def get_type(self):
75 if self.status == 'done':
76 assert self._type is not None
77 return self._type
79 if self.status == 'processing':
80 raise Exception('Already has been called, possible circular reference')
82 if self.status == 'new':
83 self.status = 'processing'
84 self._type = evaluate(self.ast, self.env)
85 assert isinstance(self._type, Expression)
86 self.status = 'done'
87 return self._type
89 raise Exception(f'Unknown status "{self.status}"')