WinDbg, 449 388 bytes
as, }@$t1
as. }0;?@$t0
asThink n10;ed8<<22;r$t0=dwo(8<<22);r$t1=0;.do{
aSa " "
asQ .printf";r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0
as/c add Q +"
aSby " "
as/c divide Q /"
asfrom 0;r$t0=-@$t0+
as/c multiply Q *"
aSnumber " "
aSof " "
asrepeat +1
as/c subtract Q -"
.for(r$t9=1;by(@$t0);r$t0=@$t0+1){j44!=by(@$t0) .printf"%c",by(@$t0);.if116!=by(@$t0-1){.printf" , "}};.printf"\b ."
-61 bytes by defining alias for repeated code
Inspired by LambdaBeta's use of #define
. This approach modifies the WordMath syntax slightly (,
and .
must be space-delimited like the other words, and ,
does not follow repeat
), and creates alias such that the modified WordMath syntax is valid WinDbg code. The last line does what the question asks and transpiles by converting the input into the modified syntax.
Input is taken by setting a string at a memory address and setting the pseudo-register $t0
to that address. Note: this will overwrite the int
at 0x2000000
, so if you start your string there, it'll be partly overwritten. $t0
will also be overwritten.
Because it creates aliases, depending on whether this code has run before or after setting teh string, the output code will be different (either aliased or not). Unfortunately, I didn't find a way to get the aliases to properly expand without being whitespace delimited (meaning the WordMath script could not just be executed directly without being transformed first).
How it works:
* $t1 is used for repeating and $t0 is used to read the input and hold the accumulator
* Alias , to }@$t1 -- closing do-while loop and allowing repeat
as , }@$t1
* Alias . to }0;?@$t0 -- close do-while loop and evaluate $t0 (accumulator)
as . }0;?@$t0
* Alias Think to (note this is one line)
as Think n10; * Set base 10
ed 8<<22; * Read ints to address 0x2000000. Enter nothing to exit input mode
r$t0 = dwo(8<<22); * Set $t0 = first int
r$t1=0;.do{ * Open do-while
* Alias a to nothing
aS a " "
* Alias add to (note one line):
as add ; * Close previous statement
r$t1=1;.do{r$t1=@$t1-1; * Open do-while (once) loop
r$t0=@$t0+ * Add number to $t0
* Alias by to nothing
aS by " "
* Alias divide to (note one line):
as divide ; * Close previous statement
r$t1=1;.do{r$t1=@$t1-1; * Open do-while (once) loop
r$t0=@$t0/ * Divide next number from $t0
* Alias from to (note one line):
as from 0; * Preceding subtract statement subtracts 0
r$t0=-@$t0+ * Subtract $t0 from next number
* Alias multiply to (note one line):
as multiply ; * Close previous statement
r$t1=1;.do{r$t1=@$t1-1; * Open do-while (once) loop
r$t0=@$t0* * Multiply next number with $t0
* Alias number to nothing
aS number " "
* Alias of to nothing
aS of " "
* Alias repeat to +1 making do-while (once) loops into do-while (once)+1
as repeat +1
* Alias subtract to (note one line):
as subtract ; * Close previous statement
r$t1=1;.do{r$t1=@$t1-1; * Open do-while (once) loop
r$t0=@$t0- * Subtract next number from $t0
.for (r$t9=1; by(@$t0); r$t0=@$t0+1) * Enumerate the string
{
j 44!=by(@$t0) * If not comma
.printf "%c",by(@$t0); * Print the char
* implicit else
.if 116!=by(@$t0-1) * Else if the previous char is not t
{
.printf " , " * Print the comma with spaces around it
}
};
.printf "\b ." * Replacing ending "." with " ."
Sample output, entering the string before running this code once (the resulting program resembles WordMath):
0:000> r$t0=8<<22
0:000> eza8<<22"Think of a number, add 5, add 10, multiply by 2, subtract 15, repeat, divide by 2."
0:000> as, }@$t1
0:000> as. }0;?@$t0
0:000> asThink n10;ed8<<22;r$t0=dwo(8<<22);r$t1=0;.do{
0:000> aSa " "
0:000> asadd ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0+
0:000> aSby " "
0:000> asdivide ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0/
0:000> asfrom 0;r$t0=-@$t0+
0:000> asmultiply ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0*
0:000> aSnumber " "
0:000> aSof " "
0:000> asrepeat +1
0:000> assubtract ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0-
0:000> .for(r$t9=1;by(@$t0);r$t0=@$t0+1){j44!=by(@$t0) .printf"%c",by(@$t0);.if116!=by(@$t0-1){.printf" , "}};.printf"\b ."
Think of a number , add 5 , add 10 , multiply by 2 , subtract 15 , repeat divide by 2 }0;?@$t0
0:000> Think of a number , add 5 , add 10 , multiply by 2 , subtract 15 , repeat divide by 2 }0;?@$t0
base is 10
02000000 6e696854 18
18
02000004 666f206b
Evaluate expression: 18 = 00000012
Sample output, entering the string after after this code has run once (the aliases are expanded when entering the string so the resulting program is not as pretty):
0:000> r$t0=8<<22
0:000> eza8<<22"Think of a number, add 5, add 10, multiply by 2, subtract 15, repeat, divide by 2."
0:000> as, }@$t1
0:000> as. }0;?@$t0
0:000> asThink n10;ed8<<22;r$t0=dwo(8<<22);r$t1=0;.do{
0:000> aSa " "
0:000> asadd ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0+
0:000> aSby " "
0:000> asdivide ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0/
0:000> asfrom 0;r$t0=-@$t0+
0:000> asmultiply ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0*
0:000> aSnumber " "
0:000> aSof " "
0:000> asrepeat +1
0:000> assubtract ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0-
0:000> .for(r$t9=1;by(@$t0);r$t0=@$t0+1){j44!=by(@$t0) .printf"%c",by(@$t0);.if116!=by(@$t0-1){.printf" , "}};.printf"\b ."
n10;ed8<<22;r$t0=dwo(8<<22);r$t1=0;.do{ number , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0+ 5 , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0+ 10 , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0* 2 , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0- 15 , repeat ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0/ 2 }0;?@$t0
0:000> n10;ed8<<22;r$t0=dwo(8<<22);r$t1=0;.do{ number , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0+ 5 , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0+ 10 , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0* 2 , ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0- 15 , repeat ;r$t1=1;.do{r$t1=@$t1-1;r$t0=@$t0/ 2 }0;?@$t0
base is 10
02000000 3b30316e 26
26
02000004 3c386465
Evaluate expression: 26 = 0000001a
Some more sample output, just using the slightly modified WordMath syntax:
0:000> Think of a number , add 1 , repeat repeat repeat divide by 3 .
base is 10
02000000 0000001a 3
3
02000004 3c386465
Evaluate expression: 2 = 00000002
0:000> Think of a number , divide by 5 , subtract from 9 .
base is 10
02000000 00000003 29
29
02000004 3c386465
Evaluate expression: 4 = 00000004
Do we have to support consecutive repeats? – darrylyeo – 2016-12-05T21:14:46.130
1Can we use floats when that's the language's default type / if it doesn't support integers? – Rainer P. – 2016-12-05T21:57:25.037
@RainerP. only if the language doesn't support integers/integer division – FlipTack – 2016-12-05T22:12:45.630
@darrylyeo yes, I'll make that clear in the spec. – FlipTack – 2016-12-05T22:12:55.210
You might want a test case with
repeat
at the end, and more than onerepeat
in a row. – mbomb007 – 2016-12-06T21:14:30.110@mbomb007 yeah, I'll do that now. – FlipTack – 2016-12-06T21:14:55.910
1What is the expected result of
-5/3
? Do we round towards0
or towards negative infinity? – Martin Ender – 2016-12-07T21:09:11.0601@MartinEnder I'd say round towards negative infinity as it's floor division, but if your language implements integer division towards 0 that's fine too. – FlipTack – 2016-12-07T21:10:40.110
The order of multiply and divide should be switched. I know that it's clear what you're saying. – Zacharý – 2016-12-27T19:05:40.283