205 lines
5.6 KiB
ObjectPascal
205 lines
5.6 KiB
ObjectPascal
unit HCL;
|
|
|
|
{$mode objfpc}{$H+}
|
|
{$linklib hcl}
|
|
{$linklib c}
|
|
{$linklib gcc}
|
|
{$linklib quadmath}
|
|
|
|
interface
|
|
|
|
type
|
|
Interp = class
|
|
public
|
|
handle: pointer;
|
|
private
|
|
handle1: integer;
|
|
handle2: integer;
|
|
handle3: integer;
|
|
handle4: integer;
|
|
handle5: integer;
|
|
handle6: integer;
|
|
public
|
|
constructor Create (x: integer);
|
|
destructor Destroy; override;
|
|
procedure Ignite(heapsize: sizeint);
|
|
procedure AddBuiltinPrims();
|
|
procedure Compile(text: pansichar);
|
|
procedure Compile(text: pansichar; len: sizeint);
|
|
procedure Compile(text: pwidechar);
|
|
procedure Compile(text: pwidechar; len: sizeint);
|
|
procedure Execute();
|
|
|
|
protected
|
|
function FetchErrorMsg(): string;
|
|
end;
|
|
|
|
InterpPtr = ^Interp;
|
|
|
|
(*----- external hcl function -----*)
|
|
function hcl_errnum_to_errbcstr(errnum: integer; errbuf: pointer; errbufsz: sizeint): pointer; cdecl; external;
|
|
function hcl_openstd(xtnsize: sizeint; errnum: pointer): pointer; cdecl; external;
|
|
procedure hcl_close(handle: pointer); cdecl; external;
|
|
function hcl_geterrbmsg(handle: pointer): pansichar; cdecl; external;
|
|
function hcl_ignite(handle: pointer; heapsize: sizeint): integer; cdecl; external;
|
|
function hcl_addbuiltinprims(handle: pointer): integer; cdecl; external;
|
|
function hcl_beginfeed(handle: pointer; on_cnode: pointer): integer; cdecl; external;
|
|
function hcl_feedbchars(handle: pointer; data: pansichar; len: sizeint): integer; cdecl; external;
|
|
function hcl_feeduchars(handle: pointer; data: pwidechar; len: sizeint): integer; cdecl; external; (* this is wrong in deed *)
|
|
function hcl_endfeed(handle: pointer): integer; cdecl; external;
|
|
|
|
function hcl_attachcciostdwithbcstr(handle: pointer; cci: pansichar): integer; cdecl; external;
|
|
procedure hcl_detachccio(handle: pointer); cdecl; external;
|
|
function hcl_attachudiostdwithbcstr(handle: pointer; udi: pansichar; udo: pansichar): integer; cdecl; external;
|
|
procedure hcl_detachudio(handle: pointer); cdecl; external;
|
|
function hcl_compile(handle: pointer; cnode: pointer; flags: integer): integer; cdecl; external;
|
|
function hcl_execute(handle: pointer): integer; cdecl; external;
|
|
procedure hcl_abort(handle: pointer) cdecl; external;
|
|
|
|
function hcl_count_ucstr(ptr: pwidechar): sizeint; cdecl; external;
|
|
(*----- end external hcl function -----*)
|
|
|
|
implementation
|
|
|
|
uses sysutils;
|
|
|
|
constructor Interp.Create (x: integer);
|
|
var
|
|
h: pointer;
|
|
errnum: integer;
|
|
errmsg: array[0..255] of AnsiChar;
|
|
begin
|
|
h := hcl_openstd(0, @errnum);
|
|
if h = nil then begin
|
|
hcl_errnum_to_errbcstr (errnum, @errmsg, length(errmsg));
|
|
raise Exception.Create(errmsg);
|
|
end;
|
|
self.handle := h;
|
|
end;
|
|
|
|
destructor Interp.Destroy;
|
|
begin
|
|
if self.handle <> nil then
|
|
begin
|
|
hcl_close(self.handle);
|
|
self.handle := nil;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
function Interp.FetchErrorMsg(): string;
|
|
var
|
|
bmsg: PAnsiChar;
|
|
begin
|
|
(* TODO: if the errocode is syntax error. use the systax error message and locations info *)
|
|
bmsg := hcl_geterrbmsg(self.handle);
|
|
exit(string(bmsg))
|
|
end;
|
|
|
|
procedure Interp.Ignite(heapsize: sizeint);
|
|
begin
|
|
if hcl_ignite(self.handle, heapsize) <= -1 then
|
|
begin
|
|
(* TODO: proper error message *)
|
|
raise Exception.Create('failed to ignite - ' + self.FetchErrorMsg())
|
|
end;
|
|
end;
|
|
|
|
procedure Interp.AddBuiltinPrims();
|
|
begin
|
|
(* TODO: proper error message *)
|
|
if hcl_addbuiltinprims(self.handle) <= -1 then
|
|
begin
|
|
raise Exception.Create('failed to add builtin primitives - ' + self.FetchErrorMsg())
|
|
end;
|
|
end;
|
|
|
|
procedure Interp.Compile(text: pansichar);
|
|
begin
|
|
self.Compile(text, sysutils.strlen(text));
|
|
end;
|
|
|
|
procedure Interp.Compile(text: pansichar; len: sizeint);
|
|
var
|
|
errmsg: string;
|
|
begin
|
|
if hcl_attachcciostdwithbcstr(self.handle, nil) <= -1 then begin
|
|
raise Exception.Create('failed to attach ccio handlers - ' + self.FetchErrorMsg())
|
|
end;
|
|
|
|
if hcl_beginfeed(self.handle, nil) <= -1 then begin
|
|
errmsg := self.FetchErrorMsg();
|
|
hcl_detachccio(self.handle);
|
|
raise Exception.Create('failed to begin feeding - ' + errmsg)
|
|
end;
|
|
|
|
if hcl_feedbchars(self.handle, text, len) <= -1 then begin
|
|
errmsg := self.FetchErrorMsg();
|
|
hcl_endfeed(self.handle);
|
|
hcl_detachccio(self.handle);
|
|
raise Exception.Create('failed to feed text - ' + errmsg)
|
|
end;
|
|
|
|
if hcl_endfeed(self.handle) <= -1 then begin
|
|
errmsg := self.FetchErrorMsg();
|
|
hcl_detachccio(self.handle);
|
|
raise Exception.Create('failed to end feeding - ' + errmsg)
|
|
end;
|
|
|
|
hcl_detachccio(self.handle);
|
|
end;
|
|
|
|
procedure Interp.Compile(text: pwidechar);
|
|
begin
|
|
self.Compile(text, sysutils.strlen(text));
|
|
end;
|
|
|
|
procedure Interp.Compile(text: pwidechar; len: sizeint);
|
|
var
|
|
errmsg: string;
|
|
begin
|
|
if hcl_attachcciostdwithbcstr(self.handle, nil) <= -1 then begin
|
|
raise Exception.Create('failed to attach ccio handlers - ' + self.FetchErrorMsg())
|
|
end;
|
|
|
|
if hcl_beginfeed(self.handle, nil) <= -1 then begin
|
|
errmsg := self.FetchErrorMsg();
|
|
hcl_detachccio(self.handle);
|
|
raise Exception.Create('failed to begin feeding - ' + errmsg)
|
|
end;
|
|
|
|
if hcl_feeduchars(self.handle, text, len) <= -1 then begin
|
|
errmsg := self.FetchErrorMsg();
|
|
hcl_endfeed(self.handle);
|
|
hcl_detachccio(self.handle);
|
|
raise Exception.Create('failed to feed text - ' + errmsg)
|
|
end;
|
|
|
|
if hcl_endfeed(self.handle) <= -1 then begin
|
|
errmsg := self.FetchErrorMsg();
|
|
hcl_detachccio(self.handle);
|
|
raise Exception.Create('failed to end feeding - ' + errmsg)
|
|
end;
|
|
|
|
hcl_detachccio(self.handle);
|
|
end;
|
|
|
|
|
|
procedure Interp.Execute();
|
|
var
|
|
n: integer;
|
|
begin
|
|
if hcl_attachudiostdwithbcstr(self.handle, nil, nil) <= -1 then begin
|
|
raise Exception.Create('failed to attach udio handlers - ' + self.FetchErrorMsg())
|
|
end;
|
|
n := hcl_execute(self.handle);
|
|
hcl_detachudio(self.handle);
|
|
if n <= -1 then
|
|
begin
|
|
raise Exception.Create('failed to execute - ' + self.FetchErrorMsg())
|
|
end;
|
|
end;
|
|
|
|
end. (* unit *)
|
|
|