1. 引言
Daslang 是一种高性能、强大的静态类型脚本语言,旨在作为实时应用程序(如游戏)的可嵌入“脚本”语言实现高性能。
Daslang 提供了广泛的功能,例如强静态类型、具有迭代类型推理的泛型编程、类似 Ruby 的块、语义缩进、本机机器类型、到 C++ 的提前“编译”,以及到 C++ 程序的快速和简化的绑定。
它的理念是围绕修改后的 Python Zen 构建的。
Daslang 应该作为“主机数据处理者”工作。 虽然从技术上讲,可以在脚本上下文中保持持久状态(设置了某个选项), Daslang 旨在转换主机 (C++) 数据/实现脚本化行为。
从某种意义上说,它是纯粹的函数式 - 即所有持久状态都超出了脚本上下文的范围,并且脚本的状态本质上是临时的。 因此,内存模型和持久状态的管理是应用程序的责任。 这导致了 Daslang 本身的极其简单和快速的内存模型。
1.1. 性能
在实际场景中,它的解释比没有 JIT 的 LuaJIT 快 10+ 倍(甚至可能比有 JIT 的 LuaJIT 快)。 对于嵌入式脚本语言来说,更重要的是,它与 C++ 的互作非常快(双向),比大多数其他流行的脚本语言快一个数量级。 从 C++ 到 Daslang 的快速调用允许您将 Daslang 用于简单的存储过程,并使其成为一种 ECS/面向数据的设计友好语言。 通过 Daslang 对 C++ 的快速调用,您可以编写处理主机 (C++) 数据并依赖绑定主机 (C++) 函数的高性能脚本。
它还允许 Ahead-of-Time 编译,这不仅在所有平台上都是可能的(与 JIT 不同),而且总是更快/不慢(众所周知 JIT 有时会减慢脚本的速度)。
Daslang 已经实现了 AoT(C++ 转译器),它生成的代码或多或少与同一程序的 C++11 性能相似。
1.2. 它看起来怎么样?
强制性斐波那契样本:
def fibR(n) {
if (n < 2) {
return n
} else {
return fibR(n - 1) + fibR(n - 2)
}
}
def fibI(n) {
var last = 0
var cur = 1
for ( i in 0..n-1 ) {
let tmp = cur
cur += last
last = tmp
}
return cur
}
具有大量空格(python 样式)的相同示例,适合喜欢此类语法的用户:
options gen2=false
def fibR(n)
if n < 2
return n
else
return fibR(n - 1) + fibR(n - 2)
def fibI(n)
var last = 0
var cur = 1
for i in 0 .. n-1
let tmp = cur
cur += last
last = tmp
return cur
此时 gen2 风格的语法 (带卷曲的护腕) 是默认的,但你可以把`gen2`选项设为 false 来切换到 gen1 风格 (带缩进)。
1.3. 泛型编程和类型系统
尽管上面的示例看起来是动态类型的,但它实际上是泛型编程。 fibI/fibR 函数的实际实例是强类型的,基本上只是接受并返回一个``int``。这类似于 C++ 中的模板(尽管 C++ 不是强类型语言)或 ML。 Daslang 中的泛型编程允许非常强大的编译时类型反射机制,从而显著简化编写最佳和清晰的代码。 与具有 SFINAE 的 C++ 不同,您可以使用通用条件 (if) 来根据其参数的类型信息来更改函数的实例。 请考虑以下示例:
def setSomeField(var obj; val) {
static_if ( typeinfo has_field<someField>(obj) ) {
obj.someField = val
}
}
此函数在提供的参数中设置`someField` 如果它是一个具有 `someField` 成员的结构体。
(有关更多信息,请参阅 Generic programming).
1.4. 编译时宏
Daslang 在编译时执行大量繁重的工作,因此它不必在运行时执行。 事实上,Daslang 编译器为每个模块运行 Daslang 解释器,并拥有整个 AST。
以下示例在编译时修改函数调用,以添加常量字符串参数的预计算哈希值:
[tag_function_macro(tag="get_hint_tag")]
class GetHintFnMacro : AstFunctionAnnotation {
def override transform(var call : smart_ptr<ExprCallFunc>; var errors : das_string) : ExpressionPtr {
if (call.arguments[1] is ExprConstString) {
unsafe {
var new_call := call // <- clone_expression(call)
let arg2 = reinterpret<ExprConstString?>(call.arguments[1])
let hint = hash("{arg2.value}")
emplace_new(new_call.arguments, new ExprConstUInt64(at = arg2.at, value = hint))
return new_call
}
}
return <- default<ExpressionPtr>
}
}
1.5. 特征
其(非)完整功能列表包括:
强类型
类似 Ruby 的块和 lambda
表
数组
字符串生成器
本机(C++ 友好)互作
泛型
类
宏,包括 Reader 宏
语义缩进
ECS 友好的互作
易于扩展的类型系统
等