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
« 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
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
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)
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)])
40 raise NotImplementedError(f'Not Implemented {ast.__class__.__name__}')
42def evaluate(ast: AST.AST, env: Environment) -> Type:
43 if isinstance(ast, AST.Expression):
44 return evaluate_expression(ast, env)
46 if isinstance(ast, AST.AliasDefinition):
47 return evaluate_expression(ast.type, env).extend(name=ast.name, env=env)
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