uncommented lines setting the error number in hak_geterrbinf() and hak_geterruinf()

This commit is contained in:
2025-10-20 01:02:23 +09:00
parent 31a673e185
commit 83051149cf
3 changed files with 161 additions and 81 deletions

View File

@ -284,7 +284,7 @@ void hak_geterrbinf (hak_t* hak, hak_errbinf_t* errinf)
const hak_ooch_t* msg; const hak_ooch_t* msg;
hak_oow_t wcslen, mbslen; hak_oow_t wcslen, mbslen;
/*errinf->num = hak->errnum;*/ errinf->num = hak->errnum;
errinf->loc.line = hak->errloc.line; errinf->loc.line = hak->errloc.line;
errinf->loc.colm = hak->errloc.colm; errinf->loc.colm = hak->errloc.colm;
if (!hak->errloc.file) errinf->loc.file = HAK_NULL; if (!hak->errloc.file) errinf->loc.file = HAK_NULL;
@ -307,7 +307,7 @@ void hak_geterruinf (hak_t* hak, hak_erruinf_t* errinf)
const hak_ooch_t* msg; const hak_ooch_t* msg;
hak_oow_t wcslen, mbslen; hak_oow_t wcslen, mbslen;
/*errinf->num = hak->errnum;*/ errinf->num = hak->errnum;
errinf->loc.line = hak->errloc.line; errinf->loc.line = hak->errloc.line;
errinf->loc.colm = hak->errloc.colm; errinf->loc.colm = hak->errloc.colm;
if (!hak->errloc.file) errinf->loc.file = HAK_NULL; if (!hak->errloc.file) errinf->loc.file = HAK_NULL;

View File

