mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-01-25 03:37:15 +00:00
as: convert to module-tagged errors, format_error/1, and error:format/1; improve specs
This commit is contained in:
parent
5e34a16dec
commit
295a44f67d
@ -36,8 +36,8 @@ main_(Argv) ->
|
||||
ok -> halt(0);
|
||||
{error, _Reason} = Error -> escript_runtime:fatal("~p\n", [Error])
|
||||
end;
|
||||
{error, ErrMsg} ->
|
||||
escript_runtime:errmsg("~s\n", [ErrMsg]),
|
||||
{error, Reason} ->
|
||||
escript_runtime:errmsg("~s\n", [error:format(Reason)]),
|
||||
usage()
|
||||
end.
|
||||
|
||||
|
||||
@ -21,11 +21,13 @@
|
||||
-module(assemble).
|
||||
|
||||
-export([ tunit/1
|
||||
, format_error/1
|
||||
]).
|
||||
|
||||
-include("tunit.hrl").
|
||||
-include_lib("lib/include/pdp10_elf36.hrl").
|
||||
|
||||
-spec tunit(#tunit{}) -> {ok, #tunit{}} | {error, {module(), term()}}.
|
||||
tunit(Tunit) ->
|
||||
sections(maps:values(Tunit#tunit.sections), Tunit).
|
||||
|
||||
@ -47,7 +49,7 @@ section(Section, Tunit) ->
|
||||
, sh_flags = ?SHF_MERGE bor ?SHF_STRINGS
|
||||
} -> comment(Section, Tunit);
|
||||
#section{ name = Name } ->
|
||||
{error, io_lib:format("don't know how to assemble section ~s", [Name])}
|
||||
{error, {?MODULE, {cannot_assemble, Name}}}
|
||||
end.
|
||||
|
||||
%% Assemble .comment -----------------------------------------------------------
|
||||
@ -100,3 +102,9 @@ insn_image(Insn) ->
|
||||
(Word bsr 18) band 511,
|
||||
(Word bsr 9) band 511,
|
||||
Word band 511].
|
||||
|
||||
%% Error reporting -------------------------------------------------------------
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
format_error({cannot_assemble, Name}) ->
|
||||
io_lib:format("don't know how to assemble section ~s", [Name]).
|
||||
|
||||
@ -21,11 +21,13 @@
|
||||
-module(input).
|
||||
|
||||
-export([ files/1
|
||||
, format_error/1
|
||||
]).
|
||||
|
||||
-include("tunit.hrl").
|
||||
-include_lib("lib/include/pdp10_elf36.hrl").
|
||||
|
||||
-spec files([string()]) -> {ok, #tunit{}} | {error, {module(), term()}}.
|
||||
files(Files) ->
|
||||
NewFiles =
|
||||
case Files of
|
||||
@ -235,9 +237,11 @@ section_dot_text() -> % ".text"
|
||||
|
||||
%% Error reporting -------------------------------------------------------------
|
||||
|
||||
%% FIXME: this is duplicated a few times, move it to scan_state.erl
|
||||
fmterr(ScanState, Fmt, Args) ->
|
||||
{ok, FileName} = scan_state:filename(ScanState),
|
||||
{ok, LineNr} = scan_state:linenr(ScanState),
|
||||
{error, lists:flatten(io_lib:format("file ~s line ~p: " ++ Fmt,
|
||||
[FileName, LineNr | Args]))}.
|
||||
{error, {?MODULE, {FileName, LineNr, Fmt, Args}}}.
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
format_error({FileName, LineNr, Fmt, Args}) ->
|
||||
io_lib:format("file ~s line ~p: " ++ Fmt, [FileName, LineNr | Args]).
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
-module(output).
|
||||
|
||||
-export([ tunit/2
|
||||
, format_error/1
|
||||
]).
|
||||
|
||||
-include("tunit.hrl").
|
||||
@ -64,6 +65,7 @@
|
||||
, strtab :: #strtab{}
|
||||
}).
|
||||
|
||||
-spec tunit(#tunit{}, string()) -> ok | {error, {module(), term()}}.
|
||||
tunit(Tunit, File) ->
|
||||
emit(layout(Tunit), File).
|
||||
|
||||
@ -330,7 +332,7 @@ emit(Context, File) ->
|
||||
emit(Funs, Context, FP, 0)
|
||||
after pdp10_stdio:fclose(FP)
|
||||
end;
|
||||
{error, Reason} -> {error, io_lib:format("opening ~s: ~p", [File, Reason])}
|
||||
{error, Reason} -> {error, {?MODULE, {cannot_open, File, Reason}}}
|
||||
end.
|
||||
|
||||
emit([], _Context, _FP, _Offset) -> ok;
|
||||
@ -558,3 +560,9 @@ image_write([H | T], FP) ->
|
||||
image_write([], _FP) -> ok;
|
||||
image_write(TByte, FP) when is_integer(TByte), 0 =< TByte, TByte =< 511 ->
|
||||
pdp10_stdio:fputc(TByte, FP).
|
||||
|
||||
%% Error reporting -------------------------------------------------------------
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
format_error({cannot_open, File, Reason}) ->
|
||||
io_lib:format("opening ~s: ~s", [File, error:format(Reason)]).
|
||||
|
||||
@ -21,12 +21,15 @@
|
||||
-module(parse).
|
||||
|
||||
-export([ stmt/1
|
||||
, format_error/1
|
||||
]).
|
||||
|
||||
-include("token.hrl").
|
||||
-include("tunit.hrl").
|
||||
-include_lib("lib/include/pdp10_opcodes.hrl").
|
||||
|
||||
-spec stmt(scan_state:scan_state())
|
||||
-> {ok, stmt()} | eof | {error, {module(), term()}}.
|
||||
stmt(ScanState) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, ?T_DOT_FILE} -> dot_file(ScanState);
|
||||
@ -303,10 +306,13 @@ dot_type(ScanState) ->
|
||||
|
||||
badtok(_ScanState, _ErrMsg, {error, _Reason} = Error) -> Error;
|
||||
badtok(ScanState, ErrMsg, {ok, Token}) ->
|
||||
fmterr(ScanState, ErrMsg ++ "; current token is ~s", [token:to_string(Token)]).
|
||||
fmterr(ScanState, ErrMsg ++ "; current token is ~s", [token:format(Token)]).
|
||||
|
||||
fmterr(ScanState, Fmt, Args) ->
|
||||
{ok, FileName} = scan_state:filename(ScanState),
|
||||
{ok, LineNr} = scan_state:linenr(ScanState),
|
||||
{error, lists:flatten(io_lib:format("file ~s line ~p: " ++ Fmt,
|
||||
[FileName, LineNr | Args]))}.
|
||||
{error, {?MODULE, {FileName, LineNr, Fmt, Args}}}.
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
format_error({FileName, LineNr, Fmt, Args}) ->
|
||||
io_lib:format("file ~s line ~p: " ++ Fmt, [FileName, LineNr | Args]).
|
||||
|
||||
@ -21,10 +21,13 @@
|
||||
-module(scan).
|
||||
|
||||
-export([ token/1
|
||||
, format_error/1
|
||||
]).
|
||||
|
||||
-include("token.hrl").
|
||||
|
||||
-spec token(scan_state:scan_state())
|
||||
-> {ok, token()} | {error, {module(), term()}}.
|
||||
token(ScanState) ->
|
||||
case scan_state:fgetc(ScanState) of
|
||||
{error, _Reason} = Error -> Error;
|
||||
@ -220,11 +223,14 @@ chval(Ch) ->
|
||||
end.
|
||||
|
||||
badchar(ScanState, Ch, Context) ->
|
||||
ChStr = char_to_string(Ch),
|
||||
{ok, FileName} = scan_state:filename(ScanState),
|
||||
{ok, LineNr} = scan_state:linenr(ScanState),
|
||||
{error, lists:flatten(io_lib:format("~s line ~p: invalid character '~s' ~s",
|
||||
[FileName, LineNr, ChStr, Context]))}.
|
||||
{error, {?MODULE, {FileName, LineNr, Ch, Context}}}.
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
format_error({FileName, LineNr, Ch, Context}) ->
|
||||
io_lib:format("~s line ~p: invalid character '~s' ~s",
|
||||
[FileName, LineNr, char_to_string(Ch), Context]).
|
||||
|
||||
char_to_string(eof) -> "<EOF>";
|
||||
char_to_string(Ch) when $\s =< Ch, Ch =< $~ -> [$', Ch, $'];
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
% meta-data accessors
|
||||
, filename/1
|
||||
, linenr/1
|
||||
, format_error/1
|
||||
]).
|
||||
|
||||
%% gen_server callbacks
|
||||
@ -52,39 +53,54 @@
|
||||
, linenr :: pos_integer()
|
||||
}).
|
||||
|
||||
-type scan_state() :: pid().
|
||||
|
||||
-export_type([scan_state/0]).
|
||||
|
||||
%% API -------------------------------------------------------------------------
|
||||
|
||||
-spec fclose(pid()) -> ok | {error, any()}.
|
||||
-spec fclose(scan_state()) -> ok | {error, {module(), term()}}.
|
||||
fclose(Pid) ->
|
||||
gen_server:call(Pid, fclose, infinity).
|
||||
|
||||
-spec fgetc(pid()) -> {ok, byte()} | eof | {error, any()}.
|
||||
-spec fgetc(scan_state()) -> {ok, byte()} | eof | {error, {module(), term()}}.
|
||||
fgetc(Pid) ->
|
||||
gen_server:call(Pid, fgetc, infinity).
|
||||
|
||||
-spec fopen(string()) -> {ok, pid()} | {error, any()}.
|
||||
-spec fopen(string()) -> {ok, scan_state()} | {error, {module(), term()}}.
|
||||
fopen(File) ->
|
||||
do_fopen(File).
|
||||
|
||||
-spec stdin() -> {ok, pid()}.
|
||||
-spec stdin() -> {ok, scan_state()}.
|
||||
stdin() ->
|
||||
do_fopen(stdin).
|
||||
|
||||
do_fopen(File) ->
|
||||
gen_server:start(?MODULE, File, []).
|
||||
|
||||
-spec ungetc(byte(), pid()) -> ok | {error, any()}.
|
||||
-spec ungetc(byte(), scan_state()) -> ok | {error, {module(), term()}}.
|
||||
ungetc(Ch, Pid) ->
|
||||
gen_server:call(Pid, {ungetc, Ch}, infinity).
|
||||
|
||||
-spec filename(pid()) -> {ok, string()}.
|
||||
-spec filename(scan_state()) -> {ok, string()}.
|
||||
filename(Pid) ->
|
||||
gen_server:call(Pid, filename, infinity).
|
||||
|
||||
-spec linenr(pid()) -> {ok, pos_integer()}.
|
||||
-spec linenr(scan_state()) -> {ok, pos_integer()}.
|
||||
linenr(Pid) ->
|
||||
gen_server:call(Pid, linenr, infinity).
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
format_error(Reason) ->
|
||||
case Reason of
|
||||
{bad_request, Req} ->
|
||||
io_lib:format("internal error: bad request: ~p", [Req]);
|
||||
ungetc ->
|
||||
"internal error: invalid ungetc";
|
||||
_ ->
|
||||
io_lib:format("~p", [Reason])
|
||||
end.
|
||||
|
||||
%% gen_server callbacks --------------------------------------------------------
|
||||
|
||||
init(stdin) ->
|
||||
@ -92,7 +108,7 @@ init(stdin) ->
|
||||
init(File) ->
|
||||
case file:open(File, [raw, read, read_ahead]) of
|
||||
{ok, IoDev} -> do_init(File, IoDev);
|
||||
{error, Reason} -> {stop, Reason}
|
||||
{error, Reason} -> {stop, {file, Reason}}
|
||||
end.
|
||||
|
||||
do_init(FileName, IoDev) ->
|
||||
@ -115,7 +131,7 @@ handle_call(Req, _From, State) ->
|
||||
linenr ->
|
||||
{reply, {ok, State#state.linenr}, State};
|
||||
_ ->
|
||||
{reply, {error, {bad_request, Req}}, State}
|
||||
{reply, {error, {?MODULE, {bad_request, Req}}}, State}
|
||||
end.
|
||||
|
||||
handle_cast(_Req, State) ->
|
||||
@ -155,7 +171,7 @@ handle_fgetc(State) ->
|
||||
_ -> State
|
||||
end};
|
||||
eof -> {eof, State};
|
||||
{error, _Reason} = Error -> {Error, State}
|
||||
{error, Reason} -> {{error, {file, Reason}}, State}
|
||||
end,
|
||||
{reply, Result, NewState};
|
||||
Ch ->
|
||||
@ -167,5 +183,5 @@ handle_fgetc(State) ->
|
||||
handle_ungetc(State, Ch) ->
|
||||
case State#state.ungetc of
|
||||
[] -> {reply, ok, State#state{ungetc = Ch}};
|
||||
_ -> {reply, {error, ungetc}, State}
|
||||
_ -> {reply, {error, {?MODULE, ungetc}}, State}
|
||||
end.
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
-module(token).
|
||||
|
||||
-export([ from_symbol/1
|
||||
, to_string/1
|
||||
, format/1
|
||||
]).
|
||||
|
||||
-include("token.hrl").
|
||||
@ -38,8 +38,8 @@ from_symbol(Name) ->
|
||||
_ -> {?T_SYMBOL, Name}
|
||||
end.
|
||||
|
||||
-spec to_string(token()) -> string().
|
||||
to_string(Token) ->
|
||||
-spec format(token()) -> io_lib:chars().
|
||||
format(Token) ->
|
||||
case Token of
|
||||
?T_DOT_FILE -> ".file";
|
||||
?T_DOT_GLOBL -> ".globl";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user