compiler-pass.spice
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2026 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | // Own imports | ||
| 4 | import "@/global/global-resource-manager"; | ||
| 5 | import "@/driver"; | ||
| 6 | import "@/symboltablebuilder/scope"; | ||
| 7 | import "@/source-file"; | ||
| 8 | |||
| 9 | public type CompilerPass struct { | ||
| 10 | public GlobalResourceManager& resourceManager | ||
| 11 | public CliOptions& cliOptions | ||
| 12 | public SourceFile* sourceFile | ||
| 13 | public Scope* rootScope | ||
| 14 | 34740 | public unsigned long manIdx = 0l | |
| 15 | public Scope* currentScope | ||
| 16 | } | ||
| 17 | |||
| 18 | 34740 | public p CompilerPass.ctor(GlobalResourceManager& resourceManager, SourceFile* sourceFile = nil<SourceFile*>) { | |
| 19 | 34740 | this.resourceManager = resourceManager; | |
| 20 | // Bind the reference field from a reference variable (assigning a call result would copy into an unbound reference) | ||
| 21 | 34740 | CliOptions& cliOptionsRef = resourceManager.getCliOptions(); | |
| 22 | 34740 | this.cliOptions = cliOptionsRef; | |
| 23 | 34740 | this.sourceFile = sourceFile; | |
| 24 | 34740 | if sourceFile != nil<SourceFile*> { | |
| 25 | 34738 | this.currentScope = this.rootScope = sourceFile.getGlobalScope(); | |
| 26 | 34738 | } else { | |
| 27 | 2 | this.currentScope = this.rootScope = nil<Scope*>; | |
| 28 | 2 | } | |
| 29 | 34740 | } | |
| 30 | |||
| 31 | /** | ||
| 32 | * Change to the passed scope. | ||
| 33 | * For nested scopes in generic functions/procedures it is important to have the right parent for symbol lookups | ||
| 34 | * Therefore, changeToScope sets the children's parent to the old scope to always have the right parent | ||
| 35 | * | ||
| 36 | * @param scope Scope to change to | ||
| 37 | * @param scopeType Expected type of the given scope | ||
| 38 | */ | ||
| 39 | 292174 | public p CompilerPass.changeToScope(Scope* scope, ScopeType scopeType) { | |
| 40 | 292174 | assert scope != nil<Scope*>; | |
| 41 | 292174 | assert scope.scopeType == scopeType; | |
| 42 | 292174 | assert !scope.isGenericScope; | |
| 43 | // Adjust members of the new scope | ||
| 44 | 292174 | scope.parent = this.currentScope; | |
| 45 | 292174 | scope.symbolTable.parent = &this.currentScope.symbolTable; | |
| 46 | // Set the scope | ||
| 47 | 292174 | this.currentScope = scope; | |
| 48 | 292174 | } | |
| 49 | |||
| 50 | /** | ||
| 51 | * Change to the scope with the given name. | ||
| 52 | * | ||
| 53 | * @param scopeName Name of the scope to change to | ||
| 54 | * @param scopeType Expected type of the given scope | ||
| 55 | */ | ||
| 56 | 27952 | public p CompilerPass.changeToScope(const String& scopeName, ScopeType scopeType) { | |
| 57 | 27952 | assert !scopeName.isEmpty(); | |
| 58 | 27952 | this.changeToScope(this.currentScope.getChildScope(scopeName), scopeType); | |
| 59 | 27952 | } | |
| 60 | |||
| 61 | /** | ||
| 62 | * Change to the parent scope of the current. | ||
| 63 | * | ||
| 64 | * @param oldScopeType Expected type of the scope to leave | ||
| 65 | */ | ||
| 66 | 212146 | public p CompilerPass.changeToParentScope(ScopeType oldScopeType) { | |
| 67 | 212146 | assert this.currentScope.scopeType == oldScopeType; | |
| 68 | 212146 | assert this.currentScope.parent != nil<Scope*>; | |
| 69 | 212146 | this.currentScope = this.currentScope.parent; | |
| 70 | 212146 | } | |
| 71 |