最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

loop unrolling - Porting duff's device from C to JavaScript - Stack Overflow

programmeradmin5浏览0评论

I have this kind of Duff's device in C and it works fine (format text as money):

#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;
}

Output:

1,234,567,890,123

But I have problems trying to implement the same in 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 this error:

        do {
        ^^
SyntaxError: Unexpected token do

My question is: Does javascript supports puted GOTO statements?

P.D: I don't want an alternative, I just want to know why is not working.

Related question: Does Duff's Device work in other languages?

I have this kind of Duff's device in C and it works fine (format text as money):

#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;
}

Output:

1,234,567,890,123

But I have problems trying to implement the same in 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 this error:

        do {
        ^^
SyntaxError: Unexpected token do

My question is: Does javascript supports puted GOTO statements?

P.D: I don't want an alternative, I just want to know why is not working.

Related question: Does Duff's Device work in other languages?

Share Improve this question edited May 23, 2017 at 12:23 CommunityBot 11 silver badge asked May 3, 2016 at 22:44 David RanieriDavid Ranieri 41.1k8 gold badges57 silver badges102 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 8

My question is: Does javascript supports puted GOTO statements?

Not really.

P.D: I don't want an alternative, I just want to know why is not working.

It's not working because in JavaScript, switch statements must only contain case blocks.

And although you might not be looking for a workaround, someone else might find this question in search of one, so I'll provide one regardless.
Credit for this one goes to mnieper who suggested it at asm.js.

The basic idea is to have a while(true) loop at the top level, and a switch statement inside it.

goto:
while(true)
{
    switch(where)
    {
        // no breaks
        case 0:
            // some code...
        case 1:
            // some other code...
        // ...
    }
}

In order to simulate a goto, one would use

where = 1;
continue goto;

In order to simulate duff's device though, one would only have to make the loop the outer structure, and use a variable in the switch statement that after the first iteration is set to a value that will trigger the switch statement to start at its very first case.

So in your case, that would mean exchanging switch and do...while() and adding a default case and a control variable:

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]);

The one huge drawback of this method in general, is of course that it will not work across callbacks, which are used just about everywhere in JavaScript.
As long as it is used in a single, sequential context though, it should work.

For more information, see the ticket posted on the asm.js repo.

JavaScript switch statements don't work like that.

switch (expr) {
  case expr:
    statements;
    break;
  case expr:
    statements;
    break;
  default:
    statements;
    break;
}

But JavaScript does offer labels to control your loops

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;
    }
发布评论

评论列表(0)

  1. 暂无评论