Transpile WordMath

C Preprocessor, 362 Bytes

I ALMOST got this working in JUST the C preprocessor, but the repeat command turns out to be far too difficult to implement. So instead I used the preprocessor to turn the input into an array that is then interpreted by some additional code.

main(){int c[]={
#define Think 
#define of
#define a
#define number 0
#define add 1,
#define subtract 2,
#define from 0,3,
#define multiply 4,
#define divide 5,
#define by
#define repeat 6, 0
#include "input.wm"
,'$'};int _,l,v;scanf("%d", &_);for(int i=1;c[i]-'$';++i){c[i]!=6?l=c[i],v=c[++i]:++i;l==1?_+=v:l==2?_-=v:l==3?_=v-_:l==4?_*=v:_/=v;}printf("%d",_);}

The input must be provided in "input.wm" or just dumped in the source at that line. I included its bytes in my count because I figure its a bit hacky and slightly against the rules of the challenge, so it is only fitting.

Anyways, once you dump your WordMath source into input.wm where a compiler can find it, you should be able to just compile this, as is, with warnings to produce an executable that does what the WordMath source says.


Retina, 170 bytes

Because who wouldn't want to see this?!

I thought of how awesome it'd be to see a Retina solution, and I decided to create it quick. It only took an hour. As usual, byte count assumes ISO 8859-1 encoding.

S`, 
\.

T.*
.*¶$$*
\;+`(.*)¶rep.*(¶?)
$1¶$1$2
\d+
$*
.*f.* (1*)
1¶x¶$¶$1¶+`x1¶
m.* 
1¶
di.* (1*)
^¶$1 ¶^(1+) (\1)+1*$¶x$$#+¶1+ 1*¶x0¶x\d+¶$$*
s.* (1*)
^$1¶
a.* 
^¶
\z
¶1

Try it online

Output has a trailing newline that should not be copied when testing the resulting program. The program does not support negatives, because Retina's standard integer range (in unary) does not.

Explanation:

S`,                 # Split input on ", " putting each command on its own line
\.                  # Remove the period

T.*                 # Think of a number -> .*\n$* (replaces input with unary)
.*¶$$*
\;+`(.*)¶rep.*(¶?)  # Loop, replacing "repeat" with the line before it
$1¶$1$2
\d+                 # Replace all numbers with their unary representation
$*
.*f.* (1*)          # Replace "subtract from " with a subtract from program
1¶x¶$¶$1¶+`x1¶
m.*                 # Replace "multiply by " with a multiply program
1¶
di.* (1*)           # Replace "divide by " by my integer division program
^¶$1 ¶^(1+) (\1)+1*$¶x$$#+¶1+ 1*¶x0¶x\d+¶$$*
s.* (1*)            # Replace "subtract " with a subtraction program
^$1¶
a.*                 # Replace "add " with an addition program
^¶
\z                  # At the end, add a stage to change unary into decimal
¶1

Math programs:

Add:

Add the number of ones to the beginning. Add 5:

^
1111

Subtract:

Remove the number of ones from the beginning. Subtract 5:

^11111

Subtract from:

Replace input 1s with xs. Put next to the fixed number. Repeatedly remove x1. Subtract from 10:

1
x
$
1111111111
+`x1

Multiply by:

Replace every 1 with a certain number of them. Multiply by 3:

1
111

Divide by:

This uses my Retina program for Integer Division. Divide by 2:

^                   # Place the fixed divisor before the dividend
11 
^(.+) (\1)+.*$      # Match the divisor, followed by each occurrence in the dividend.
x$#+                # Replace with the number of matches. Trailing ones are dropped
.+ .*               # If there are still two numbers, the result is zero
x0
x\d+                # Replace result (marked with an 'x') with unary
$*

05AB1E, 59 56 54 52 bytes

„, ¡¦vyDþs.AJá'bK"dmas""/*+-"‡„-f„s-.:«D'rQi®}©}J'rK

Try it online!

My brain hurts like hell after that... It outputs in 05AB1E code as follows:

  • Think of a Number is removed, due to implicit input.
  • Subtract From # coverts to #s- (swap a and b and perform operation).
  • Subtract # converts to #-.
  • Add # converts to #+.
  • Multiply by # converts to #*.
  • Divide by # converts to #/.
  • Repeat grabs whatever was last stored in the register and concatenates it.

Explained:

„, ¡                                                 # Split on ', '.
    ¦                                                # Remove the 'Think of a number'.
     vy                                        }     # Loop through chunks.
       Dþs                                           # Dupe, push only digits, swap.
          .AJá                                       # Acronymify without digits.
              'bK                                    # Remove the `b`.
                 "dmas""/*+-"‡                       # Replace letters with OPs.
                              „-f„s-.:               # Replace '-f' with 's-'.
                                      «              # Concat # with OP.
                                       D'rQ          # Dupe, push 1 if OP='r'.
                                           i®}       # If 'r', push last #OP.
                                              ©      # Store current OP.
                                                J'rK # Join, remove remaining r's.

Example:

Input:

Think of a number, divide by 2, multiply by 10, add 8, subtract 6, subtract from 9, repeat, repeat, subtract 41.

Output:

2/10*8+6-9s-9s-9s-41-

Try solution with input of 10:

Try it online!

See it on google:

Here's a link to the same equation typed into google.