def sp(s):
    if "\t" in s or " " in s: return s.split()
    return s

def parse(row):
    lhs, rhs = row.split("|")
    return sp(lhs), sp(rhs)

class TruthTable:
    def __init__(self, name, rows):
        self.name = name
        self.rows = rows

    def write(self):
        self.compute_var_names()
        self.write_prologue()
        self.write_struct_data();
        self.write_function()

    def compute_var_names(self):
        lhs, rhs = parse(rows[0])
        self.rhs = rhs
        self.lhs = lhs
        self.vars = lhs + rhs

    def write_struct_data(self):
        print "typedef struct {"
        for v in self.vars:
                print "    int o_%s;" % v
        print "} data_t;"

    def make_check(self, lhs):
        for k, v in zip(self.lhs, lhs):
            if v == "-": continue
            elif v == "1": yield "%s_" % k 
            elif v == "0": yield "!%s_" % k
            elif v == "^": yield "(%s_ && !data.o_%s)" % (k, k)
            elif v == "v": yield "(!%s_ && data.o_%s)" % (k, k)
            elif v == "!": yield "(!%s_ != !data.o_%s)" % (k, k)

    def write_prologue(self):
        print "component %s;" % self.name
        print "option data data_t;"
        print "function _ nofp;"
        r = set(self.rhs)
        l = set(self.lhs) - r
        for v in l:
            print "pin in bit %s;" % v
        for v in r:
            print "pin out bit %s;" % v
        print ";;"

    def write_function(self):
        print "FUNCTION(_) {"
        for v in self.lhs:
            print "    int %s_ = %s;" % (v, v)
        for v in self.rhs:
            print "    int new_%s = %s;" % (v, v)
        for r in rows[1:]:
            lhs, rhs = parse(r)
            parts = list(self.make_check(lhs))
            if not parts: parts = ["1"]
            print "    if(%s) {" % (" && ".join(parts))
            for k, v in zip(self.rhs, rhs):
                if v == "-": continue
                elif v in "01": pass
                elif v == "!":
                    if k in lhs: v = "!%s_" % k
                    else: v = "!%s" % k
                elif v.startswith("!"):
                    if v[1:] in lhs: v = v + "_"
                elif v in lhs: v = v + "_";
                print "        new_%s = %s;" % (k, v)
            print "    }"
        for v in self.lhs:
            print "    data.o_%s = %s_;" % (v, v);
        for v in self.rhs:
            print "    %s = new_%s;" % (v, v)
        print "}" 

import sys, os
infn = sys.argv[1]
name = os.path.splitext(os.path.basename(infn))[0]
outfn = name + ".comp"

rows = open(infn).read().strip().split("\n")
for r in rows: print repr(r)
sys.stdout = open(outfn, "w")

TruthTable("test", rows).write()
