import t, c
from stdint import *
import stdio
import string


# ============================================================
# c.Attribute 装饰器测试
#
# 测试 @c.Attribute(...) 对函数属性的设置：
# - t.attr.always_inline()  -> alwaysinline
# - t.attr.noinline()       -> noinline
# - t.attr.noreturn()       -> noreturn
# - t.attr.pure()           -> readonly (LLVM 函数属性)
# - t.attr.llvm.nounwind    -> nounwind
# ============================================================


# Test 1: always_inline 属性
@c.Attribute(t.attr.always_inline())
def AlwaysInlineFunc(x: t.CInt) -> t.CInt:
    return x * 2


# Test 2: noinline 属性
@c.Attribute(t.attr.noinline())
def NoInlineFunc(x: t.CInt) -> t.CInt:
    return x + 100


# Test 3: noreturn 属性（函数确实不返回）
@c.Attribute(t.attr.noreturn())
def NoReturnFunc() -> t.CInt:
    stdio.printf("NoReturnFunc called (does not return)\n")
    return 0


# Test 4: 普通函数对照（无装饰器）
def NormalFunc(x: t.CInt) -> t.CInt:
    return x * 3


# Test 5: 多属性组合
@c.Attribute(t.attr.always_inline(), t.attr.pure())
def MultiAttrFunc(x: t.CInt) -> t.CInt:
    return x + 1


# Test 6: 无括号属性引用 t.attr.packed
@c.Attribute(t.attr.packed)
def PackedAttrFunc(x: t.CInt) -> t.CInt:
    return x - 1


def test_always_inline() -> t.CInt:
    stdio.printf("--- Test 1: c.Attribute(always_inline) ---\n")
    r: t.CInt = AlwaysInlineFunc(21)
    stdio.printf("AlwaysInlineFunc(21)=%d (expect 42)\n", r)
    if r == 42:
        stdio.printf("AlwaysInlineFunc OK\n")
    else:
        stdio.printf("AlwaysInlineFunc FAIL\n")
    return 0


def test_noinline() -> t.CInt:
    stdio.printf("--- Test 2: c.Attribute(noinline) ---\n")
    r: t.CInt = NoInlineFunc(5)
    stdio.printf("NoInlineFunc(5)=%d (expect 105)\n", r)
    if r == 105:
        stdio.printf("NoInlineFunc OK\n")
    else:
        stdio.printf("NoInlineFunc FAIL\n")
    return 0


def test_noreturn() -> t.CInt:
    stdio.printf("--- Test 3: c.Attribute(noreturn) ---\n")
    stdio.printf("NoReturnFunc declared with noreturn attr\n")
    stdio.printf("NoReturnFunc OK (not called to avoid UB)\n")
    return 0


def test_normal() -> t.CInt:
    stdio.printf("--- Test 4: normal function (no attr) ---\n")
    r: t.CInt = NormalFunc(7)
    stdio.printf("NormalFunc(7)=%d (expect 21)\n", r)
    if r == 21:
        stdio.printf("NormalFunc OK\n")
    else:
        stdio.printf("NormalFunc FAIL\n")
    return 0


def test_multi_attr() -> t.CInt:
    stdio.printf("--- Test 5: c.Attribute(always_inline, pure) ---\n")
    r: t.CInt = MultiAttrFunc(10)
    stdio.printf("MultiAttrFunc(10)=%d (expect 11)\n", r)
    if r == 11:
        stdio.printf("MultiAttrFunc OK\n")
    else:
        stdio.printf("MultiAttrFunc FAIL\n")
    return 0


def test_packed_attr() -> t.CInt:
    stdio.printf("--- Test 6: c.Attribute(packed) ---\n")
    r: t.CInt = PackedAttrFunc(10)
    stdio.printf("PackedAttrFunc(10)=%d (expect 9)\n", r)
    if r == 9:
        stdio.printf("PackedAttrFunc OK\n")
    else:
        stdio.printf("PackedAttrFunc FAIL\n")
    return 0


# Test 7: t.attr.llvm.nounwind 属性
@c.Attribute(t.attr.llvm.nounwind)
def NoUnwindFunc(x: t.CInt) -> t.CInt:
    return x + 1


