2025-09-02 23:58:15 +09:00
unit HAK;
2024-02-02 14:57:46 +09:00
{$mode objfpc} {$H+}
2024-09-23 20:31:11 +09:00
{$macro on}
2025-09-02 23:58:15 +09:00
{$linklib hak}
2024-02-02 14:57:46 +09:00
{$linklib c}
2024-02-18 10:12:56 +09:00
{$linklib dl}
{$linklib gcc}
2024-02-13 00:57:30 +09:00
2025-09-02 23:58:15 +09:00
{$if defined(HAK_LIB_QUADMATH_REQUIRED)}
2024-02-02 14:57:46 +09:00
{$linklib quadmath}
2024-02-13 00:57:30 +09:00
{$endif}
2024-02-02 14:57:46 +09:00
interface
2024-02-03 13:36:05 +09:00
type
2025-09-02 23:58:15 +09:00
BitMask = longword ; (* this must match hak_bitmask_t in hak.h *)
2024-02-11 16:39:16 +09:00
( * const
2024-07-06 12:16:05 +09:00
TRAIT_LANG_ENABLE_EOL = ( BitMask( 1 ) shl 1 4 ) ; * )
2024-02-11 16:39:16 +09:00
type
2025-09-02 23:58:15 +09:00
TraitBit = ( (* this enum must follow hak_trait_t in hak.h *)
2024-07-06 12:16:05 +09:00
LANG_ENABLE_EOL = ( BitMask( 1 ) shl 1 4 )
2024-02-11 16:39:16 +09:00
) ;
2025-09-02 23:58:15 +09:00
Option = ( (* this enum must follow hak_option_t in hak.h *)
2024-02-11 16:39:16 +09:00
TRAIT,
LOG_MASK,
LOG_MAXCAPA
) ;
2025-09-02 23:58:15 +09:00
IoCmd = ( (* this enum must follow hak_io_cmd_t in hak.h *)
2024-02-13 00:57:30 +09:00
IO_OPEN,
IO_CLOSE,
IO_READ,
IO_READ_BYTES,
IO_WRITE,
IO_WRITE_BYTES,
IO_FLUSH
) ;
2025-09-02 23:58:15 +09:00
{$ifndef HAK_CCI_BUF_LEN}
{$define HAK_CCI_BUF_LEN := 2048}
2024-02-19 20:48:14 +09:00
{$endif}
2024-02-20 15:52:28 +09:00
//{$packrecords c}
2024-02-13 00:57:30 +09:00
CciArgPtr = ^ CciArg;
2025-09-02 23:58:15 +09:00
CciArg = record (* this record must follow the public part of hak_io_cciarg_t in hak.h *)
2024-02-13 00:57:30 +09:00
name : pwidechar ;
handle: pointer ;
2024-05-19 17:09:31 +09:00
byte_oriented: integer ;
2025-09-02 23:58:15 +09:00
buf: array [ 0 .. ( HAK_CCI_BUF_LEN - 1 ) ] of widechar ;
2024-02-13 00:57:30 +09:00
xlen: System. SizeUint;
includer: CciArgPtr;
end ;
2024-02-20 15:52:28 +09:00
//{$packrecords normal}
2024-02-13 00:57:30 +09:00
2024-02-02 14:57:46 +09:00
Interp = class
2024-02-03 13:36:05 +09:00
protected
2024-02-02 14:57:46 +09:00
handle: pointer ;
2024-02-23 00:32:17 +09:00
basefile: string ;
2024-02-03 13:36:05 +09:00
2024-02-02 14:57:46 +09:00
public
2024-02-13 00:57:30 +09:00
constructor Create( x: integer ) ;
destructor Destroy( ) ; override ;
procedure Ignite( heapsize: System. SizeUint) ;
2024-02-02 14:57:46 +09:00
procedure AddBuiltinPrims( ) ;
2024-02-13 00:57:30 +09:00
procedure CompileFile( filename: pansichar ) ;
2024-02-20 15:52:28 +09:00
procedure CompileText( text : pansichar ) ;
procedure CompileText( text : pansichar ; len: System. SizeUint) ;
procedure CompileText( text : pwidechar ) ;
procedure CompileText( text : pwidechar ; len: System. SizeUint) ;
2024-02-02 14:57:46 +09:00
procedure Execute( ) ;
protected
function FetchErrorMsg( ) : string ;
end ;
2024-02-20 15:40:39 +09:00
InterpExt = record
self: Interp;
end ;
InterpExtPtr = ^ InterpExt;
2024-02-13 00:57:30 +09:00
IO = class
public
procedure Open( ) ; virtual ; abstract ;
procedure Close( ) ; virtual ; abstract ;
function Read( ) : System. SizeUint; virtual ; abstract ;
end ;
2024-02-03 13:36:05 +09:00
Location = record
2024-02-13 00:57:30 +09:00
line: System. SizeUint;
colm: System. SizeUint;
2024-02-03 13:36:05 +09:00
filp: pwidechar ;
end ;
Synerr = record
num: integer ;
loc: Location;
tgt: record
val: array [ 0 .. 2 5 5 ] of widechar ;
2024-02-13 00:57:30 +09:00
len: System. SizeUint;
2024-02-03 13:36:05 +09:00
end ;
end ;
SynerrPtr = ^ Synerr;
2024-02-02 14:57:46 +09:00
2025-09-02 23:58:15 +09:00
(*----- external hak function -----*)
function hak_errnum_to_errbcstr( errnum: integer ; errbuf: pointer ; errbufsz: System. SizeUint) : pointer ; cdecl ; external ;
function hak_errnum_is_synerr( errnum: integer ) : boolean ; cdecl ; external ;
2024-02-03 13:36:05 +09:00
2025-09-02 23:58:15 +09:00
function hak_openstd( xtnsize: System. SizeUint; errnum: pointer ) : pointer ; cdecl ; external ;
procedure hak_close( handle: pointer ) ; cdecl ; external ;
function hak_getxtn( handle: pointer ) : InterpExtPtr; cdecl ; external ;
2024-02-11 16:39:16 +09:00
2025-09-02 23:58:15 +09:00
function hak_setoption( handle: pointer ; option: Option; value: pointer ) : integer ; cdecl ; external ;
function hak_getoption( handle: pointer ; option: Option; value: pointer ) : integer ; cdecl ; external ;
2024-02-11 16:39:16 +09:00
2025-09-02 23:58:15 +09:00
procedure hak_seterrnum ( handle: pointer ; errnum: integer ) ; cdecl ; external ;
function hak_geterrnum( handle: pointer ) : integer ; cdecl ; external ;
2024-02-19 20:48:14 +09:00
2025-09-02 23:58:15 +09:00
procedure hak_seterrbmsg ( handle: pointer ; errnum: integer ; errmsg: pansichar ) ; cdecl ; external ;
function hak_geterrbmsg( handle: pointer ) : pansichar ; cdecl ; external ;
2024-02-19 20:48:14 +09:00
2025-09-02 23:58:15 +09:00
function hak_ignite( handle: pointer ; heapsize: System. SizeUint) : integer ; cdecl ; external ;
function hak_addbuiltinprims( handle: pointer ) : integer ; cdecl ; external ;
function hak_beginfeed( handle: pointer ; on_cnode: pointer ) : integer ; cdecl ; external ;
function hak_feedbchars( handle: pointer ; data: pansichar ; len: System. SizeUint) : integer ; cdecl ; external ;
function hak_feeduchars( handle: pointer ; data: pwidechar ; len: System. SizeUint) : integer ; cdecl ; external ; (* this is wrong in deed - hak_uchar_t may not been widechar ..*)
function hak_endfeed( handle: pointer ) : integer ; cdecl ; external ;
2024-02-02 14:57:46 +09:00
2025-09-02 23:58:15 +09:00
function hak_attachccio( handle: pointer ; cci: pointer ) : integer ; cdecl ; external ;
function hak_attachcciostdwithbcstr( handle: pointer ; cci: pansichar ) : integer ; cdecl ; external ;
procedure hak_detachccio( handle: pointer ) ; cdecl ; external ;
function hak_attachudiostdwithbcstr( handle: pointer ; udi: pansichar ; udo: pansichar ) : integer ; cdecl ; external ;
procedure hak_detachudio( handle: pointer ) ; cdecl ; external ;
function hak_compile( handle: pointer ; cnode: pointer ; flags: integer ) : integer ; cdecl ; external ;
function hak_execute( handle: pointer ) : pointer ; cdecl ; external ;
procedure hak_abort( handle: pointer ) cdecl ; external ;
2024-02-02 14:57:46 +09:00
2025-09-02 23:58:15 +09:00
procedure hak_getsynerr( handle: pointer ; synerr: SynerrPtr) cdecl ; external ;
function hak_syserrstrb( handle: pointer ; syserr_type: integer ; syserr_code: integer ; buf: pansichar ; len: System. SizeUint) : integer ; cdecl ; external ;
function hak_count_ucstr( ptr: pwidechar ) : System. SizeUint; cdecl ; external ;
(*----- end external hak function -----*)
2024-02-02 14:57:46 +09:00
implementation
2024-02-13 00:57:30 +09:00
uses SysUtils, Math, Classes;
2024-02-02 14:57:46 +09:00
2024-02-23 00:32:17 +09:00
type
NamedHandle = record
handle: THandle;
name : System. RawByteString ;
end ;
NamedHandlePtr = ^ NamedHandle;
2024-02-02 14:57:46 +09:00
constructor Interp. Create ( x: integer ) ;
2024-02-03 13:36:05 +09:00
var
2024-02-02 14:57:46 +09:00
h: pointer ;
errnum: integer ;
errmsg: array [ 0 .. 2 5 5 ] of AnsiChar ;
2024-02-11 16:39:16 +09:00
tb: BitMask;
2024-02-20 15:40:39 +09:00
ext: InterpExtPtr;
2024-02-02 14:57:46 +09:00
begin
2025-09-02 23:58:15 +09:00
h : = hak_openstd( System. SizeOf( Interp) , @ errnum) ;
2024-02-02 14:57:46 +09:00
if h = nil then begin
2025-09-02 23:58:15 +09:00
hak_errnum_to_errbcstr( errnum, @ errmsg, length( errmsg) ) ;
2024-02-11 16:39:16 +09:00
raise Exception. Create( errmsg) ;
end ;
2025-09-02 23:58:15 +09:00
if hak_getoption( h, Option. TRAIT, @ tb) < = - 1 then tb : = 0 ;
2024-02-20 15:40:39 +09:00
2024-07-06 12:16:05 +09:00
tb : = tb or BitMask( TraitBit. LANG_ENABLE_EOL) ;
2025-09-02 23:58:15 +09:00
if hak_setoption( h, Option. TRAIT, @ tb) < = - 1 then begin
hak_errnum_to_errbcstr( errnum, @ errmsg, length( errmsg) ) ;
hak_close( h) ;
2024-02-02 14:57:46 +09:00
raise Exception. Create( errmsg) ;
end ;
2024-02-20 15:40:39 +09:00
2024-02-02 14:57:46 +09:00
self. handle : = h;
2024-02-20 15:40:39 +09:00
2025-09-02 23:58:15 +09:00
ext : = hak_getxtn( h) ;
2024-02-20 15:40:39 +09:00
ext^ . self : = self;
2024-02-02 14:57:46 +09:00
end ;
destructor Interp. Destroy;
begin
if self. handle < > nil then
begin
2025-09-02 23:58:15 +09:00
hak_close( self. handle) ;
2024-02-02 14:57:46 +09:00
self. handle : = nil ;
end ;
inherited ;
end ;
function Interp. FetchErrorMsg( ) : string ;
var
2024-02-03 13:36:05 +09:00
num: integer ;
bmsg: pansichar ;
serr: Synerr;
filp: pwidechar ;
tgt: array [ 0 .. 2 5 5 ] of widechar ;
2024-02-02 14:57:46 +09:00
begin
2025-09-02 23:58:15 +09:00
num : = hak_geterrnum( self. handle) ;
if hak_errnum_is_synerr( num) then begin
hak_getsynerr( self. handle, @ serr) ;
bmsg : = hak_geterrbmsg( self. handle) ;
2024-02-03 13:36:05 +09:00
filp : = pwidechar( widestring( '' ) ) ;
if serr. loc. filp < > nil then filp : = serr. loc. filp;
if serr. tgt. len > 0 then begin
2024-02-13 00:57:30 +09:00
SysUtils. Strlcopy( @ tgt, serr. tgt. val, Math. Min( serr. tgt. len, length( tgt) - 1 ) ) ;
exit( SysUtils. Format( '%s at %s[%u:%u] - %s' , [ string( bmsg) , string( filp) , serr. loc. line, serr. loc. colm, string( tgt) ] ) ) ;
2024-02-03 13:36:05 +09:00
end
else begin
2024-02-13 00:57:30 +09:00
exit( SysUtils. Format( '%s at %s[%u:%u]' , [ string( bmsg) , string( filp) , serr. loc. line, serr. loc. colm] ) ) ;
2024-02-03 13:36:05 +09:00
end ;
end
else begin
2025-09-02 23:58:15 +09:00
bmsg : = hak_geterrbmsg( self. handle) ;
2024-02-03 13:36:05 +09:00
exit( string( bmsg) )
end ;
2024-02-02 14:57:46 +09:00
end ;
2024-02-13 00:57:30 +09:00
procedure Interp. Ignite( heapsize: System. SizeUint) ;
2024-02-02 14:57:46 +09:00
begin
2025-09-02 23:58:15 +09:00
if hak_ignite( self. handle, heapsize) < = - 1 then
2024-02-02 14:57:46 +09:00
begin
raise Exception. Create( 'failed to ignite - ' + self. FetchErrorMsg( ) )
end ;
end ;
procedure Interp. AddBuiltinPrims( ) ;
begin
2025-09-02 23:58:15 +09:00
if hak_addbuiltinprims( self. handle) < = - 1 then
2024-02-02 14:57:46 +09:00
begin
raise Exception. Create( 'failed to add builtin primitives - ' + self. FetchErrorMsg( ) )
end ;
end ;
2024-02-20 15:40:39 +09:00
function handle_to_self( handle: pointer ) : Interp;
var
ext: InterpExtPtr;
begin
2025-09-02 23:58:15 +09:00
ext : = hak_getxtn( handle) ;
2024-02-20 15:40:39 +09:00
exit( ext^ . self) ;
end ;
2024-02-13 00:57:30 +09:00
function cci_handler( handle: pointer ; cmd: IoCmd; arg: CciArgPtr) : integer ; cdecl ;
var
2024-02-23 00:32:17 +09:00
nf: NamedHandlePtr;
2024-02-13 00:57:30 +09:00
len: System. LongInt ;
2024-02-19 20:48:14 +09:00
err: System. Integer ;
2024-02-20 15:40:39 +09:00
name : System. RawByteString ;
2024-02-23 00:32:17 +09:00
basedir: System. RawByteString ;
2024-02-20 15:40:39 +09:00
self: Interp;
2024-02-13 00:57:30 +09:00
begin
case cmd of
IO_OPEN: begin
2024-02-20 15:40:39 +09:00
self : = handle_to_self( handle) ;
2024-02-23 00:32:17 +09:00
if arg^ . includer = nil then begin
(* main stream *)
name : = self. basefile;
end
else begin
(* included file *)
nf : = NamedHandlePtr( arg^ . includer^ . handle) ;
basedir : = SysUtils. ExtractFilePath( nf^ . name ) ;
2024-09-23 20:31:11 +09:00
name : = System. UTF8Encode( WideString( arg^ . name ) ) ;
2024-02-23 00:32:17 +09:00
if SysUtils. CompareStr( basedir, '' ) < > 0 then
name : = SysUtils. ConcatPaths( [ basedir, name ] ) ;
end ;
System. New( nf) ;
if nf = nil then begin
2024-02-19 20:48:14 +09:00
err : = SysUtils. GetLastOSError( ) ;
2025-09-02 23:58:15 +09:00
hak_seterrbmsg( handle, hak_syserrstrb( handle, 0 , err, nil , 0 ) , pansichar( SysUtils. SysErrorMessage( err) ) ) ;
2024-02-13 00:57:30 +09:00
exit( - 1 ) ;
end ;
2024-02-23 00:32:17 +09:00
if arg^ . includer < > nil then begin
(* included file *)
nf^ . handle : = SysUtils. FileOpen( name , SysUtils. fmOpenRead) ;
if nf^ . handle = System. THandle( - 1 ) then begin
err : = SysUtils. GetLastOSError( ) ;
2025-09-02 23:58:15 +09:00
hak_seterrbmsg( handle, hak_syserrstrb( handle, 0 , err, nil , 0 ) , pansichar( SysUtils. SysErrorMessage( err) ) ) ;
2024-02-23 00:32:17 +09:00
System. Dispose( nf) ;
exit( - 1 ) ;
end ;
end
else begin
nf^ . handle : = THandle( - 1 ) ;
end ;
nf^ . name : = name ;
arg^ . handle : = pointer( nf) ;
2024-05-19 17:09:31 +09:00
arg^ . byte_oriented : = 1 ;
2024-02-13 00:57:30 +09:00
end ;
IO_CLOSE: begin
2024-02-23 00:32:17 +09:00
nf : = NamedHandlePtr( arg^ . handle) ;
if nf^ . handle < > System. THandle( - 1 ) then SysUtils. FileClose( nf^ . handle) ;
System. Dispose( nf) ;
2024-02-13 00:57:30 +09:00
end ;
IO_READ_BYTES: begin
2024-02-23 00:32:17 +09:00
nf : = NamedHandlePtr( arg^ . handle) ;
len : = SysUtils. FileRead( nf^ . handle, arg^ . buf, System. SizeOf( arg^ . buf) ) ; (* use SizeOf a widechar buffer as it needs to fill it with bytes *)
2024-02-13 00:57:30 +09:00
if len < = - 1 then begin
2025-09-02 23:58:15 +09:00
hak_seterrbmsg( handle, hak_syserrstrb( handle, 0 , err, nil , 0 ) , pansichar( SysUtils. SysErrorMessage( err) ) ) ;
2024-02-13 00:57:30 +09:00
exit( - 1 ) ;
end ;
arg^ . xlen : = len;
end ;
IO_FLUSH:
(* no effect on an input stream *)
;
( * the following operations are prohibited on the code input stream:
2024-02-20 15:52:28 +09:00
IO_READ:
2024-02-13 00:57:30 +09:00
IO_WRITE:
IO_WRITE_BYTES:
* )
else begin
2025-09-02 23:58:15 +09:00
hak_seterrnum( handle, 9 9 9 ) ; (* TODO: change error code *)
2024-02-13 00:57:30 +09:00
exit( - 1 ) ;
end ;
end ;
exit( 0 ) ;
end ;
procedure Interp. CompileFile( filename: pansichar ) ;
var
f: System. THandle = - 1 ;
attached: boolean = false ;
feed_ongoing: boolean = false ;
errnum: System. Integer ;
errmsg: string ;
buf: array [ 0 .. 1 0 2 3 ] of ansichar ;
len: System. LongInt ;
label
oops;
begin
f : = SysUtils. FileOpen( filename, SysUtils. fmOpenRead) ;
2024-02-20 15:52:28 +09:00
if f = System. THandle( - 1 ) then begin
2024-02-23 00:54:36 +09:00
errmsg : = 'failed to open ' + filename + ' - ' + SysUtils. SysErrorMessage( SysUtils. GetLastOSError( ) ) ;
2024-02-13 00:57:30 +09:00
goto oops;
end ;
2024-02-23 00:32:17 +09:00
self. basefile : = filename;
2025-09-02 23:58:15 +09:00
if hak_attachccio( self. handle, @ cci_handler) < = - 1 then begin
2024-02-13 00:57:30 +09:00
errmsg : = 'failed to attach ccio handler - ' + self. FetchErrorMsg( ) ;
goto oops;
end ;
attached : = true ;
2025-09-02 23:58:15 +09:00
if hak_beginfeed( self. handle, nil ) < = - 1 then begin
2024-02-13 00:57:30 +09:00
errmsg : = 'failed to begin feeding - ' + self. FetchErrorMsg( ) ;
goto oops;
end ;
feed_ongoing : = true ;
while true do begin
len : = SysUtils. FileRead( f, buf, System. SizeOf( buf) ) ;
if len < = - 1 then begin
2024-02-23 00:54:36 +09:00
errmsg : = 'failed to read ' + filename + ' - ' + SysUtils. SysErrorMessage( SysUtils. GetLastOSError( ) ) ;
2024-02-13 00:57:30 +09:00
goto oops;
end ;
if len = 0 then break;
2025-09-02 23:58:15 +09:00
if hak_feedbchars( self. handle, buf, len) < = - 1 then begin
errnum : = hak_geterrnum( self. handle) ;
2024-02-13 00:57:30 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
if not hak_errnum_is_synerr( errnum) then errmsg : = 'failed to feed text - ' + errmsg;
2024-02-13 00:57:30 +09:00
goto oops;
end ;
end ;
2025-09-02 23:58:15 +09:00
if hak_endfeed( self. handle) < = - 1 then begin
2024-02-13 00:57:30 +09:00
errmsg : = 'failed to end feeding - ' + self. FetchErrorMsg( ) ;
goto oops;
end ;
feed_ongoing : = false ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-23 00:32:17 +09:00
self. basefile : = '' ;
2024-02-13 00:57:30 +09:00
SysUtils. FileClose( f) ;
exit( ) ;
oops:
2025-09-02 23:58:15 +09:00
if feed_ongoing then hak_endfeed( self. handle) ;
if attached then hak_detachccio( self. handle) ;
2024-02-23 00:32:17 +09:00
self. basefile : = '' ;
2024-02-23 00:54:36 +09:00
if f < > System. THandle( - 1 ) then SysUtils. FileClose( f) ;
2024-02-13 00:57:30 +09:00
raise Exception. Create( errmsg) ;
end ;
2024-02-20 15:52:28 +09:00
procedure Interp. CompileText( text : pansichar ) ;
2024-02-02 14:57:46 +09:00
begin
2024-02-20 15:52:28 +09:00
self. CompileText( text , SysUtils. Strlen( text ) ) ;
2024-02-02 14:57:46 +09:00
end ;
2024-02-20 15:52:28 +09:00
procedure Interp. CompileText( text : pansichar ; len: System. SizeUint) ;
2024-02-02 14:57:46 +09:00
var
2024-02-03 13:36:05 +09:00
errnum: integer ;
2024-02-02 14:57:46 +09:00
errmsg: string ;
begin
2025-09-02 23:58:15 +09:00
if hak_attachcciostdwithbcstr( self. handle, nil ) < = - 1 then
2024-02-13 00:57:30 +09:00
raise Exception. Create( 'failed to attach ccio handler - ' + self. FetchErrorMsg( ) ) ;
2024-02-02 14:57:46 +09:00
2025-09-02 23:58:15 +09:00
if hak_beginfeed( self. handle, nil ) < = - 1 then begin
2024-02-02 14:57:46 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-13 00:57:30 +09:00
raise Exception. Create( 'failed to begin feeding - ' + errmsg) ;
2024-02-02 14:57:46 +09:00
end ;
2024-02-03 13:36:05 +09:00
2025-09-02 23:58:15 +09:00
if hak_feedbchars( self. handle, text , len) < = - 1 then begin
errnum : = hak_geterrnum( self. handle) ;
2024-02-02 14:57:46 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_endfeed( self. handle) ;
hak_detachccio( self. handle) ;
if hak_errnum_is_synerr( errnum) then
2024-02-03 13:36:05 +09:00
raise Exception. Create( errmsg)
else
raise Exception. Create( 'failed to feed text - ' + errmsg) ;
2024-02-02 14:57:46 +09:00
end ;
2025-09-02 23:58:15 +09:00
if hak_endfeed( self. handle) < = - 1 then begin
2024-02-02 14:57:46 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-02 14:57:46 +09:00
raise Exception. Create( 'failed to end feeding - ' + errmsg)
end ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-02 14:57:46 +09:00
end ;
2024-02-20 15:52:28 +09:00
procedure Interp. CompileText( text : pwidechar ) ;
2024-02-02 14:57:46 +09:00
begin
2024-02-20 15:52:28 +09:00
self. CompileText( text , SysUtils. Strlen( text ) ) ;
2024-02-02 14:57:46 +09:00
end ;
2024-02-20 15:52:28 +09:00
procedure Interp. CompileText( text : pwidechar ; len: System. SizeUint) ;
2024-02-02 14:57:46 +09:00
var
2024-02-03 13:36:05 +09:00
errnum: integer ;
2024-02-02 14:57:46 +09:00
errmsg: string ;
begin
2025-09-02 23:58:15 +09:00
if hak_attachcciostdwithbcstr( self. handle, nil ) < = - 1 then
2024-02-13 00:57:30 +09:00
raise Exception. Create( 'failed to attach ccio handler - ' + self. FetchErrorMsg( ) ) ;
2024-02-02 14:57:46 +09:00
2025-09-02 23:58:15 +09:00
if hak_beginfeed( self. handle, nil ) < = - 1 then begin
2024-02-02 14:57:46 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-13 00:57:30 +09:00
raise Exception. Create( 'failed to begin feeding - ' + errmsg) ;
2024-02-02 14:57:46 +09:00
end ;
2025-09-02 23:58:15 +09:00
if hak_feeduchars( self. handle, text , len) < = - 1 then begin
errnum : = hak_geterrnum( self. handle) ;
2024-02-02 14:57:46 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_endfeed( self. handle) ;
hak_detachccio( self. handle) ;
if hak_errnum_is_synerr( errnum) then
2024-02-03 13:36:05 +09:00
raise Exception. Create( errmsg)
2024-02-13 00:57:30 +09:00
else
2024-02-03 13:36:05 +09:00
raise Exception. Create( 'failed to feed text - ' + errmsg) ;
2024-02-02 14:57:46 +09:00
end ;
2025-09-02 23:58:15 +09:00
if hak_endfeed( self. handle) < = - 1 then begin
2024-02-02 14:57:46 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-02 14:57:46 +09:00
raise Exception. Create( 'failed to end feeding - ' + errmsg)
end ;
2025-09-02 23:58:15 +09:00
hak_detachccio( self. handle) ;
2024-02-02 14:57:46 +09:00
end ;
procedure Interp. Execute( ) ;
var
2024-02-03 13:36:05 +09:00
errmsg: string ;
2024-02-02 14:57:46 +09:00
begin
2025-09-02 23:58:15 +09:00
if hak_attachudiostdwithbcstr( self. handle, nil , nil ) < = - 1 then begin
2024-02-02 14:57:46 +09:00
raise Exception. Create( 'failed to attach udio handlers - ' + self. FetchErrorMsg( ) )
end ;
2025-09-02 23:58:15 +09:00
if hak_execute( self. handle) = nil then begin
2024-02-03 13:36:05 +09:00
errmsg : = self. FetchErrorMsg( ) ;
2025-09-02 23:58:15 +09:00
hak_detachudio( self. handle) ;
2024-02-03 13:36:05 +09:00
raise Exception. Create( 'failed to execute - ' + errmsg)
2024-02-02 14:57:46 +09:00
end ;
2024-02-03 13:36:05 +09:00
2025-09-02 23:58:15 +09:00
hak_detachudio( self. handle) ;
2024-02-02 14:57:46 +09:00
end ;
end . (* unit *)