Coverage for kye/parser/kye_evaluate.py: 21%

29 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-27 17:23 -0700

1from kye.parser.environment import Environment 

2import kye.parser.kye_ast as AST 

3from kye.parser.types import Type, Edge 

4 

5def evaluate_type_expression(ast: AST.Expression, env: Environment) -> Type: 

6 if isinstance(ast, AST.Identifier): 

7 typ = env.lookup(ast.name) 

8 if typ is None: 

9 raise Exception(f'Undefined Type: {repr(ast)}') 

10 return typ.type 

11 

12 if isinstance(ast, AST.LiteralExpression): 

13 base_type = None 

14 if type(ast.value) is str: 

15 base_type = 'String' 

16 if isinstance(ast.value, (float, int)): 

17 base_type = 'Number' 

18 assert base_type is not None 

19 return Type( 

20 extends=env.root.get_child(base_type).type, 

21 filters={'eq': ast.value}, 

22 ) 

23 

24 raise NotImplementedError(f'Not Implemented {ast.__class__.__name__}') 

25 

26def evaluate_edge(ast: AST.EdgeDefinition, env: Environment) -> Edge: 

27 return Edge( 

28 name=ast.name, 

29 returns=evaluate_type_expression(ast.type, env), 

30 nullable=ast.cardinality in ('?','*'), 

31 multiple=ast.cardinality in ('+','*'), 

32 ) 

33 

34def evaluate(ast: AST.AST, env: Environment) -> Type: 

35 if isinstance(ast, AST.Expression): 

36 return evaluate_type_expression(ast, env) 

37 

38 if isinstance(ast, AST.AliasDefinition): 

39 return Type( 

40 name=ast.name, 

41 extends=evaluate_type_expression(ast.type, env), 

42 ) 

43 

44 if isinstance(ast, AST.EdgeDefinition): 

45 return evaluate_type_expression(ast.type, env) 

46 

47 if isinstance(ast, AST.ModelDefinition): 

48 return Type( 

49 name=ast.name, 

50 indexes=ast.indexes, 

51 edges={ 

52 edge.name: evaluate_edge(edge, env) 

53 for edge in ast.edges 

54 } 

55 )