#!/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
# wczytaj dwie linie inputu
N
s/ //g
/^[01]\+\n[01]\+$/! {
i\
ERROR: WRONG INPUT DATA
d
q
}
# dodaj C i S (Suma na razie pusty string)
s/.*/&\n0\n/

# Wygląd stosu w holdzie:
#
# A Argument 1 |
# B Argument 2 \_____ Wygląd na wejściu
# C Carry-in bit (C in) /
# S Suma |
#====== Opcjonalnie:
# Tmp1
# Tmp2
# Tmp3
# ....

# <= Wejście do maszynki, stos jak w opisie wyżej.
:LOOP

# Wyłuskaj A0, B0 (najmlodsze bity) i zapamietaj w Temp1
# skroc też A i B o najmlodsze bity i zapamiętaj w holdzie
s/^\(.*\)\(.\)\n\(.*\)\(.\)\n\(.\)\n\(.*\)$/\1\n\3\n\5\n\6\n\2\4/
h

# Wyłuskaj A0B0
s/^.*\n.*\n.\n.*\n\(.*\)$/\1/

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

# Zapisz wynik XOR w Temp2 (Half Sum), X
H

# Wyłuskaj A0B0 raz jeszcze
g
s/^.*\n.*\n.\n.*\n\(.*\)\n.*$/\1/

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

# Zapisz wynik AND w Temp3 (Half C), Y
H

# Wyłuskaj XC potrzebne do następnych operacji i zapisz w Temp1,
# Y przechowaj w 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

# Wyłuskaj XC
s/^.*\n.*\n.\n.*\n\(.*\)\n.*$/\1/

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

# Zapisz wynik w Temp3 (Suma całkowita) S
H

# Wyłuskaj XC raz jeszcze
g
s/^.*\n.*\n.\n.*\n\(.*\)\n.*\n.*$/\1/

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

# Zapisz wynik w Temp4 (Half C) Z
H

# Wyłuskaj YZ (Y w Temp2, Z w Temp4)
g
s/^.*\n.*\n.\n.*\n.*\n\(.*\)\n.*\n\(.*\)$/\1\2/

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

# Zapisz wynik w Temp5 (C out)
H

# Przepisz wynik do postaci wejściowej dla następnego bitu
# Dodaj Temp3 na początku (jako najstarszy bit) S
# Przepisz C out (Temp5) do C (C in), usuń pozostałe 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/


# Jeśli A i B puste koniec pieśni, wypisz wynik w postaci CS
/^\n\n/ {
s/^\n\n\(.\)\n\(.*\)$/\1\2/
q
}

# Jeśli A puste dopisz 0
s/^\n\(.*\)\n\(.*\)\n\(.*\)$/0\n\1\n\2\n\3/
# Jeśli B puste dopisz 0
s/^\(.*\)\n\n\(.*\)\n\(.*\)$/\1\n0\n\2\n\3/

b LOOP