import ast
from itertools import combinations

import tac
import tac_analysis

ivy_type_decls = open('ivy_type_decls.ivy').read()

def test_function():
    #lst = ((1,2), ('a','b'))
    #lst = [(1,2), ('a', 'b',) , ([],[]), (((),),), 1+x]
    lst = []
    lst = lst + [(1,2)]
    lst = lst + [('a','b')]
    #lst.append((1,2))
    #lst.append(('a','b'))
    for x in lst:
        y = x[0] + x[1]
    #x,y = z
    #v0 = 1
    #v1 = 'a'
    #v2 = None
    #x = (v0, v1, v2) #1,'a',None)
    #y = x[2]

def test_function():
    # lst = []
    # lst = lst + [(1,2)]
    # lst = lst + [('a',None)]
    # for x in lst:
    #     i = x[0]
    #     j = x[1]
    #     k = i + 1

    lst = [('a', 'b')]
    lst = lst + [(1,2)]
    lst = lst + [([1],['a'])]
    #lst = lst + [([1],'a')]
    for x in lst:
        k = x[0] + x[1]

    # lst = []
    # lst = lst + [(1,2)]
    # lst = lst + [('a',None)]
    # for x in lst:
    #     y = x[0] + x[1]
    # z = 'a' + None

def test_function2():
    x = 0
    y = 1 < True
    while True:
        z = x + y
        x = "aaa"
        #y = "b"
        x = 2
    if (x > 0):
        y = 1
    else:
        y = 2
    z = x + y



# def test_function():
#     x = 1
#     y = '' #None
#     if (x > 0):
#         y = 1
#     else:
#         y = 2
#     z = x + y

# def test_function():
#     x1 = a + b
#     x2 = a ** b
#     x3 = x1 * x2
#     y = not x1
#     z1 = 1
#     z2 = '1'
#     z3 = True
#     z4 = False
#     z5 = None
#     # if (ha>3):
#     #    print('yes')
#     # z6 = -z1

#     # if x:
#     #     y = 1
#     # else:
#     #     x = 1


def parse_literal_expression(string_expr):
    if tac.is_stackvar(string_expr):
        return ast.Name
    body = ast.parse(string_expr).body
    assert len(body) == 1
    expr = body[0]
    return type(expr.value)

def ivy_and(*exprs):
    if len(exprs) == 0:
        return "true"
    else:
        return '(' + ' & '.join(
            '({})'.format(e) for e in exprs
        ) + ')'

def ivy_or(*exprs):
    if len(exprs) == 0:
        return "false"
    else:
        return '(' + ' | '.join(
            '({})'.format(e) for e in exprs
        ) + ')'



class TacToIvy(object):

    def ivy_type_of_lit(self, x):
        ast_class = parse_literal_expression(x)
        if ast_class is ast.Num:
            return 't_intbool'
        elif ast_class is ast.Str:
            return 't_str'
        elif ast_class is ast.NameConstant and x in ['True', 'False']:
            return 't_intbool'
        elif ast_class is ast.NameConstant and x == 'None':
            return 't_none'
        else:
            return None

    def ivy_obj_of(self, x):