定义

Nim 代码是特定的计算单元,作用于称为 locations “地址”组件构成的内存。 变量本质上是地址的名称,每个变量和地址都有特定的 type “类型”,变量的类型被称为 static type “静态类型”, 地址的类型被称为 dynamic type “动态类型”。如果静态类型与动态类型不相同,它就是动态类型的父类或子类。

identifier “标识符”是变量、类型、过程等的名称声明符号,一个声明所适用的程序区域被称为该声明的 scope “作用域”, 作用域可以嵌套,一个标识符的含义由标识符所声明的最小包围作用域决定,除非重载的解析规则另有建议。

一个表达式特指产生值或地址的计算,产生地址的表达式被称为 l-values “左值”,左值可以表示地址,也可以表示该地址包含的值,这取决于上下文。

Nim program “程序”由一个或多个包含 Nim 代码的文本 source files “源文件”组成,由Nim compiler “编译器”处理成 executable “可执行”文件,这个可执行文件的性质取决于编译器实现,例如,它可能是一个本地二进制文件或 JavaScript 源代码。

常规的 Nim 程序,大部分代码被编译至可执行文件,而有些代码可能会在 compile-time “编译期” 执行。 包括常量表达式、宏定义和宏定义使用的 Nim 程序。 编译期执行支持 Nim 语言的大部分,但有限制 — 详情查看编译期执行限制。 其术语 runtime “运行时”涵盖了编译期执行和可执行文件的代码执行。

编译器将 Nim 源码解析成称为 abstract syntax tree (AST) “抽象语法树”的内部数据结构,在执行代码或将其编译为可执行文件之前,通过 semantic analysis “语义分析”对AST进行转换,增加了语义信息,如表达式类型、标识符的含义,以及在某些情况下表达式的值。在语义分析中检测到的错误被称为 static error “静态错误”,当前手册中描述的错误在没有其他约定时,就是静态错误。

panic “恐慌”是在运行时执行检测和报告的错误。这种错误的报告,通过 引发异常以致命错误 结束的方式。 也提供了一种方法来禁用这些 runtime checks “运行时检查”。详见编译指示一节。

恐慌的结果是异常还是致命的错误,实现是特定的,因此,下面的程序无效,尽管代码试图捕获越界访问数组的 IndexDefect ,但编译器可能会以致命错误结束程序。

  1. var a: array[0..1, char]
  2. let i = 5
  3. try:
  4. a[i] = 'N'
  5. except IndexDefect:
  6. echo "invalid index"

目前允许通过 --panics:on|off 在不同方式之间切换,当打开时,程序会因恐慌而结束,当关闭时,运行时的错误会变为异常。 --panics:on 的好处是产生的二进制代码更小,编译器可以更自由地优化。

unchecked runtime error “未检查的运行时错误”是不能保证被检测到的错误,它可能导致计算产生意外后果,如果只使用 safe “安全”的语言特性,并且没有禁用运行时检查,就不会产生这类错误。

constant expression “常量表达式”,在对包含它的代码进行语义分析时,其值就可以被计算出来,并且不局限于语义分析时求值的能力,例如常量折叠。它从来不会是左值,也不会有副作用。它可以使用编译期支持执行的所有 Nim 语言特性。由于常量表达式可以作为语义分析时的输入,比如定义数组边界,鉴于这种灵活性要求,编译器交错进行语义分析和编译期代码执行。

想象一下,语义分析原本在源代码中从上到下、从左到右地进行,而在必要时,为了计算后续语义分析所需要的数值,交错执行编译期的代码,产生了语义分析并不完全是自上而下、自左而右进行的情况。这一点非常明确,我们将在文档的后面进一步了解。宏调用需要这种交错。