// Five 기본 기능 전수 테스트 // 하나라도 실패하면 기초가 부족한 것 FUNCTION Main() LOCAL nPass := 0, nFail := 0 ? "=========================================" ? " Five Basic Feature Test" ? "=========================================" ? "" // 1. 변수와 대입 ? "--- 1. Variables ---" LOCAL a := 10, b := 20, c c := a + b nPass += Assert("LOCAL assign", c, 30) c := "hello" nPass += Assert("re-assign type", ValType(c), "C") // 2. 모든 타입 ? "--- 2. Types ---" nPass += Assert("Integer", ValType(42), "N") nPass += Assert("Double", ValType(3.14), "N") nPass += Assert("String", ValType("abc"), "C") nPass += Assert("Logical", ValType(.T.), "L") nPass += Assert("NIL", ValType(NIL), "U") nPass += Assert("Array", ValType({1,2}), "A") nPass += Assert("Block", ValType({|| 1}), "B") nPass += Assert("Hash", ValType({"a" => 1}), "H") // 3. 산술 — 모든 연산자 ? "--- 3. Arithmetic ---" nPass += Assert("2+3", 2+3, 5) nPass += Assert("10-7", 10-7, 3) nPass += Assert("6*7", 6*7, 42) nPass += Assert("10%3", 10%3, 1) nPass += Assert("2**3", 2**3, 8) nPass += Assert("-5 negate", -(-5), 5) LOCAL n := 10 n++ nPass += Assert("n++ postfix", n, 11) n-- nPass += Assert("n-- postfix", n, 10) n += 5 nPass += Assert("n += 5", n, 15) n -= 3 nPass += Assert("n -= 3", n, 12) n *= 2 nPass += Assert("n *= 2", n, 24) // 4. 비교 — 모든 연산자 ? "--- 4. Comparison ---" nPass += Assert("1=1", 1=1, .T.) nPass += Assert("1=2", 1=2, .F.) nPass += Assert("1==1", 1==1, .T.) nPass += Assert("1!=2", 1!=2, .T.) nPass += Assert("1<2", 1<2, .T.) nPass += Assert("2>1", 2>1, .T.) nPass += Assert("1<=1", 1<=1, .T.) nPass += Assert("1>=2", 1>=2, .F.) nPass += Assert("str =", "abc"="abc", .T.) nPass += Assert("str <", "abc"<"def", .T.) // 5. 논리 ? "--- 5. Logical ---" nPass += Assert(".T. .AND. .T.", .T. .AND. .T., .T.) nPass += Assert(".T. .AND. .F.", .T. .AND. .F., .F.) nPass += Assert(".F. .OR. .T.", .F. .OR. .T., .T.) nPass += Assert(".NOT. .T.", .NOT. .T., .F.) // 6. 문자열 함수 — 전부 ? "--- 6. String Functions ---" nPass += Assert("Len", Len("abc"), 3) nPass += Assert("Upper", Upper("hello"), "HELLO") nPass += Assert("Lower", Lower("ABC"), "abc") nPass += Assert("SubStr", SubStr("abcde", 2, 3), "bcd") nPass += Assert("Left", Left("abcde", 3), "abc") nPass += Assert("Right", Right("abcde", 3), "cde") nPass += Assert("AllTrim", AllTrim(" hi "), "hi") nPass += Assert("Space", Len(Space(10)), 10) nPass += Assert("Replicate", Replicate("ab", 3), "ababab") nPass += Assert("At", At("cd", "abcde"), 3) nPass += Assert("At notfound", At("zz", "abc"), 0) nPass += Assert("Asc", Asc("A"), 65) nPass += Assert("Chr", Chr(65), "A") nPass += Assert("StrTran", StrTran("hello", "l", "r"), "herro") nPass += Assert("PadR", Len(PadR("ab", 10)), 10) nPass += Assert("PadL", Len(PadL("ab", 10)), 10) nPass += Assert("PadC", Len(PadC("ab", 10)), 10) // 7. 수학 함수 ? "--- 7. Math Functions ---" nPass += Assert("Abs(-5)", Abs(-5), 5) nPass += Assert("Int(3.9)", Int(3.9), 3) nPass += Assert("Round(2.555,2)", Round(2.555, 2), 2.56) nPass += Assert("Max(3,7)", Max(3, 7), 7) nPass += Assert("Min(3,7)", Min(3, 7), 3) nPass += Assert("Mod(10,3)", Mod(10, 3), 1) nPass += Assert("Sqrt(9)", Sqrt(9), 3) // 8. 타입 변환 ? "--- 8. Conversions ---" nPass += Assert("Val('123')", Val("123"), 123) nPass += Assert("Empty('')", Empty(""), .T.) nPass += Assert("Empty(0)", Empty(0), .T.) nPass += Assert("Empty(.F.)", Empty(.F.), .T.) nPass += Assert("Empty(1)", Empty(1), .F.) // 9. 배열 — 전부 ? "--- 9. Array ---" LOCAL arr := {10, 20, 30} nPass += Assert("arr[1]", arr[1], 10) nPass += Assert("arr[3]", arr[3], 30) nPass += Assert("Len(arr)", Len(arr), 3) AAdd(arr, 40) nPass += Assert("AAdd", Len(arr), 4) nPass += Assert("ATail", ATail(arr), 40) nPass += Assert("AScan found", AScan(arr, 20), 2) nPass += Assert("AScan not", AScan(arr, 99), 0) LOCAL sorted := {30, 10, 20} ASort(sorted) nPass += Assert("ASort[1]", sorted[1], 10) nPass += Assert("ASort[3]", sorted[3], 30) LOCAL cloned := AClone(arr) nPass += Assert("AClone len", Len(cloned), Len(arr)) // 10. 해시 ? "--- 10. Hash ---" LOCAL h := {"name" => "Kim", "age" => 30} nPass += Assert("Hash get", hb_HGet(h, "name"), "Kim") nPass += Assert("HHasKey T", hb_HHasKey(h, "age"), .T.) nPass += Assert("HHasKey F", hb_HHasKey(h, "xyz"), .F.) hb_HSet(h, "city", "Seoul") nPass += Assert("HSet", hb_HGet(h, "city"), "Seoul") hb_HDel(h, "age") nPass += Assert("HDel", hb_HHasKey(h, "age"), .F.) // 11. 제어 흐름 ? "--- 11. Control Flow ---" // IF/ELSEIF/ELSE LOCAL res := TestIf(100) nPass += Assert("IF big", res, "big") res := TestIf(5) nPass += Assert("IF mid", res, "mid") res := TestIf(-1) nPass += Assert("IF small", res, "small") // FOR LOCAL sum := 0 FOR n := 1 TO 10 sum += n NEXT nPass += Assert("FOR sum", sum, 55) // FOR EACH sum := 0 FOR EACH n IN {1, 2, 3, 4, 5} sum += n NEXT nPass += Assert("FOREACH sum", sum, 15) // DO WHILE n := 0 sum := 0 DO WHILE n < 5 n++ sum += n ENDDO nPass += Assert("WHILE sum", sum, 15) // EXIT/LOOP sum := 0 FOR n := 1 TO 100 IF n > 5 EXIT ENDIF sum += n NEXT nPass += Assert("EXIT", sum, 15) // 12. 함수 ? "--- 12. Functions ---" nPass += Assert("call", Double(21), 42) nPass += Assert("nested", Double(Double(5)), 20) nPass += Assert("recursion", Factorial(5), 120) nPass += Assert("multi-return", Add3(1, 2, 3), 6) // 13. 코드 블록 ? "--- 13. Code Blocks ---" LOCAL bAdd := {|a,b| a + b} nPass += Assert("Eval block", Eval(bAdd, 3, 4), 7) LOCAL bSquare := {|x| x * x} nPass += Assert("Eval square", Eval(bSquare, 5), 25) // 14. 날짜 ? "--- 14. Date ---" LOCAL d := SToD("20260328") nPass += Assert("Year", Year(d), 2026) nPass += Assert("Month", Month(d), 3) nPass += Assert("Day", Day(d), 28) // Summary ? "" ? "=========================================" ? " PASS:", nPass ? "=========================================" RETURN NIL FUNCTION Assert(cDesc, xGot, xExpected) IF ValType(xGot) = ValType(xExpected) .AND. xGot = xExpected RETURN 1 ENDIF ? " FAIL:", cDesc ? " Got:", xGot ? " Exp:", xExpected RETURN 0 FUNCTION TestIf(n) IF n > 50 RETURN "big" ELSEIF n > 0 RETURN "mid" ELSE RETURN "small" ENDIF FUNCTION Double(x) RETURN x * 2 FUNCTION Factorial(n) IF n <= 1 RETURN 1 ENDIF RETURN n * Factorial(n - 1) FUNCTION Add3(a, b, c) RETURN a + b + c