Write a Morse Calculator
Retina, 132 bytes
A messy, first pass solution.
(-)+\.+
5$*.$#1$*.
(-|(\.))+ ?
$#2
\d+
$*
+`(1(_)1|(_1+)|_|\+)(.*)
$2$4$3
1+
$.0
\d
$*x5$*-
(x)+x{5}-*
$#1$*-xxxx
(\S{5})\S*
$1
x
.
Try it online!
Pyth, 69 63 bytes
J_.:s*R5"-.-"5jdm@Jsd`s*MC,mssdc`MKmxJdcz)"-1"+1mtyq\+@cz)dx_1K
Try it here
Or use a test suite
Explanation
J_.:s*R5"-.-"5 - Construct the morse sequence 0-10
jd - Prettify output (join by spaces)
m@Jsd - 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\+@cz)dx_1K - Turn `+` and `_` to +-1
Saved 6 bytes thanks to @Jakube!
MATL, 75 71 69 68 bytes
5:t!<t~v45+cXIO1Oj6ZC"@2#0)Iw!Xmfqb+wXK32=?10*}*+K?K9\6-O}V47-Y)Z{Zc
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