@ -1,4 +1,4 @@
unit HAK; unit Hak;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{$macro on} {$macro on}
@ -13,6 +13,8 @@ unit HAK;
interface interface
uses SysUtils;
type type
BitMask = longword; (* this must match hak_bitmask_t in hak.h *) BitMask = longword; (* this must match hak_bitmask_t in hak.h *)
@ -51,6 +53,35 @@ type
IO_FLUSH IO_FLUSH
); );
LocationB = record
line: System.SizeUint;
colm: System.SizeUint;
filp: PBchar;
end;
LocationU = record
line: System.SizeUint;
colm: System.SizeUint;
filp: PUchar;
end;
ErrorException = class(SysUtils.Exception)
private
error_code: integer;
error_file: string;
error_line: System.SizeUint;
error_colm: System.SizeUint;
public
constructor Create(const msg: string); overload;
constructor Create(const msg: string; cod: integer; const fil: string; lin: System.SizeUint; col: System.SizeUint); overload;
property Code: integer read error_code;
property Line: System.SizeUint read error_line;
property Column: System.SizeUint read error_colm;
property FileName: string read error_file;
end;
{$ifndef HAK_CCI_BUF_LEN} {$ifndef HAK_CCI_BUF_LEN}
{$define HAK_CCI_BUF_LEN := 2048} {$define HAK_CCI_BUF_LEN := 2048}
{$endif} {$endif}
@ -89,7 +120,7 @@ type
procedure Execute(); procedure Execute();
protected protected
function FetchErrorMsg(): string; function FetchException(const hdr: string): Exception;
end; end;
InterpExt = record InterpExt = record
@ -105,18 +136,6 @@ type
function Read(): System.SizeUint; virtual; abstract; function Read(): System.SizeUint; virtual; abstract;
end; end;
LocationB = record
line: System.SizeUint;
colm: System.SizeUint;
filp: PBchar;
end;
LocationU = record
line: System.SizeUint;
colm: System.SizeUint;
filp: PUchar;
end;
SynerrBPtr = ^SynerrB; SynerrBPtr = ^SynerrB;
SynerrB = record SynerrB = record
num: integer; num: integer;
@ -140,6 +159,7 @@ type
Errinf = Erruinf; Errinf = Erruinf;
ErrinfPtr = ErruinfPtr; ErrinfPtr = ErruinfPtr;
(*----- external hak function -----*) (*----- external hak function -----*)
function hak_errnum_to_errbcstr(errnum: integer; errbuf: pointer; errbufsz: System.SizeUint): pointer; cdecl; external; 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; function hak_errnum_is_synerr(errnum: integer): boolean; cdecl; external;
@ -183,7 +203,7 @@ function hak_count_ucstr(ptr: PUchar): System.SizeUint; cdecl; external;
implementation implementation
uses SysUtils, Math, Classes; uses Math, Classes;
type type
NamedHandle = record NamedHandle = record
@ -231,6 +251,20 @@ begin
exit(UCS4StringToWideString(arr)); exit(UCS4StringToWideString(arr));
end; end;
constructor ErrorException.Create (const msg: string);
begin
inherited Create(msg);
end;
constructor ErrorException.Create (const msg: string; cod: integer; const fil: string; lin: System.SizeUint; col: System.SizeUint);
begin
inherited Create(msg);
self.error_code := cod;
self.error_file := fil;
self.error_line := lin;
self.error_colm := col;
end;
constructor Interp.Create (x: integer); constructor Interp.Create (x: integer);
var var
h: pointer; h: pointer;
@ -273,24 +307,29 @@ begin
inherited; inherited;
end; end;
function Interp.FetchErrorMsg(): string; function Interp.FetchException(const hdr: string): Exception;
var var
num: integer; ebi: Errbinf;
bmsg: PBchar;
serr: SynerrB; serr: SynerrB;
filp: PBchar; filp: PBchar;
xmsg: string;
begin begin
num := hak_geterrnum(self.handle); hak_geterrbinf(self.handle, @ebi);
if hak_errnum_is_synerr(num) then begin if hak_errnum_is_synerr(ebi.num) then begin
bmsg := hak_geterrbmsg(self.handle);
hak_getsynerrb(self.handle, @serr); hak_getsynerrb(self.handle, @serr);
filp := PBchar(''); filp := PBchar('');
if serr.loc.filp <> nil then filp := serr.loc.filp; if serr.loc.filp <> nil then filp := serr.loc.filp;
exit(SysUtils.Format('%s at %s[%u:%u]', [string(bmsg), string(filp), serr.loc.line, serr.loc.colm])); exit(ErrorException.Create(string(ebi.msg), ebi.num, string(filp), serr.loc.line, serr.loc.colm));
end
else if ebi.loc.line > 0 then begin
exit(ErrorException.Create(string(ebi.msg), ebi.num, string(ebi.loc.filp), ebi.loc.line, ebi.loc.colm));
end end
else begin else begin
bmsg := hak_geterrbmsg(self.handle); if hdr = '' then
exit(string(bmsg)) xmsg := string(ebi.msg)
else
xmsg := SysUtils.Format('%s - %s', [hdr, string(ebi.msg)]);
exit(Exception.Create(xmsg));
end; end;
end; end;
@ -298,7 +337,7 @@ procedure Interp.Ignite(heapsize: System.SizeUint);
begin begin
if hak_ignite(self.handle, heapsize) <= -1 then if hak_ignite(self.handle, heapsize) <= -1 then
begin begin
raise Exception.Create('failed to ignite - ' + self.FetchErrorMsg()) raise self.FetchException('failed to ignite');
end; end;
end; end;
@ -306,7 +345,7 @@ procedure Interp.AddBuiltinPrims();
begin begin
if hak_addbuiltinprims(self.handle) <= -1 then if hak_addbuiltinprims(self.handle) <= -1 then
begin begin
raise Exception.Create('failed to add builtin primitives - ' + self.FetchErrorMsg()) raise self.FetchException('failed to add builtin primitives');
end; end;
end; end;
@ -409,28 +448,27 @@ var
f: System.THandle = -1; f: System.THandle = -1;
attached: boolean = false; attached: boolean = false;
feed_ongoing: boolean = false; feed_ongoing: boolean = false;
errnum: System.Integer;
errmsg: string;
buf: array[0..1023] of System.AnsiChar; buf: array[0..1023] of System.AnsiChar;
len: System.LongInt; len: System.LongInt;
excpt: SysUtils.Exception;
label label
oops; oops;
begin begin
f := SysUtils.FileOpen(filename, SysUtils.fmOpenRead); f := SysUtils.FileOpen(filename, SysUtils.fmOpenRead);
if f = System.THandle(-1) then begin if f = System.THandle(-1) then begin
errmsg := 'failed to open ' + filename + ' - ' + SysUtils.SysErrorMessage(SysUtils.GetLastOSError()); excpt := Exception.Create('failed to open ' + filename + ' - ' + SysUtils.SysErrorMessage(SysUtils.GetLastOSError()));
goto oops; goto oops;
end; end;
self.basefile := filename; self.basefile := filename;
if hak_attachccio(self.handle, @cci_handler) <= -1 then begin if hak_attachccio(self.handle, @cci_handler) <= -1 then begin
errmsg := 'failed to attach ccio handler - ' + self.FetchErrorMsg(); excpt := self.FetchException('failed to attach ccio handler');
goto oops; goto oops;
end; end;
attached := true; attached := true;
if hak_beginfeed(self.handle, nil) <= -1 then begin if hak_beginfeed(self.handle, nil) <= -1 then begin
errmsg := 'failed to begin feeding - ' + self.FetchErrorMsg(); excpt := self.FetchException('failed to begin feeding');
goto oops; goto oops;
end; end;
feed_ongoing := true; feed_ongoing := true;
@ -438,21 +476,19 @@ begin
while true do begin while true do begin
len := SysUtils.FileRead(f, buf, System.SizeOf(buf)); len := SysUtils.FileRead(f, buf, System.SizeOf(buf));
if len <= -1 then begin if len <= -1 then begin
errmsg := 'failed to read ' + filename + ' - ' + SysUtils.SysErrorMessage(SysUtils.GetLastOSError()); excpt := Exception.Create('failed to read ' + filename + ' - ' + SysUtils.SysErrorMessage(SysUtils.GetLastOSError()));
goto oops; goto oops;
end; end;
if len = 0 then break; if len = 0 then break;
if hak_feedbchars(self.handle, buf, len) <= -1 then begin if hak_feedbchars(self.handle, buf, len) <= -1 then begin
errnum := hak_geterrnum(self.handle); excpt := self.FetchException('failed to feed text');
errmsg := self.FetchErrorMsg();
if not hak_errnum_is_synerr(errnum) then errmsg := 'failed to feed text - ' + errmsg;
goto oops; goto oops;
end; end;
end; end;
if hak_endfeed(self.handle) <= -1 then begin if hak_endfeed(self.handle) <= -1 then begin
errmsg := 'failed to end feeding - ' + self.FetchErrorMsg(); excpt := self.FetchException('failed to end feeding');
goto oops; goto oops;
end; end;
feed_ongoing := false; feed_ongoing := false;
@ -467,7 +503,7 @@ oops:
if attached then hak_detachccio(self.handle); if attached then hak_detachccio(self.handle);
self.basefile := ''; self.basefile := '';
if f <> System.THandle(-1) then SysUtils.FileClose(f); if f <> System.THandle(-1) then SysUtils.FileClose(f);
raise Exception.Create(errmsg); raise excpt;
end; end;
procedure Interp.CompileText(text: System.PAnsiChar); procedure Interp.CompileText(text: System.PAnsiChar);
@ -477,33 +513,30 @@ end;
procedure Interp.CompileText(text: System.PAnsiChar; len: System.SizeUint); procedure Interp.CompileText(text: System.PAnsiChar; len: System.SizeUint);
var var
errnum: integer; excpt: Exception;
errmsg: string;
begin begin
if hak_attachcciostdwithbcstr(self.handle, nil) <= -1 then if hak_attachcciostdwithbcstr(self.handle, nil) <= -1 then begin
raise Exception.Create('failed to attach ccio handler - ' + self.FetchErrorMsg()); excpt := self.FetchException('failed to attach ccio handler');
raise excpt;
end;
if hak_beginfeed(self.handle, nil) <= -1 then begin if hak_beginfeed(self.handle, nil) <= -1 then begin
errmsg := self.FetchErrorMsg(); excpt := self.FetchException('failed to begin feeding');
hak_detachccio(self.handle); hak_detachccio(self.handle);
raise Exception.Create('failed to begin feeding - ' + errmsg); raise excpt;
end; end;
if hak_feedbchars(self.handle, text, len) <= -1 then begin if hak_feedbchars(self.handle, text, len) <= -1 then begin
errnum := hak_geterrnum(self.handle); excpt := self.FetchException('failed to feed text');
errmsg := self.FetchErrorMsg();
hak_endfeed(self.handle); hak_endfeed(self.handle);
hak_detachccio(self.handle); hak_detachccio(self.handle);
if hak_errnum_is_synerr(errnum) then raise excpt;
raise Exception.Create(errmsg)
else
raise Exception.Create('failed to feed text - ' + errmsg);
end; end;
if hak_endfeed(self.handle) <= -1 then begin if hak_endfeed(self.handle) <= -1 then begin
errmsg := self.FetchErrorMsg(); excpt := self.FetchException('failed to end feeding');
hak_detachccio(self.handle); hak_detachccio(self.handle);
raise Exception.Create('failed to end feeding - ' + errmsg) raise excpt;
end; end;
hak_detachccio(self.handle); hak_detachccio(self.handle);
@ -544,33 +577,30 @@ end;
procedure Interp.CompileText(text: PUchar; len: System.SizeUint); procedure Interp.CompileText(text: PUchar; len: System.SizeUint);
var var
errnum: integer; excpt: Exception;
errmsg: string;
begin begin
if hak_attachcciostdwithbcstr(self.handle, nil) <= -1 then if hak_attachcciostdwithbcstr(self.handle, nil) <= -1 then begin
raise Exception.Create('failed to attach ccio handler - ' + self.FetchErrorMsg()); excpt := self.FetchException('failed to attach ccio handler');
raise excpt;
end;
if hak_beginfeed(self.handle, nil) <= -1 then begin if hak_beginfeed(self.handle, nil) <= -1 then begin
errmsg := self.FetchErrorMsg(); excpt := self.FetchException('failed to begin feeding');
hak_detachccio(self.handle); hak_detachccio(self.handle);
raise Exception.Create('failed to begin feeding - ' + errmsg); raise excpt;
end; end;
if hak_feeduchars(self.handle, text, len) <= -1 then begin if hak_feeduchars(self.handle, text, len) <= -1 then begin
errnum := hak_geterrnum(self.handle); excpt := self.FetchException('failed to feed text');
errmsg := self.FetchErrorMsg();
hak_endfeed(self.handle); hak_endfeed(self.handle);
hak_detachccio(self.handle); hak_detachccio(self.handle);
if hak_errnum_is_synerr(errnum) then raise excpt;
raise Exception.Create(errmsg)
else
raise Exception.Create('failed to feed text - ' + errmsg);
end; end;
if hak_endfeed(self.handle) <= -1 then begin if hak_endfeed(self.handle) <= -1 then begin
errmsg := self.FetchErrorMsg(); excpt := self.FetchException('failed to end feeding');
hak_detachccio(self.handle); hak_detachccio(self.handle);
raise Exception.Create('failed to end feeding - ' + errmsg) raise excpt;
end; end;
hak_detachccio(self.handle); hak_detachccio(self.handle);
@ -579,19 +609,19 @@ end;
procedure Interp.Execute(); procedure Interp.Execute();
var var
errmsg: string; excpt: Exception;
begin begin
if hak_attachudiostdwithbcstr(self.handle, nil, nil) <= -1 then begin if hak_attachudiostdwithbcstr(self.handle, nil, nil) <= -1 then begin
raise Exception.Create('failed to attach udio handlers - ' + self.FetchErrorMsg()) excpt := self.FetchException('failed to attach udio handlers');
raise excpt;
end; end;
if hak_execute(self.handle) = nil then begin if hak_execute(self.handle) = nil then begin
errmsg := self.FetchErrorMsg(); excpt := self.FetchException(''); (* no header message used to make the error format the same as bin/hak *)
hak_detachudio(self.handle); hak_detachudio(self.handle);
raise Exception.Create('failed to execute - ' + errmsg) raise excpt;
end; end;
hak_detachudio(self.handle); hak_detachudio(self.handle);
end; end;
end. (* unit *) end. (* unit *)

