hvml-spec-predefined-variables-v1.0-zh.md 208 KB
Newer Older
Vincent Wei's avatar
Vincent Wei committed
1
# HVML 预定义变量
2

Vincent Wei's avatar
Vincent Wei committed
3
Subject: HVML Predefined Variables  
Vincent Wei's avatar
Vincent Wei committed
4
Version: 1.0-RC4  
5
Author: Vincent Wei  
Vincent Wei's avatar
Vincent Wei committed
6
Category: Language Specification  
Vincent Wei's avatar
Vincent Wei committed
7
Creation Date: Nov. 1, 2021  
8
Last Modified Date: July 1, 2022  
Vincent Wei's avatar
Vincent Wei committed
9
Status: Release Candidate  
Vincent Wei's avatar
tune    
Vincent Wei committed
10
Release Name: 硕鼠  
11
12
13
14
Language: Chinese

*Copyright Notice*

Vincent Wei's avatar
Vincent Wei committed
15
版权所有 © 2021, 2022 魏永明  
Vincent Wei's avatar
Vincent Wei committed
16
版权所有 © 2021, 2022 北京飞漫软件技术有限公司  
17
18
19
20
保留所有权利

此文档不受 HVML 相关软件开源许可证的管辖。

Vincent Wei's avatar
Vincent Wei committed
21
版权所有人公开此文档的目标,用于向开发者解释 HVML 相关设计原理或者相关规范。在未获得版权所有人书面许可之前,任何人不得复制或者分发本文档的全部或部分内容,或利用本文档描绘的技术思路申请专利、撰写学术论文等。
22

Vincent Wei's avatar
Vincent Wei committed
23
本文提及的版权所有人相关注册商标或商标之详细列表,请查阅文档末尾。
24

Vincent Wei's avatar
tune    
Vincent Wei committed
25
**目录**
26

