- Compiler: PP → Lexer → Parser → Analyzer → Gengo pipeline - Parser: 232/236 (98%) Harbour compatibility, registry-based dispatch - RTL: 351 Harbour-compatible functions - RDD: DBF/NTX/CDX engines with Rushmore bitmap optimization - Go Interop: IMPORT + pkg.Func() + obj:Method() with FastPath (15M calls/sec) - HB_FUNC API: Full Harbour C API compatible Go bridge - Concurrency: SPAWN/LAUNCH/GOROUTINE, <-, WATCH, PARALLEL FOR, ASYNC/AWAIT - Extensions: Multi-return, DEFER, Slice, f-string, Nil-safe ?:, CONST - Macro Compiler: Runtime AST parsing and evaluation - Debugger: TUI debugger with source display, breakpoints, stepping - FRB: Native + Pcode dual mode runtime binary - Tests: 13 packages ALL PASS Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
124 lines
2.6 KiB
Go
124 lines
2.6 KiB
Go
package hbrtl
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestBin2I(t *testing.T) {
|
|
_, th := setupVM()
|
|
// 0x0100 little-endian = 1 (low byte) + 0 (high byte) = 1
|
|
th.PushString("\x01\x00")
|
|
th.PendingParams2(1)
|
|
Bin2I(th)
|
|
if r := th.GetRetValue().AsLong(); r != 1 {
|
|
t.Errorf("BIN2I(0x0100) = %d, want 1", r)
|
|
}
|
|
|
|
// 0xFF7F = 32767
|
|
th.PushString("\xFF\x7F")
|
|
th.PendingParams2(1)
|
|
Bin2I(th)
|
|
if r := th.GetRetValue().AsLong(); r != 32767 {
|
|
t.Errorf("BIN2I(0xFF7F) = %d, want 32767", r)
|
|
}
|
|
|
|
// Negative: 0xFEFF = -2 as signed 16-bit LE
|
|
th.PushString("\xFE\xFF")
|
|
th.PendingParams2(1)
|
|
Bin2I(th)
|
|
if r := th.GetRetValue().AsLong(); r != -2 {
|
|
t.Errorf("BIN2I(0xFEFF) = %d, want -2", r)
|
|
}
|
|
}
|
|
|
|
func TestBin2L(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushString("\x01\x00\x00\x00")
|
|
th.PendingParams2(1)
|
|
Bin2L(th)
|
|
if r := th.GetRetValue().AsLong(); r != 1 {
|
|
t.Errorf("BIN2L = %d, want 1", r)
|
|
}
|
|
|
|
// 100000 = 0x000186A0 LE = A0 86 01 00
|
|
th.PushString("\xA0\x86\x01\x00")
|
|
th.PendingParams2(1)
|
|
Bin2L(th)
|
|
if r := th.GetRetValue().AsLong(); r != 100000 {
|
|
t.Errorf("BIN2L = %d, want 100000", r)
|
|
}
|
|
}
|
|
|
|
func TestBin2W(t *testing.T) {
|
|
_, th := setupVM()
|
|
// Unsigned: 0xFFFF = 65535 (not -1)
|
|
th.PushString("\xFF\xFF")
|
|
th.PendingParams2(1)
|
|
Bin2W(th)
|
|
if r := th.GetRetValue().AsLong(); r != 65535 {
|
|
t.Errorf("BIN2W(0xFFFF) = %d, want 65535", r)
|
|
}
|
|
}
|
|
|
|
func TestI2Bin(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushLong(1)
|
|
th.PendingParams2(1)
|
|
I2Bin(th)
|
|
r := th.GetRetValue().AsString()
|
|
if r != "\x01\x00" {
|
|
t.Errorf("I2BIN(1) = %x, want 0100", []byte(r))
|
|
}
|
|
}
|
|
|
|
func TestL2Bin(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushLong(100000)
|
|
th.PendingParams2(1)
|
|
L2Bin(th)
|
|
r := th.GetRetValue().AsString()
|
|
if r != "\xA0\x86\x01\x00" {
|
|
t.Errorf("L2BIN(100000) = %x, want a0860100", []byte(r))
|
|
}
|
|
}
|
|
|
|
func TestW2Bin(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushLong(65535)
|
|
th.PendingParams2(1)
|
|
W2Bin(th)
|
|
r := th.GetRetValue().AsString()
|
|
if r != "\xFF\xFF" {
|
|
t.Errorf("W2BIN(65535) = %x, want ffff", []byte(r))
|
|
}
|
|
}
|
|
|
|
func TestRoundTrip(t *testing.T) {
|
|
_, th := setupVM()
|
|
// I2BIN(12345) → BIN2I → 12345
|
|
th.PushLong(12345)
|
|
th.PendingParams2(1)
|
|
I2Bin(th)
|
|
binStr := th.GetRetValue().AsString()
|
|
|
|
th.PushString(binStr)
|
|
th.PendingParams2(1)
|
|
Bin2I(th)
|
|
if r := th.GetRetValue().AsLong(); r != 12345 {
|
|
t.Errorf("I2BIN/BIN2I roundtrip: got %d, want 12345", r)
|
|
}
|
|
|
|
// L2BIN(999999) → BIN2L → 999999
|
|
th.PushLong(999999)
|
|
th.PendingParams2(1)
|
|
L2Bin(th)
|
|
binStr = th.GetRetValue().AsString()
|
|
|
|
th.PushString(binStr)
|
|
th.PendingParams2(1)
|
|
Bin2L(th)
|
|
if r := th.GetRetValue().AsLong(); r != 999999 {
|
|
t.Errorf("L2BIN/BIN2L roundtrip: got %d, want 999999", r)
|
|
}
|
|
}
|