
编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载Wing 是一门面向云计算的编程语言其for..in循环是处理数组、集合Set与数值区间range的统一迭代语法在 preflight基础设施定义阶段与 inflight运行时阶段中均可使用。本文以仓库中的 for_loop.test.w 编译快照 为骨架结合 tests/valid/for_loop.test.w 原始用例、语言参考文档 以及wingc编译器的类型检查与代码生成源码完整还原 Wing 循环语法的语义、边界行为并逐段解读其面向 AWStf-aws的 Terraform 部署产物与运行时 JavaScript 代码帮助你彻底理解写一段循环最终会变成什么。一、快照文件是什么hangar 测试框架的编译产物记录tools/hangar/__snapshots__/test_corpus/valid/目录下的快照文件是 Wing 官方测试框架hangar在编译/运行合法用例后自动生成的黄金文件golden snapshot。快照文件名遵循{用例名}.test.w_{编译目标}.md的约定for_loop.test.w_compile_tf-aws.md记录用例在tf-awsTerraform AWS目标下的完整编译产物同目录下的for_loop.test.w_test_sim.md记录同一用例在sim本地模拟器目标下的运行输出。以for_loop.test.w_compile_tf-aws.md为例其正文依次包含四个章节## inflight.$Closure1-1.cjs—— 闭包$Closure1即new cloud.Function(inflight () {...})的处理器的 inflight JavaScript 代码## inflight.Foo-1.cjs—— 类Foo中inflight hello()方法的 inflight JavaScript 代码## main.tf.json—— 生成的 Terraform JSON 清单描述 AWS 上要创建的全部基础设施资源## preflight.cjs—— preflight 阶段的完整 JavaScript 代码循环逻辑逐条翻译为$helpers.range(...)与for...of。这个快照是理解Wing 源码 → 编译产物映射关系的第一手材料也是本文所有分析的起点。二、Wing for..in 语言语义速览Wing 语言参考在 「2.6 for」 一节明确了循环的核心语义for..in语句用于遍历数组array、集合set或数值区间range区间默认是包含起始值、不包含结束值inclusive of the start, exclusive of the end即0..5遍历 0、1、2、3、4循环变量loop invariant隐式可重新赋值var无需也不能额外声明使用..语法表示闭区间含结束值。官方 by-example 教程 给出了最直观的入门示例// a standard for loop左闭右开区间 for item in 1..3 { log(item); // 输出 1、2 } // for-in with arrays let arr [1, 2, 3]; for item in arr { log(item); // 输出 1、2、3 } // break a loop let items Setnum[1, 2, 3]; for item in items { if item 1 { break; } log(item); } // continue the next iteration of the loop for item in 1..10 { if item % 2 0 { continue; } log(item); // 输出 1、3、5、7、9 }三、从测试用例反推完整语法语义for_loop.test.w 是本文对应快照的源程序它系统性地覆盖了for..in的绝大多数场景。逐段拆解如下。3.1 数组与集合的嵌套遍历let words [wing, lang, dang]; let uniqueNumbers Setnum[ 1, 2, 3 ]; for word in words { for number in uniqueNumbers { assert(number 0); log({word}: {number}); } }要点words是数组uniqueNumbers是Setnum两者都可用for..in直接遍历支持多层嵌套循环内层循环可引用外层循环变量如字符串插值{word}: {number}assert(number 0)与log(...)可以出现在循环体内任意位置。3.2 break提前终止内层循环let var i 0; for word in words { i i 1; let var preBreakHits 0; let var postBreakHits 0; for number in uniqueNumbers { assert(number 0); log({word}: {number}); preBreakHits preBreakHits 1; if (number 2) { break; } postBreakHits postBreakHits 1; } assert(preBreakHits 2); assert(postBreakHits 1); } assert(i 3);这段用例精确刻画了break的行为uniqueNumbers包含 1、2、3 三个元素当number 2时中断因此每个内层循环体实际执行 2 次preBreakHits 2而break之后的语句只执行 1 次postBreakHits 1外层循环完整执行 3 轮i 3。同时注意let var声明Wing 默认变量不可重新赋值循环内需要计数的变量必须用var修饰。3.3 continue跳过本轮剩余语句let var j 0; for word in words { j j 1; let var preContinueHits 0; let var postContinueHits 0; for number in uniqueNumbers { assert(number 0); log({word}: {number}); preContinueHits preContinueHits 1; if (number 0) { continue; } postContinueHits postContinueHits 1; } assert(preContinueHits 3); assert(postContinueHits 0); } assert(j 3);条件number 0恒为真所以每一轮都continuecontinue之后的语句一次都不会执行postContinueHits 0但循环体整体仍完整执行 3 次preContinueHits 3。3.4 区间range的完整边界矩阵测试用例如同一张真值表覆盖了区间在正向、反向、零长度、含端/不含端、负边界、变量与表达式边界下的全部行为Wing 写法语义实际迭代序列来自 sim 快照 stdout0..0左闭右开、起点终点无迭代theres no value to iterate0..0闭区间、起点终点00..2左闭右开0, 10..2闭区间0, 1, 22..0反向、开区间2, 12..0反向、闭区间2, 1, 00..-2反向负边界、开区间0, -10..-2反向负边界、闭区间0, -1, -2-2..0正向负起点-2, -1-2..0正向负起点、闭区间-2, -1, 00..zz2变量做边界0, 10..z变量做边界、闭区间0, 1, 2z..0变量做起始边界、反向2, 10..(z*2)表达式做边界0, 1, 2, 30..(z*2)表达式做边界、闭区间0, 1, 2, 3, 4(z*2)..0表达式做起始边界、反向4, 3, 2, 1这些断言揭示了两个关键结论Wing 的区间天然支持反向迭代——2..0会从 2 递减到 1而不是像多数语言那样产生空区间区间的起止值可以是任意数值表达式包括负数、变量z与算术表达式z*2且左右边界均支持..闭区间变体。对应的运行期证据可查看 for_loop.test.w 的 sim 运行快照其stdout.log逐行印证了上表全部序列。3.5 inflight 场景与类方法内的循环用例末尾把循环放进了云资源与类方法中bring cloud; new cloud.Function(inflight () { for x in 0..10 { assert(x 0); assert(x 10); log({x}); } }); // for loop in a class class Foo { inflight hello() { for p in [hello] { log(p); } } }说明for..in在inflight 闭包作为cloud.Function的处理器和inflight 类方法内部同样一等公民这也是快照中会出现inflight.$Closure1-1.cjs与inflight.Foo-1.cjs两份独立产物的原因。注意第 2 行死循环assert(x 0)恒假是刻意为之用于验证区间在 inflight 上下文中的编译与断言机制。四、编译器如何实现 for..inwingc 源码级拆解Wing 编译器wingc用 Rust 实现for..in从源码到 JavaScript 的旅程可分为三个环节。4.1 语法解析区分..与..在 parser.rs 的build_loop_range_expression中解析器通过语法树节点是否携带inclusive字段决定区间开闭let inclusive if expression_node.child_by_field_name(inclusive).is_some() { Some(true) } else { Some(false) }; Ok(Expr::new( ExprKind::Range { start: Box::new(self.build_expression(...)?), inclusive: inclusive, end: Box::new(self.build_expression(...)?), }, ... ))即0..2的inclusive为false0..2的inclusive为true起止点则作为普通表达式递归解析这解释了为何变量与算术表达式都能直接充当边界。AST 定义见 ast.rs 的ExprKind::Range { start, inclusive: Optionbool, end }。4.2 类型检查只有可迭代类型能进入循环在 type_check.rs 的type_check_for_loop中先对iterable做类型检查若类型不可迭代则报错Unable to iterate over {type}遍历元素类型按 iterable 的具体类型推导数组/集合取元素类型Type::Array(t) *t等Anything保留原类型循环变量以自由变量make_free_variable形式定义在新建的作用域环境中因此它在循环体内天然可读写呼应loop invariant 隐式为 var的语言参考描述。对应地仓库中的 tests/invalid/for_loop.test.w 演示了错误路径对cloud.Bucket执行for test in bucket编译器在 invalid.ts.snap 快照 中同时给出两条诊断error: Reserved word -- for_loop.test.w:5:5 error: Unable to iterate over Bucket -- for_loop.test.w:5:13第一条 Reserved word 由 parser.rs 的check_reserved_symbol触发——test是 Wing 保留字第二条则由上文类型检查产生。这组 invalid 快照恰好构成语义的反例证据。4.3 代码生成for..of $helpers.range在 jsify.rs 中StmtKind::ForLoop被翻译为标准的for...offor (const , jsify_symbol(iterator), of , self.jsify_expression(iterable, ctx), ) {而区间表达式ExprKind::Range则被翻译为对运行时助手函数的调用jsify.rsformat!({HELPERS_VAR}.range(), start, ,, end, ,, inclusive, )运行时助手位于 sdk 的 helpers.tsexport function range(start: number, end: number, inclusive: boolean) { function* iterator() { let i start; let limit inclusive ? (end start ? end - 1 : end 1) : end; while (i limit) yield i; while (i limit) yield i--; } return iterator(); }range是一个生成器函数其实现正是反向区间可行的根源inclusive false时limit end只按一个方向推进inclusive true时根据end start决定把limit向多走一步的方向调整正向end 1反向end - 1从而让闭区间同时覆盖正向与反向两种迭代方向两个while分别处理i limit递增与i limit递减两种情况互斥生效。assert助手同样定义在同文件helpers.ts断言失败时抛出assertion failed: message异常。五、逐文件解读 tf-aws 编译产物回到快照正文逐一对照编译产物中每个文件与源程序的对应关系。5.1 preflight.cjs循环逻辑的逐行直译preflight.cjs 是整体骨架其关键映射如下数组与 Set 遍历直接翻译为for (const word of words)/for (const number of uniqueNumbers)log({word}: {number})的字符串插值被编译为console.log(String.raw({ raw: [, : , ] }, word, number))——String.raw拆分静态片段与表达式正是 jsify.rs 中插值字符串的处理区间循环全部翻译为for (const x of $helpers.range(0,2,false))形式第三参即inclusive布尔值表达式边界z*2与负边界-2原样保留为表达式参数break/continue直译为 JavaScript 同名关键字因此计数断言preBreakHits 2等在产物中表现为$helpers.eq(...)调用文件末尾通过$PlatformManager.createApp(...)创建应用并调用$APP.synth()触发 Terraform 合成。5.2 inflight 文件云函数与类方法的运行时闭包inflight.$Closure1-1.cjs对应cloud.Function的处理器async handle()内是for (const x of $helpers.range(0,10,false))的循环印证区间在 inflight 闭包内直接可用inflight.Foo-1.cjs对应class Foo的inflight hello()for (const p of [hello])遍历字面量数组两个闭包都通过require(winglang/sdk/lib/helpers)获取$helpers说明运行时依赖由 SDK 提供_liftMap见 preflight.cjs 中get _liftMap()声明该闭包无需捕获任何外部变量因此两个 inflight 文件的module.exports function({ })参数列表为空。5.3 main.tf.json循环引发的 AWS 资源清单main.tf.json 展示了一次new cloud.Function(...)在 tf-aws 目标下生成的完整资源集合资源类型资源 ID作用aws_s3_bucketCode存放函数代码的 S3 桶bucket_prefix: code-c84a50b1-aws_s3_objectFunction_S3Object_C62A0C2D代码包对象source/key为占位符ASSET_SOURCE/ASSET_KEYaws_lambda_functionFunctionLambda 函数本体runtime: nodejs20.x、architectures: [arm64]、memory_size: 1024、timeout: 60aws_cloudwatch_log_groupFunction_CloudwatchLogGroup_ABDCF4C4日志组/aws/lambda/Function-c852aba6retention_in_days: 30aws_iam_roleFunction_IamRole_678BE84C假定lambda.amazonaws.com的执行角色aws_iam_role_policyFunction_IamRolePolicy_E3B26607内联策略此处为占位none:nullaws_iam_role_policy_attachmentFunction_IamRolePolicyAttachment_CACE1358附加AWSLambdaBasicExecutionRole托管策略每个资源都带有//.metadata标注path构造树中的逻辑路径如root/Default/Default/Function与uniqueId稳定唯一 ID。函数环境变量注入WING_TARGET: tf-aws与WING_FUNCTION_NAMEhandler: index.handler、publish: true说明 Wing 的cloud.Function在 AWS 上以代码入 S3 Lambda 引用的标准模式落地。注意循环本身是语言级结构不会在 Terraform 清单中产生任何额外资源——它只存在于函数/闭包的 JavaScript 实现中。六、本地运行与验证方式快照对应的运行结果可通过 Wing 自带的模拟器目标sim直接验证。参考 for_loop.test.w 的 sim 快照其stdout.log从上到下依次输出嵌套遍历的 9 行word: number、break 变体每轮 2 行与 continue 变体每轮 3 行的日志、随后是 16 段---分隔的区间迭代日志最终以pass ─ for_loop.test.wsim (no tests)结束。若想在自己的机器上复现可创建main.w并写入本文 第 2 节 的示例然后在仓库根目录执行# 本地模拟器运行wing it 为 console 本地运行命令 wing it # 编译到 tf-aws 目标并查看生成的 Terraform 清单 wing compile -t tf-aws main.w要重新生成或校验官方快照可运行 hangar 测试框架tools/hangar其测试入口位于 generated_test_targets.tstest_corpus快照即由 hangar 对 tests/valid 下全部用例编译/测试后落盘而成。七、小结一张图理解 for..in 的全链路从语言语义到云资源for..in的完整链路可以概括为编写对数组、Set 或区间..开 /..闭使用for..in循环变量隐式为var支持break/continue、嵌套与反向区间编译parser.rs 解析出ExprKind::Range→ type_check.rs 校验 iterable 可迭代并推导元素类型 → jsify.rs 生成for...of与$helpers.range(start, end, inclusive)运行helpers.ts 的生成器range根据inclusive与方向决定迭代序列assert负责运行时断言部署若循环出现在cloud.Function处理器中则连同函数一起编译为 Lambda 闭包并在 main.tf.json 中生成完整的 AWS 资源清单。整个过程的每一步都有仓库快照与源码作为证据想要深入调试或贡献可以从 tests/valid/for_loop.test.w 与 tools/hangar/snapshots/test_corpus/valid/ 这对源码—快照组合入手对照 wingc 与 sdk helpers 逐行验证。赞分享编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载相关推荐Wing 语言 util.sleep 延迟执行解析从 inflight 语义到 tf-aws 编译产物快照验证Wing 语言 util.sleep 延迟执行解析从 inflight 语义到 tf aws 编译产物快照验证 util.sleep 是 Wing 标准库中唯编程语言编译器云原生语言运行时深入解析 Wing math.sign() 与 Hangar 快照测试从 SDK 源码、tf-aws 编译产物到模拟器验证深入解析 Wing math.sign 与 Hangar 快照测试从 SDK 源码、tf aws 编译产物到模拟器验证 本篇技术指南以 Wing 仓库中 si编程语言编译器云原生语言运行时深入解读 Wing 语言 math.toRadix 的 tf-aws 编译快照从 API 用法到 Hangar 快照测试机制深入解读 Wing 语言 math.toRadix 的 tf aws 编译快照从 API 用法到 Hangar 快照测试机制 本文以仓库快照文档 toradi编程语言编译器云原生语言运行时上一篇终极D2DX补丁指南三步让你的暗黑破坏神2在现代PC上完美重生下一篇英雄联盟Akari助手免费开源游戏效率工具完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考