将 duff 的设备从 C 移植到 JavaScript
Porting duff's device from C to JavaScript
我在 C 中有这种 Duff 的设备,它工作正常(将文本格式设置为货币):
#include <stdio.h>
#include <string.h>
char *money(const char *src, char *dst)
{
const char *p = src;
char *q = dst;
size_t len;
len = strlen(src);
switch (len % 3) {
do {
*q++ = ',';
case 0: *q++ = *p++;
case 2: *q++ = *p++;
case 1: *q++ = *p++;
} while (*p);
}
*q++ = 0;
return dst;
}
int main(void)
{
char str[] = "1234567890123";
char res[32];
printf("%s\n", money(str, res));
return 0;
}
输出:
1,234,567,890,123
但是我在 Javascript 中尝试实现相同的方法时遇到了问题:
function money(src, dst) {
var len = src.length;
var i = 0;
switch (len % 3) {
do {
dst += ',';
case 0: dst += src[i++];
case 2: dst += src[i++];
case 1: dst += src[i++];
} while (src[i]);
}
return dst;
}
var str = "1234567890123";
var res = "";
console.log(money(str, res));
nodejs returns 这个错误:
do {
^^
SyntaxError: Unexpected token do
我的问题是:javascript 是否支持计算 GOTO 语句?
P.D:我不想要替代方案,我只想知道为什么不起作用。
相关问题:Does Duff's Device work in other languages?
JavaScript switch
语句不是那样工作的。
switch (expr) {
case expr:
statements;
break;
case expr:
statements;
break;
default:
statements;
break;
}
但是 JavaScript 确实提供 labels 来控制您的循环
Example from MDN
var itemsPassed = 0;
var i, j;
top:
for (i = 0; i < items.length; i++){
for (j = 0; j < tests.length; j++) {
if (!tests[j].pass(items[i])) {
continue top;
}
}
itemsPassed++;
}
Another example from MDN
var allPass = true;
var i, j;
top:
for (i = 0; items.length; i++)
for (j = 0; j < tests.length; i++)
if (!tests[j].pass(items[i])){
allPass = false;
break top;
}
My question is: Does javascript supports computed GOTO statements?
不是真的。
P.D: I don't want an alternative, I just want to know why is not working.
它不起作用,因为在 JavaScript、switch
statements must only contain case
blocks。
虽然 你 可能不在寻找解决方法,但 其他人 可能会找到这个问题来寻找解决方法,所以我'无论如何都会提供一个。
此功劳归功于 mnieper who suggested it at asm.js.
基本思路是在顶层有一个 while(true)
循环,里面有一个 switch
语句。
goto:
while(true)
{
switch(where)
{
// no breaks
case 0:
// some code...
case 1:
// some other code...
// ...
}
}
为了模拟 goto,可以使用
where = 1;
continue goto;
为了模拟 duff 的设备,只需将循环作为外部结构,并在 switch 语句中使用一个变量,该变量在第一次迭代后设置为将触发 switch 语句的值从第一个案例开始。
所以在你的情况下,这意味着交换 switch
和 do...while()
并添加一个 default
案例和一个控制变量:
var where = len % 3;
do {
switch (where) {
default: dst += ',';
case 0: dst += src[i++];
case 2: dst += src[i++];
case 1: dst += src[i++];
}
where = -1;
} while (src[i]);
一般来说,这种方法的一个巨大缺点当然是它不能跨回调工作,回调在 JavaScript.
中几乎无处不在。
不过,只要它在单个顺序上下文中使用,它就应该可以工作。
有关详细信息,请参阅 the ticket posted on the asm.js repo。
我在 C 中有这种 Duff 的设备,它工作正常(将文本格式设置为货币):
#include <stdio.h>
#include <string.h>
char *money(const char *src, char *dst)
{
const char *p = src;
char *q = dst;
size_t len;
len = strlen(src);
switch (len % 3) {
do {
*q++ = ',';
case 0: *q++ = *p++;
case 2: *q++ = *p++;
case 1: *q++ = *p++;
} while (*p);
}
*q++ = 0;
return dst;
}
int main(void)
{
char str[] = "1234567890123";
char res[32];
printf("%s\n", money(str, res));
return 0;
}
输出:
1,234,567,890,123
但是我在 Javascript 中尝试实现相同的方法时遇到了问题:
function money(src, dst) {
var len = src.length;
var i = 0;
switch (len % 3) {
do {
dst += ',';
case 0: dst += src[i++];
case 2: dst += src[i++];
case 1: dst += src[i++];
} while (src[i]);
}
return dst;
}
var str = "1234567890123";
var res = "";
console.log(money(str, res));
nodejs returns 这个错误:
do {
^^
SyntaxError: Unexpected token do
我的问题是:javascript 是否支持计算 GOTO 语句?
P.D:我不想要替代方案,我只想知道为什么不起作用。
相关问题:Does Duff's Device work in other languages?
JavaScript switch
语句不是那样工作的。
switch (expr) {
case expr:
statements;
break;
case expr:
statements;
break;
default:
statements;
break;
}
但是 JavaScript 确实提供 labels 来控制您的循环
Example from MDN
var itemsPassed = 0;
var i, j;
top:
for (i = 0; i < items.length; i++){
for (j = 0; j < tests.length; j++) {
if (!tests[j].pass(items[i])) {
continue top;
}
}
itemsPassed++;
}
Another example from MDN
var allPass = true;
var i, j;
top:
for (i = 0; items.length; i++)
for (j = 0; j < tests.length; i++)
if (!tests[j].pass(items[i])){
allPass = false;
break top;
}
My question is: Does javascript supports computed GOTO statements?
不是真的。
P.D: I don't want an alternative, I just want to know why is not working.
它不起作用,因为在 JavaScript、switch
statements must only contain case
blocks。
虽然 你 可能不在寻找解决方法,但 其他人 可能会找到这个问题来寻找解决方法,所以我'无论如何都会提供一个。
此功劳归功于 mnieper who suggested it at asm.js.
基本思路是在顶层有一个 while(true)
循环,里面有一个 switch
语句。
goto:
while(true)
{
switch(where)
{
// no breaks
case 0:
// some code...
case 1:
// some other code...
// ...
}
}
为了模拟 goto,可以使用
where = 1;
continue goto;
为了模拟 duff 的设备,只需将循环作为外部结构,并在 switch 语句中使用一个变量,该变量在第一次迭代后设置为将触发 switch 语句的值从第一个案例开始。
所以在你的情况下,这意味着交换 switch
和 do...while()
并添加一个 default
案例和一个控制变量:
var where = len % 3;
do {
switch (where) {
default: dst += ',';
case 0: dst += src[i++];
case 2: dst += src[i++];
case 1: dst += src[i++];
}
where = -1;
} while (src[i]);
一般来说,这种方法的一个巨大缺点当然是它不能跨回调工作,回调在 JavaScript.
中几乎无处不在。
不过,只要它在单个顺序上下文中使用,它就应该可以工作。
有关详细信息,请参阅 the ticket posted on the asm.js repo。