|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
×
本帖最后由 ic_fisher 于 2025-12-13 16:14 编辑
写在开头
感谢大家支持,接着上一篇,在这篇学习笔记里,我主要整理了一下,函数命名方式、函数调用、语法细节、数据类型等基础内容。这些都是学习 SKILL 脚本前先打牢的底层概念,也希望大家能在学习时少踩一些坑,文章同步更新到个人公众号 “ic打工人摸鱼笔记” ,欢迎围观。
一、命名规范:Cadence 的雷区
SKILL 的命名都有有严格约定,尤其要避免与 Cadence 内部符号冲突。
✅ 用户自定义命名黄金法则
- 函数名 & 变量名必须以大写字母开头!
这是官方反复强调的避坑指南。Cadence 自家函数/变量几乎都用小写(或带前缀),你用大写就能天然隔离。
- ; GOOD
- MyCustomFunction()
- NetList_Buffer = list("A" "B")
- ; BAD — 可能覆盖内部变量!
- netlist_buffer = ... ; 小写开头,危险!
复制代码
🔒 Cadence 私有函数:别碰!
- 函数名以 `_` 开头的(如 `_dbGetObj`)是 Cadence-private functions。
- 它们未文档化、不支持、随时可能被删除或修改。
- 即使你能调用成功,也绝不该在生产脚本中使用。
🧩 Cadence 内部命名结构(供理解,勿模仿)
Cadence 内部函数通常采用:`[前缀][根名]` 结构:
- 前缀:2~5 个小写字母,表示功能模块(如 `db` 表示 database)
- 根名:首字母大写
- 示例:`dbCreateInst()`、`rodCreatePath()`
同时,前缀首字母还有含义:
| 字符 | 含义 | | b | 位域常量 (bit-field constant) | | c | 枚举常量 (enumerated constant) | | e | 错误结构体 | | i | 内部函数(不应直接调用) | | f | 函数指示符(少见) | | m | 宏(罕见) | | v | 公共全局变量 |
避坑提醒:
别试图去 set 那些内部变量(如 `gcdisable`, `_gcprint`, `printlength` 等),除非你完全清楚后果——它们多用于调试,乱改可能导致内存泄漏或程序崩溃。
二、函数调用:SKILL 是函数式的
SKILL 本质是 Lisp 方言,一切皆函数调用。
两种调用语法(任选其一)
1. 代数式(Algebraic):`func(arg1 arg2)` ← 推荐,更像 C
2. 前缀式(Prefix / Lisp 式):`(func arg1 arg2)`
⚠️ 关键限制:
函数名和左括号之间不能有空格!
- f(a b) ; ✅ 正确
- f (a b) ; ❌ 错误!会被解析成“调用变量 f”再传参,大概率报错
复制代码
运算符也是函数!
- `+` 就是 `plus` 函数
- `x + y` 等价于 `plus(x y)` 或 `(plus x y)`
- 甚至 `if`、`while` 这类控制结构,也是特殊函数
把 `a + b * c` 想成 `(plus a (times b c))`,你就理解了 SKILL 的求值逻辑——从内到外,函数嵌套。
三、语法细节:空格、括号、注释的魔鬼
🚫 空格不是随便加的
| 场景 | 正确 | 错误 | | 函数调用 | `f(a b)` | `f (a b)` | | 一元负号 | `-1`, `-a` | `- 1`, `- a` | | 二元减号 | `a - b` 或 `a-b` | `a -b`(歧义!) |
为什么?
SKILL 解析器对 token 边界极其敏感。`- a` 会被看作“负号”和“变量 a”两个独立 token,而非“对 a 取负”。
📌 括号:不是 C 里的装饰品
- 在 C 中:`if (x) ...` 的括号是语法要求
- 在 SKILL 中:括号 = 函数调用
- `(x)` 表示“调用名为 x 的函数” → 如果 x 是变量,就报错!
- 所以:永远不要给单独的变量或常量加括号!
- x = 5
- if(x then ...) ; ✅ x 是条件表达式
- if((x) then ...) ; ❌ 试图调用函数 x,错误!
复制代码
💡 超级右括号 `]`:交互式输入的偷懒技巧
- 用于一次性闭合所有未匹配的 `(`
- 示例:
- f1( f2( f3( f4( x ] ; 等价于 f1(f2(f3(f4(x))))
复制代码 - 但官方不推荐在脚本中使用——可读性差,易出错。
📝 注释:两种风格,注意续行
1. 块注释:`/* ... */`
- 不能嵌套!第一个 `*/` 就结束整个注释。
2. 行注释:`; ...`
- 支持用 `\` 续行:
- a = 1 ; 这是一个很长的注释 \\
- 第二行继续说明
复制代码
- ⚠️ 如果 `\` 后紧跟代码,整行都会被注释掉!
- ; 错误示范:
- b = 2 ; 注释\
- a + b ; 这行不会执行!
- ; 正确做法:在 \ 后加空格
- b = 2 ; 注释\
- a + b ; ✅ 会执行
复制代码
🔧 反引号 `` ` ``、逗号 `,` 与 `,@`:高级列表构造
这是 SKILL 的“模板字符串”机制,用于选择性求值。
- y = 10
- z = '(a b)
- '(x y z) => (x y z) ; 全不求值
- `(x ,y z) => (x 10 z) ; ,y 被求值
- `(x ,@z w) => (x a b w) ; ,@z 展开列表
复制代码
典型用途:写宏(macro)时动态生成代码。
- defmacro(myWhen ([url=home.php?mod=space&uid=84690]@rest[/url] body)
- `(if ,(car body) (progn ,@(cdr body))))
复制代码
四、数据特性:SKILL 的积木块
🧱 数据类型概览
SKILL 是动态类型语言,变量无需声明类型。支持的核心类型包括:
| 类型 | Mnemonic | 说明 | | `integer` / `flonum` | `n` / `f` | 整数(32位)、浮点数 | | `string` | `t` | 字符串,最大输入长度 8191 | | `symbol` | `s` | 符号(即变量名),可存值、函数、属性 | | `list` | `l` | 链表,核心聚合结构 | | `port` | `p` | I/O 端口(如 `stdout`, `stdin`) | | `array` | `a` | 数组 | | `dbobject` | `d` | Virtuoso 数据库对象(版图/电路核心) |
注意:`nil` 既是“假”,也是“空列表”;`t` 永远为真。二者不能用作变量名!
🔢 数字:进制与缩放因子
整数表示
| 进制 | 前缀 | 示例 | | 二进制 | `0b` | `0b1010` (=10) | | 八进制 | `0` | `012` (=10) | | 十六进制 | `0x` | `0xA` (=10) |
⚠️ 整数范围:-2,147,483,647 ~ +2,147,483,647(32位有符号)
缩放因子(工程单位)
直接在数字后加单位字母,中间不能有空格:
- 10k => 10000 ; kilo
- 1.2u => 1.2e-6 ; micro
- 10G => 10000000000 ; Giga
复制代码
完整缩放因子见下表:
| 字符 | 含义 | 乘数 | | Y | Yotta | 1e24 | | Z | Zetta | 1e21 | | E | Exa | 1e18 | | P | Peta | 1e15 | | T | Tera | 1e12 | | G | Giga | 1e9 | | M | Mega | 1e6 | | k | kilo | 1e3 | | % | percent | 1e-2 | | m | milli | 1e-3 | | u | micro | 1e-6 | | n | nano | 1e-9 | | p | pico | 1e-12 | | ... | ... | ... |
🔤 字符与符号:SKILL 的原子
- 字符(Character) 在 SKILL 中用 符号(Symbol) 表示
- char = getc(instring("A")) ; 返回符号 'A
- type(char) => symbol
- printf("%c" char) => 打印 A
复制代码 - 符号名规则:
- 可含:字母、数字、`_`、`?`
- 若以数字开头,需转义:`\1`, `\2`
- 特殊字符需转义:`\!`, `\( `, `\space` 等
- 最长 255 字符
避坑:
不要给同一个符号既赋值又绑定函数(如 `x=5` 和 `procedure(x()...)`),行为未定义!
总结:关键知识点速查表
| 类别 | 关键点 | 注意事项 | | 命名 | 用户函数/变量以大写开头 | 避免与 Cadence 小写符号冲突 | | 私有函数 | 以 `_` 开头 | 禁止使用 | | 函数调用 | `f(a b)` 或 `(f a b)` | 函数名与 `(` 间无空格 | | 空格规则 | 一元 `-` 紧贴操作数;二元 `-` 两边同有或同无空格 | `- a` 非法 | | 括号 | `(x)` = 调用函数 x | 勿对变量/常量加括号 | | 注释续行 | `;\` 续行 | `\` 后紧跟代码会导致代码被注释 | | 反引号 | `` `(a ,b ,@c) `` | `,` 求值;`,@` 求值并展开列表 | | 数据类型 | 动态类型,`nil`=`false`=`()` | `t`/`nil` 不能作变量名 | | 数字缩放 | `10k`, `1.2u` | 数字与单位间无空格 | | 字符表示 | 用符号表示字符 | `getc` 返回 symbol,非 char 类型 |
|
|