Skip to content

Latest commit

 

History

History
141 lines (98 loc) · 4.17 KB

1.数据、表达式和动态变量.md

File metadata and controls

141 lines (98 loc) · 4.17 KB

数据、表达式和动态变量

数据

Chill 语言中,信息处理的基本单位是 数据(Data)。 数据是信息在计算机中的一种表示。

在Chill语言中,数据可以表示为能直接被语法分析器解析的 字面量(Literal),如:

5    ; 数值
"S"  ; 字符串
T    ; 布尔真
F    ; 布尔假
nil  ; 空值
:sym ; 符号量

也可以借助字面量从而表示成一种组合的 结构(Structure)

(new Point 5 6)       ; 表示二维点的二元组
(new (Array Int 5) 0) ; 表示定长为5,全部元素为 0 的 Int数组

又可以引用、存储抑或间接引用 在识别为 标识符(Identifier) 的变量中:

(let a 5)   ; 动态变量 a 引用了 数据5, 通过使用 a 来使用 a 所引用的数据

(dim b Int) ; 声明了一个 类型为Int的 静态变量 b
(set b 5)   ; 静态变量 b 存储了 数据5

(ref c a)   ; 引用变量 c 引用了 变量a, c 间接引用了 a 的数据。 同时 a 的变化会直接反映到 c

甚至可以储存于 存储空间(Memory Space) 中,通过地址来访问:

(new-ptr Number 0x00010cab) ; 将首地址为0x00010cab的一段数据视为Number数据并获取之

表达式

表达式(Expression) 是一种由关键词、变量和数据等组成的,带有一定结构的、可运算的式子。

如同许多 Lisp 方言,Chill 语言 的表达式是一种前缀记法。如:

(+ 5 6)
(? T 5 6)

有所不同的是,Chill 语言中,在一个表达式中,必须有置于开头的函数或操作符。

当表达一个纯数据的列表时,使用 (list ...) 来处理。如:

(list 1 2 3)
(list (+ 5 6) a)
(list (list 5) 6)

为了方便起见,可以使用 [...] 来替代 (list ...) ,如:

[1 2 3]
[(+ 5 6) a]
[[5] 6]

通常,表达式是立即求值的。意即,在使用了嵌套表达式的情况下,外层表达式运算时,必然已经得到了内层表达式的值。 如 (+ 5 (+ 6 (+ 7 8))) 的求值顺序:

(+ 5 (+ 6 (+ 7 8)))
(+ 5 (+ 6 15))
(+ 5 21)
26

这一点在条件表达式、迭代表达式等中是例外。 条件表达式的子式、迭代表达式的循环式 都是惰性求值的。详细见后续内容。

值得一提的是,Chill 语言只规定了 外层 和 内层 的求值顺序。在同一层的表达式之间,其求值顺序是未定义的。 如 (+ 5 (+ 7 2) (+ 3 6)) 只保证在求 最外层 的时候内层计算全部完成,而 (+ 7 2)(+ 3 6) 的先后顺序是未定义的。

有时,需要将多个表达式组成为一个表达式。这个时候使用 do 表达式 。 如:

(do
  (+ 5 6)
  (+ 1)
  5
)

do 表达式的值为从上到下计算各个表达式后,最后一个表达式的值。

如果直接使用 (do) ,则表示空式。其值为 nil

do 表达式 经常用于某些特殊表达式的子式中。 如 ? 表达式 等。

动态变量

动态变量(Dynamic Variable) 是一种使用自由的数据携带者。

动态变量的着重点在于,通过直接对数据的 引用(refer) 而便利地、安全地处理数据。

使用 let 可以使动态变量引用某个数据。

(let a 5) ; 令 a 引用 数据 5

通常情况下,直接使用动态变量的名字,可以表示该动态变量所引用的数据。

(+ a 5) ; 使用了 a 所引用的数据,根据之前的代码,a 表示 数据 5

一个自由的动态变量可以引用任何被允许引用的数据。

(let a 5)                   ; 引用了 数据5
(let b (new (Array Int 5))) ; 引用了 一个新建的定长5的Int数组
(let c b)                   ; 引用了 a 所引用的数据

(dim stvarb Int) ; 声明一个静态变量,静态变量拥有特有空间
(let c stvarb)   ; 引用了这个静态变量的空间

[?] 动态变量的唯一操作是引用 let。 动态变量不能直接改变其引用空间的数据,但可以通过一些空间修改的函数,来改变其引用空间数据的部分。

(let a [5 6 7])  ; a 引用了一个列表
(set a 0 3) ; 将 a 引用的列表的首元素设置为 3,此时 a 所引用的数据为 [3 6 7]