Files
five/CLAUDE.md
CharlesKWON 66882c30bd fix(cdx): Harbour-compatible layout — compound root, RCHB sig, leaf format
Align Five's CDX file layout with Harbour's expectations:
- Compound root header at 0, compound leaf at 1024, tags at 1536+
- "RCHB" signature at offset 20 in compound root
- IgnoreCase/collation flags at offset 503-505
- Compound leaf: LeftPtr/RightPtr = 0xFFFFFFFF, recBits=16 fixed
- Tags sorted alphabetically in compound directory B-tree
- Tag IndexOpt: TypeCompact | TypeCompound (0x60)

Status of Harbour cross-read verification:
- CHAR-only CDX tags: layout matches Harbour byte-for-byte
- Numeric tags: Harbour uses IEEE double (8-byte) key encoding,
  Five uses DBF ASCII key bytes — causes DBFCDX/1012 corruption
  when Harbour reads Five-created CDX with numeric tags
- Five reading Harbour CDX: works perfectly (existing)
- Five reading Five CDX: works perfectly

Remaining: numeric key encoding for full Harbour write-compatibility.
CLAUDE.md updated to reflect this single remaining limitation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 01:33:52 +09:00

5.7 KiB

Five — 개발 규칙

절대 규칙: 변경 후 반드시 검증

어떤 파일이든 수정한 후, 다음 3개 테스트를 모두 통과해야 한다. 하나라도 실패하면 해당 변경을 되돌린다.

# 1. Go 유닛 테스트
go test ./...

