代码格式化系统
代码格式化系统是 Alia 语言的运行时对象序列化与代码格式化机制,支持将任意对象转换为可读的结构描述或可执行的代码,并支持 ANSI 染色输出。
1. 运行时序列化方法
每个 Alia 内置类型都实现了四个核心方法,用于将对象转换为不同格式的字符串。
方法总览
| 方法 | 用途 | 输出格式 |
|---|---|---|
toDescription() | 结构描述 | String "hello" / Number 42 / Object *[...] |
toColoredDescription() | 染色结构描述 | ColoredString 对象 |
toCode() | 可执行代码 | "hello" / 42 / *[key: value] |
toColoredCode() | 染色可执行代码 | ColoredString 对象 |
标准结构描述格式
toDescription() 输出遵循统一的标准结构描述范式:
对象
Object *[
String name: "Alice",
Number age: 30,
Object address: *[
String city: "Beijing",
Number zip: 100000
],
Array tags: [String "admin", String "user"]
]
数组
Array [Number 1, String "hello", Boolean true]
值类型
String "Hello World"
Number 42
Boolean true
Null null
Alias 类型
Alias(greet)
Alias(add)
类型颜色映射
| 类型 | 颜色 |
|---|---|
| String | 绿色 #00FF00 |
| Number | 品红 #FF00FF |
| Boolean | 黄色 #FFFF00 |
| Object | 青色 #00FFFF |
| Array | 蓝色 #0000FF |
| Alias | 亮品红 #DA77F2 |
| Null | 灰色 #808080 |
| Error | 红色 #FF0000 |
2. 代码格式化 API
格式化与高亮由宿主接口提供,均接收 Alia 代码字符串与可选配置对象:
| 方法 | 输入 | 输出 |
|---|---|---|
format | Alia 代码字符串、配置对象 | 格式化后的代码字符串 |
color | Alia 代码字符串、配置对象 | 位置保持的 ANSI 高亮字符串 |
配置选项:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
indentSize | Number | 2 | 缩进空格数 |
useTabs | Boolean | false | 是否使用 Tab 缩进 |
compact | Boolean | false | 紧凑模式:移除 Stack/集合内空格,冒号后不留空格,元素以 , 分隔 |
quoteStyle | String | 'single' | 字符串引号风格:'single' / 'double' |
bracketSpacing | Boolean | true | Stack 单行折叠时大括号内是否保留空格({ a } / {a}) |
collectionSpacing | Boolean | false | 数组/对象字面量括号内是否保留空格([a, b] / [ a, b ]) |
emptyCollectionSpacing | Boolean | true | 空集合是否保留内空格({ } / {}、[ ] / []) |
endOfLine | String | 'lf' | 换行符:'lf' / 'crlf' / 'cr' |
insertFinalNewline | Boolean | false | 输出末尾是否追加换行 |
forceMultiline | Boolean | false | 单条指令的 Stack 强制展开为多行 |
keepColorDirectives | Boolean | true | 输出中是否保留 @colorAlias、@colorClass 等颜色声明指令 |
宿主调用示例(JavaScript):
const Alia = require('./Base/Executor')
const alia = new Alia()
alia.format('alias greet <String name> { print name }', { indentSize: 4 })
alia.color('alias greet <String name> { print name }')
配置对象仅在宿主调用 format 或 color 时传入,Alia 代码中没有对应的调用语法。
编辑器侧的格式化、高亮、查找与补全统一由 Base/Executor/Analyzer 提供
(format/highlight、定义/注释/类型/翻译查找、按栈可用列表补全),VSCodeExt
仅保留 VSCode 接口适配。
3. 颜色声明指令
通过 @ 前缀指令在 Alia 源代码中声明颜色配置,这些指令会在代码格式化时被自动收集并应用。
Color.set
Color.set 用于注册颜色名。color() 的输出按位置保持的纯高亮渲染,区分以下颜色类别,可通过 Color.set 覆盖任一类别默认色:
| 类别 | 默认颜色 | 含义 |
|---|---|---|
DeclKeyword | 亮红 | 声明类关键字(const、let、class、alias、new、import、export、type、typify、test、remove、enable、disable、mut) |
Keyword | 亮黄 | 流程控制类关键字(print、if、each、return、call、assert 等)与语句级运算符(=、+=、++) |
Operator | 亮白 | 表达式内算术/比较运算符(+、<= 等) |
Variable | 亮绿 | 普通变量标识符 |
ConstVariable | 亮青 | const 声明的常量及其引用 |
KeyArgument | 亮蓝 | 调用中的 Key 参数与别名形参 |
Alias | 亮品红 | 别名名与 alias 模式字面量(如 and)、类方法 |
Type | 青色 | 类型名(String、Number 等) |
Property | 蓝色 | 类体与对象字面量成员键、点号访问的成员名(self.name、obj.key) |
语法:
Color.set <String name> to <Color color>
Color.set 向颜色名称注册表注册一个颜色名,之后可用 new Color ['注册名', 'Name'] 引用该颜色。若注册名与上述颜色类别同名,则该类别的默认颜色被覆盖。
示例:
~ 注册颜色名 Accent
Color.set 'Accent' to new Color ['#FF0000', 'Hex']
~ 引用已注册的颜色名
const accent = new Color ['Accent', 'Name']
~ 将 Keyword 类别覆盖为红色
Color.set 'Keyword' to new Color ['#FF0000', 'Hex']
@colorAlias
设置别名模式中各内含关键字的颜色。
语法:
@colorAlias <Keys aliasPattern> -> <Sheet keyAndColorMap>
颜色映射使用 new Sheet [['关键字', '颜色'], ...] 二维表形式(Sheet 允许重复键)。
示例:
~ 为带 and 内含关键字的别名设置颜色
@colorAlias add <Number a> and <Number b> -> new Sheet [['and', '#00FF00']]
执行格式化时,add 1 and 1 调用中的 and 等内含关键字会应用映射中的预定颜色;未在映射中的内含关键字与语法关键字本身保持相同的 Alias 颜色类。
@colorClass
设置类中各成员的颜色。
语法:
@colorClass <Key className> -> <Object everyClassItemColorMap>
颜色映射使用 *[ <Key member>: <Color color>, ... ] 对象字面量形式,每个成员对应一个 Color 对象。
示例:
~ 为 Person 类的属性设置颜色
@colorClass Person -> *[name: new Color ['#FFFF00', 'Hex'], age: new Color ['#FF00FF', 'Hex'], address: new Color ['#00FFFF', 'Hex']]
执行格式化时,const Alice = new Person *[name: 'Alice', age: 21] 等构造语句中的成员键保持默认颜色,而 Alice.name 等成员访问中的成员名会应用预定的颜色。
收集机制
Color.set 语句与 @colorAlias、@colorClass 颜色声明指令在格式化时被自动收集并注册到 ColorRegistry,影响该次格式化会话中的所有染色输出。color() 对源码进行位置保持的纯高亮:对输入代码仅插入 ANSI 转义码,不改变任何字符位置。
4. 中间表示:ColoredString
染色输出统一使用 ColoredString 对象作为中间表示:
const red = new Color ['#FF0000', 'Hex']
const cs = new ColoredString ['Hello World']
cs.color red at [0, 5] ~ 将 "Hello" 染为红色
print call cs.toTerminal ~ 输出 ANSI 染色字符串
ColoredString 通过 toTerminal 方法转换为 ANSI 转义码字符串,支持真彩色(TrueColor)输出。
5. 最佳实践
推荐使用标准结构描述
在调试和日志输出时,优先使用 toDescription() 获得带类型前缀的标准结构描述:
print call someValue.toDescription
~:
Object *[
String name: "Alice",
Number age: 30
]
:~
自定义颜色主题
在项目入口处统一声明颜色主题:
~ my-theme.alia
Color.set 'String' to new Color ['#E06C75', 'Hex']
Color.set 'Number' to new Color ['#56B6C2', 'Hex']
Color.set 'Boolean' to new Color ['#E5C07B', 'Hex']
Color.set 'Object' to new Color ['#61AFEF', 'Hex']
Color.set 'Array' to new Color ['#C678DD', 'Hex']
export this