View File

@ -2,19 +2,65 @@ program main;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
uses HAK, SysUtils; uses Hak, SysUtils, GetOpts;
var var
x: HAK.Interp = nil;
(*c: System.AnsiChar;*)
c: Char;
optind: System.LongInt;
opts: array[0..2] of GetOpts.TOption;
source_file: string;
x: Hak.Interp = nil;
procedure print_usage_and_halt();
begin begin
(* System.ParamCount() returns only the number of argumetns except System.ParamStr(0). It is the upper bound to System.ParamStr(). *)
if System.ParamCount() <> 1 then begin
writeln(System.Stderr, SysUtils.Format('Usage: %s <filename>', [SysUtils.ExtractFileName(System.ParamStr(0))])); writeln(System.Stderr, SysUtils.Format('Usage: %s <filename>', [SysUtils.ExtractFileName(System.ParamStr(0))]));
System.Halt(-1); System.Halt(-1);
end; end;
begin
(* System.ParamCount() returns only the number of argumetns except System.ParamStr(0). It is the upper bound to System.ParamStr(). *)
opts[0].name := 'heapsize';
opts[0].has_arg := 1;
opts[0].value := #0;
opts[0].flag := nil;
opts[1].name := 'modlibdirs';
opts[1].has_arg := 1;
opts[1].value := #0;
opts[1].flag := nil;
opts[2].name := ''; (* marker for the last item *)
opts[2].has_arg := 0;
opts[2].value := #0;
opts[2].flag := nil;
(* TODO: proper command-line options handling *)
c := #0;
GetOpts.OptErr := false;
repeat
c := GetOpts.GetLongOpts(':', @opts[0], optind);
case c of
#0:
begin
(*TODO: process options.. *)
(*opts[optind].name*)
(*GetOpts.OptArg is the value *)
end;
'?', ':':
print_usage_and_halt;
end;
until c = GetOpts.EndOfOptions;
if GetOpts.OptInd <> System.ParamCount() then begin
print_usage_and_halt;
end;
source_file := System.ParamStr(GetOpts.OptInd);
try try
x := HAK.Interp.Create(100); x := Hak.Interp.Create(100);
x.Ignite(0); x.Ignite(0);
x.AddBuiltinPrims(); x.AddBuiltinPrims();
@ -30,13 +76,17 @@ begin
x.Compile(pwidechar('(printf "%d %d\n" 동가리오 (동가리오 * 동가리오))'#10'printf "hello, world\n";;;'#10)); x.Compile(pwidechar('(printf "%d %d\n" 동가리오 (동가리오 * 동가리오))'#10'printf "hello, world\n";;;'#10));
*) *)
x.CompileFile(pansichar(ansistring(System.ParamStr(1)))); x.CompileFile(pansichar(ansistring(source_file)));
x.Execute(); // check if exception... x.Execute(); // check if exception...
except except
on e: Hak.ErrorException do begin
if e.FileName <> '' then source_file := e.FileName;
writeln('ERROR: ', SysUtils.Format('%s[%u,%u] %s', [source_file, e.Line, e.Column, e.Message]));
end;
on e: Exception do on e: Exception do
writeln('exception: ', e.Message); writeln('ERROR: ', e.Message);
else else
writeln('unknonw exception'); writeln('ERROR: unknonw exception');
end; end;
if x <> nil then x.Destroy(); if x <> nil then x.Destroy();