Sweet.js 教程 2 递归宏以及自定义模式类

本文是 Sweet.js 教程的第二部分,探讨了如何创建复杂的宏,包括递归宏和自定义模式类。通过实例展示了如何实现 ES6 非结构化赋值的宏,详细解释了递归宏的工作原理和自定义模式类的使用方法,以提高宏的灵活性和可读性。
摘要由CSDN通过智能技术生成

from http://jlongster.com/Sweet.js-Tutorial--2--Recursive-Macros-and-Custom-Pattern-Classes

在第一篇教程 http://jlongster.com/Writing-Your-First-Sweet.js-Macro 翻译 http://segmentfault.com/blog/tcdona/1190000002490290 。我们讲到基本的一些 sweet.js 概念。现在我们来看一些技术,来创建更复杂的宏:递归和自定义模式类。

所有的这些教程在 repo sweet.js-tutorials https://github.com/jlongster/sweet.js-tutorials 包含了可以编译的 sweet.js 宏工作环境。

让我们创建一个 es6 非结构化变量 http://wiki.ecmascript.org/doku.php?id=harmony:destructuring 赋值特性宏。开始应该这样:

let var = macro {
  rule { [$var (,) ...] = $obj:expr } => {
    var i = 0;
    var arr = $obj;
    $(var $var = arr[i++]) (;) ...
  }

  rule { $id } => {
    var $id
  }
}

var [foo, bar, baz] = arr;
var i = 0;
var arr$2 = arr;
var foo = arr$2[i++];
var bar = arr$2[i++];
var baz = arr$2[i++];

这仅仅处理了基础的简单数组。我们把目标对象分配给 arr 确保表达式只执行了一次。 es6 非结构化变量赋值,处理了很多复杂的情况。

  • 对象/哈希: var {foo, bar} = obj;
  • 默认值: var [foo, bar=5] = arr;
  • 重命名: var {foo: myFoo} = obj;
  • 混合的解构: var {foo, bar: [x, y]} = obj;

你可以用学到的所有概念,把上面的宏写出来,但是当你尝试支持更缤纷的语法时,你可能被卡住。现在我们来看看一些技术来处理更复杂的情况。

递归宏

我在前一篇教程小提过递归宏,它们指的更深入的研究,以用来解决实际问题。

宏的输出总是被 sweet.js 再次展开,所以写递归宏和写递归函数是一样自然的。只要一个规则 rule 再次调用宏,然后其他的规则匹配了这个暂停的情况,并且停止本次展开。

一个普通的递归宏用例是处理一组不统一的语法。通常用重复格式 $item (,) ...匹配一组语法,用组 $($item = $arr[$i]) ... 甚至可以匹配复杂的。问题是每个组中的元素必须是同样的结构。你不能匹配语法类型不同的组。 sweet.js 没有类似正则重的或 | 操作符,或者可选择的 ? 符号。

例如,我们想匹配一组名字,可能含有初始化赋值语句: x, y, z=5, w=6。 我们想迭代 items 并形成不同的代码如果初始化赋值语句存在的话。来看用递归宏怎么做:

macro define {
  rule { , $item = $init:expr $rest ... ; } => {
    var $item = $init;
    define $rest ... ;
  }

  rule { , $item $rest ... ; } => {
    var $item;
    define $rest ... ;
  }

  rule { ; } => { ; }

  rule { $items ... ; } => {
    define , $items ... ;
  }
}

define x, y, z=5, w=6;
var x;
var y;
var z = 5;
var w = 6;
;

当使用了递归宏,你需要考虑到边缘的情况,比如后面的逗号。因为我们匹配的是逗号分割的组,我们需要剥开逗号,但是我们不能一直有逗号,因为最后的元素没有。我们解决这个问题依靠在组的开头加一个逗号,然后当迭代器穿过这个组的时候剥开逗号。因为初始的调用不会有逗号在前面,所以会匹配到最后一个规则,添加逗号并且递归调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值