Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
github: [LunaStev]
custom: [https://www.lunastev.org/ko/sponsor]
102 changes: 72 additions & 30 deletions llvm_temporary/src/llvm_temporary/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ pub fn generate_statement_ir<'ctx>(
}) => {
let current_fn = builder.get_insert_block().unwrap().get_parent().unwrap();

let cond_value = generate_expression_ir(
let cond_any = generate_expression_ir(
context,
builder,
condition,
Expand All @@ -587,15 +587,32 @@ pub fn generate_statement_ir<'ctx>(
struct_field_indices,
);

let cond_i1 = match cond_any {
BasicValueEnum::IntValue(iv) => {
if iv.get_type().get_bit_width() == 1 {
iv
} else {
let zero = iv.get_type().const_zero();
builder.build_int_compare(inkwell::IntPredicate::NE, iv, zero, "if_cond").unwrap()
}
}
BasicValueEnum::FloatValue(fv) => {
let zero = fv.get_type().const_float(0.0);
builder.build_float_compare(inkwell::FloatPredicate::ONE, fv, zero, "if_cond").unwrap()
}
BasicValueEnum::PointerValue(pv) => builder.build_is_not_null(pv, "if_cond").unwrap(),
_ => panic!("Unsupported if condition type"),
};

let then_block = context.append_basic_block(current_fn, "then");
let else_block_bb = context.append_basic_block(current_fn, "else");
let merge_block = context.append_basic_block(current_fn, "merge");

let _ = builder.build_conditional_branch(
cond_value.try_into().unwrap(),
cond_i1,
then_block,
else_block_bb,
);
).unwrap();

// ---- then block ----
builder.position_at_end(then_block);
Expand All @@ -615,19 +632,20 @@ pub fn generate_statement_ir<'ctx>(
struct_field_indices,
);
}
let then_has_terminator = then_block.get_terminator().is_some();
if !then_has_terminator {
let _ = builder.build_unconditional_branch(merge_block);

let then_end = builder.get_insert_block().unwrap();
if then_end.get_terminator().is_none() {
builder.build_unconditional_branch(merge_block).unwrap();
}

// ---- else block ----
builder.position_at_end(else_block_bb);
let _ = builder.position_at_end(else_block_bb);
let mut current_check_bb = else_block_bb;

let else_has_terminator = if let Some(else_ifs) = else_if_blocks {
let mut current_bb = else_block_bb;
if let Some(else_ifs) = else_if_blocks {
for (else_if_cond, else_if_body) in else_ifs.iter() {
let current_fn = builder.get_insert_block().unwrap().get_parent().unwrap();
let cond_value = generate_expression_ir(
builder.position_at_end(current_check_bb);

let c_any = generate_expression_ir(
context,
builder,
else_if_cond,
Expand All @@ -638,13 +656,30 @@ pub fn generate_statement_ir<'ctx>(
&struct_types,
struct_field_indices,
);
let c_i1 = match c_any {
BasicValueEnum::IntValue(iv) => {
if iv.get_type().get_bit_width() == 1 { iv } else {
let zero = iv.get_type().const_zero();
builder.build_int_compare(inkwell::IntPredicate::NE, iv, zero, "elif_cond").unwrap()
}
}
BasicValueEnum::FloatValue(fv) => {
let zero = fv.get_type().const_float(0.0);
builder.build_float_compare(inkwell::FloatPredicate::ONE, fv, zero, "elif_cond").unwrap()
}
BasicValueEnum::PointerValue(pv) => builder.build_is_not_null(pv, "elif_cond").unwrap(),
_ => panic!("Unsupported else-if condition type"),
};

let then_bb = context.append_basic_block(current_fn, "else_if_then");
let next_check_bb = context.append_basic_block(current_fn, "next_else_if");

let _ = builder.build_conditional_branch(
cond_value.try_into().unwrap(),
c_i1,
then_bb,
next_check_bb,
);
).unwrap();

builder.position_at_end(then_bb);
for stmt in else_if_body {
generate_statement_ir(
Expand All @@ -662,13 +697,17 @@ pub fn generate_statement_ir<'ctx>(
struct_field_indices,
);
}
if then_bb.get_terminator().is_none() {

let end_bb = builder.get_insert_block().unwrap();
if end_bb.get_terminator().is_none() {
let _ = builder.build_unconditional_branch(merge_block);
}
builder.position_at_end(next_check_bb);
current_bb = next_check_bb;

current_check_bb = next_check_bb;
}

builder.position_at_end(current_check_bb);

// === FIX: Generate else_block after else_if blocks ===
if let Some(else_body) = else_block {
for stmt in else_body.iter() {
Expand All @@ -687,11 +726,18 @@ pub fn generate_statement_ir<'ctx>(
struct_field_indices,
);
}
current_bb.get_terminator().is_some()
} else {
current_bb.get_terminator().is_some()
}
} else if let Some(else_body) = else_block {
let else_end = builder.get_insert_block().unwrap();
if else_end.get_terminator().is_none() {
builder.build_unconditional_branch(merge_block).unwrap();
}

builder.position_at_end(merge_block);
}

builder.position_at_end(current_check_bb);

if let Some(else_body) = else_block.as_deref() {
for stmt in else_body.iter() {
generate_statement_ir(
context,
Expand All @@ -708,18 +754,14 @@ pub fn generate_statement_ir<'ctx>(
struct_field_indices,
);
}
else_block_bb.get_terminator().is_some()
} else {
false
};

if !else_has_terminator {
let _ = builder.build_unconditional_branch(merge_block);
}

if !then_has_terminator || !else_has_terminator {
builder.position_at_end(merge_block);
let else_end = builder.get_insert_block().unwrap();
if else_end.get_terminator().is_none() {
builder.build_unconditional_branch(merge_block).unwrap();
}

builder.position_at_end(merge_block);
}
ASTNode::Statement(StatementNode::While { condition, body }) => {
let current_fn = builder.get_insert_block().unwrap().get_parent().unwrap();
Expand Down
35 changes: 29 additions & 6 deletions tools/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import subprocess
import time
from pathlib import Path
import threading
import socket

ROOT = Path(__file__).resolve().parent.parent
TEST_DIR = ROOT / "test"
Expand All @@ -13,18 +15,33 @@
RED = "\033[91m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
CYAN = "\033[96m"
RESET = "\033[0m"

KNOWN_TIMEOUT = {
"test22.wave", # input() not implemented
}

if not WAVEC.exists():
print("wavec not found. Run `cargo build --release` first.")
exit(1)

results = []

def send_udp_for_test61():
time.sleep(0.5)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(b"hello from python\n", ("127.0.0.1", 8080))
sock.close()

def run_and_classify(name, cmd):
print(f"{BLUE}RUN {name}{RESET}")

try:
if name == "test61.wave":
t = threading.Thread(target=send_udp_for_test61, daemon=True)
t.start()

result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
Expand All @@ -41,11 +58,13 @@ def run_and_classify(name, cmd):
return 0

except subprocess.TimeoutExpired:
print(f"{YELLOW}→ TIMEOUT ({TIMEOUT_SEC}s){RESET}\n")
return -1

if name in KNOWN_TIMEOUT:
print(f"{CYAN}→ SKIP (expected blocking / unimplemented){RESET}\n")
return 2
else:
print(f"{YELLOW}→ TIMEOUT ({TIMEOUT_SEC}s){RESET}\n")
return -1

# test*.wave
for path in sorted(TEST_DIR.glob("test*.wave")):
name = path.name
cmd = [str(WAVEC), "run", f"test/{name}"]
Expand All @@ -63,12 +82,11 @@ def run_and_classify(name, cmd):
)
results.append(("test28 (dir)", result))

# 집계
pass_tests = [name for name, r in results if r == 1]
fail_tests = [name for name, r in results if r == 0]
timeout_tests = [name for name, r in results if r == -1]
skip_tests = [name for name, r in results if r == 2]

# 최종 출력
print("\n=========================")
print("🎉 FINAL TEST RESULT")
print("=========================\n")
Expand All @@ -77,6 +95,10 @@ def run_and_classify(name, cmd):
for name in pass_tests:
print(f" - {name}")

print(f"\n{CYAN}SKIP ({len(skip_tests)}){RESET}")
for name in skip_tests:
print(f" - {name}")

print(f"\n{RED}FAIL ({len(fail_tests)}){RESET}")
for name in fail_tests:
print(f" - {name}")
Expand All @@ -87,6 +109,7 @@ def run_and_classify(name, cmd):

print("\n=========================")
print(f"{GREEN}PASS: {len(pass_tests)}{RESET}")
print(f"{CYAN}SKIP: {len(skip_tests)}{RESET}")
print(f"{RED}FAIL: {len(fail_tests)}{RESET}")
print(f"{YELLOW}TIMEOUT: {len(timeout_tests)}{RESET}")
print("=========================\n")