语境
创建于 2023-04-27 / 最近更新于 2023-04-27 /
1426
字体:
[默认]
[大]
[更大]
语境是青语言中十分重要的概念,所有的代码执行均依赖于语境,所以再进一步了解青语言的执行过程前,我们先来了解一下语境。
语境类似于其他语言中的符号表或作用域的概念,用于在程序执行期间,记录变量名和变量值的绑定关系,因此其本质上是一个映射表,但添加了层级关系。语境类的定义:
public class Ctx {
public Dictionary<string, Expr> Map { get; set; } //存储变量的表
public Ctx? Father; //上级语境
public CtxTp Tp = CtxTp.Default; //语境类型,主要是为了标记程序自动创建的临时语境,如循环、函数
……
}
这里的层级关系,对应的JS中的作用域链,因此在在语境中对变量进行查找、设值等操作时,除了本级语境外,还需考虑当前的语境链。因此,语境的相关操作基本包括两套逻辑。
public void PutNow(string k, Expr v) {
Map[k] = v;
}
public Expr GetNow(string k) {
Expr v = Map.GetValueOrDefault(k, new Expr(TP.None, 0));
return v;
}
public Expr RemoveNow(string k) {
if (Map.ContainsKey(k)) {
Map.Remove(k);
return new Expr(TP.Bool, true);
} else {
return new Expr(TP.Bool, false);
}
}
这3个方法分别对应向语境中添加变量绑定、获取变量值、删除绑定的操作,并且只在当前语境中完成。
public void Put(string k, Expr v) {
Ctx curr = this;
/*逐级向上查找*/
while (!curr.Map.ContainsKey(k) && curr.Father != null) {
/*
* 不能修改LibCtx中的绑定关系
* 如果发现上级已经是LibCtx
* 那么直接再本级绑定
* 相当于是全局变量
*/
if (curr.Father.Father == null) {
curr.Map[k] = v;
return;
}
curr = curr.Father;
}
curr.Map[k] = v;
return;
}
public Expr Get(string k) {
Ctx curr = this;
while (!curr.Map.ContainsKey(k) && curr.Father != null) {
curr = curr.Father;
}
Expr v = curr.Map.GetValueOrDefault(k, new Expr(TP.None, 0));
return v;
}
public Expr Remove(string k) {
Ctx? ctx = this;
while (ctx != null) {
if (ctx.Map.ContainsKey(k)) {
if (ctx.Father == null) {
return new Expr(TP.Bool, false);
}
Map.Remove(k);
return new Expr(TP.Bool, true);
}
ctx = ctx.Father;
}
return new Expr(TP.Bool, false);
}
这里的3个方法同样对应添加变量绑定、获取变量值、删除绑定的操作,与前面不同的是,这些操作会沿着语境链逐层向上查找。
对于获取变量操作,向上查找的过程中一旦发现了某个语境中存在对应的记录,那么会立即返回该语境中记录的值。
对于添加和删除变量绑定操作,同样向上查找的过程中如果发现存在记录,那么就在该语境中执行对应的操作。但是这个逐级向上的操作最多可到达用户语境,而不会继续向上到达库语境,这么做是为了保护库语境中的记录,库语境是只读的。
语境的操作方式对应到语法中会出现2种设值方式,使用等号=进行赋值,那么会逐层向上查找,而如果使用冒号:进行赋值,那么只会在当前语境进行操作。
青语言的对象本质上也是语境:
public class Obj : Ctx {
/*
* 这里定义了一个raw,用来存放原生的对象
* 如果需要封装C#原生的功能
* 可以继承Obj类,把原始的对象放到raw里
* 再添加对原始对象的操作方法
* 相应的例子在Proto命名空间里
*/
public object Raw { get; set; }
……
}
对象的封装类型继承了语境类型,但添加了一个Raw用于保存原生的对象。
0 人点赞过