#!/bin/sed -f
# (C) 2005 by Mariusz Woloszyn :)

##############################
# PURE SED BINARY FULL ADDER #
##############################

# INPUT: two ninary numbers, one per line for example:
# echo "101010011\n11000111010101" | ./full_add.sed
# OUTPUT: sum


# Prepare input data
# read two lines
N
s/ //g
/^[01]\+\n[01]\+$/! {
i\
ERROR: WRONG INPUT DATA
d
q
}
# add C and S
s/.*/&\n0\n/

# Stack in hold:
#
# A Argument 1 |
# B Argument 2 \_____ Stack on input
# C Carry-in bit (C in) /
# S Sum |
#====== Optional:
# Tmp1
# Tmp2
# Tmp3
# ....

# <= Adder input, stack like described above
:LOOP

# Obtain A0, B0 (lowet bits) and put in Temp1
# Trim lowest bits from A and B and put result to hold
s/^\(.*\)\(.\)\n\(.*\)\(.\)\n\(.\)\n\(.*\)$/\1\n\3\n\5\n\6\n\2\4/
h

# Obtain A0B0
s/^.*\n.*\n.\n.*\n\(.*\)$/\1/

# A0 XOR B0
s/\(.\)\1/0/
s/../1/

# Save XOR result in Temp2 (Half sum), X
H

# Obtain A0B0 again
g
s/^.*\n.*\n.\n.*\n\(.*\)\n.*$/\1/

# A0 AND B0
s/11/1/
s/../0/

# Save AND result in Temp3 (Half C), Y
H

# Obtain XC for next operations and put in Temp1,
# Save Y in Temp2
# 3C 4S 5T1 6T2(X 7T3(Y
g
s/^\(.*\)\n\(.*\)\n\(.\)\n\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)$/\1\n\2\n\3\n\4\n\6\3\n\7/
h

# Obtain XC
s/^.*\n.*\n.\n.*\n\(.*\)\n.*$/\1/

# X XOR C
s/\(.\)\1/0/
s/../1/

# Save result in Temp3 (total sum) S
H

# Obtain XC again
g
s/^.*\n.*\n.\n.*\n\(.*\)\n.*\n.*$/\1/

# X AND C
s/11/1/
s/../0/

# Save result in Temp4 (Half X) Z
H

# Obtain YZ (Y in Temp2, Z in Temp4)
g
s/^.*\n.*\n.\n.*\n.*\n\(.*\)\n.*\n\(.*\)$/\1\2/

# Y OR Z
s/00/0/
s/../1/

# Save result in Temp5 (C out)
H

# Rewrite result to format required for next bit input
# Put Temp3 at start (oldest bit) S
# Rewrite C out (Temp5) to C (C in), remove other Temp...
# 3C 4S 5T1 6T2 7T3(S 8T4 9T5(C
g
s/^\(.*\)\n\(.*\)\n\(.\)\n\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)$/\1\n\2\n\9\n\7\4/


# If A and B are empty we're done. Print the result as CS
/^\n\n/ {
s/^\n\n\(.\)\n\(.*\)$/\1\2/
q
}

# If A is empty prepend it with 0
s/^\n\(.*\)\n\(.*\)\n\(.*\)$/0\n\1\n\2\n\3/
# If B is empty prepend it with 0
s/^\(.*\)\n\n\(.*\)\n\(.*\)$/\1\n0\n\2\n\3/

b LOOP