- 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>
76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
|
|
// All rights reserved.
|
|
|
|
// Binary conversion functions: BIN2I, BIN2L, BIN2W, I2BIN, L2BIN, W2BIN
|
|
// These convert between Harbour strings and numeric values using
|
|
// little-endian byte order (Clipper/Harbour convention).
|
|
|
|
package hbrtl
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"five/hbrt"
|
|
)
|
|
|
|
// BIN2I(cBuffer) → nValue (16-bit signed)
|
|
func Bin2I(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
buf := padBuf(t.Local(1).AsString(), 2)
|
|
t.RetInt(int64(int16(binary.LittleEndian.Uint16(buf))))
|
|
}
|
|
|
|
// BIN2L(cBuffer) → nValue (32-bit signed)
|
|
func Bin2L(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
buf := padBuf(t.Local(1).AsString(), 4)
|
|
t.RetInt(int64(int32(binary.LittleEndian.Uint32(buf))))
|
|
}
|
|
|
|
// BIN2W(cBuffer) → nValue (16-bit unsigned)
|
|
func Bin2W(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
buf := padBuf(t.Local(1).AsString(), 2)
|
|
t.RetInt(int64(binary.LittleEndian.Uint16(buf)))
|
|
}
|
|
|
|
// I2BIN(nValue) → cBuffer (16-bit signed, 2 bytes)
|
|
func I2Bin(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
buf := make([]byte, 2)
|
|
binary.LittleEndian.PutUint16(buf, uint16(int16(t.Local(1).AsLong())))
|
|
t.RetString(string(buf))
|
|
}
|
|
|
|
// L2BIN(nValue) → cBuffer (32-bit signed, 4 bytes)
|
|
func L2Bin(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
buf := make([]byte, 4)
|
|
binary.LittleEndian.PutUint32(buf, uint32(int32(t.Local(1).AsLong())))
|
|
t.RetString(string(buf))
|
|
}
|
|
|
|
// W2BIN(nValue) → cBuffer (16-bit unsigned, 2 bytes)
|
|
func W2Bin(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
buf := make([]byte, 2)
|
|
binary.LittleEndian.PutUint16(buf, uint16(t.Local(1).AsLong()))
|
|
t.RetString(string(buf))
|
|
}
|
|
|
|
// padBuf ensures the byte buffer has at least n bytes (zero-padded).
|
|
func padBuf(s string, n int) []byte {
|
|
b := []byte(s)
|
|
if len(b) >= n {
|
|
return b[:n]
|
|
}
|
|
buf := make([]byte, n)
|
|
copy(buf, b)
|
|
return buf
|
|
}
|