编程语言语言运行时编译器【免费下载链接】wrenThe Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.项目地址https://gitcode.com/gh_mirrors/wr/wren点击查看免费下载本文以 Wren 官方文档 values.markdown 为骨架系统讲解 Wren 中五种内置原子值类型——Bool、Num、String、Range与Null——的字面量语法、逃逸与插值规则、区间运算等核心知识点并结合src/vm/wren_compiler.c的词法分析与src/vm/wren_core.c、src/vm/wren_core.wren的核心类实现从源码层面印证每种字面量是如何被解析与构造的。读完本文你将能熟练写出正确的 Wren 字面量表达式理解转义、插值与原始字符串的确切行为并掌握区间在迭代、列表切片与字符串切片中的实战用法。Wren 是一门小巧、快速、基于类的并发脚本语言。在 Wren 中值value是所有其他对象由之组合而成的内置原子对象类型它们可以通过字面量literal——即求值为某个值的表达式——直接创建。一个关键特性是所有值都是不可变的immutable——一旦创建便不会改变。数字3永远是数字3字符串frozen的字符数组也永远无法被原地修改。这种不可变性让值可以安全地在 Fiber 之间共享是 Wren 并发模型见 concurrency.markdown的重要基础。布尔值Bool布尔值boolean表示真或假。Wren 只有两个布尔字面量true与false它们对应Bool类。在 wren_core.wren 中Bool被声明为一个空的核心类class Bool {} class Fiber {} class Fn {} class Null {} class Num {}从词法分析器看true与false是 Wren 的关键字而非普通标识符在 wren_compiler.c 的关键字表中可以找到{true, 4, TOKEN_TRUE}与{false, 5, TOKEN_FALSE}两项编译期前缀解析函数 boolean() 会根据 token 类型直接发射CODE_TRUE或CODE_FALSE字节码。布尔值在条件判断if、while中扮演核心角色相关用法参见 control-flow.markdown。数字Num与其他脚本语言类似Wren 只提供一种数字类型双精度浮点数double-precision floating point。数字字面量的写法与主流语言一致0 1234 -5678 3.14159 1.0 -12.34 0.0314159e02 0.0314159e02 314.159e-02 0xcaffe2其中整数与小数直接书写即可1.0与1在内部都是同一个双精度浮点值支持科学计数法指数部分可带符号e02、e02、e-02支持十六进制字面量以0x开头的数字按十六进制解析0xcaffe2即十进制13313506。数字字面量的底层解析在词法分析器 wren_compiler.c 中当读到字符0并紧跟x时会调用readHexNumber()进入十六进制分支否则走普通十进制数字扫描。十六进制解析逻辑位于 readHexNumber()跳过x后循环调用readHexDigit()接受0-9、a-f、A-F非法字符返回-1收集所有十六进制位最后由makeNumber()完成数值转换。这意味着0x后面必须是合法的十六进制数字否则会触发编译错误。数字对应Num类Num提供了、-、*、/、%、比较、位运算以及min、max、clamp、sqrt、pow等一整套方法is判断、toString格式化等能力详见 modules/core/num.markdown。字符串String字符串是字节数组array of bytes。通常它们存储按 UTF-8 编码的字符但你可以放入任意字节值——包括零字节或非法 UTF-8 序列不过要把后者打印到终端上可能会有点麻烦。字符串字面量用双引号包围hi there字符串也可以跨越多行。跨行时字符串内的换行符一律归一化为\n\r\n会被规范化成\nhi there, again在 readString() 的实现中可以看到扫描普通字符串时遇到\r会直接continue跳过从而保证源码中的回车符不会进入字符串内容同时若遇到文件结束符\0而仍未闭合引号会报 Unterminated string. 编译错误。转义字符EscapingWren 支持一小组转义序列\0 // NUL 字节0 \ // 双引号 \\ // 反斜杠 \% // 百分号 \a // 响铃谁会用它 \b // 退格 \e // ESC 字符 \f // 换页 \n // 换行 \r // 回车 \t // 制表符 \v // 垂直制表符 \x48 // 未编码字节 2 位十六进制 \u0041 // Unicode 码点 4 位十六进制 \U0001F64A // Unicode 码点 8 位十六进制其中十六进制与 Unicode 转义的使用规则如下\x后跟2 位十六进制数字指定一个未编码的原始字节System.print(\x48\x69\x2e) // Hi.\u后跟4 位十六进制数字指定一个 Unicode 码点System.print(\u0041\u0b83\u00DE) // AஃÞ大写\U后跟8 位十六进制数字可以表示基本多文种平面BMP之外的码点比如至关重要的 emojiSystem.print(\U0001F64A\U0001F680) // 测试文件 test/language/string/unicode_escapes.wren 正是对这些转义行为的回归验证。转义的源码实现转义处理同样位于词法分析器 readString() 中遇到\后读取下一个字符并进入switch按字符写入对应字节如\n写入\n、\e写入\33遇到无法识别的转义字符则报 Invalid escape character 编译错误。\x分支调用readHexEscape(parser, 2, byte)其中 readHexEscape() 读取固定位数的十六进制位并累加为数值若位数不足或出现非法十六进制字符会分别报 Incomplete byte escape sequence. 或 Invalid byte escape sequence.。\u与\U分支调用 readUnicodeEscape()先读取 4 位或 8 位十六进制数得到码点再通过wrenUtf8EncodeNumBytes()计算该码点需要的 UTF-8 字节数并用wrenUtf8Encode()将其编码进字符串缓冲区——这正是\U0001F64A能被正确编码为 4 字节 UTF-8 序列、最终打印出 的原因。插值Interpolation字符串字面量还支持插值interpolation如果出现百分号%后跟一个带括号的表达式该表达式会被求值结果对象的toString方法被调用然后插入到字符串中System.print(Math %(3 4 * 5) is fun!) // Math 23 is fun!括号内允许任意复杂的表达式System.print(wow %((1..3).map {|n| n * n}.join())) // wow 149插值表达式甚至可以包含字符串字面量而后者又包含自己的嵌套插值——只不过这样写很快就会变得难以阅读。嵌套限制在 wren_compiler.c 中定义了#define MAX_INTERPOLATION_NESTING 8即插值最多只能嵌套 8 层。词法分析器在 readString() 中遇到%时会检查嵌套深度超过 8 层会报 Interpolation may only nest 8 levels deep. 编译错误同时要求%后必须紧跟(否则报 Expect ( after %.。从编译流程看插值字符串会被切分成多个 tokenTOKEN_INTERPOLATION表示插值表达式前的字符串部分TOKEN_STRING表示最后一段纯字符串。编译期函数 stringInterpolation() 会为每一段调用addCore_(_)方法将各个片段拼接为最终的字符串常量。原始字符串Raw strings字符串字面量还可以用三引号创建解析为原始字符串raw string。原始字符串与其他字符串没有本质区别只是解析方式不同原始字符串不处理转义也不应用任何插值。hi there当原始字符串跨越多行、且三引号独占一行时该行上的任何空白都会被忽略。也就是说只要开闭引号行只包含空白空格 制表符它们就不会被计入字符串内容。例如 Hello world 上面代码得到的字符串没有换行符或尾部空白——注意Hello前面的空格会被保留Hello world原始字符串在文件中会被原样解析不做任何修改。这意味着它可以包含引号、非法语法、其他数据格式等Wren 都不会去动它 { hello: wren, from : json } 再举一个例子——安全地把 Wren 代码嵌入字符串 A markdown string with embedded wren code example. class Example { construct code() { // } } 原始字符串的源码实现原始字符串的解析由独立的 readRawString() 完成函数先消费开头的两个第一个已由调用方读取随后持续扫描直到遇到连续的扫描过程中遇到\r直接跳过与普通字符串一致关键逻辑在于空白裁剪skipStart记录开头可跳过的空白起点skipEnd记录结尾可跳过的空白终点只有当三引号所在行只含空白时开头的firstNewline与结尾的lastNewline才会触发裁剪。最终offset与count计算后wrenNewStringLength()生成去掉首尾空白行的字符串若到文件结束仍未找到闭合的会报 Unterminated raw string. 编译错误。测试 test/language/string/literals.wren 覆盖了大量边界情形例如 A raw string保留前导空格、A raw string 保留尾部空格、三引号行带缩进或带尾随空格时均不影响内容、newline after\n与\nnewline before的换行裁剪等。区间Range区间range是一个表示连续数字范围的小对象。它没有专属的字面量语法而是由数字类实现的..与...运算符operators创建3..8这会创建从 3 到 8 的区间包含 8 本身。如果想要半开区间使用...4...6这会创建从 4 到 6、不包含 6的区间。区间的底层实现与实战用途在 wren_core.c 中num_dotDot与num_dotDotDot两个内建原语分别调用wrenNewRange(vm, from, to, true/false)创建区间对象isInclusive布尔值区分闭区间与半开区间右操作数若非数字则报 Right hand side of range 类型错误。区间对象还提供from、to、min、max、isInclusive等访问器见 wren_core.c 附近的range_from、range_to、range_min、range_max并在 wren_core.wren 中声明class Range is Sequence {}使其天然具备Sequence的map、where、reduce、toList等全部方法。区间最常见的用途是迭代数字序列for循环语法见 control-flow.markdown但它在其他场景也很有用。例如把区间传给列表的下标运算符可以取出子列表传给字符串则可以取出子串var list [a, b, c, d, e] var slice list[1..3] System.print(slice) // [b, c, d] var string hello wren var wren string[-4..-1] System.print(wren) // wren注意字符串切片中使用了负索引-4..-1从字符串末尾倒数取子串得到wren。列表与字符串的下标实现均接受数字或区间在 wren_core.c 中列表的subscript原语会检查下标参数若非数字或区间则报 Subscript must be a number or a range.随后通过calculateRange()把闭/半开区间换算为实际的起始位置与元素个数。空值NullWren 有一个特殊值null它是Null类唯一的实例注意大小写区别值是小写null类是大写Null。它的作用有点像其他语言中的void表示值的缺失。如果你调用一个不返回任何内容的方法并获取其返回值得到的就是null。var result someMethodThatReturnsNothing() System.print(result) // null在核心类声明 wren_core.wren 中Null与Bool、Num等并列定义。null常与/!配合做存在性判断其完整 API!取反、、toString等见 modules/core/null.markdown。小结值类型字面量示例对应类不可变性布尔true、falseBool是数字0、3.14、1e-2、0xcaffe2Num是字符串hi、rawString是区间3..8、4...6运算符创建Range是空值nullNull是这五种值类型构成了 Wren 中所有复合对象列表、映射、类实例等的原子构件。理解它们的字面量语法与不可变语义是编写正确、健壮的 Wren 代码的第一步而词法分析器 wren_compiler.c 与核心运行时 wren_core.c、wren_core.wren 中的实现细节则为你提供了从语言规范到虚拟机行为的完整闭环。下一步可以继续阅读列表与映射了解这些值是如何被组织成复合数据结构的。赞分享编程语言语言运行时编译器【免费下载链接】wrenThe Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.项目地址https://gitcode.com/gh_mirrors/wr/wren点击查看免费下载相关推荐PRQL 字面量Literals完全指南数字、字符串、布尔、Null 与日期时间语法详解PRQL 字面量Literals完全指南数字、字符串、布尔、Null 与日期时间语法详解 字面量Literal是 PRQL 中表示常量值的表达式每种后端TypeSpec 字面量类型完全指南字符串、多行字符串、模板字面量与数值/布尔字面量TypeSpec 字面量类型完全指南字符串、多行字符串、模板字面量与数值/布尔字面量 在设计 API 时我们经常需要把接口结构定义成具体的字面量值——例如某编程语言编译器后端Slang 字面量表达式完全指南布尔、整数、浮点、字符串与字符字面量的语法与类型推断Slang 字面量表达式完全指南布尔、整数、浮点、字符串与字符字面量的语法与类型推断 字面量表达式Literal Expressions是 Slang 语编译器图形学编程语言上一篇完整指南免费开源霞鹜文楷字体在三大系统的终极安装方案下一篇5个实用技巧如何定制Yarn Spinner for Unity编辑器提升对话开发效率创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考