1 /// Copyright: Copyright (c) 2017-2019 Andrey Penechko.
2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
3 /// Authors: Andrey Penechko.
4 module vox.fe.ast.decl.module_;
5 
6 import vox.all;
7 
8 /// Index into CompilationContext.files
9 struct ModuleIndex
10 {
11 	uint fileIndex;
12 }
13 
14 /// If `module` declaration is found in the module points to that token
15 @(AstType.decl_module)
16 struct ModuleDeclNode {
17 	mixin ScopeDeclNodeData!(AstType.decl_module, 0, AstNodeState.name_register_self_done);
18 	ScopeIndex memberScope;
19 	/// Linear list of all functions of a module (including nested and methods and externals)
20 	/// Order may be different from declaration order, because conditionaly compiled functions are added later
21 	AstNodes functions;
22 	IrModule irModule;
23 	IrModule lirModule;
24 	LinkIndex objectSymIndex;
25 	ModuleIndex moduleIndex;
26 	/// module identifier. Used by import declaration.
27 	Identifier fqn;
28 	/// Points to PackageDeclNode
29 	AstIndex parentPackage = CommonAstNodes.node_root_package;
30 
31 	bool isTopLevel() { return parentPackage == CommonAstNodes.node_root_package; }
32 
33 	void addFunction(AstIndex func, CompilationContext* c) {
34 		functions.put(c.arrayArena, func);
35 	}
36 
37 	string fileName(CompilationContext* c) {
38 		return c.files[moduleIndex.fileIndex].name;
39 	}
40 
41 	FunctionDeclNode* tryFindFunction(Identifier id, CompilationContext* c) {
42 		AstIndex sym = memberScope.lookup_scope(id, c);
43 		if (sym.isUndefined) return null;
44 		return sym.get!FunctionDeclNode(c);
45 	}
46 }
47 
48 
49 void print_module(ModuleDeclNode* node, ref AstPrintState state)
50 {
51 	state.print("MODULE ", state.context.files[node.moduleIndex.fileIndex].name,
52 		" ", node.fqn.pr(state.context));
53 	print_ast(node.declarations, state);
54 }
55 
56 void name_register_nested_module(ModuleDeclNode* node, ref NameRegisterState state) {
57 	node.state = AstNodeState.name_register_nested;
58 	require_name_register(node.declarations, state);
59 	node.state = AstNodeState.name_register_nested_done;
60 }
61 
62 void name_resolve_module(ModuleDeclNode* node, ref NameResolveState state) {
63 	node.state = AstNodeState.name_resolve;
64 	require_name_resolve(node.declarations, state);
65 	node.state = AstNodeState.name_resolve_done;
66 }
67 
68 void type_check_module(ModuleDeclNode* node, ref TypeCheckState state)
69 {
70 	node.state = AstNodeState.type_check;
71 	require_type_check(node.declarations, state);
72 	node.state = AstNodeState.type_check_done;
73 }
74 
75 void ir_gen_module_globals(ref IrGenState gen, ModuleDeclNode* m)
76 {
77 	CompilationContext* c = gen.context;
78 
79 	foreach (AstIndex decl; m.declarations)
80 	{
81 		ir_gen_decl(gen, decl);
82 	}
83 }
84 
85 void ir_gen_module_func(ref IrGenState gen, ModuleDeclNode* m)
86 {
87 	CompilationContext* c = gen.context;
88 
89 	foreach (AstIndex decl; m.functions)
90 	{
91 		FunctionDeclNode* func = c.getAst!FunctionDeclNode(decl);
92 		ir_gen_function(gen, func);
93 
94 		IrFunction* irData = c.getAst!IrFunction(func.backendData.irData);
95 		// irData can be null if function is external
96 		if (irData) m.irModule.addFunction(c, irData);
97 	}
98 }