# 2. FiveSql2 SQL 테스트 (43/43)
./five build _FiveSql2/test/test_sql1999.prg _FiveSql2/src/*.prg -o /tmp/test_sql
cd ~/tmp && rm -f *.dbf __cte_*.dbf && /tmp/test_sql

# 3. Harbour 호환 테스트 (51/51)
./five build tests/compat_harbour.prg -o /tmp/test_compat && /tmp/test_compat

절대로 "나중에 확인" 하지 않는다. 매 변경마다 즉시.


파일별 영향 범위

수정하는 파일에 따라 어디가 깨질 수 있는지:

hbrt/ (런타임 — 가장 위험)

파일 변경 시 영향 주의사항
thread.go 모든 것 Frame/EndProc/Local 수정 시 FiveSql2 전체 crash 가능. EndProc은 반드시 re-panic 방식 유지
ops_arith.go 모든 산술/FOR 루프 LocalAdd/LocalAddInt는 byref-aware 필수
ops_compare.go 모든 비교/IF/WHILE PopLogical은 NIL→false 유지. LocalLessEqualInt는 byref-aware 필수
ops_collection.go 배열/해시 접근 ArrayPush/ArrayPop은 hash + string 인덱싱 지원 필수
value.go 모든 것 Value 구조체 크기(24B) 변경 금지. HbRefCell은 ptr 필드 사용
call.go 모든 함수 호출 Function()의 pop/push 순서 변경 금지. copy 최적화 시도 금지 (이전에 실패)
class.go 모든 메서드 호출 Send()의 pendingParams 설정 순서 유지

compiler/gengo/ (코드 생성 — 두 번째로 위험)

파일 변경 시 영향 주의사항
gengo.go 모든 생성 코드 emitExpr의 BinaryExpr: short-circuit AND/OR 유지. emitBlock: RefCell 기반 mutable capture 유지. emitAssignExpr: 블록 내 += 처리 필수
gen_class.go 클래스/메서드 blockSeq는 함수 간 공유됨 (reset 불필요)
gen_cmd.go USE/INDEX 등 명령 USE ALIAS (expr) 동적 별칭 유지

hbrtl/ (RTL 함수)

파일 변경 시 영향 주의사항
array.go AEval/ASort/AScan AEval: push 순서 = index먼저, element나중 (Frame이 상단에서 가져감)
database.go DB 함수 전체 dbUseArea 실패 시 반드시 *HbError panic
register.go 함수 등록 새 함수 추가 시 이름 충돌 확인

_FiveSql2/src/ (SQL 엔진 PRG)

파일 주의사항
TSqlExecutor.prg 세미콜론 인라인 IF...ENDIF 사용 금지 (Five 파서 미지원). ENDIF 개수 반드시 IF와 매칭 확인
TSqlDDL.prg @byref 미지원이었으나 이제 동작함. MemoRead 사용 유지
TFiveSQL.prg Query Plan Cache: parse tree가 실행 중 변경됨(aTables 등). 캐시 시 deep clone 필수

알려진 제약사항

항목 상태 비고
CDX 바이너리 Harbour 호환 ⚠️ CHAR 태그만 호환 숫자 키: Harbour는 IEEE double 8B, Five는 DBF ASCII. Five↔Five 완벽 동작. Harbour가 Five CDX 읽기 시 숫자 태그에서 corruption

해결된 제약 (2026-04-11~13)

항목 커밋
세미콜론 IF...ENDIF 이미 동작 확인 (2026-04-13)
`{
CDX compound index 쓰기 미지원 CDX 빌더 구현 (비트팩 리프+compound root)
STATIC inside FUNCTION → panic 5bfdc47 — Go 패키지 변수로 emit
FIELD->NAME 빈 값 반환 e95afad — GetAliasField 반환 타입 수정
OrdSetFocus(n) 무동작 e95afad — 숫자→문자열 변환 수정
Break("string") RECOVER USING panic 3adc9d7 — BreakValue duck-type dispatch
SET INDEX TO a, b, c 마지막만 열림 3adc9d7 — 파서+gengo 다중 파일 지원
PCount() 항상 0 반환 3adc9d7 — CallerParamCount + Frame.paramCount
OutStd()/OutErr() 미등록 e95afad — RTL 등록
Date + Numeric panic 6c53747 — NumInt→Numeric 확장
STATIC += / -= 단순 대입으로 처리 5bfdc47 — compound assign 지원

최적화 시 주의

  1. thread.go의 pop() slot clearing — 제거하면 stale 데이터 문제 가능. 현재 cachedNil로 클리어 유지
  2. call.go의 copy 최적화 — 이전에 시도했으나 pendingSyms desync 발생. 시도 금지
  3. growStack/growFrame 분리 — 가능하지만 다른 변경과 동시 적용 금지. 단독 적용 + 전체 테스트
  4. FiveSql2 PRG 최적화 — 한 번에 하나씩. Column Binding, CTE in-memory 등은 별도 브랜치에서

빌드 환경

  • /mnt/d/ (NTFS 9P): 5~15x 느림. 벤치마크는 반드시 ~/tmp/ (ext4)에서 실행
  • Five 컴파일러: go build -o five ./cmd/five
  • FiveSql2: 다중 파일 빌드 필수 ./five build test.prg src/*.prg -o output
  • Go 경로: export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin

현재 지표 (2026-04-13)

  • Go test: ALL PASS (14 packages)
  • RTL 함수: 483개
  • FiveSql2: 43/43 (100%)
  • Compat: 51/51 (100%)
  • Syntax test: 100/100
  • RDD test: 44/44
  • RTL test: 114/114
  • Harbour RDD parity: diff 0 (281-line NTX+CDX comparison)
  • Windows cross-compile: OK (five.exe 4.0MB)
  • Linux cross-compile: OK (five_linux 3.8MB)
  • @byref: 동작 (RefCell)
  • Mutable closure: 동작 (RefCell + EnsureLocalRef)
  • FIELD->NAME: 동작 (읽기/쓰기)
  • STATIC inside FUNCTION: 동작 (패키지 변수 + 함수 스코프 격리)
  • PCount(): 동작 (CallerParamCount)
  • Break/RECOVER USING: 동작 (BreakValue duck-type)
  • 파일 락킹: POSIX fcntl + Windows LockFileEx
  • INDEX 성능: Harbour 대비 12% faster (50k records)