Vincent Wei's avatar
Vincent Wei committed
27
28
[//]:# (START OF TOC)

Vincent Wei's avatar
Vincent Wei committed
29
30
- [1) 介绍](#1-介绍)
   + [1.1) 规范及术语](#11-规范及术语)
31
   + [1.2) 二进制格式表示法](#12-二进制格式表示法)
Vincent Wei's avatar
Vincent Wei committed
32
33
   + [1.3) 格式化修饰符](#13-格式化修饰符)
   + [1.4) 撰写要求](#14-撰写要求)
Vincent Wei's avatar
Vincent Wei committed
34
35
36
37
38
39
- [2) 非动态变量](#2-非动态变量)
   + [2.1) `TIMERS`](#21-timers)
      * [2.1.1) 批量新增定时器](#211-批量新增定时器)
      * [2.1.2) 新增一个定时器](#212-新增一个定时器)
      * [2.1.3) 移除一个定时器](#213-移除一个定时器)
      * [2.1.4) 修改特定定时器的属性](#214-修改特定定时器的属性)
Vincent Wei's avatar
Vincent Wei committed
40
   + [2.2) `REQUEST`](#22-request)
Vincent Wei's avatar
Vincent Wei committed
41
- [3) 必要动态变量](#3-必要动态变量)
42
43
44
45
46
47
   + [3.1) `SYSTEM`](#31-system)
      * [3.1.1) `const` 方法](#311-const-方法)
      * [3.1.2) `uname` 方法](#312-uname-方法)
      * [3.1.3) `uname_prt` 方法](#313-uname_prt-方法)
      * [3.1.4) `locale` 方法](#314-locale-方法)
      * [3.1.5) `time` 方法](#315-time-方法)
48
      * [3.1.6) `time_us` 方法](#316-time_us-方法)
49
50
51
52
53
54
      * [3.1.7) `sleep` 方法](#317-sleep-方法)
      * [3.1.8) `timezone` 方法](#318-timezone-方法)
      * [3.1.9) `cwd` 方法](#319-cwd-方法)
      * [3.1.10) `env` 方法](#3110-env-方法)
      * [3.1.11) `random_sequence` 方法](#3111-random_sequence-方法)
      * [3.1.12) `random` 方法](#3112-random-方法)
55
   + [3.2) `SESSION`](#32-session)
Vincent Wei's avatar
RC3    
Vincent Wei committed
56
57
      * [3.2.1) `app` 方法](#321-app-方法)
      * [3.2.2) `runner` 方法](#322-runner-方法)
Vincent Wei's avatar
Vincent Wei committed
58
      * [3.2.3) `myObj` 静态属性](#323-myobj-静态属性)
Vincent Wei's avatar
RC3    
Vincent Wei committed
59
      * [3.2.4) `user` 方法](#324-user-方法)
60
61
   + [3.3) `DATETIME`](#33-datetime)
      * [3.3.1) `time_prt` 方法](#331-time_prt-方法)
Vincent Wei's avatar
Vincent Wei committed
62
63
64
65
66
      * [3.3.2) `utctime` 方法](#332-utctime-方法)
      * [3.3.3) `localtime` 方法](#333-localtime-方法)
      * [3.3.4) `mktime` 方法](#334-mktime-方法)
      * [3.3.5) `fmttime` 方法](#335-fmttime-方法)
      * [3.3.6) `fmtbdtime` 方法](#336-fmtbdtime-方法)
67
   + [3.4) `HVML`](#34-hvml)
68
      * [3.4.1) `target` 方法](#341-target-方法)
Vincent Wei's avatar
tune    
Vincent Wei committed
69
70
71
72
73
      * [3.4.2) `base` 方法](#342-base-方法)
      * [3.4.3) `max_iteration_count` 方法](#343-max_iteration_count-方法)
      * [3.4.4) `max_recursion_depth` 方法](#344-max_recursion_depth-方法)
      * [3.4.5) `max_embedded_levels` 方法](#345-max_embedded_levels-方法)
      * [3.4.6) `timeout` 方法](#346-timeout-方法)
74
      * [3.4.7) `cid` 方法](#347-cid-方法)
75
76
77
78
79
80
81
82
83
84
85
86
87
88
   + [3.5) `DOC`](#35-doc)
      * [3.5.1) `doctype` 方法](#351-doctype-方法)
      * [3.5.2) `query` 方法](#352-query-方法)
   + [3.6) `EJSON`](#36-ejson)
      * [3.6.1) `type` 方法](#361-type-方法)
      * [3.6.2) `count` 方法](#362-count-方法)
      * [3.6.3) `numberify` 方法](#363-numberify-方法)
      * [3.6.4) `booleanize` 方法](#364-booleanize-方法)
      * [3.6.5) `stringify` 方法](#365-stringify-方法)
      * [3.6.6) `serialize` 方法](#366-serialize-方法)
      * [3.6.7) `sort` 方法](#367-sort-方法)
      * [3.6.8) `shuffle` 方法](#368-shuffle-方法)
      * [3.6.9) `compare` 方法](#369-compare-方法)
      * [3.6.10) `parse` 方法](#3610-parse-方法)
Vincent Wei's avatar
Vincent Wei committed
89
      * [3.6.11) `isequal` 方法](#3611-isequal-方法)
Vincent Wei's avatar
Vincent Wei committed
90
91
      * [3.6.12) `fetchstr` 方法](#3612-fetchstr-方法)
      * [3.6.13) `fetchreal` 方法](#3613-fetchreal-方法)
92
93
94
95
96
      * [3.6.14) `crc32` 方法](#3614-crc32-方法)
      * [3.6.15) `md5` 方法](#3615-md5-方法)
      * [3.6.16) `sha1` 方法](#3616-sha1-方法)
      * [3.6.17) `pack` 方法](#3617-pack-方法)
      * [3.6.18) `unpack` 方法](#3618-unpack-方法)
Vincent Wei's avatar
tune    
Vincent Wei committed
97
98
99
100
      * [3.6.19) `bin2hex` 方法](#3619-bin2hex-方法)
      * [3.6.20) `hex2bin` 方法](#3620-hex2bin-方法)
      * [3.6.21) `base64_encode` 方法](#3621-base64_encode-方法)
      * [3.6.22) `base64_decode` 方法](#3622-base64_decode-方法)
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
   + [3.7) `L`](#37-l)
      * [3.7.1) `not` 方法](#371-not-方法)
      * [3.7.2) `and` 方法](#372-and-方法)
      * [3.7.3) `or` 方法](#373-or-方法)
      * [3.7.4) `xor` 方法](#374-xor-方法)
      * [3.7.5) `eq` 方法](#375-eq-方法)
      * [3.7.6) `ne` 方法](#376-ne-方法)
      * [3.7.7) `gt` 方法](#377-gt-方法)
      * [3.7.8) `ge` 方法](#378-ge-方法)
      * [3.7.9) `lt` 方法](#379-lt-方法)
      * [3.7.10) `le` 方法](#3710-le-方法)
      * [3.7.11) `streq` 方法](#3711-streq-方法)
      * [3.7.12) `strne` 方法](#3712-strne-方法)
      * [3.7.13) `strgt` 方法](#3713-strgt-方法)
      * [3.7.14) `strge` 方法](#3714-strge-方法)
      * [3.7.15) `strlt` 方法](#3715-strlt-方法)
      * [3.7.16) `strle` 方法](#3716-strle-方法)
      * [3.7.17) `eval` 方法](#3717-eval-方法)
   + [3.8) `T`](#38-t)
      * [3.8.1) `map` 静态属性](#381-map-静态属性)
      * [3.8.2) `get` 方法](#382-get-方法)
   + [3.9) `STR`](#39-str)
      * [3.9.1) `contains` 方法](#391-contains-方法)
      * [3.9.2) `starts_with` 方法](#392-starts_with-方法)
      * [3.9.3) `ends_with` 方法](#393-ends_with-方法)
      * [3.9.4) `explode` 方法](#394-explode-方法)
      * [3.9.5) `implode` 方法](#395-implode-方法)
      * [3.9.6) `shuffle` 方法](#396-shuffle-方法)
      * [3.9.7) `replace` 方法](#397-replace-方法)
      * [3.9.8) `format_c` 方法](#398-format_c-方法)
Vincent Wei's avatar
Vincent Wei committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
      * [3.9.9) `scan_c` 方法](#399-scan_c-方法)
      * [3.9.10) `format_p` 方法](#3910-format_p-方法)
      * [3.9.11) `scan_p` 方法](#3911-scan_p-方法)
      * [3.9.12) `join` 方法](#3912-join-方法)
      * [3.9.13) `nr_chars` 方法](#3913-nr_chars-方法)
      * [3.9.14) `tolower` 方法](#3914-tolower-方法)
      * [3.9.15) `toupper` 方法](#3915-toupper-方法)
      * [3.9.16) `substr` 方法](#3916-substr-方法)
      * [3.9.17) `substr_compare` 方法](#3917-substr_compare-方法)
      * [3.9.18) `substr_count` 方法](#3918-substr_count-方法)
      * [3.9.19) `substr_replace` 方法](#3919-substr_replace-方法)
      * [3.9.20) `strstr` 方法](#3920-strstr-方法)
      * [3.9.21) `strpos` 方法](#3921-strpos-方法)
      * [3.9.22) `strpbrk` 方法](#3922-strpbrk-方法)
      * [3.9.23) `split` 方法](#3923-split-方法)
      * [3.9.24) `chunk_split` 方法](#3924-chunk_split-方法)
      * [3.9.25) `trim` 方法](#3925-trim-方法)
      * [3.9.26) `pad` 方法](#3926-pad-方法)
      * [3.9.27) `repeat` 方法](#3927-repeat-方法)
      * [3.9.28) `reverse` 方法](#3928-reverse-方法)
      * [3.9.29) `tokenize` 方法](#3929-tokenize-方法)
      * [3.9.30) `translate` 方法](#3930-translate-方法)
      * [3.9.31) `htmlentities_encode` 方法](#3931-htmlentities_encode-方法)
      * [3.9.32) `htmlentities_decode` 方法](#3932-htmlentities_decode-方法)
      * [3.9.33) `nl2br` 方法](#3933-nl2br-方法)
      * [3.9.34) `rot13` 方法](#3934-rot13-方法)
      * [3.9.35) `count_chars` 方法](#3935-count_chars-方法)
      * [3.9.36) `count_bytes` 方法](#3936-count_bytes-方法)
159
   + [3.10) `URL`](#310-url)
Vincent Wei's avatar
tune    
Vincent Wei committed
160
161
      * [3.10.1) `encode` 方法](#3101-encode-方法)
      * [3.10.2) `decode` 方法](#3102-decode-方法)
162
163
164
165
      * [3.10.3) `build_query` 方法](#3103-build_query-方法)
      * [3.10.4) `parse_query` 方法](#3104-parse_query-方法)
      * [3.10.5) `parse` 方法](#3105-parse-方法)
      * [3.10.6) `assemble` 方法](#3106-assemble-方法)
166
167
   + [3.11) `STREAM`](#311-stream)
      * [3.11.1) `open` 方法](#3111-open-方法)
168
169
170
171
172
173
174
175
176
177
      * [3.11.2) `close` 方法](#3112-close-方法)
      * [3.11.3) `stdin` 静态属性](#3113-stdin-静态属性)
      * [3.11.4) `stdout` 静态属性](#3114-stdout-静态属性)
      * [3.11.5) `stderr` 静态属性](#3115-stderr-静态属性)
      * [3.11.6) 流实体的 `readstruct` 方法](#3116-流实体的-readstruct-方法)
      * [3.11.7) 流实体的 `writestruct` 方法](#3117-流实体的-writestruct-方法)
      * [3.11.8) 流实体的 `readlines` 方法](#3118-流实体的-readlines-方法)
      * [3.11.9) 流实体的 `writelines` 方法](#3119-流实体的-writelines-方法)
      * [3.11.10) 流实体的 `readbytes` 方法](#31110-流实体的-readbytes-方法)
      * [3.11.11) 流实体的 `writebytes` 方法](#31111-流实体的-writebytes-方法)
Vincent Wei's avatar
tune    
Vincent Wei committed
178
      * [3.11.12) 流实体的 `seek` 方法](#31112-流实体的-seek-方法)
Vincent Wei's avatar
Vincent Wei committed
179
      * [3.11.13) `pipe` 流实体](#31113-pipe-流实体)
Vincent Wei's avatar
Vincent Wei committed
180
181
182
183
- [4) 可选动态变量](#4-可选动态变量)
   + [4.1) `MATH`](#41-math)
      * [4.1.1) `pi` 方法](#411-pi-方法)
      * [4.1.2) `e` 方法](#412-e-方法)
gengyue's avatar
gengyue committed
184
      * [4.1.3) `const` 方法](#413-const-方法)
Vincent Wei's avatar
Vincent Wei committed
185
186
187
188
189
      * [4.1.4) `add` 方法](#414-add-方法)
      * [4.1.5) `sub` 方法](#415-sub-方法)
      * [4.1.6) `mul` 方法](#416-mul-方法)
      * [4.1.7) `div` 方法](#417-div-方法)
      * [4.1.8) `eval` 和 `eval_l` 方法](#418-eval-和-eval_l-方法)
gengyue's avatar
gengyue committed
190
      * [4.1.9) `sin` 和 `sin_l` 方法](#419-sin-和-sin_l-方法)
gengyue's avatar
gengyue committed
191
192
      * [4.1.10) `cos` 和 `cos_l` 方法](#4110-cos-和-cos_l-方法)
      * [4.1.11) `tan` 和 `tan_l` 方法](#4111-tan-和-tan_l-方法)
gengyue's avatar
gengyue committed
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
      * [4.1.12) `sinh` 和 `sinh_l` 方法](#4112-sinh-和-sinh_l-方法)
      * [4.1.13) `cosh` 和 `cosh_l` 方法](#4113-cosh-和-cosh_l-方法)
      * [4.1.14) `tanh` 和 `tanh_l` 方法](#4114-tanh-和-tanh_l-方法)
      * [4.1.15) `asin` 和 `asin_l` 方法](#4115-asin-和-asin_l-方法)
      * [4.1.16) `acos` 和 `acos_l` 方法](#4116-acos-和-acos_l-方法)
      * [4.1.17) `atan` 和 `atan_l` 方法](#4117-atan-和-atan_l-方法)
      * [4.1.18) `asinh` 和 `asinh_l` 方法](#4118-asinh-和-asinh_l-方法)
      * [4.1.19) `acosh` 和 `acosh_l` 方法](#4119-acosh-和-acosh_l-方法)
      * [4.1.20) `atanh` 和 `atanh_l` 方法](#4120-atanh-和-atanh_l-方法)
      * [4.1.21) `fmod` 和 `fmod_l` 方法](#4121-fmod-和-fmod_l-方法)
      * [4.1.22) `fabs` 方法](#4122-fabs-方法)
      * [4.1.23) `log` 和 `log_l` 方法](#4123-log-和-log_l-方法)
      * [4.1.24) `log10` 和 `log10_l` 方法](#4124-log10-和-log10_l-方法)
      * [4.1.25) `pow` 和 `pow_l` 方法](#4125-pow-和-pow_l-方法)
      * [4.1.26) `exp` 和 `exp_l` 方法](#4126-exp-和-exp_l-方法)
      * [4.1.27) `floor` 和 `floor_l` 方法](#4127-floor-和-floor_l-方法)
      * [4.1.28) `ceil` 和 `ceil_l` 方法](#4128-ceil-和-ceil_l-方法)
      * [4.1.29) `sqrt` 和 `sqrt_l` 方法](#4129-sqrt-和-sqrt_l-方法)
Vincent Wei's avatar
Vincent Wei committed
211
212
213
   + [4.2) `FS`](#42-fs)
      * [4.2.1) `list` 方法](#421-list-方法)
      * [4.2.2) `list_prt` 方法](#422-list_prt-方法)
214
      * [4.2.3) `basename` 方法](#423-basename-方法)
215
216
217
218
219
220
221
      * [4.2.4) `chgrp` 方法](#424-chgrp-方法)
      * [4.2.5) `chmod` 方法](#425-chmod-方法)
      * [4.2.6) `chown` 方法](#426-chown-方法)
      * [4.2.7) `copy` 方法](#427-copy-方法)
      * [4.2.8) `dirname` 方法](#428-dirname-方法)
      * [4.2.9) `disk_usage` 方法](#429-disk_usage-方法)
      * [4.2.10) `file_exists` 方法](#4210-file_exists-方法)
Vincent Wei's avatar
Vincent Wei committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
      * [4.2.11) `file_is` 方法](#4211-file_is-方法)
      * [4.2.12) `lchgrp` 方法](#4212-lchgrp-方法)
      * [4.2.13) `lchown` 方法](#4213-lchown-方法)
      * [4.2.14) `linkinfo` 方法](#4214-linkinfo-方法)
      * [4.2.15) `lstat` 方法](#4215-lstat-方法)
      * [4.2.16) `link` 方法](#4216-link-方法)
      * [4.2.17) `mkdir` 方法](#4217-mkdir-方法)
      * [4.2.18) `pathinfo` 方法](#4218-pathinfo-方法)
      * [4.2.19) `readlink` 方法](#4219-readlink-方法)
      * [4.2.20) `realpath` 方法](#4220-realpath-方法)
      * [4.2.21) `rename` 方法](#4221-rename-方法)
      * [4.2.22) `rmdir` 方法](#4222-rmdir-方法)
      * [4.2.23) `stat` 方法](#4223-stat-方法)
      * [4.2.24) `symlink` 方法](#4224-symlink-方法)
      * [4.2.25) `tempname` 方法](#4225-tempname-方法)
      * [4.2.26) `touch` 方法](#4226-touch-方法)
      * [4.2.27) `umask` 方法](#4227-umask-方法)
      * [4.2.28) `unlink` 方法](#4228-unlink-方法)
Vincent Wei's avatar
Vincent Wei committed
240
241
      * [4.2.29) `file_contents` 方法](#4229-file_contents-方法)
      * [4.2.30) `opendir` 方法](#4230-opendir-方法)
242
243
244
      * [4.2.31) `closedir` 方法](#4231-closedir-方法)
      * [4.2.32) 目录流实体的 `read` 方法](#4232-目录流实体的-read-方法)
      * [4.2.33) 目录流实体的 `rewind` 方法](#4233-目录流实体的-rewind-方法)
Vincent Wei's avatar
Vincent Wei committed
245
   + [4.3) `FILE`](#43-file)
Vincent Wei's avatar
Vincent Wei committed
246
247
248
249
250
251
      * [4.3.1) 文本文件](#431-文本文件)
         - [4.3.1.1) `txt.head` 方法](#4311-txthead-方法)
         - [4.3.1.2) `txt.tail` 方法](#4312-txttail-方法)
      * [4.3.2) 二进制文件](#432-二进制文件)
         - [4.3.2.1) `bin.head` 方法](#4321-binhead-方法)
         - [4.3.2.2) `bin.tail` 方法](#4322-bintail-方法)
252
- [附录](#附录)
Vincent Wei's avatar
Vincent Wei committed
253
   + [附.1) 修订记录](#附1-修订记录)
Vincent Wei's avatar
Vincent Wei committed
254
      * [RC4) 220701](#rc4-220701)
Vincent Wei's avatar
RC3    
Vincent Wei committed
255
      * [RC3) 220601](#rc3-220601)
Vincent Wei's avatar
tune    
Vincent Wei committed
256
      * [RC2) 220501](#rc2-220501)
257
      * [RC1) 220401](#rc1-220401)
Vincent Wei's avatar
Vincent Wei committed
258
259
      * [BRC) 220201](#brc-220201)
   + [附.2) 贡献者榜单](#附2-贡献者榜单)
260
261
   + [附.3) 废弃的内容](#附3-废弃的内容)
      * [`const_obj` 静态属性](#const_obj-静态属性)
Vincent Wei's avatar
Vincent Wei committed
262
   + [附.3) 商标声明](#附3-商标声明)
263

Vincent Wei's avatar
Vincent Wei committed
264
[//]:# (END OF TOC)
265

Vincent Wei's avatar
Vincent Wei committed
266
## 1) 介绍
267

Vincent Wei's avatar
Vincent Wei committed
268
本文档是 HVML 规范的一部分,用于详细定义 HVML 解释器必须支持或者可选支持的预定义变量。
269

Vincent Wei's avatar
Vincent Wei committed
270
271
### 1.1) 规范及术语

Vincent Wei's avatar
Vincent Wei committed
272
273
本文档遵循的技术规范或术语如下所列:

Vincent Wei's avatar
Vincent Wei committed
274
- HVML(Hybrid Virtual Markup Language),是[魏永明](https://github.com/VincentWei)提出的一种数据驱动的可编程标记语言。[HVML 规范](hvml-spec-v1.0-zh.md) 的如下部分和本文档相关:
Vincent Wei's avatar
Vincent Wei committed
275
  1. 2.1) 术语及基本原理
Vincent Wei's avatar
Vincent Wei committed
276
  1. 2.2) 规则、表达式及方法的描述语法
Vincent Wei's avatar
Vincent Wei committed
277
- 解释器(interpreter),指解析并运行 HVML 程序的计算机软件。
278
279
- 渲染器(renderer),指渲染 HVML 协程生成的目标文档并和用户交互的计算机软件。
- 会话(session),指一个解释器实例的上下文信息;每个解释器实例对应一个 HVML 会话,每个 HVML 会话运行多个 HVML 协程,对应渲染器中的多个窗口。
280
281
- 静态属性(static property),指一个对象上键值为普通数据的属性,其键值不是动态值。我们通常使用小写开头的驼峰命名法命名这类属性,如 `myObj`
- 方法(method),指一个对象上键值为动态值的属性。我们通常使用下划线连接的全小写命名法,如 `starts_with`
Vincent Wei's avatar
Vincent Wei committed
282
283
- 获取器(getter),指一个方法的获取器。调用获取器返回该方法的动态属性值。
- 设置器(setter),指一个方法的设置器。调用特定方法的设置器,将完成对应属性的设置工作。
Vincent Wei's avatar
Vincent Wei committed
284

285
按是否含有动态对象划分,HVML 预定义变量可分为:
Vincent Wei's avatar
Vincent Wei committed
286
287
288
289
290
291

1. 非动态变量,即变量对应的数据不提供动态方法。所有本规范定义的非动态变量都是内置(built-in)且必要的(required)。
1. 动态变量,即变量对应的数据提供动态方法。动态变量又分为必要(required)动态变量及可选(optional)动态变量。通常,动态变量可设计为可加载的(loadable)共享库或者模块。解释器应根据本文档的要求将动态变量实现为内置的或可加载的;可选动态变量是否实现为可加载的,由解释器决定。

按变量对应数据的作用域,可分为:

292
293
294
295
1. 会话级变量。指该变量对应的数据对当前解释器实例中的所有 HVML 协程可见。也就是说,同一会话中的不同协程对应同一个数据副本。
1. 协程级变量。指该变量对应的数据仅对当前解释器实例中的单个 HVML 协程可见。也就是说,不同的 HVML 协程有一个自己的数据副本。

需要注意,会话级变量的实现应考虑多线程(当解释器以进程方式运行,每个解释器实例对应一个独立线程)情形下的线程安全和可重入性。
Vincent Wei's avatar
Vincent Wei committed
296

Vincent Wei's avatar
Vincent Wei committed
297
298
299
**约定**  
解释器可自行实现全局变量,作为约定,解释器自行实现的全局变量,其名称应以 ASCII U+005F LOW LINE(`_`)打头,使用全大写字母并添加解释器前缀。如 `_PURC_VAR`。而一般的变量,使用全小写字母。

300
301
### 1.2) 二进制格式表示法

Vincent Wei's avatar
tune    
Vincent Wei committed
302
为配合流实体要求的流式读写方法(`readstruct``writestruct`)以及字节序列的数值化,我们定义了一种二进制格式表示法。
303
304
305
306
307

我们用一个字符串表示一个二进制结构中的各个构成部分,多个构成部分之间使用空白字符(空格、制表符、换行符等)分隔,每个构成部分使用一个类型字符串表示其类型,如果是大于一个字节的整数或浮点数,其后紧跟可选的 `le` 或者 `be` 表示小头(little endian)或者大头(big endian)。

如,`i32le s128 f64`,表示一个结构,其中前 4 个字节是一个 32 位整数,小头存储,紧接着是一个 128 字节的字符串,最后 8 字节是一个 64 位浮点数。该结构一共 140 字节。

308
309
在对字节序列执行数值化操作时,我们通过单个关键词来指定字节序列的二进制格式,比如 `i32le` 表示小头存储的 32 位有符号整数。

310
311
下表给出了本表示法支持的各种结构构成部分之类型标记:

Vincent Wei's avatar
Vincent Wei committed
312
313
| 类型               |  表示方法                    | 对应的 HVML 数据类型         |
| ----------------   |  --------                    | ---------------------------- |
Vincent Wei's avatar
tune    
Vincent Wei committed
314
315
316
317
| 1 字节整数         |  `i8[:<QUANTITY>]`           | longint, longint 数组    |
| 2 字节整数         |  `i16[le/be][:<QUANTITY>]`   | longint, longint 数组    |
| 4 字节整数         |  `i32[le/be][:<QUANTITY>]`   | longint, longint 数组    |
| 8 字节整数         |  `i64[le/be][:<QUANTITY>]`   | longint, longint 数组    |
Vincent Wei's avatar
tune    
Vincent Wei committed
318
319
320
321
322
323
324
| 1 字节无符号整数   |  `u8[:<QUANTITY>]`           | ulongint, ulongint 数组  |
| 2 字节无符号整数   |  `u16[le/be][:<QUANTITY>]`   | ulongint, ulongint 数组  |
| 4 字节无符号整数   |  `u32[le/be][:<QUANTITY>]`   | ulongint, ulongint 数组  |
| 8 字节无符号整数   |  `u64[le/be][:<QUANTITY>]`   | ulongint, ulongint 数组  |
| 2 字节浮点型       |  `f16[le/be][:<QUANTITY>]`   | number, number 数组      |
| 4 字节浮点型       |  `f32[le/be][:<QUANTITY>]`   | number, number 数组      |
| 8 字节浮点型       |  `f64[le/be][:<QUANTITY>]`   | number, number 数组      |
Vincent Wei's avatar
tune    
Vincent Wei committed
325
326
| 12 字节浮点型      |  `f96[le/be][:<QUANTITY>]`   | longdouble, longdouble 数组 |
| 16 字节长双精度    |  `f128[le/be][:<QUANTITY>]`  | longdouble, longdouble 数组 |
Vincent Wei's avatar
Vincent Wei committed
327
328
| 字节序列           |  `bytes:<SIZE>`              | bsequence;SIZE 指定字节数量。 |
| UTF-8编码的字符串  |  `utf8[:<SIZE>]`             | string;SIZE 可选:指定字节数量,未指定时,到空字符(0x00)为止。|
Vincent Wei's avatar
tune    
Vincent Wei committed
329
330
| UTF-16编码的字符串 |  `utf16[le/be][:<SIZE>]`     | string;SIZE 可选:指定字节数量,未指定时,到空字符(连续两个 0x00 字节)为止。|
| UTF-32编码的字符串 |  `utf32[le/be][:<SIZE>]`     | string;SIZE 可选:指定字节数量,未指定时,到空字符(连续四个 0x00 字节)为止。|
Vincent Wei's avatar
Vincent Wei committed
331
| 填白               |  `padding:<SIZE>`            | 无,将跳过指定数量的字节;SIZE 指定字节数量。     |
332

Vincent Wei's avatar
tune    
Vincent Wei committed
333
对 8 位以上整数、浮点数以及 UTF-16、UTF-32 编码,使用如下可选后缀表示大小头:
334
335
336
337
338
339

| 类型 | 类型标志 |
| ---- | -------- |
| 小头 | le       |
| 大头 | be       |

Vincent Wei's avatar
tune    
Vincent Wei committed
340
未指定时,默认跟随当前架构。
341
342
343

不同类型的表示方法:

Vincent Wei's avatar
Vincent Wei committed
344
345
346
| 类型              | 表示方法              | 备注                                                                      | 举例                  |
| --------          | ------------------    | --------------------------------------------                              | -----------------     |
| 数值类型          | 类型 + 大/小头        | 如不标大、小头,则跟随当前架构                                            | u16、u32be、u64le     |
Vincent Wei's avatar
tune    
Vincent Wei committed
347
| 连续数值类型      | 类型 + 大/小头 + 个数 | 如不标大、小头,则跟随当前架构,个数指该类数值的数值,必须大于零          | u16:10、u32be:10      |
Vincent Wei's avatar
Vincent Wei committed
348
| 字节序列          | 类型 + 长度           |                                                                           | bytes:234             |
Vincent Wei's avatar
tune    
Vincent Wei committed
349
350
351
| UTF-8 编码字符串  | 类型 + 长度 / 类型    | 如不标长度,则自动计算字符串长度(数据需包含表示结尾的字节零)            | utf8、utf8:123        |
| UTF-16 编码字符串 | 类型 + 长度 / 类型    | 如不标长度,则自动计算字符串长度(数据需包含表示结尾的十六位零)          | utf16、utf16:120      |
| UTF-32 编码字符串 | 类型 + 长度 / 类型    | 如不标长度,则自动计算字符串长度(数据需包含表示结尾的三十二位零)        | utf32be、utf32be:120  |
352

Vincent Wei's avatar
tune    
Vincent Wei committed
353
注意:
354

355
- 二进制格式关键词区分大小写。
Vincent Wei's avatar
tune    
Vincent Wei committed
356
- 字节序列、填白以及字符串的长度均以字节为单位。
357
- 我们使用多个构成部分组成的字符串来表示一个结构,不同构成部分之间使用空白字符分隔。
358

Vincent Wei's avatar
tune    
Vincent Wei committed
359
如,`i32le utf8:128 f64`,表示一个结构的构成部分依次如下:
360
361

1. 其中前 4 个字节是一个 32 位整数,小头存储;
Vincent Wei's avatar
tune    
Vincent Wei committed
362
1. 紧接着是一个 128 字节的 UTF-8 编码字符串;
363
364
365
366
1. 最后 8 字节是一个 64 位浮点数。

该结构一共 140 字节。

Vincent Wei's avatar
Vincent Wei committed
367
368
369
370
371
### 1.3) 格式化修饰符

<https://www.php.net/manual/en/function.sprintf.php>

### 1.4) 撰写要求
Vincent Wei's avatar
Vincent Wei committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386

对一个方法的描述应包含如下部分(section):

- `描述`(Description;必需):首先按 [HVML 规范 - 2.2.4) 动态对象方法的描述语法](/zh/hvml-spec-v1.0-zh.md#224-动态对象方法的描述语法) 定义的语法给出方法的原型,其中包括对参数(形参)和返回值的简短描述。然后给出对该方法用途的简短描述。
- `参数`(Parameters;可选)。必要时给出对该方法参数的完整描述。
- `返回值`(Return Value;可选)。必要时给出对该方法返回值的完整描述。
- `异常`(Exceptions;必需)。列出此方法可能抛出的异常。
- `示例`(Examples;必需)。
- `参见`(See Also;可选)。列出相关的外部链接。
- `备注`(Notes;可选)。

某些方法可返回 `false``undefined` 等值标记错误。此等情形仅出现在当前动作元素设置有 `silently` 副词属性,且仅遇到可忽略异常的情况下。当一个方法在设置有 `silently` 副词属性的元素中被调用时,我们称该方法被要求“静默求值(evaluate silently)”。对支持静默求值的方法,对其用途的描述参照如下形式:

> 该方法改变当前的工作路径。成功时返回 `true`;失败时抛出异常,或在静默求值时,对可忽略异常返回 `false`。

Vincent Wei's avatar
Vincent Wei committed
387
388
389
390
## 2) 非动态变量

### 2.1) `TIMERS`

391
`TIMERS` 是一个协程级内置变量。该变量是一个对象集合(对象的 `id` 属性做唯一性键值)。
Vincent Wei's avatar
Vincent Wei committed
392
393
394

用于描述一个定时器对象的属性如下:

Vincent Wei's avatar
tune    
Vincent Wei committed
395
```js
Vincent Wei's avatar
Vincent Wei committed
396
{
Vincent Wei's avatar
tune    
Vincent Wei committed
397
398
399
    'id': <string: `the timer identifier, the key with unique restriction`>,
    'interval': <string: `the interval of the timer in milliseconds`>,
    'active': <string: `activated or not`>
Vincent Wei's avatar
Vincent Wei committed
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
}
```

该变量用于定义定时器,其上不提供动态方法;程序通过 `update` 元素修改该变量对应的容器数据来操作定时器。

#### 2.1.1) 批量新增定时器

```html
    <update on="$TIMERS" to="unite">
        [
            { "id" : "foo", "interval" : 1000, "active" : "no" },
            { "id" : "bar", "interval" : 2000, "active" : "no" },
        ]
    </update>
```


#### 2.1.2) 新增一个定时器

```html
    <update on="$TIMERS" to="append">
        { "id" : "foobar", "interval" : 3000, "active" : "yes" }
    </update>
```

#### 2.1.3) 移除一个定时器

```html
    <update on="$TIMERS" to="subtract">
        { "id" : "foobar" }
    </update>
```

#### 2.1.4) 修改特定定时器的属性

```html
    <!-- activate the timer `foo` -->
    <choose on="$TIMERS" by="FILTER: AS 'foo'">
        <update on="$?" at=".active" with="yes" />
    </choose>
```

或,

```html
    <update on="$TIMERS" to="overwrite">
        { "id" : "foo", "interval": 1500, "active" : "yes" }
    </update>
```

Vincent Wei's avatar
Vincent Wei committed
450
451
### 2.2) `REQUEST`

452
`REQUEST` 是一个协程级内置变量。该变量用来保存装载一个 HVML 程序时传递给该程序的请求参数,以对象形式保存。
Vincent Wei's avatar
Vincent Wei committed
453

Vincent Wei's avatar
Vincent Wei committed
454
比如下面的 Python 脚本装载一个 HVML 程序,并传递了 `nrUsers` 参数:
Vincent Wei's avatar
Vincent Wei committed
455
456
457
458
459

```python
hvml.load ("a.hvml", { "nrUsers" : 10 })
```

460
在程序中,我们可使用 `$REQUEST.nrUsers``$REQUEST['nrUsers']` 来引用上述脚本代码传入的数值(`10`)。
Vincent Wei's avatar
Vincent Wei committed
461

Vincent Wei's avatar
Vincent Wei committed
462
463
## 3) 必要动态变量

464
### 3.1) `SYSTEM`
Vincent Wei's avatar
Vincent Wei committed
465

466
该变量是一个会话级内置变量,主要用于获得或设置系统信息。该内置变量的实现,需要考虑如下要求:
Vincent Wei's avatar
Vincent Wei committed
467

468
- 在某个协程中调用 `$SYSTEM` 的设置器方法,可能产生 `change` 事件,解释器应该将该事件广播到所有会话,并进一步转发给会话中的所有协程。
469

470
#### 3.1.1) `const` 方法
471
472
473
474
475

获取系统常量。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
476
```js
477
478
479
480
481
$SYSTEM.const(
        <string $name: `the constant name`>
) any : `the constant value`
```

482
该方法获取指定常量的值。成功时返回对应的数据;失败时将抛出 `NoSuchKey` 异常,或在静默求值时,返回 `undefined`
483
484
485
486

注意,如下常量应由所有 HVML 解释器定义:

- `HVML_SPEC_RELEASE`: HVML 规范版本号,如 `硕鼠`
Vincent Wei's avatar
tune    
Vincent Wei committed
487
- `HVML_SPEC_VERSION`: HVML 规范版本号,如 `1.0`
Vincent Wei's avatar
Vincent Wei committed
488
- `HVML_PREDEF_VARS_SPEC_RELEASE`: HVML 预定义变量规范版本号,如 `硕鼠`
Vincent Wei's avatar
tune    
Vincent Wei committed
489
- `HVML_PREDEF_VARS_SPEC_VERSION`: HVML 预定义变量规范版本号,如 `1.0`
490
491
- `HVML_INTRPR_NAME`: HVML 解释器的名称,如 `PurC`
- `HVML_INTRPR_RELEASE`: HVML 解释器的发布名称,如 `立春`
Vincent Wei's avatar
tune    
Vincent Wei committed
492
- `HVML_INTRPR_VERSION`: HVML 解释器的版本名称,如 `0.5.0`
493

494
495
496
497
**异常**

- `NoSuchKey`:可忽略异常。

498
499
**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
500
```js
501
502
503
504
505
// 获取常量 `HVML_SPEC_VER` 的值
$SYSTEM.const('HVML_SPEC_VERSION')
    // string: '1.0'
```

506
#### 3.1.2) `uname` 方法
507

508
获取系统信息。
509

510
**描述**
511

Vincent Wei's avatar
tune    
Vincent Wei committed
512
```js
Vincent Wei's avatar
Vincent Wei committed
513
514
$SYSTEM.uname object :
    `an object contains the following properties:`
Vincent Wei's avatar
tune    
Vincent Wei committed
515
516
517
518
519
520
521
522
        - 'kernel-name':        < string: `kernel name (e.g., 'Linux')` >
        - 'kernel-release':     < string: `kernel release (e.g., '2.6.28')` >
        - 'kernel-version':     < string: `kernel version` >
        - 'nodename':           < string: `the network node hostname` >
        - 'machine':            < string: `machine hardware name` >
        - 'processor':          < string: `the processor type` >
        - 'hardware-platform':  < string: `the hardware platform` >
        - 'operating-system':   < string: `the operating system (e.g., 'GNU/Linux')` >
523
524
```

Vincent Wei's avatar
tune    
Vincent Wei committed
525
526
527
528
529
该方法获取系统信息,返回包含有内核名称、版本号等键值对的对象。注意,对某些不支持的系统特征,将返回空字符串。

**异常**

(无)
530

531
532
**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
533
```js
534
$SYSTEM.uname
Vincent Wei's avatar
tune    
Vincent Wei committed
535
536
537
538
    /* object:
       {
            'kernel-name':      'Linux',
            'kernel-release':   '5.4.0-99-generic',
Vincent Wei's avatar
tune    
Vincent Wei committed
539
540
541
542
543
544
            'kernel-version':   '#112-Ubuntu SMP Thu Feb 3 13:50:55 UTC 2022',
            'nodename':         'magicBook',
            'machine':          'x86_64',
            'processor':        'x86_64',
            'hardware-platform':'x86_64',
            'operating-system': 'GNU/Linux'
Vincent Wei's avatar
tune    
Vincent Wei committed
545
546
       }
    */
547
548
```

549
#### 3.1.3) `uname_prt` 方法
550

551
552
获取可打印的系统信息。

Vincent Wei's avatar
tune    
Vincent Wei committed
553
554
**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
555
```js
Vincent Wei's avatar
tune    
Vincent Wei committed
556
$SYSTEM.uname_prt string: `the kernel name.`
557
558
559
```

该方法获取内核名称,返回字符串。
560

Vincent Wei's avatar
tune    
Vincent Wei committed
561
```js
562
$SYSTEM.uname_prt(
Vincent Wei's avatar
tune    
Vincent Wei committed
563
        <'[kernel-name || kernel-release || kernel-version || nodename || machine || processor || hardware-platform || operating-system] | all | default' $which = 'default':
Vincent Wei's avatar
tune    
Vincent Wei committed
564
565
566
567
568
569
570
571
572
573
            - 'kernel-name':        `includes kernel name (e.g., 'Linux')`
            - 'kernel-release':     `includes kernel release (e.g., '2.6.28')`
            - 'kernel-version':     `includes kernel version`
            - 'nodename':           `includes the network node hostname`
            - 'machine':            `includes machine hardware name`
            - 'processor':          `includes the processor type`
            - 'hardware-platform':  `includes the hardware platform`
            - 'operating-system':   `includes the operating system (e.g., 'GNU/Linux')`
            - 'all':                `includes all parts`
            - 'default':            `is equivalent to 'kernel-name'`
574
        >
Vincent Wei's avatar
Vincent Wei committed
575
) string: `the string concatenated the desired system information parts together.`
576
577
```

Vincent Wei's avatar
tune    
Vincent Wei committed
578
579
580
581
582
该方法返回多个指定特征的特征值,用空格分隔,串接为一个字符串返回。注意,对某些不支持的系统特征,按对应的特征值为空字符串处理。

**异常**

(无)
583

584
**示例**
585

Vincent Wei's avatar
tune    
Vincent Wei committed
586
```js
Vincent Wei's avatar
tune    
Vincent Wei committed
587
588
589
590
// 获取内核名称
$SYSTEM.uname_prt
    // string: 'Linux'

591
// 获取内核名称及版本号
592
$SYSTEM.uname_prt('kernel-name kernel-release kernel-version')
593
    // string: "Linux 5.4.0-80-generic #90-Ubuntu SMP Fri Jul 9 22:49:44 UTC 2021"
594
595
```

596
#### 3.1.4) `locale` 方法
597

598
599
600
601
获取或设置区域(locale)。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
602
```js
Vincent Wei's avatar
Vincent Wei committed
603
$SYSTEM.locale string : `the locale for the messages category.`
604
605
606
607
```

该方法获得消息分类(messages category)的区域,返回字符串。

Vincent Wei's avatar
tune    
Vincent Wei committed
608
```js
609
$SYSTEM.locale(
Vincent Wei's avatar
tune    
Vincent Wei committed
610
        < 'ctype | numeric | time | collate | monetary | messages | paper | name | address | telephone | measurement | identification' $category = 'messages':
Vincent Wei's avatar
tune    
Vincent Wei committed
611
612
613
614
615
616
617
618
619
620
621
622
            - 'ctype':          `Character classification`
            - 'numeric':        `Formatting of nonmonetary numeric values`
            - 'time':           `Formatting of date and time values`
            - 'collate':        `String collation`
            - 'monetary':       `Formatting of monetary values`
            - 'messsages':      `Localizable natural-language messages`
            - 'paper':          `Settings related to the standard paper size (*)`
            - 'name':           `Formatting of salutations for persons (*)`
            - 'address':        `Formatting of addresses and geography-related items (*)`
            - 'telephone':      `Formats to be used with telephone services (*)`
            - 'measurement':    `Settings related to measurements (metric versus US customary) (*)`
            - 'identification': `Metadata describing the locale (*)`
623
        >
Vincent Wei's avatar
tune    
Vincent Wei committed
624
) string | undefined : `the locale like 'zh_CN'.`
625
626
```

Vincent Wei's avatar
tune    
Vincent Wei committed
627
该方法获取指定分类的区域,返回字符串。某些平台可能不支持特定的区域分类,比如姓名(`name`)分类。对不支持的区域分类,该函数将抛出 `Unsupported` 异常,或静默求值时返回 `undefined`
628

Vincent Wei's avatar
tune    
Vincent Wei committed
629
```js
630
631
$SYSTEM.locale(!
        < '[ctype || numeric || time || collate || monetary || messages || paper || name || address || telephone || measurement || identification] | all' $categories:
Vincent Wei's avatar
tune    
Vincent Wei committed
632
633
634
635
636
637
638
639
640
641
642
643
644
            - 'ctype':          `Character classification`
            - 'numeric':        `Formatting of nonmonetary numeric values`
            - 'time':           `Formatting of date and time values`
            - 'collate':        `String collation`
            - 'monetary':       `Formatting of monetary values`
            - 'messsages':      `Localizable natural-language messages`
            - 'paper':          `Settings related to the standard paper size (*)`
            - 'name':           `Formatting of salutations for persons (*)`
            - 'address':        `Formatting of addresses and geography-related items (*)`
            - 'telephone':      `Formats to be used with telephone services (*)`
            - 'measurement':    `Settings related to measurements (metric versus US customary) (*)`
            - 'identification': `Metadata describing the locale (*)`
            - 'all':            `All of the locale categories`
645
        >,
Vincent Wei's avatar
Vincent Wei committed
646
        <string $locale: `the locale for $categories`>
Vincent Wei's avatar
tune    
Vincent Wei committed
647
) true | false
648
649
```

Vincent Wei's avatar
tune    
Vincent Wei committed
650
651
652
653
该方法设置指定分类(单个或多个)的区域。成功时返回 `true`,失败时返回 `false`。某些平台可能不支持特定的区域分类,比如姓名(`name`)分类。对不支持的区域分类,该函数将抛出 `Unsupported` 异常,或在静默求值时返回 `false`

**异常**

654
655
- `Unsupported`:不支持的区域分类。可忽略异常。

Vincent Wei's avatar
tune    
Vincent Wei committed
656
**备注**
657
658

1. 在 HVML 中,表示区域的字符串始终使用 `en_US``zh_CN` 这种形式。
Vincent Wei's avatar
Vincent Wei committed
659
1. 在 HVML 应用框架中,要求始终使用 UTF-8 编码。
660
1. 对特定区域的修改,将在 `$SYSTEM` 变量上产生 `change:locale/<category>` 事件。
661
662

**示例**
663

Vincent Wei's avatar
tune    
Vincent Wei committed
664
```js
665
$SYSTEM.locale
Vincent Wei's avatar
Vincent Wei committed
666
    // string: "en_US"
667

668
$SYSTEM.locale(! 'all', 'zh_CN')
Vincent Wei's avatar
Vincent Wei committed
669
    // boolean: true
670

671
$SYSTEM.locale
Vincent Wei's avatar
Vincent Wei committed
672
    // string: "zh_CN"
673
674
```

675
676
677
678
679
680
#### 3.1.5) `time` 方法

获取或设置日历时间(calendar time)。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
681
```js
Vincent Wei's avatar
Vincent Wei committed
682
$SYSTEM.time longint: `the calendar time (seconds since Epoch)`
683
684
```

Vincent Wei's avatar
Vincent Wei committed
685
该方法获取当前日历时间(自 Epoch 以来的秒数),返回值类型为 `longint`
686

Vincent Wei's avatar
tune    
Vincent Wei committed
687
```js
688
$SYSTEM.time(!
Vincent Wei's avatar
Vincent Wei committed
689
        <real $seconds: `seconds since Epoch`>
690
691
692
) true | false
```

Vincent Wei's avatar
Vincent Wei committed
693
该方法设置系统时间,整数部分表示自 Epoch 以来的秒数,小数部分表示微秒数。成功时返回 `true`,失败时抛出 `AccessDenied` 异常,静默求值时返回 `false`
694
695
696

**异常**

Vincent Wei's avatar
Vincent Wei committed
697
- `InvalidValue`:传入无效参数,如负值或者大于 100,000 或小于 0 的微秒值。
698
- `AccessDenied`:当前会话的所有者没有权限设置系统时间时,将抛出该异常。
699

Vincent Wei's avatar
tune    
Vincent Wei committed
700
**备注**
701
702
703
704
705

1. 对日历时间的修改,将在 `$SYSTEM` 变量上产生 `change:time` 事件。

**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
706
```js
707
$SYSTEM.time
Vincent Wei's avatar
Vincent Wei committed
708
    // longint: 123456789L
709
710
711
712
```

**参见**

713
714
715
716
717
718
719
720
721
722
723
- C 标准函数:`gettimeofday()``settimeofday()`
- PHP: <https://www.php.net/manual/en/ref.datetime.php>
- PHP: <https://www.php.net/manual/en/datetime.formats.php>
- PHP DateTime 类:<https://www.php.net/manual/en/class.datetime.php>

#### 3.1.6) `time_us` 方法

获取或设置具有微秒精度的系统时间。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
724
```js
Vincent Wei's avatar
Vincent Wei committed
725
$SYSTEM.time_us longdouble :
Vincent Wei's avatar
tune    
Vincent Wei committed
726
    `A long double number representing the number of seconds (integral part) and microseconds (fractional part) since Epoch.`
Vincent Wei's avatar
Vincent Wei committed
727
728
```

Vincent Wei's avatar
Vincent Wei committed
729
该方法获取当前系统时间,包括自 Epoch 以来的秒数以及微秒数,返回值 longdouble 数值,小数部分为微秒值。
Vincent Wei's avatar
Vincent Wei committed
730

Vincent Wei's avatar
tune    
Vincent Wei committed
731
```js
Vincent Wei's avatar
Vincent Wei committed
732
$SYSTEM.time_us(
Vincent Wei's avatar
Vincent Wei committed
733
734
735
        [
            < 'longdouble | object' $return_type = 'longdouble': `indicate the return type: a long double number or an object.`>
        ]
736
) longdouble | object : `A long double number or an object representing the number of seconds and microseconds since Epoch:`
Vincent Wei's avatar
Vincent Wei committed
737
738
        - 'sec': < longint: `seconds since Epoch` >
        - 'usec': < longint: `microseconds` >
739
740
```

Vincent Wei's avatar
Vincent Wei committed
741
该方法获取当前系统时间,包括自 Epoch 以来的秒数以及微秒数,返回值类型为 longdouble 数值或包含 `sec``usec` 两个属性的对象。
742

Vincent Wei's avatar
tune    
Vincent Wei committed
743
```js
Vincent Wei's avatar
tune    
Vincent Wei committed
744
745
$SYSTEM.time_us(!
        <real $sec_us: `seconds with microseconds since Epoch`>
746
747
748
) true | false
```

Vincent Wei's avatar
Vincent Wei committed
749
该方法用一个实数(整数部分表示自 Epoch 以来的秒数,小数部分表示微秒数)设置系统时间。成功时返回 `true`,失败时抛出异常,静默求值时返回 `false`
750

Vincent Wei's avatar
tune    
Vincent Wei committed
751
```js
752
$SYSTEM.time_us(!
Vincent Wei's avatar
Vincent Wei committed
753
        <object $time_with_us: `An object representing the number of seconds and microseconds since Epoch`>
754
755
756
757
758
759
760
) true | false
```

该方法使用表示系统时间的对象设置系统时间。成功时返回 `true`,失败时抛出异常,静默求值时返回 `false`

**异常**

Vincent Wei's avatar
Vincent Wei committed
761
762
- `InvalidValue`:获取器被调用时,传入错误参数时(如错误的返回类型),将抛出该异常;静默求值时,返回 `longdouble` 类型的当前事件。设置器被调用时,传入无效参数时(如负值或者大于 100,000 或小于 0 的微秒值)时,将抛出该异常。
- `AccessDenied`:设置器被调用时,当运行解释器的所有者没有权限设置系统时间时,将抛出该异常。
763

Vincent Wei's avatar
tune    
Vincent Wei committed
764
**备注**
765
766
767
768
769

1. 对系统时间的修改,将在 `$SYSTEM` 变量上产生 `change:time` 事件。

**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
770
```js
Vincent Wei's avatar
Vincent Wei committed
771
772
$SYSTEM.time_us
    // longdouble: 123456789.456789
773
774
775
776
777
```

**参见**

- C 标准函数:`gettimeofday()``settimeofday()`
778
779
780
781
- PHP: <https://www.php.net/manual/en/ref.datetime.php>
- PHP: <https://www.php.net/manual/en/datetime.formats.php>
- PHP DateTime 类:<https://www.php.net/manual/en/class.datetime.php>

782
#### 3.1.7) `sleep` 方法
Vincent Wei's avatar
Vincent Wei committed
783

784
暂停当前会话的执行。
Vincent Wei's avatar
Vincent Wei committed
785
786
787
788
789

**描述**

```js
$SYSTEM.sleep(
790
791
        real $delay_time: `the delay time in seconds; a double or long double number representing the number of seconds (integral part) and microseconds/nanoseconds (fractional part) to delay.`
) real | false
Vincent Wei's avatar
Vincent Wei committed
792
793
```

794
该方法暂停当前 HVML 会话的执行以指定的秒数。若使用浮点数指定秒数,则小数部分可指定要休眠的纳秒数。正常情况下,该方法返回 0;当休眠被信号打断时,则返回剩余的秒数(返回值的类型和参数类型一致)。
Vincent Wei's avatar
Vincent Wei committed
795
796
797

**异常**

798
799
800
801
- `ArgumentMissed`:未指定必要参数。可忽略异常;静默求值时返回 `false`
- `WrongDataType`:非实数类参数类型。可忽略异常;静默求值时返回 `false`
- `InvalidValue`:传入无效参数,如负值。可忽略异常;静默求值时返回 `false`
- `SystemFault`:操作系统故障。不可忽略异常。
Vincent Wei's avatar
Vincent Wei committed
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

**示例**

```js
$SYSTEM.sleep(1UL)
    // ulongint: 0UL

$SYSTEM.sleep(0.3)
    // longdouble: 0.0FL
```

**参见**

- POSIX 函数:`sleep()``usleep()``nanosleep()`

817
#### 3.1.8) `timezone` 方法
818
819
820
821
822

获取或设置时区。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
823
```js
Vincent Wei's avatar
Vincent Wei committed
824
$SYSTEM.timezone : string | false
825
826
827
828
```

该方法返回当前时区。

Vincent Wei's avatar
tune    
Vincent Wei committed
829
```js
Vincent Wei's avatar
Vincent Wei committed
830
831
$SYSTEM.timezone(!
        <string $timezone: `new timezone`>
Vincent Wei's avatar
Vincent Wei committed
832
833
834
        [,
            < 'local | global' $permanently = 'local': `change timezone permanently/globally or temporarily/locally.`>
        ]
Vincent Wei's avatar
Vincent Wei committed
835
) true | false
836
837
```

838
该方法设置当前时区。成功时返回 `true`,失败时抛出异常,静默求值时返回 `false`
839

840
841
842
843
844
845
846
847
848
HVML 推荐使用类似 `Asia/Shanghai` 这样的字符串来表示时区。实质上,这个字符串是 POSIX 系统保存时区信息的文件路径,比如对 `Asia/Shanghai`,其时区信息通常保存在 `/usr/share/zoneinfo/Asia/Shanghai` 文件或 `/var/db/timezone/zoneinfo/Asia/Shanghai` 中。也支持如下特别的时区名称:

- `PRC`:中国标准时间,即北京时间,同 `Asia/Shanghai`
- `Hongkong`:香港时间,同 `Asia/Hong_Kong`
- `UTC`:协调世界时,同 `Etc/UTC`
- `UCT`:协调世界时的另一个名称,同 `Etc/UTC`
- `Greenwich`:格林威治时间,同 `Etc/GM`
- `GMT`:格林威治时间的简称,同 `Etc/GMT`
- `posixrules`:POSIX 默认时区规则,同 `America/New_York`
Vincent Wei's avatar
Vincent Wei committed
849

850
851
**异常**

Vincent Wei's avatar
Vincent Wei committed
852
- `InvalidValue`:无效的时区字符串。对无效的选项关键词,静默求值时,将被视作 `local`
Vincent Wei's avatar
Vincent Wei committed
853
- `AccessDenied`:当前会话的所有者没有权限持久更改系统时区。
854

Vincent Wei's avatar
tune    
Vincent Wei committed
855
**备注**
856
857

1. 对系统时区的修改,将在 `$SYSTEM` 变量上产生 `change:timezone` 事件。
Vincent Wei's avatar
Vincent Wei committed
858
1. 系统时区的全局、持久修改,可能需要重新启动操作系统。
859
860
861

**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
862
```js
Vincent Wei's avatar
Vincent Wei committed
863
864
865
866
867
868
869
870
871
872
$SYSTEM.timezone
    // string: "Asia/Shanghai"

$SYSTEM.timezone(! 'America/New_York' )
    // true

$SYSTEM.timezone
    // string: "America/New_York"
```

873
874
875
876
877
**参见**

- C 标准函数:`tzset()`
- PHP: <https://www.php.net/manual/en/timezones.php>

878
#### 3.1.9) `cwd` 方法
879

880
获取或设置当前工作路径。
881
882
883

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
884
```js
885
$SYSTEM.cwd string | false: `returns the current working directory on success, or @false on failure.`
886
887
888
889
```

该方法获取当前工作路径。成功时返回 `true`,失败时抛出异常;在静默求值时,对可忽略异常返回 `false`

Vincent Wei's avatar
tune    
Vincent Wei committed
890
```js
891
$SYSTEM.cwd(!
892
893
894
895
896
897
898
899
        <string $dir: `the new path for the current working directory.`>
) boolean: `returns @true on success or @false on failure.`
```

该方法改变当前工作路径。成功时返回 `true`,失败时抛出异常;在静默求值时,对可忽略异常返回 `false`

**异常**

900
901
902
903
904
905
906
907
908
909
该方法可能产生的异常,均为可忽略异常:

- `InvalidValue`:传入的目录字符串含有底层操作系统不支持的非法字符。
- `EntityNotFound`:指定的目录不存在。
- `AccessDenied`:无访问权限。
- `TooMany`:太长的符号链接跳转。
- `TooLong`:太长的目录名。
- `IOFailure`:输入输出错误。
- `OSFailure`:其他操作系统错误。

Vincent Wei's avatar
tune    
Vincent Wei committed
910
**备注**
911
912
913
914
915
916
917

1. 对当前工作路径的修改,将在 `$SYSTEM` 变量上产生 `change:cwd` 事件。

**参见**

- C 标准函数:`chdir()`, `getcwd()`

918
#### 3.1.10) `env` 方法
919
920
921
922
923

获取或设置系统环境变量。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
924
```js
925
926
927
928
929
930
931
$SYSTEM.env(
        <string: `the environment variable name`>
) string | undefined
```

该方法获取指定环境变量的值(字符串);未设置时抛出 `NoSuchKey` 异常,静默求值时返回 `undefined`

Vincent Wei's avatar
tune    
Vincent Wei committed
932
```js
933
934
$SYSTEM.env(!
        <string: `the environment variable name`>,
Vincent Wei's avatar
Vincent Wei committed
935
        <string | undefined: `the value`>
Vincent Wei's avatar
tune    
Vincent Wei committed
936
) true | false: `returns @true on success, otherwise @false if evaluated silently.`
937
938
939
940
941
942
943
944
945
946
947
```

该方法设置指定的环境变量,返回布尔数据,指明是否覆盖了已有环境变量。

**异常**

该方法可能产生的异常,均为可忽略异常:

- `InvalidValue`:非法的环境变量名称。
- `NoSuchKey`:不存在指定的环境变量。

Vincent Wei's avatar
tune    
Vincent Wei committed
948
**备注**
949

950
1. 新增特定的环境变量,将在 `$SYSTEM` 变量上产生 `change:env/grown` 事件,事件参数为一个对象,包含以新增环境变量名称为键,对应值为键值的键值对。
951
1. 对特定环境变量的修改,将在 `$SYSTEM` 变量上产生 `change:env` 事件,事件参数为一个对象,包含以修改的环境变量名称为键,对应值为键值的键值对。
952
1. 删除特定的环境变量,将在 `$SYSTEM` 变量上产生 `change:env/shrunk` 事件,事件参数为被移除的环境变量名称。
953

954
955
**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
956
```js
957
958
959
960
// 设置环境变量 `LOGNAME` 的值
$SYSTEM.env(! 'LOGNAME', 'tom' )
    // boolean: true
```
961

962
#### 3.1.11) `random_sequence` 方法
963
964
965
966
967

从内核获取指定的随机数据,可用于随机数发生器的种子或加密用途。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
968
```js
969
$SYSTEM.random_sequence(
970
        <number $length: `the length of the random byte sequence`>
Vincent Wei's avatar
Vincent Wei committed
971
) bsequence | false
972
973
```

Vincent Wei's avatar
Vincent Wei committed
974
该方法从内核获取指定长度的随机数据,可用于随机数发生器的种子或加密用途。该方法返回指定长度的字节序列或抛出异常;静默求值时,返回 `false`
975
976
977

**异常**

Vincent Wei's avatar
Vincent Wei committed
978
979
- `InvalidValue``$length` 无效的长度;长度需大于 0 小于等于 256。
- `NotSupported`:不支持。
980
981
982

**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
983
```js
984
// 从内核获得随机数据用于当前会话的随机数发生器种子。
Vincent Wei's avatar
tune    
Vincent Wei committed
985
$SYSTEM.random(! $EJSON.fetchreal($SYSTEM.random_sequence(4), 'u32') )
986
987
988
989
990
991
992
    // boolean: true
```

**参见**

- Linux 特有接口:`getrandom()`

993
#### 3.1.12) `random` 方法
Vincent Wei's avatar
Vincent Wei committed
994
995
996
997
998

获取随机值。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
999
```js
Vincent Wei's avatar
Vincent Wei committed
1000
$SYSTEM.random longint: `a random between 0 and RAND_MAX.`
Vincent Wei's avatar
Vincent Wei committed
1001
1002
```

Vincent Wei's avatar
Vincent Wei committed
1003
该方法获取 0 到 C 标准函数库定义的 `RAND_MAX`(至少 `32767`)之间的一个随机值(`longint`)。
Vincent Wei's avatar
Vincent Wei committed
1004

Vincent Wei's avatar
tune    
Vincent Wei committed
1005
```js
Vincent Wei's avatar
Vincent Wei committed
1006
1007
$SYSTEM.random(
        <real $max: `the max value`>
Vincent Wei's avatar
Vincent Wei committed
1008
) real | false: `A random real number between 0 and $max. The type of return value will be same as the type of $max.`
Vincent Wei's avatar
Vincent Wei committed
1009
1010
1011
1012
```

该方法获取 0 到指定的最大值之间的一个随机值。返回值的类型同参数 `$max` 的类型。

Vincent Wei's avatar
tune    
Vincent Wei committed
1013
```js
Vincent Wei's avatar
Vincent Wei committed
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
$SYSTEM.random(!
        <real $seed: `the random seed`>
        [, <number $complexity: `a number equal or greater than 8 to indicates how sophisticated the random number generator it should use - the larger, the better the random numbers will be.>
        ]
) boolean: `@true for success, @false otherwise.`
```

该方法设置随机数发生器的种子(`$seed`)和/或复杂度(`$complexity`)。该方法在成功时返回 `true`;失败时抛出异常,或在静默求值时,对可忽略异常返回 `false`

**异常**

`InvalidValue`:传入了无效参数,比如过小的 `$complexity` 值。

**示例**

Vincent Wei's avatar
tune    
Vincent Wei committed
1029
```js
Vincent Wei's avatar
Vincent Wei committed
1030
// 使用当前系统日历时间设置随机数种子。
1031
$SYSTEM.random(! $SYSTEM.time )
Vincent Wei's avatar
Vincent Wei committed
1032
1033
1034
    // true

// 使用当前系统日历时间设置随机数种子,并设置随机数发生器的复杂度为最高。
1035
$SYSTEM.random(! $SYSTEM.time, 256 )
Vincent Wei's avatar
Vincent Wei committed
1036
1037
1038
    // true

$SYSTEM.random
Vincent Wei's avatar
Vincent Wei committed
1039
    // longint: 8899L
Vincent Wei's avatar
Vincent Wei committed
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056

$SYSTEM.random(1)
    // number: 0.789

$SYSTEM.random(1000L)
    // longint: 492L

$SYSTEM.random(-10FL)
    // longdouble: -8.96987678FL
```

**参见**

- C 标准函数:`random_r()`
- C 标准函数:`srandom_r()`
- C 标准函数:`initstate_r()`

1057
1058
### 3.2) `SESSION`

Vincent Wei's avatar
RC3    
Vincent Wei committed
1059
该变量是一个会话级内置变量,解释器在创建一个新的会话时,会自动创建并绑定。该变量主要用于会话相关的信息,并提供给用户在当前会话的不同 HVML 协程之间共享数据的机制。
1060

Vincent Wei's avatar
RC3    
Vincent Wei committed
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
#### 3.2.1) `app` 方法

获取当前会话的应用名称。

**描述**

```js
$SESSION.app
    string : `the app name of current session.`
```

该方法获取当前会话的应用名称。

**异常**

该方法不产生异常。

**示例**

```js
$SESSION.app
    // string: 'cn.fmsoft.hvml.sample'
```

#### 3.2.2) `runner` 方法

获取当前会话的行者名称。

**描述**

```js
$SESSION.runner
    string : `the runner name of current session.`
```

该方法获取当前会话的应用名称。

**异常**

该方法不产生异常。

**示例**

```js
$SESSION.runner
    // string: 'hello'
```

1109
#### 3.2.3) `myObj` 静态属性
1110

1111
`myObj``SESSION` 的一个静态属性,用来定义用户自定义键值对,初始为一个空对象。程序可使用 `update` 元素设置其内容:
1112
1113
1114
1115
1116

```html
<!DOCTYPE hvml>
<hvml target="html">
    <head>
1117
        <update on="$SESSION.myObj" to="displace">
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
            {
                "AUTHOR": "Vincent Wei",
            }
        </update>
    </head>

    <body>
        ...
    </body>
</hvml>
```

1130
由于 `$SESSION` 是会话级变量,故而可以在当前会话的另一个 HVML 协程中观察该数据上的变化:
1131
1132

```html
1133
    <observe on="$SESSION.myObj" for="change:AUTHOR" in="#theStatusBar">
1134
1135
1136
1137
        ...
    </observe>
```

Vincent Wei's avatar
RC3    
Vincent Wei committed
1138
#### 3.2.4) `user` 方法
1139
1140
1141
1142
1143

获取或设置用户键值对。

**描述**

Vincent Wei's avatar
tune    
Vincent Wei committed
1144
```js