vscode-prism
VSCode extension for the Prism hardware DSL — 一门"算法-调度分离 + RTL/TLM 同源双出 + 三方 cosim 闭环"的硬件高层次设计语言。
语言本身见 Prism 工程内的 prism/docs/prism-language.md(完备版规范);原语登记的单一事实源是 prism/frontend/keywords.py。
功能
- 语法高亮(TextMate grammar):
- 顶层声明八类:
import / interface / module / composer / blackbox / @schedule / design / run … of …
- 端口面:方向词
in / out / both、内建端口类型 Signal<T> / Stream<T> / Stream<T, ready>、复合类型 array<T, N>、位类型 bit / iN / uN、泛型 kind 约束 bits / int、implements 契约遵从
- 类型转换
u<N>(x) / i<N>(x) / 不写宽度的 u(x) / i(x) / bit(x) / 泛型形参 T(x)
- wire 全形态
wire NAME [: TYPE] [= EXPR] [-> SINK]、模块体内带类型局部信号、批量 connect { … }、常量 tie-off、源端落位标注 connect u8(s.q) -> k.d、generate for、实例实参 (leaf = u_op)
- 时序与存储:
reg(含数组形态 reg NAME : [N] T)/ mem(初值只有数组字面量,文件镜像写在 run 的 image 段)/ on clock / prime 记号 ' / if (cond) 与 else、else if / switch 多路分支 / for i in 0..3 编译期展开 / 高阻字面量 1'bz
- 分支与成员:三元
cond ? a : b(右结合可链式)、match 两形态、_ 兜底、成员测试 x in [a, b] / x in lo..hi
- 表达式:一元
- ~ !、* / %、移位、关系、位运算、逻辑、切片 x[hi:lo]、拼接 {a, b}、复制 {N{x}}
fsm 块:states / reset / enc / illegal / latency / 转移行(自环可省 = 缺省保持本态)/ ctrl.is(S) / ctrl.was(S) / ctrl.will(S) / ctrl.state
expose:as 单名、-> 名1, 名2 多重别名、[lo..hi] -> 名[lo..hi] 通配整段、任意多层 composer 路径(cpu.exu.exec.alu_mod.result)
@schedule 八字段与其取值(storage 档位闭合集 reg|shift_reg|mem|reg_array|dual_port_ram|host)、blackbox 的 verilog / filelist
- 测试与运行层:表式
stim(列头一次、值按列切拍、行尾期望组 [..]、扫掠 lo..hi by s)、show(裸列 / 表达式列 as / let 宏 / 范围糖 / fmt 混排与 %0d %0x %0X %0b %0o %%)、until 三形态、repeat、image : { 别名 : 实例[字节偏移:字节数] = @load("文件") } 镜像装载(字节数可省 = 按文件长度)、host : { 名 = uart_8n1(…) } 宿主对端绑定与 名.tx.count / 名.rx.last 观测列
- 字面量:十六进制(含
_ 分隔位)、整数、浮点、字符串、// 注释
- 代码片段 48 条:上面每个构造一条骨架,含 interface / composer 依赖注入 / 类型转换 / both 三态 / fsm 三时相谓词 /
if-else / switch / for 展开 / mem 数组字面量初值 / run image 装载 / host 绑定 / blackbox / run 全形态,外加四层齐备的完整模板与 Counter 模板。
- 关键字补全:纯 JS 提供器,敲
@ / . / : / 空格触发。条目对齐 keywords.py 的 PRISM_KEYWORDS / SCHEDULE_FIELDS / BLACKBOX_FIELDS / STREAM_FIELDS / FSM_PROPS / FSM_VALUES / RUN_WORDS / HOST_CODECS / TYPE_NAMES 全集,含只在其上下文里生效的上下文词与预留字。
- 语言配置:
// 注释、括号自动闭合、{ 缩进、wordPattern 覆盖 prime 记号 x'。
- 文件后缀:
.prism / .psm / .pi(languageId = prism)。
与 Prism 编译器解耦
本扩展不调用 prism.py:不做类型检查、诊断、跳转、悬浮提示,聚焦"看得见、写得快"。语言服务(诊断 / 语义跳转)走独立 LSP 分支,不在本仓库。
开发
npm install # 装 @vscode/vsce 与 tokenize 测试依赖
npm test # grammar 测试:夹具逐行 tokenize + scope 正反断言
code . # 打开工程,F5 起 Extension Development Host
npm test 跑三件互不重叠的事:
- 夹具 tokenize ——
scripts/fixtures/syntax_test_prism.prism 是每条上色规则的密集标本,逐行走 vscode-textmate + oniguruma,保证 pattern 编得起来、规则嵌套不炸。
- scope 断言 —— 逐行检查目标 token 拿到的 scope(101 条,其中 23 条反向)。其中反向断言(
until : / IDLE: / reset : 之类的 名 : 值 行不许被例化规则吃掉;从语言里移除的写法不许拿到任何语义色)与正向断言同权重——只写正例的语法测试等于没测。
- 插件内部对账 —— grammar 的词表(
keyword / storage / fsm-word / schedule-value / …)与 extension.js 的 COMPLETIONS 标签双向比对:高亮认识而补全没有 ⇒ 用户敲不出来;补全里有而高亮不认 ⇒ 多半是语言已移除该词、补全该删。只允许 EXEMPT 里写明理由的词(属性泛匹配、形态通配、预留字)单边存在。
夹具留在本仓库:插件的测试不吃外部工程的目录布局。
打包
npm run package # 产出 vscode-prism-<version>.vsix
code --install-extension vscode-prism-0.8.0.vsix
目录
vscode-prism/
├── package.json # 扩展清单(contributes.languages/grammars/snippets)
├── language-configuration.json # 括号/注释/缩进/wordPattern
├── extension.js # 关键字补全提供器(纯 JS,无编译步骤)
├── syntaxes/
│ └── prism.tmLanguage.json # TextMate 语法
├── snippets/
│ └── prism.json # 代码片段
└── scripts/
├── tm-test.js # grammar 测试(npm test)
└── fixtures/
└── syntax_test_prism.prism # 上色规则标本,只喂测试
同步策略
Prism 语言原语的单一事实源是 prism/frontend/keywords.py。本插件与之对账三处:
syntaxes/prism.tmLanguage.json 的 keyword / storage / type-name / primitive-type / schedule-field / fsm-word / fsm-reference / branch-word / schedule-value / run-* / port-direction / host-codec 匹配集
extension.js 的 COMPLETIONS 数组(分组注释即 keywords.py 的集合名)
snippets/prism.json 的模板骨架
两段链接的分工:keywords.py ↔ 本插件那一段是人工——keywords.py 在邻居工程里,本仓库的测试资产不吃它的路径;插件内部那一段(grammar 词表 ↔ COMPLETIONS)由 npm test 的 RECON 双向锁住,当前 grammar 90 词 ↔ COMPLETIONS 96 条、豁免 6 条,0 缺项。Prism 侧 drift_check() 保证编译器不会悄悄加未登记原语,RECON 保证插件自己两处不会各说各话。
加新原语按这条序走:keywords.py 登记 → grammar → COMPLETIONS → snippets → fixture 补一行标本 + tm-test.js 补正反断言 → npm test。
变更记录
- 0.8.0 — 对齐 10-05 镜像装载新语法:run 字段加
image(别名 : 实例[字节偏移:字节数] = @load("文件"),字节数可省 = 按文件长度),补全与片段新增 image / @load;@init 出语言——mem 条与 design 模板按"初值只有数组字面量,文件镜像写在 run 的 image 段"改口径,片段 mem 从文件装载 换成 run image 镜像装载;夹具与 scope 断言改按 实例[字节偏移:字节数] 标本,image : { 断 keyword.control.run-field。grammar 89 → 90 词、COMPLETIONS 95 → 96 条。
- 0.7.0 — 对齐 9-28 之后的语言演进:
on clock 的 else / else if / switch / for 展开上色并补片段;fsm 的 enc / illegal / latency 属性行与 was / will 谓词(谓词要求点号前缀,裸 state、will_on 不再被抢色),自环可省;实例实参 (leaf = u_op)、host : { 名 = uart_8n1(…) } 与 名.tx.count 观测列;expose 认任意层 composer 路径与 [lo..hi] -> 名[lo..hi] 通配整段;成员测试 in;reg 数组形态。清掉编译器不再接受的取值(distributed_reg / single_port_ram / ram / sync_high / param / auto / multi)、未登记的 check / exclusive / microarch、非语言类型的 bool / fixed / float。新增 npm test 的 grammar ↔ COMPLETIONS 双向 RECON;scope 断言 58 → 101 条(反向 23),snippets 41 → 48 条。
- 0.6.0 — grammar 测试改为"仓库内夹具 + 反向 scope 断言":
scripts/fixtures/syntax_test_prism.prism 承载每条上色规则的标本,断言 37 → 58 条,反向断言与正向同权重;examples/ 那批手写教学样例移除,教材职责归 prism-testsuite。
- 0.5.0 — 对齐完备版语言规范:高亮与补全加
interface / composer / implements / 端口方向 both / 类型转换 u(x) T(x) / 一元 ! 与 % / 高阻字面量 / expose -> 多重别名 / wire 省 :TYPE;补全表按 keywords.py 全集对齐(57 词 0 缺失),不再给废弃写法语义色;snippets 按规范的语法面重写(interface / composer 依赖注入 / 类型转换 / both 三态 / mem 数组字面量初值 / run 表式与具名期望组 / 零驱动列表,重写四层齐备模板)。
- 0.4.0 — 三元运算符
cond ? a : b 的 ? 入 operator;if (cond) { reg' = val } 条件更新(if 进 keywords.py timing),新增 if-cond 规则与补全条目。
- 0.3.0 — 测试与运行层:
run … of … 声明头、stim / show / until 字段、let 宏、end of stim、上下文词、&& / || / ..、fmt 占位符;scope 断言 18→34 条。
- 0.2.0 — 对齐
keywords.py 单一事实源:blackbox / match 两形态 / fsm / design 级 wire + 裸赋值 / expose … as … / import / generate for / 切片 / 拼接 / 复制;类型词改小写 array。
- 0.1.0 — 初版:高亮 + 关键字补全 + snippets。
License
MIT