跳到主要内容

栈系统

栈(Stack)是 Alia 语言的核心执行机制,用于管理代码的执行环境和上下文。栈以字面量或 new Stack 表达式创建,以 Stack 对象形式持有,通过其成员完成执行、语境与状态操作。

1. 栈的定义​

语法​

{} ~ 使用原语境的栈
*{} ~ 新建语境的栈
mut {} ~ 使用原语境的可变栈(支持 this 语境操作)
mut *{} ~ 新建语境的可变栈(支持 this 语境操作)
new Stack <String content> ~ 新建栈(Eval)

{}、*{}、mut {}、mut *{} 作为表达式求值为 Stack 对象;*{} 与 mut *{} 运行时创建独立语境。栈字面量作为独立语句出现时仅构造 Stack 对象而不执行栈体,执行由 call <Stack>.run 完成。

new Stack 接受源码字符串或源码数组,运行时解析并构造等价栈:

const stack = new Stack 'let y = 20
print y'
call stack.run ~ 输出 20

const stack2 = new Stack ['let x = 5
let y = 3
x * y']
print call stack2.run ~ 输出 15

类型前缀栈​

在栈体前使用类型名(内置类型,或 type/typify/class 声明的自定义类型)可以声明栈的返回值:

run Number { 42 } ~ 并行执行一个返回 Number 的栈
mut String { 'hi' } ~ 类型前缀可变栈
const typed = Number { 9 } ~ 类型前缀栈
enter Number { 3 } ~ enter 目标
alias f -> Number { 42 } ~ Alias 实现体
  • 栈内的 return / return-val 必须与声明类型匹配,不匹配时检查期报 TYPE_MISMATCH
  • 栈节点的推断类型为 Stack<T>,await <Stack> 的推断结果为 T
  • 栈字面量、并行栈与标准库异步 Stack 的 typeOf 均为 'Stack',Ok/as 可正常判定
  • 未定义的类型名作为前缀时,检查期报 TYPE_INVALID_OPERATION

2. 栈操作​

操作描述适用
call <Stack>.run执行栈内容,返回栈末尾值或 break 值全部
<Stack>.define <String name> <Value val>在语境中定义变量可变栈
<Stack>.set <String name> <Value val>设置语境中的变量可变栈
<Stack>.resolve <String name>从语境中查找变量可变栈
<Stack>.has <String name>检查语境中是否存在变量可变栈
<Stack>.context <Object context>将对象成员注入语境可变栈
compile编译期覆写语境内提供的子节点编译函数仅编译期

run、result、join、detach 为零参成员,调用时使用 call。define、set、resolve、has 按位置接收参数,使用语法式调用。context 接收单个对象:对象以变量形式提供时写作 <Stack>.context <Object var>,以字面量形式提供时写作 call <Stack>.context *[ ... ]。

const stack = *{
let x = 10
x + 5
}

const result = call stack.run
print result ~ 输出 15

print call stack.run ~ 仍输出 15

3. 栈内操作​

可变栈的执行语境内含 this,指向可变语境对象。this 的成员与栈成员一致:

  • call this.run:递归执行当前栈
  • this.define <String name> <Value val>:在语境中定义变量
  • this.set <String name> <Value val>:设置语境中的变量
  • this.resolve <String name>:从语境中查找变量
  • this.has <String name>:检查语境中是否存在变量
  • this.context <Object context>:将对象成员注入语境
const stack = mut *{
this.define 'name' 'Alice'
this.set 'name' 'Bob'
this.resolve 'name'
}
print call stack.run ~ 输出 'Bob'
const stack = mut *{
print name
print age
}
call stack.context *[ name: 'Bob', age: 25 ]
call stack.run ~ 输出 Bob 与 25
const stack = mut *{
call this.context *[ name: 'Alice' ]
name
}
print call stack.run ~ 输出 'Alice'

4. 栈的创建方式​

方式一:字面量创建​

const newContextStack = *{
let x = 1
x
}

const sameContextStack = {
let y = 2
y
}

方式二:使用 new Stack​

const stack = new Stack 'let x = 10
print x'
call stack.run ~ 输出 10

5. 栈的返回值​

栈的返回值默认为栈体的最后一项;break <Value return> 使栈返回其携带的值。

const stack1 = *{
let x = 1
x + 1
}
print call stack1.run ~ 输出 2

const stack2 = *{
break '自定义返回值'
}
print call stack2.run ~ 输出 '自定义返回值'

break 在 if / if else 分支中直接使上层栈返回;在 while/for/repeat 循环体中则终止当前循环。

6. 栈与作用域​

*{} 新建独立语境,{} 沿用原语境。两者均需通过 call <Stack>.run 执行。

let x = 0
call {
let x = 10
x + 5
}.run
print x ~ 输出 10

let y = 0
call *{
let y = 10
y + 5
}.run
print y ~ 输出 0

7. 示例代码​

~ 1. 基本栈操作
const stack = *{
let x = 10
let y = 20
x + y
}
const result = call stack.run
print '栈的返回值: ' .. result

~ 2. 栈的嵌套
const outerStack = *{
let outerVar = 'outer'
const innerStack = *{
let innerVar = 'inner'
outerVar .. ' ' .. innerVar
}
call innerStack.run
}
print call outerStack.run

~ 3. 栈的语境操作
const contextStack = mut *{
this.define 'name' 'Alice'
this.define 'age' 30
print 'Name: ' .. name
print 'Age: ' .. age
this.set 'age' 31
print 'Updated age: ' .. age
'Context updated successfully'
}
print call contextStack.run

~ 4. 栈的循环执行
let count = 0
const loopStack = {
count = count + 1
if count >= 5 {
break
}
call this.run
}
call loopStack.run
print count

~ 5. 使用 new Stack
const evalStack = new Stack 'let x = 5
let y = 3
x * y'
print 'Eval result: ' .. call evalStack.run

8. 可变栈特性​

可变栈(mut {} 或 mut *{})在语境内支持 Has 与 enter,并可在多次执行间保持状态。

Has 关键字​

Has 检查可变栈语境内是否存在指定变量,返回 Boolean。

const stack = mut *{
if Has 'var' {
var
} else {
let var = 10
var
}
}
print call stack.run ~ 输出 10
stack.set 'var' 20
print call stack.run ~ 输出 20

类型收窄​

在 if 条件中使用 Has 时,类型检查器将该变量类型从 <Null> 收窄为 <Value>:

const stack = mut *{
if Has 'name' {
name
} else {
let name = 'x'
name
}
}

enter 关键字​

enter 进入栈的语境。enter <Stack> 执行目标栈;enter <Stack> <Stack body> 在目标语境中执行 body,修改持久化到原栈。

const stack = mut *{
let val = 100
val
}
call stack.run

enter (stack) {
if Has 'val' {
print val ~ 输出 100
}
}

目标栈以变量形式提供时,enter 的操作数带括号(enter (stack) { ... }),以免被解析为类型前缀栈。

const stack = mut *{
let count = 0
count
}
call stack.run

enter (stack) {
this.set 'count' 5
}

print stack.resolve 'count' ~ 输出 5

9. 栈的作用​

  1. 语境隔离:通过栈创建独立的执行环境
  2. 代码组织:将代码块封装为栈,提高可维护性
  3. 控制流管理:通过栈操作控制代码的执行流程
  4. 状态保持:可变栈可在多次执行间保持状态
  5. 递归执行:通过 call this.run 实现栈的递归调用

下一步​