Reverse morse code

The original code

3 min readOct 19, 2020

Believe it or not, the following code is completely viable in C. This code can be compiled, via gcc, and can then be executed.

When run, it allows the user to input a string of characters and output its translation into Morse Code.

Example of execution

The original program is making use (and abuse) of the C preprocessing programs (which is the first of the four steps of compilation). In the code, we can use the preprocessing command #define, which takes 2 arguments given a string. During the preprocessing, all the occurences of the first straing are replaced by the second string.

For example, “#define DIT” ( replace all the strong “DIT” by string “(“.

We can see exactly what the preprocessor does in the first step by stopping the compilation after preprocessing, using command gcc -E

Output of gcc -E of the original program

This gets better and closer to being readable, but still difficult due to the function / variable names being all named something like …DIT… or …DAH…

In order to make it more readable, we copy the code and use the find/replace functionality. We’ve replaced : __DIT by var1, _DIT_ by var2, _DAH_ by alphabet, _DIT by word1, DAH_ by word2, DIT_ by word3, _DAH by word4.

After a little bit of cleaning and some re-arragements, the code now looks like this :

This getting clearer but, now we notice that word4 and var1 are actually name of functions and that our variables names wordI and varI can be further reduced to wI and vI.

The transformed code

After all these transformations and after having reformatted a little bit (removing / adding space), the original code is now equivalent to the transformed code below :

Transformed code

This code compiles like the original code and produces exactly the same output. What do we see in this code.

Firstly, an alphabet variable which is an encoding of the morse binary tree encoder :

  • E and T are the 2 level-1 nodes, E is “.” while T is “-” in morse
  • I A N M are the level-2 nodes, I is “..”, A is “.-”, N is “-.”, M is “ — ”
  • etc…

Then playing with the 3 for loops, and alongside some simple (but not that easy to understand) binary operations, the transformed program :

  • first loop : gets a string from the user, with a preallocated max size of 81, stored in w1
  • second loop : goes through each letter of w1 and calls the function named function1, which takes the ASCII code of the letter and, via alphabet, translates it into “.” or “-”
  • last loop : converts all lower case letter into uppercase, to be then translated using the alphabet table

And… that’s it.