javascript - 如何在 sweet.js 中创建参数化中缀宏

标签 javascript macros infix-notation sweet.js

bluebird wiki article about JavaScript optimization killers ,作者提到将 arguments 关键字传递给任何函数(apply 除外)都会导致父函数不可优化。我想创建一个sweet.js宏允许我编写标准惯用的 JavaScript,但会处理优化 killer 。

理想情况下,我想要一个具有以下功能的宏:

function foo() {
    var args = [].slice.call(arguments);
    return args;
}

并输出如下内容:

function foo() {
    var args = [];
    for(var i, len = arguments.length; i < len; i++) {
        args.push(arguments[i]);
    }
    return args;
}

但是,我无法正确获取 sweet.js 宏语法。 This is what I have so far :

示例.sjs

let arguments = macro {
    rule infix {
         [].slice.call | 
    } => {
        [];
        for(var i = 0, len = arguments.length; i < len; i++) {
            args.push(arguments[i])
        }
    }
}

function toArray() {
    var args = [].slice.call  arguments
    return args;
}

输出如下:

function toArray() {
    var args$2 = [];
    for (var i = 0, len = arguments.length; i < len; i++) {
        args.push(arguments[i]);
    }
    return args$2;
}

我尝试让我的宏在 arguments 关键字周围加上括号,并包含 var 声明,但没有成功。我尝试过这样的事情:

无效的宏

let arguments = macro {
    rule infix {
        var $var = [].slice.call ( | ) 
    } => {
        var $var = [];
        for(var i = 0, len = arguments.length; i < len; i++) {
            args.push(arguments[i])
        }
    }
}

这会产生以下错误:

SyntaxError: [syntaxCase] Infix macros require a `|` separator
414: 
                                ^

最佳答案

是的,有几种方法可以做到这一点。提出论点 括号内部不起作用,因为中缀宏无法与外部匹配 包含分隔符,因此当 arguments 宏被调用时 在它之前或之后看到零个标记(错误应该更清楚)。

您的另一个解决方案遇到了卫生问题,因为 arguments 宏需要访问 args 标识符,但需要中缀 当宏位于等号之前时不允许匹配 var 语句,因此它实际上无法匹配 args 标识符。

有几个解决方案。最简单的就是做类似的事情 bluebird 维基建议:

macro argify {
    rule { ( $arg ) } => {
    var $arg;
    for (var i, len = arguments.length; i < len; i++) {
        args.push(arguments[i]);
    }
    }
}

function foo() {
    argify(args)
    return args;
}

你也可以走不卫生的路线(不真正推荐,但 arguments 已经有点不卫生了,所以……):

let function = macro {
    case {$mname $name ( $parens ...) { $body ... } } => {
    letstx $args = [makeIdent("args", #{$mname})];
    return #{
        function $name ( $parens ...) {
        var $args = [];
        for (var i, len = arguments.length; i < len; i++) {
            $args.push(arguments[i]);
        }
        $body ...
        }
    }
    }
}

function foo() {
    return args;
}

编辑:

我只是想到了另一种解决方案,它允许您通过覆盖 var 来保留当前语法:

let var = macro {
    rule { $args = [].slice.call(arguments) } => {
        var $args = [];
        for(var i, len = arguments.length; i < len; i++) {
            $args.push(arguments[i]);
        }
    }
    rule { $rest ... } => { var $rest ... }
}

function foo() {
    var args = [].slice.call(arguments);
}

关于javascript - 如何在 sweet.js 中创建参数化中缀宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26555614/

相关文章:

java - 使用堆栈(LinkedList)将中缀转换为前缀

javascript - map API v3 : Calculate bearing

javascript - 如何将对象从另一个文件实例化到另一个文件 - javascript

c++ - putc 在 C++ 中实现为宏?

c - #定义 int16_t 类型的东西

postfix-notation - 如何检查给定表达式是中缀表达式、后缀表达式还是前缀表达式?

java - 使用ADT的Postfix的双链接双栈Java

javascript - 在一个语句中声明具有属性的函数?

javascript - 2的补码校验和

vim - 如何防止或替换粘贴的 Vim 宏中的奇怪字符