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

1from __future__ import annotations 

2from typing import Literal, Optional, TYPE_CHECKING 

3from kye.parser.evaluate import evaluate 

4from kye.parser.expressions import Expression 

5 

6if TYPE_CHECKING: 

7 from kye.parser.environment import ChildEnvironment, Environment 

8 import kye.parser.kye_ast as AST 

9 

10class Edges: 

11 edges: dict[tuple[str, str], Edge] 

12 

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 ): 

22 

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 ) 

32 

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 

41 

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 

58 

59 

60class ASTEdge(Edge): 

61 ast: AST.EdgeDefinition 

62 status: Literal['new', 'processing', 'done'] 

63 

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 

73 

74 def get_type(self): 

75 if self.status == 'done': 

76 assert self._type is not None 

77 return self._type 

78 

79 if self.status == 'processing': 

80 raise Exception('Already has been called, possible circular reference') 

81 

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 

88 

89 raise Exception(f'Unknown status "{self.status}"') 

90 

91