╔═══════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ Paper6 编程语言 v6.0 ║ ║ ║ ║ 格言:最简单的动态,最片面的全面,最可开发的 ║ ║ ║ ║ 让 Win32 编程像在纸上画一样简单 ║ ║ ║ ╚═══════════════════════════════════════════════════════════════════════════════╝ ═══════════════════════════════════════════════════════════════════════════════ 第四章:表达式 ═══════════════════════════════════════════════════════════════════════════════ Paper6 表达式按优先级从低到高排列如下(同一行优先级相同): 4.1 赋值表达式 x = 10 ——普通赋值 nums.all = 1 ——批量赋值(所有元素赋为 1) labels.all.text = "Hi" ——批量属性赋值 vec.all = this + 1 ——基于当前元素赋值 vec.all.show() ——批量方法调用 批量操作 .all:将 .all 标记为循环起点,后续表达式逐元素执行。 展开为:for (int i = 0; i < arr.size(); i++) arr[i] = expr; 关键字替换(仅在 .all 上下文内合法): this → 当前元素(arr[i]) index → 当前索引(i) serial → 当前索引+1(i+1) .all 规则: · .all 是循环构造,不能做右值(右侧出现 .all 直接报错) · 右侧表达式可以是任意合法表达式(标量、函数调用、数组索引等) · 右侧表达式类型需与元素类型匹配,否则报错 · this/serial/index 在非 .all 上下文中使用报错 · 空数组的 .all 操作正常,不执行任何操作 · 对 const 容器执行 .all 赋值报错 · 列表推导式可作为右值,但赋给 .all 时类型需匹配元素类型 示例: nums.all = 1 → for(int i=0;i b 大于 a <= b 小于等于 a >= b 大于等于 4.5 算术运算 a + b 加(数值相加或字符串拼接) a - b 减 a * b 乘 a / b 除(整数除法或浮点除法,取决于操作数类型) a % b 取模 4.6 范围运算符 a .. b 区间:产生从 a 到 b 的整数序列 [1..5] → {1, 2, 3, 4, 5} [1..10, 2] → {1, 3, 5, 7, 9}(步长为 2) 4.7 一元运算 -a 取负 !a 逻辑取反 4.8 成员访问与索引 obj.name 对象属性访问 arr[0] 容器下标访问 obj.method() 方法调用 vec[index] 带索引的元素访问(index 为整数) 支持链式访问:data.items[0].name 4.9 函数调用 alert("hello") ——Win32 消息框 len(s) ——标准库函数 obj.method(args) ——对象方法 ClassName{field=val} ——对象构造表达式 4.10 类型判断 is(x, int) ——判断 x 的类型名是否为 "int" is(x, Student) ——判断 x 是否为 Student 类的实例 is(x, class) ——判断 x 是否为某个类实例 4.11 编译期查询 therebe(class Student) ——编译期:Student 类是否存在? therebe(function foo) ——编译期:函数 foo 是否已定义? have(Student, .name) ——编译期:Student 类是否有 name 字段或方法? 这三个表达式在编译时求值,结果直接替换为 true/false。 4.12 三元表达式 cond ? a : b x > 0 ? "正数" : "负数" 4.13 when 编译期类型分支 when (x) { is int -> 1; is string -> 2; else -> 0; } 根据 x 的 typeName 在不同分支中选择表达式,最终返回一个 Value。 4.14 字面量表达式 100 整数字面量 3.14 浮点数字面量 "hello" 字符串字面量 #FF0000 颜色字面量 true / false 布尔字面量 null 空值字面量 4.15 数组字面量 {1, 2, 3} ——普通数组 {"a", "b", "c"} ——字符串数组 {key: "value"} ——映射字面量 ═══════════════════════════════════════════════════════════════════════════════ 第十二章:常见问题 ═══════════════════════════════════════════════════════════════════════════════ Q: 编译时提示 "file not found"? A: 确保 .paper 文件路径正确,或使用相对于 paper6c.exe 的路径。 Q: 中文显示乱码? A: Paper6 自动处理 UTF-8 → GBK 转换。检查 .paper 文件是否保存为 UTF-8 编码。 Q: 如何嵌入图标? A: 将 .ico 文件放入项目目录,在 paper 块中指定 icon = "icon/Paper6.ico"; Q: 标准库函数在哪里? A: pslib/ 目录下,每个 .pslib 文件对应一个功能模块。 Q: value 和 int 有什么区别? A: value 是动态类型,运行时根据 typeName 决定含义;int 在编译时确定为整数类型。 相同计算结果,int 执行效率更高,value 灵活性更强。 Q: .all 批量操作失败? A: 确保操作对象是容器类型(array/container),且右侧表达式能作用于单个元素。 例如:nums.all = this * 2,this 代表当前元素 nums[i],展开为逐元素乘以 2。 右侧出现 .all 会报错(.all 不能做右值)。 this/serial/index 只能在 .all 语句内使用。 Q: 范围过滤函数 [a..b, func()] 怎么用? A: func 接收每个元素作为参数,返回布尔值(或可转为布尔的值)。 结果为真的元素保留,结果为假的元素过滤掉。 注意:func 必须已定义,否则编译报错。 Q: 为什么 vec.all = [x*x for x in [1..10]] 报错? A: 右侧列表推导式返回数组,而 .all 要求右侧表达式结果与元素类型匹配。 如需整体赋值,用 vec = [x*x for x in [1..10]](不带 .all)。 ═══════════════════════════════════════════════════════════════════════════════ 格言 ═══════════════════════════════════════════════════════════════════════════════ 最简单的动态,最片面的全面,最可开发的 让 Win32 编程像在纸上画一样简单 ═══════════════════════════════════════════════════════════════════════════════