Coverage for kye/parser/compile.py: 11%

65 statements  

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

1import kye.parser.kye_ast as AST 

2 

3def compile_type_expression(ast: AST.Expression, typ: dict): 

4 assert isinstance(ast, AST.Expression) 

5 if isinstance(ast, AST.Identifier): 

6 assert ast.name[0].isupper() 

7 typ['type'] = ast.name 

8 elif isinstance(ast, AST.LiteralExpression): 

9 typ['const'] = ast.value 

10 elif isinstance(ast, AST.Operation): 

11 if ast.name == 'filter': 

12 assert isinstance(ast.children[0], AST.Identifier) 

13 assert len(ast.children) <= 2 

14 typ['type'] = ast.children[0].name 

15 if len(ast.children) == 2: 

16 typ['filter'] = ast.children[1].meta.text 

17 else: 

18 typ['expr'] = ast.meta.text 

19 else: 

20 raise Exception('Unknown Expression') 

21 

22def compile_edge(ast: AST.EdgeDefinition, edges: dict): 

23 assert isinstance(ast, AST.EdgeDefinition) 

24 edge = {} 

25 edges[ast.name] = edge 

26 if ast.cardinality in ('?','*'): 

27 edge['nullable'] = True 

28 if ast.cardinality in ('+','*'): 

29 edge['multiple'] = True 

30 compile_type_expression(ast.type, edge) 

31 

32def compile_alias(ast: AST.AliasDefinition, models: dict, path: tuple[str]): 

33 assert isinstance(ast, AST.AliasDefinition) 

34 alias = {} 

35 path += (ast.name,) 

36 models['.'.join(path)] = alias 

37 compile_type_expression(ast.type, alias) 

38 

39def compile_model(ast: AST.ModelDefinition, models: dict, path: tuple[str]): 

40 

41 def compile_index(index: list[str]): 

42 assert len(index) >= 1 

43 if len(index) == 1: 

44 return index[0] 

45 return index 

46 

47 assert isinstance(ast, AST.ModelDefinition) 

48 path += (ast.name,) 

49 model = { 'edges': {} } 

50 

51 assert len(ast.indexes) >= 1 

52 if len(ast.indexes) == 1: 

53 model['index'] = compile_index(ast.indexes[0]) 

54 else: 

55 model['indexes'] = [compile_index(idx) for idx in ast.indexes] 

56 

57 for subtype in ast.subtypes: 

58 compile_type_definition(subtype, models, path) 

59 for edge in ast.edges: 

60 compile_edge(edge, model['edges']) 

61 models['.'.join(path)] = model 

62 

63def compile_type_definition(ast: AST.TypeDefinition, models: dict, path: tuple[str]): 

64 assert isinstance(ast, AST.TypeDefinition) 

65 if isinstance(ast, AST.AliasDefinition): 

66 compile_alias(ast, models, path) 

67 elif isinstance(ast, AST.ModelDefinition): 

68 compile_model(ast, models, path) 

69 else: 

70 raise Exception('Unknown TypeDefinition') 

71 

72def compile_ast(ast: AST.AST): 

73 if isinstance(ast, AST.Expression): 

74 return ast.meta.text 

75 if isinstance(ast, AST.ModuleDefinitions): 

76 models = {} 

77 for definition in ast.children: 

78 compile_type_definition(definition, models, tuple()) 

79 return models