-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
runtime-module-manager.spice
87 lines (69 loc) · 3.32 KB
/
runtime-module-manager.spice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const string STRING_RT_IMPORT_NAME = "__rt_string";
const string RESULT_RT_IMPORT_NAME = "__rt_result";
const string MEMORY_RT_IMPORT_NAME = "__rt_memory";
const string RTTI_RT_IMPORT_NAME = "__rt_rtti";
public type RuntimeModule enum {
STRING_RT = 1,
RESULT_RT = 2,
ARRAY_RT = 4,
OBJECT_RT = 8
}
type ModuleNamePair struct {
string importName
string fileName
}
public type RuntimeModuleManager struct {
GlobalResourceManager &resourceManager
UnorderedMap<RuntimeModule, SourceFile *> modules
}
public p RuntimeModuleManager.ctor(GlobalResourceManager &resourceManager) {
this.resourceManager = resourceManager;
}
public f<SourceFile *> RuntimeModuleManager.requestModule(SourceFile* parentSourceFile, RuntimeModule requestedModule) {
const string importName = resolveNamePair(requestedModule).importName;
// Check if the requested module is available already, if not load it
dyn rtFile = isModuleAvailable(requestedModule) ? getModule(requestedModule) : loadModule(parentSourceFile, requestedModule);
// Add the dependency to the parent source file
parentSourceFile.addDependency(rtFile, parentSourceFile.ast, importName, rtFile.filePath.str());
assert parentSourceFile.dependencies.contains(importName);
SourceFile* runtimeFile = parentSourceFile.dependencies.get(importName);
modules.insert(requestedModule, runtimeFile);
// Merge the module name registry with the one of the source file
parentSourceFile.mergeNameRegistries(*rtFile, importName);
// Tell the source file, that the requested runtime has been imported
parentSourceFile.importedRuntimeModules |= requestedModule;
return runtimeFile;
}
public f<SourceFile *> RuntimeModuleManager.getModule(RuntimeModule requestedModule) {
assert modules.contains(requestedModule);
return modules.get(requestedModule);
}
public f<bool> RuntimeModuleManager.isModuleAvailable(RuntimeModule requestedModule) {
return modules.contains(requestedModule);
}
public f<SourceFile *> RuntimeModuleManager.loadModule(SourceFile* parentSourceFile, RuntimeModule requestedModule) {
const ModuleNamePair namePair = resolveNamePair(requestedModule);
const string filePath = FileUtil::getStdDir() / "runtime" / fileName / ".spice";
assert filePath != parentSourceFile.filePath;
// Instruct the global resource manager to create a new source file
SourceFile* moduleSourceFile = resourceManager.createSourceFile(parentSourceFile, importName, filrPath, true);
moduleSourceFile.mainFile = false;
// Run frontend and first type checker run for the loaded source file
moduleSourceFile.runFrontEnd();
moduleSourceFile.runTypeCheckerPre();
return moduleSourceFile;
}
public f<ModuleNamePair> RuntimeModuleManager.resolveNamePair(RuntimeModule requestedModule) {
switch requestedModule {
case RuntimeModule::STRING_RT:
return ModuleNamePair{STRING_RT_IMPORT_NAME, "string_rt"};
case RuntimeModule::RESULT_RT:
return ModuleNamePair{RESULT_RT_IMPORT_NAME, "result_rt"};
case RuntimeModule::ARRAY_RT:
return ModuleNamePair{MEMORY_RT_IMPORT_NAME, "memory_rt"};
case RuntimeModule::OBJECT_RT:
return ModuleNamePair{RTTI_RT_IMPORT_NAME, "rtti_rt"};
default:
panic(Error("Requested unknown runtime module"));
}
}