# Test 8: t.attr.llvm.noredzone 属性
@c.Attribute(t.attr.llvm.noredzone)
def NoRedZoneFunc(x: t.CInt) -> t.CInt:
    return x + 2


# Test 9: t.attr.llvm.willreturn 属性
@c.Attribute(t.attr.llvm.willreturn)
def WillReturnFunc(x: t.CInt) -> t.CInt:
    return x + 3


# Test 10: t.attr.llvm.mustprogress 属性
@c.Attribute(t.attr.llvm.mustprogress)
def MustProgressFunc(x: t.CInt) -> t.CInt:
    return x + 4


# Test 11: t.attr.const() -> readnone
@c.Attribute(t.attr.const())
def ConstFunc(x: t.CInt) -> t.CInt:
    return x * 0 + 42


# Test 12: 多属性组合（alwaysinline + nounwind + noredzone）
@c.Attribute(t.attr.always_inline(), t.attr.llvm.nounwind, t.attr.llvm.noredzone)
def TripleAttrFunc(x: t.CInt) -> t.CInt:
    return x + 5


def test_nounwind() -> t.CInt:
    stdio.printf("--- Test 7: c.Attribute(llvm.nounwind) ---\n")
    r: t.CInt = NoUnwindFunc(10)
    stdio.printf("NoUnwindFunc(10)=%d (expect 11)\n", r)
    if r == 11:
        stdio.printf("NoUnwindFunc OK\n")
    else:
        stdio.printf("NoUnwindFunc FAIL\n")
    return 0


def test_noredzone() -> t.CInt:
    stdio.printf("--- Test 8: c.Attribute(llvm.noredzone) ---\n")
    r: t.CInt = NoRedZoneFunc(10)
    stdio.printf("NoRedZoneFunc(10)=%d (expect 12)\n", r)
    if r == 12:
        stdio.printf("NoRedZoneFunc OK\n")
    else:
        stdio.printf("NoRedZoneFunc FAIL\n")
    return 0


def test_willreturn() -> t.CInt:
    stdio.printf("--- Test 9: c.Attribute(llvm.willreturn) ---\n")
    r: t.CInt = WillReturnFunc(10)
    stdio.printf("WillReturnFunc(10)=%d (expect 13)\n", r)
    if r == 13:
        stdio.printf("WillReturnFunc OK\n")
    else:
        stdio.printf("WillReturnFunc FAIL\n")
    return 0


def test_mustprogress() -> t.CInt:
    stdio.printf("--- Test 10: c.Attribute(llvm.mustprogress) ---\n")
    r: t.CInt = MustProgressFunc(10)
    stdio.printf("MustProgressFunc(10)=%d (expect 14)\n", r)
    if r == 14:
        stdio.printf("MustProgressFunc OK\n")
    else:
        stdio.printf("MustProgressFunc FAIL\n")
    return 0


def test_const_attr() -> t.CInt:
    stdio.printf("--- Test 11: c.Attribute(const) ---\n")
    r: t.CInt = ConstFunc(99)
    stdio.printf("ConstFunc(99)=%d (expect 42)\n", r)
    if r == 42:
        stdio.printf("ConstFunc OK\n")
    else:
        stdio.printf("ConstFunc FAIL\n")
    return 0


def test_triple_attr() -> t.CInt:
    stdio.printf("--- Test 12: c.Attribute(always_inline, nounwind, noredzone) ---\n")
    r: t.CInt = TripleAttrFunc(10)
    stdio.printf("TripleAttrFunc(10)=%d (expect 15)\n", r)
    if r == 15:
        stdio.printf("TripleAttrFunc OK\n")
    else:
        stdio.printf("TripleAttrFunc FAIL\n")
    return 0


def attr_test() -> t.CInt:
    stdio.printf("=== attr_test: c.Attribute 装饰器测试 ===\n\n")
    test_always_inline()
    test_noinline()
    test_noreturn()
    test_normal()
    test_multi_attr()
    test_packed_attr()
    test_nounwind()
    test_noredzone()
    test_willreturn()
    test_mustprogress()
    test_const_attr()
    test_triple_attr()
    stdio.printf("\n=== attr_test 完成 ===\n")
    return 0
