2个版本
0.1.1 | 2023年9月20日 |
---|---|
0.1.0 | 2023年9月20日 |
#288 在 编程语言 中
170KB
4.5K SLoC
seraphine
seraphine是一种动态的、强类型和解释型的编程语言。
目前,seraphine是我探索将可读源代码转换为可执行代码过程的学习和实验项目。这就是为什么它的语言核心没有使用外部依赖实现。由于解释器非常原始,seraphine目前非常慢。在我的机器上,与等效的Python实现相比,sudoku示例慢了约2.5倍,与等效的Rust实现相比慢了约200倍。
了解语言的最佳方式是看一个示例
// This function returns a new counter object. Since the last expression is
// returned automatically, we can simply use double curly braces.
fn new_counter(initial_count) {{
count: initial_count,
previous_counts: [],
increment() {
// `this` receiver to access object
this.previous_counts.push(this.count)
this.count = this.count + 1
},
for_each_count(func) {
// Boolean coercion
if (func) {
// For loops to iterate over lists
for (c in this.previous_counts) {
func(c)
}
}
},
get_initial_count() {
if (this.previous_counts.length == 0) {
return this.count
} else {
return this.previous_counts[0]
}
},
}}
counter = new_counter(42)
println("Counter at", counter.count)
while (counter.count < 45) {
counter.increment()
}
println("Counter at", counter.count)
// Anonymous functions (closures are possible)
counter.for_each_count(fn (count) {
println("Counter was", count)
})
println("Initial count was", counter.get_initial_count())
更多示例可以在示例目录中找到。
特性
- 算术和逻辑运算
- 带有
else if
和else
的if语句 - while和for循环
break
和continue
- 内置和用户定义的函数
- 函数自动返回最后一个表达式
- 类型
null
数字
布尔
字符串
函数
列表
对象
迭代器
- 对值进行索引和成员访问
this
对象方法接收者- 从stdin读取并写入stdout和stderr
- 使用
//
的注释 - 对换行字符进行宽松解析,允许将代码拆分为多行
- 用户友好的错误消息,包括堆栈跟踪
- 注意:堆栈跟踪目前在REPL中不可用
- REPL(读取-评估-打印循环)
执行模型
有两种可能的执行Seraphine代码的方式。这没有实际用途。这只是语言发展的方式——由于这是一个学习项目,我想保留两种方法。
第一种方法是较老的一种:直接由 评估器 评估抽象语法树(AST)。
第二种方法使用 AST 生成简单的指令形式的字节码。然后,虚拟机(VM) 执行这些指令。字节码也可以被序列化。
目前,序列化的字节码还包含编译它的代码。该代码仅用于在运行时错误发生时生成用户友好的错误信息。
REPL
可以使用 REPL 与语言进行交互式探索并评估代码。要启动 REPL,将 repl
作为 CLI 的第一个参数传递(例如:seraphine repl
)。REPL 目前使用评估器执行代码。
REPL 使用原始终端并提供以下功能:
- 在当前行移动光标
- 历史记录
- 清屏
- 评估不适合一行代码的代码(例如,具有非平凡主体的 if 语句)
构建和运行
由于 Seraphine 是用 Rust 实现的,因此您首先需要 安装 Rust 工具链。
要在调试模式下运行 REPL,可以使用以下命令:cargo run -- repl
。您也可以选择使用 cargo run -- eval my_file.sr
评估文件。为了获得更好的性能,您应该在 cargo run
之后放置 --release
标志。为了仅构建可执行文件,请使用 cargo build --release
。可执行文件将放在目录 target/release
中。
测试
所有 Seraphine 功能都由测试覆盖。使用 cargo test --workspace
运行测试套件。
工作空间结构
seraphine-core
包含核心功能(令牌化器、解析器、评估器、字节码生成和序列化、VM)seraphine-cli
包含 CLI 和 REPL 功能的可执行文件