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 computed 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?
Not really.
It's not working because in JavaScript,
switch
statements must only containcase
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 aswitch
statement inside it.In order to simulate a goto, one would use
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
anddo...while()
and adding adefault
case and a control variable: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.