ARC Language
========================================================================================================================
*Arc Readable Configuration*

Purpose
------------------------------------------------------------------------------------------------------------------------

- ARC 是一种可读的序列化格式, 可以作为配置文件和日志文件
- ARC 可以无歧义地映射为哈希表, 其他语言能很容易的解析出封装的数据结构.
- ARC 被设计成能压缩成单行, 也就是说换行和空格是无所谓的.

Table of Contents
------------------------------------------------------------------------------------------------------------------------
1. [注释](#standard-comment)
2. [键值对](#standard-record)
3. [字符串](#standard-string)
4. [特殊值](#standard-special-value)
5. [引用值](#standard-reference-value)
6. [宏](#standard-macro)
7. [数字](#standard-number)
8. [字典](#standard-dict)
9. [列表](#standard-list)
- [Additional](./addition/Readme.md)


注释(Comment) <a id="standard-comment">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

百分号 (Percent Sign) 会将该行余下的部分标记为注释

```md
% 这是一个单行注释
%%% 这是多行注释
*这里高亮 markdown 语法*
**可以设置 meta 信息**
*`$` 用来表示唯一属性*
- $version = '1.0'
- $md5 = '5C8607DF825EB982'
*`@` 用来表示可变属性*
- @align-comment = true
- @empty-line = 2
**Arc 在注释中 lint 自身**
%%%
```

ARC 中使用 `,` 以及 `;` 作为 eos 分隔符, 这两者是等价的.

出现大于一个 eos 表示空声明, 没有任何作用.

键值对(Record)<a id="standard-record">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

> ARC 被设计成可以无歧义地映射为哈希表

因此 ARC 最基本的构成单元是键值对(Record)

键名(Key)在绑定符的左边而值(Value)在右边, 键名和键值周围的空白会被忽略

绑定符你可以使用 js 风格的 `:`, 也可以使用 py 风格的 `=`.

**只需把 json 开头末尾的 `{ }` 对删除就可以得到合法的 `arc` 文件!**

路由
------------------------------------------------------------------------------------------------------------------------

```arc
root/key = 1
```

等价于:

```ts
module.exports = {
    root : {
        key: 1
    }
}
```

`/` 用于分割路由, `/` 两边的空格会被无视.

键不需要加引号, 除非包含 `/` 与空格换行等, 或者由纯数字构成.

#### 最佳实践
- 使用等号分隔键值对
- 等号两边使用一个空格分割
- 末尾不加任何符号
- `/` 两边不加空格

字符串<a id="standard-string">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------
``" "`` 和 ``' '`` 引起的部分是字符串.

区别在于前者带转义, 后者是字面量.

关于转义和多行字符串参见: [#RFC15]() 与 [#RFC16]()

局部化DSL<a id="standard-macro">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

`@` 开头的符号是宏标记.

``@marco`DSL` ``是 `@macro"""DSL"""` 的简写

用于指定特殊的量.

十进制整数<a id="standard-number">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

- `十进制整数`有数字, 下划线以及加减号组成, 对应类型为大整数.
- 负数的前缀是减号, 正数可以有加号前缀.
- 允许前导零, 前导零也可加符号
- 整数值 `-0` 与 `+0` 是有效的, 并等同于无前缀的零。

```arc
int1 = 42
int2 =+0
int3 = 0
int4 =-000017
int5 = 123_000    # 123 k
int6 = 233_3333   # 233万
int7 = 1_2_3_4_5  # 合法但不鼓励
```

- 每个下划线两侧必须至少有一个数字。

整数也可解析为 64 bit
如若这是一个默认行为, 应该弹出一个 warning, 提示可能发生精度损失
用户可以使用参数显式指定从而避免 warning.


#### 最佳实践
- 对于6位以上的大数, 在数字之间用下划线来增强可读性.
- 每4位或者3位使用分隔符



十进制小数
------------------------------------------------------------------------------------------------------------------------

- `十进制小数` 由整数和点构成.
- `0.` 开头属于合法的小数, 整数部分是 `0` 不可以省略
- 但是 `.` 是不行的
- 允许加减号前缀
- `-0.0` | `+0.0` | `.0` 这四种写法都是合法的.





一个浮点数由一个整数部分（遵从与十进制整数值相同的规则）后跟上一个小数部分和/或一个指数部分组成。
如果小数部分和指数部分兼有，那小数部分必须在指数部分前面。


小数部分是一个小数点后跟一个或多个数字。

一个指数部分是一个 E（大小写均可）后跟一个整数部分（遵从与十进制整数值相同的规则）。

与整数相似，你可以使用下划线来增强可读性。
每个下划线必须被至少一个数字围绕。


```arc
# 小数
flt1 =+1.0
flt2 = 3.1415
flt3 =-0.01
flt8 = 224_617.445_991_228
```

- **十进制小数不是 IEEE 754 所规定的浮点数!**

不区分大小写, 具体取决于对应语言的实现.

```arc
# 无穷
sf1 = infinity  % 正无穷
sf2 =+Infinity  % 正无穷
sf3 =-INFINITY  % 负无穷
# 非数
sf4 = nan       % 等同于 NaN
sf5 =+NaN       % 实际上对应信号非数码还是静默非数码，取决于实现
sf6 =-NAN       % 有效，实际码取决于实现
```
小数也可解析为 浮点数


如若这是一个默认行为, 应该弹出一个 warning, 提示可能发生精度损失
用户可以使用参数显式指定从而避免 warning.

特殊数值字面量<a id="standard-special-value">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

ARC 中, 值不能是字母, 除非是特殊值.

例如 `true`, `false`, `null` 等

其他常量参考: [#RFC11]()

引用量<a id="standard-reference-value">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

`$` 开头的符号是引用路径.

用于避免多处写同一个变量.

字典字面量<a id="standard-dict">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

字典字面量用 `{ }` 对表示, 里面每一项必须是键值对


字典域
------------------------------------------------------------------------------------------------------------------------


(dict)

字典域继承
------------------------------------------------------------------------------------------------------------------------

(/inherit)

#### 最佳实践
- 每次继承使用双空格缩进


列表字面量<a id="standard-list">&nbsp;</a>
------------------------------------------------------------------------------------------------------------------------

列表字面量用 `[ ]` 表示, 里面每一项必须是值

数组是内含值的方括号。
空白会被忽略。
子元素由逗号分隔。
值和结束括号前可以存在任意数量的换行和注释。
不可以使用多余的分隔符

```arc
list1 = [1, 2, 3]
list2 = ["red", "yellow", "green"]
list3 = ["所有（写法的）", '字符串', """都是一样的""", '''类型''']
list4 = [[1, 2], ["a", "b", "c"]]  # 数据类型可以不同
list5 = [[1, 2.0]]  # 同一个列表里数据类型也可以不同
list6 = [
  1;  % 使用 ; 分割
  2,  % 使用 , 分割
  3   % 也可以什么都不使用
]
```

#### 最佳实践
- 使用 `,` 分割
- `,` 后面加一个小空格
- 如果是单行, 最后一个元素不加 `,`
- 如果是多方, 最后一个元素要加 `,`


### Advance
使用数据结构标注:

```arc
list1@List  = [1, 2, "2"]
list1@Tuple = [1, 2, 2]
list1@Set   = [1, 2, 3]
```






列表域
------------------------------------------------------------------------------------------------------------------------


 
- [#RFC13](https://github.com/Moe-Net/Arc-Language/blob/master/RFCs/RFC13%20-%20Inherit%20Scope.md#design): 列表域不能是空的! 



列表域不能继承, 只能挂载在字典域下面!