Coverage for kye/parser/evaluate.py: 0%

42 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-01 16:37 -0700

1from kye.parser.environment import Environment, ChildEnvironment 

2import kye.parser.kye_ast as AST 

3from kye.parser.types import Model, Type, Edge, Expression 

4 

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

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 env.root.get_child(base_type).type.select(ast.value) 

20 

21 if isinstance(ast, AST.Operation): 

22 if ast.name == 'filter': 

23 typ = evaluate_expression(ast.children[0], env) 

24 if len(ast.children) == 0: 

25 return typ 

26 return typ.extend( 

27 filter=evaluate_expression(ast.children[1], typ.env) 

28 ) 

29 elif ast.name == 'dot': 

30 typ = evaluate_expression(ast.children[0], env) 

31 for child in ast.children[1:]: 

32 typ = evaluate_expression(child, typ.env) 

33 return typ 

34 else: 

35 typ = evaluate_expression(ast.children[0], env) 

36 for child in ast.children[1:]: 

37 typ = typ[f'__{ast.name}__'].apply(values=[evaluate_expression(child, env)]) 

38 

39 

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

41 

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

43 if isinstance(ast, AST.Expression): 

44 return evaluate_expression(ast, env) 

45 

46 if isinstance(ast, AST.AliasDefinition): 

47 return evaluate_expression(ast.type, env).extend(name=ast.name, env=env) 

48 

49 elif isinstance(ast, AST.ModelDefinition): 

50 typ = Model( 

51 name=ast.name, 

52 indexes=ast.indexes, 

53 env=env, 

54 ) 

55 for edge in ast.edges: 

56 typ.edges[edge.name] = Edge( 

57 owner=typ, 

58 name=edge.name, 

59 returns=evaluate_expression(edge.type, env), 

60 nullable=edge.cardinality in ('?','*'), 

61 multiple=edge.cardinality in ('+','*'), 

62 ) 

63 return typ