Repository navigation
Expand file tree
/
Copy pathscope.ts
More file actions
165 lines (141 loc) · 4.61 KB
/
Copy pathscope.ts
File metadata and controls
165 lines (141 loc) · 4.61 KB
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
3
8000
2
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import { Type, FuncType, Variable, Function } from "./type";
/** 作用域种类 */
enum ScopeType {
/** 全局作用域 */
Global,
/** 函数作用域 */
Func,
/** 局部作用域 */
Local,
}
/** 作用域 */
export class Scope {
/** 作用域名 */
readonly name: string;
/** 作用域种类,见 {@link ScopeType} */
private readonly type: ScopeType;
/** 符号表 */
private symbols: Map<string, Variable | Function>;
/** 下一个变量在栈帧中的偏移量 */
nextOffset: number = 0;
/** 局部变量所占的内存大小 */
localVarSize: number = 0;
constructor(name: string, type: ScopeType) {
this.name = name;
this.type = type;
this.symbols = new Map();
}
/** 在该作用域中定义一个变量 */
declareVar(name: string, type: Type, isGlobal: boolean): Variable {
let v = new Variable(name, type, this.nextOffset, false, isGlobal);
this.nextOffset += v.type.sizeof();
this.symbols.set(name, v);
return v;
}
/** 在该作用域中定义一个参数 */
declareParam(name: string, type: Type, index: number): Variable {
let v = new Variable(name, type, index, true);
this.symbols.set(name, v);
return v;
}
/** 在该作用域中定义一个函数 */
declareFunc(name: string, type: FuncType): Function {
let f = new Function(name, type);
this.symbols.set(name, f);
return f;
}
/** 在该作用域中查找名为 `name` 的符号 */
find(name: string): Variable | Function {
return this.symbols.get(name);
}
isGlobal(): boolean {
return this.type === ScopeType.Global;
}
isFunc(): boolean {
return this.type == ScopeType.Func;
}
isLocal(): boolean {
return this.type === ScopeType.Local;
}
static newGlobal(): Scope {
return new Scope("GLOBAL", ScopeType.Global);
}
static newFunc(name: string): Scope {
857C
return new Scope(name, ScopeType.Func);
}
static newLocal(): Scope {
return new Scope("LOCAL", ScopeType.Local);
}
}
/** 多个嵌套的作用域构成的栈 */
export class ScopeStack {
private scopes: Scope[] = [];
/** 当前作用域,即最里层作用域 */
private current(): Scope {
return this.scopes[this.scopes.length - 1];
}
/** 当前的全局作用域 */
currentGlobal(): Scope {
return this.scopes[0];
}
/** 当前的函数作用域 */
currentFunc(): Scope {
return this.scopes[1];
}
/** 打开一个作用域 `scope`,会将其压入栈顶 */
open(scope: Scope) {
if (scope.isLocal()) {
scope.nextOffset = this.current().nextOffset;
}
this.scopes.push(scope);
}
/** 关闭最里层的作用域,即从栈顶弹出 */
close() {
let scope = this.scopes.pop();
if (scope.isLocal()) {
let func = this.currentFunc();
func.localVarSize = Math.max(func.localVarSize, scope.nextOffset);
}
}
/** 当前作用域是否可以定义名为 `name` 的符号 */
canDeclare(name: string): boolean {
if (this.current().find(name)) {
return false;
}
// 如果上层作用域是函数作用域,且与其中的符号同名(参数),不允许定义
if (this.scopes.length > 1) {
let funcScope = this.scopes[this.scopes.length - 2];
if (funcScope.isFunc() && funcScope.find(name)) {
return false;
}
}
return true;
}
/** 在当前作用域中定义一个变量 */
declareVar(name: string, type: Type, isGlobal: boolean): Variable {
return this.current().declareVar(name, type, isGlobal);
}
/** 在当前作用域中定义一个参数。
*
* @param name 参数名
* @param type 参数类型
* @param index 第几个参数
*/
declareParam(name: string, type: Type, index: number): Variable {
return this.current().declareParam(name, type, index);
}
/** 在当前作用域中定义一个函数 */
declareFunc(name: string, type: FuncType, defined?: boolean): Function {
let f = this.current().declareFunc(name, type);
if (defined) f.defined = true;
return f;
}
/** 从里到外依次在各作用域中查找名为 `name` 的变量 */
find(name: string): Variable | Function {
for (let i = this.scopes.length - 1; i >= 0; i--) {
let v = this.scopes[i].find(name);
if (v) return v;
}
return null;
}
}