Write a Morse Calculator

Retina, 132 bytes

A messy, first pass solution.

(-|(\.))+ ?

Try it online!

Pyth, 69 63 bytes

J_.:s*R5"-.-"[email protected]`s*MC,mssdc`MKmxJdcz)"-1"+1mtyq\[email protected])dx_1K

Try it here

Or use a test suite


J_.:s*R5"-.-"5                                                  - Construct the morse sequence 0-10
              jd                                                - Prettify output (join by spaces)
                [email protected]                                           - Get the morse for each character in output
                     `s                                         - Convert to a string
                         C,mssdc`MKmxJdcz)"-1"                  - Get the numbers
                       *M                                       - Multiply the numbers by the operators
                                              +1mtyq\[email protected])dx_1K - Turn `+` and `_` to +-1

Saved 6 bytes thanks to @Jakube!

MATL, 75 71 69 68 bytes


Try it online!

General explanation

I use code format in the following so that indentation expresses the nesting of operations.

The input is split into chunks of 6 characters. The last chunk will have
5 characters padded by a 0 char.
   A 0 is initially pushed. This will contain the accumulated global result.
      Each operand (sequence of digits) is processed as follows. A "sign digit",
      1 or -1, has been previously pushed according to whether the preceding
      operator was + or - (for the first operand 1 is used as sign digit).
      Then a 0 is pushed. This will contain the accumulated operand value.
         Each digit of the operand is transformed into the a number `0`...`9` and
         accumulated to the operand value, with successive multiplications by `10`.
      When a + or - is detected, the current operand is finished. So it is 
      multiplied by its sign digit, and added to the acumulated global result.
      A new sign digit is pushed (1 for +, -1 for -), and a new 0 is pushed
      as initial accumulated operand value for the next operand.
   When a 0 char is detected instead of + or -, this marks the end of the input.
   The current global accumulated result is the definitive value. This is
   tranformed into Morse digits and displayed.

Detailed explanation

5:t!<         % first half of the 10x5 array of Morse digits, with 0 for - and 1 for .
t~v           % vertically concat second half, i.e. first half vertically flipped
45+cXI        % transform 0 1 to chars - . Copy this "digit table" to clipboard I
O             % push 0: initial value for accumulated global result
1             % push 1: sign digit for first operand
O             % push 0: initial value of operand
j             % input string
6ZC           % arrange 6-length non-overlapping blocks as columns. Last is 0-padded
"             %   for each column
  @           %   push column
  2#0)        %   split into last element and vector or remaining elements
  I           %   push digit table
  w!          %   swap and transposed into a row
  Xmfq        %   index of that row in the digit table. Subtract 1: gives the digit
  b+          %   bubble up current operand value to top. Add to the new found digit
  wXK         %   swap last char of column (+,-,space,0) to top. Copy to clipboard K
  32=         %   is it space?
  ?           %   if so
    10*       %     multiply by 10. The operand will continue with next digit
  }           %   else: the operand is done
    *         %     multiply by sign digit
    +         %     add this operand with its sign to accumulated global result
    K         %     push last char of column again
    ?         %     if it's not 0
      K9\6-   %       push 1 if it's a +, -1 if it's a -: sign digit of next operand
      O       %       push 0 to initiallize accumulated operand value of next operand
    }         %     else: it's a 0: we're done computing the result
      V       %       convert result to string to get its digits
      47-Y)   %       index the rows of the digit table that was initially pushed
      Z{Zc    %       join rows by spaces
              %     end if, implicit
              %   end if, implicit
              % end for each, implicit
              % display, implicit