mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-01-24 03:18:22 +00:00
as: parse: use tokens' location tags for diagnostics
This commit is contained in:
parent
34202b2e2f
commit
589e2c40bb
@ -43,11 +43,11 @@ stmt(ScanState) ->
|
||||
{ok, {_Location, ?T_DOT_SUBSECTION}} -> dot_subsection(ScanState);
|
||||
{ok, {_Location, ?T_DOT_TEXT}} -> dot_text(ScanState);
|
||||
{ok, {_Location, ?T_DOT_TYPE}} -> dot_type(ScanState);
|
||||
{ok, {_Location, {?T_SYMBOL, Name}}} -> stmt_after_symbol(ScanState, Name);
|
||||
{ok, {Location, {?T_SYMBOL, Name}}} -> stmt_after_symbol(ScanState, Location, Name);
|
||||
{ok, {_Location, {?T_UINTEGER, UInt}}} -> stmt_after_uinteger(ScanState, UInt);
|
||||
{ok, {_Location, ?T_NEWLINE}} -> stmt(ScanState);
|
||||
{ok, {_Location, ?T_EOF}} -> eof;
|
||||
ScanRes -> badtok(ScanState, "expected directive, label, or instruction", ScanRes)
|
||||
ScanRes -> badtok("expected directive, label, or instruction", ScanRes)
|
||||
end.
|
||||
|
||||
%% Instructions and labels -----------------------------------------------------
|
||||
@ -94,120 +94,120 @@ stmt(ScanState) ->
|
||||
%% This means that "opcode (...)" is interpreted as having a displacement but no
|
||||
%% index. Use "opcode 0(index)" if an index with zero displacement is needed.
|
||||
|
||||
stmt_after_symbol(ScanState, Name) ->
|
||||
stmt_after_symbol(ScanState, Location, Name) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_COLON}} -> {ok, #s_label{name = Name}};
|
||||
{ok, {_Location, ?T_NEWLINE}} -> make_insn(ScanState, Name, false, false, false, false);
|
||||
{ok, {_Location, {?T_UINTEGER, UInt}}} -> insn_uint(ScanState, Name, UInt);
|
||||
{ok, {_Location, {?T_SYMBOL, Symbol}}} -> insn_symbol(ScanState, Name, Symbol);
|
||||
{ok, {_Location, ?T_NEWLINE}} -> make_insn(Location, Name, false, false, false, false);
|
||||
{ok, {_Location, {?T_UINTEGER, UInt}}} -> insn_uint(ScanState, Location, Name, UInt);
|
||||
{ok, {_Location, {?T_SYMBOL, Symbol}}} -> insn_symbol(ScanState, Location, Name, Symbol);
|
||||
{ok, {_Location, {?T_LOCAL_LABEL, Number, Direction}}} ->
|
||||
insn_local_label(ScanState, Name, Number, Direction);
|
||||
ScanRes -> badtok(ScanState, "junk after symbol", ScanRes)
|
||||
insn_local_label(ScanState, Location, Name, Number, Direction);
|
||||
ScanRes -> badtok("junk after symbol", ScanRes)
|
||||
end.
|
||||
|
||||
%% <stmt> ::= <uinteger> . ":"
|
||||
stmt_after_uinteger(ScanState, UInt) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_COLON}} -> {ok, #s_local_label{number = UInt}};
|
||||
ScanRes -> badtok(ScanState, "junk after symbol", ScanRes)
|
||||
ScanRes -> badtok("junk after symbol", ScanRes)
|
||||
end.
|
||||
|
||||
%% Seen "<symbol> <uinteger>". The <uinteger> is the <accumulator> if followed
|
||||
%% by ",", otherwise (the start of) the <displacement>.
|
||||
insn_uint(ScanState, Name, UInt) ->
|
||||
insn_uint(ScanState, Location, Name, UInt) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_COMMA}} -> % the Uint is the Accumulator, parse EA next
|
||||
insn_ea(ScanState, Name, _AccOrDev = UInt);
|
||||
insn_ea(ScanState, Location, Name, _AccOrDev = UInt);
|
||||
{ok, {_Location, ?T_LPAREN}} -> % the Uint is the Displacement, parse Index next
|
||||
Displacement = #e_integer{value = UInt},
|
||||
insn_ea_index(ScanState, Name, _AccOrDev = false, _At = false, Displacement);
|
||||
insn_ea_index(ScanState, Location, Name, _AccOrDev = false, _At = false, Displacement);
|
||||
{ok, {_Location, ?T_NEWLINE}} -> % the Uint is the Displacement
|
||||
Displacement = #e_integer{value = UInt},
|
||||
make_insn(ScanState, Name, _AccOrDev = false, _At = false, Displacement, _Index = false);
|
||||
ScanRes -> badtok(ScanState, "junk after <symbol> <uinteger>", ScanRes)
|
||||
make_insn(Location, Name, _AccOrDev = false, _At = false, Displacement, _Index = false);
|
||||
ScanRes -> badtok("junk after <symbol> <uinteger>", ScanRes)
|
||||
end.
|
||||
|
||||
%% Seen "<symbol> <symbol2>". The <symbol2> is (the start of) the <displacement>.
|
||||
%% TODO: permit <symbol2> to be the <accumulator> (named register or device).
|
||||
insn_symbol(ScanState, Name, Symbol2) ->
|
||||
insn_symbol(ScanState, Location, Name, Symbol2) ->
|
||||
Displacement = #e_symbol{name = Symbol2},
|
||||
insn_ea_disp(ScanState, Name, _AccOrDev = false, _At = false, Displacement).
|
||||
insn_ea_disp(ScanState, Location, Name, _AccOrDev = false, _At = false, Displacement).
|
||||
|
||||
%% Seen "<symbol> <local label>". The <local label> is (the start of) the <displacement>.
|
||||
insn_local_label(ScanState, Name, Number, Direction) ->
|
||||
insn_local_label(ScanState, Location, Name, Number, Direction) ->
|
||||
Displacement = #e_local_label{number = Number, direction = Direction},
|
||||
insn_ea_disp(ScanState, Name, _AccOrDev = false, _At = false, Displacement).
|
||||
insn_ea_disp(ScanState, Location, Name, _AccOrDev = false, _At = false, Displacement).
|
||||
|
||||
%% <symbol> <accordev> "," . [ ["@"] <displacement> ["(" <index> ")"] ] <newline>
|
||||
insn_ea(ScanState, Name, AccOrDev) ->
|
||||
insn_ea(ScanState, Location, Name, AccOrDev) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_NEWLINE}} ->
|
||||
make_insn(ScanState, Name, AccOrDev, _At = false, _Displacement = false, _Index = false);
|
||||
{ok, {_Location, ?T_AT}} -> insn_ea_at(ScanState, Name, AccOrDev);
|
||||
make_insn(Location, Name, AccOrDev, _At = false, _Displacement = false, _Index = false);
|
||||
{ok, {_Location, ?T_AT}} -> insn_ea_at(ScanState, Location, Name, AccOrDev);
|
||||
{ok, {_Lcation, {?T_UINTEGER, UInt}}} ->
|
||||
Displacement = #e_integer{value = UInt},
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, _At = false, Displacement);
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, _At = false, Displacement);
|
||||
{ok, {_Location, {?T_SYMBOL, Symbol}}} ->
|
||||
Displacement = #e_symbol{name = Symbol},
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, _At = false, Displacement);
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, _At = false, Displacement);
|
||||
{ok, {_Location, {?T_LOCAL_LABEL, Number, Direction}}} ->
|
||||
Displacement = #e_local_label{number = Number, direction = Direction},
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, _At = false, Displacement);
|
||||
ScanRes -> badtok(ScanState, "junk after comma", ScanRes)
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, _At = false, Displacement);
|
||||
ScanRes -> badtok("junk after comma", ScanRes)
|
||||
end.
|
||||
|
||||
%% <symbol> [<accordev> ","] "@" . <displacement> ["(" <index> ")"] <newline>
|
||||
insn_ea_at(ScanState, Name, AccOrDev) ->
|
||||
insn_ea_at(ScanState, Location, Name, AccOrDev) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, {?T_UINTEGER, UInt}}} ->
|
||||
Displacement = #e_integer{value = UInt},
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, _At = true, Displacement);
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, _At = true, Displacement);
|
||||
{ok, {_Location, {?T_SYMBOL, Symbol}}} ->
|
||||
Displacement = #e_symbol{name = Symbol},
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, _At = true, Displacement);
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, _At = true, Displacement);
|
||||
{ok, {_Location, {?T_LOCAL_LABEL, Number, Direction}}} ->
|
||||
Displacement = #e_local_label{number = Number, direction = Direction},
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, _At = true, Displacement);
|
||||
ScanRes -> badtok(ScanState, "junk after @", ScanRes)
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, _At = true, Displacement);
|
||||
ScanRes -> badtok("junk after @", ScanRes)
|
||||
end.
|
||||
|
||||
%% <symbol> [<accordev> ","] ["@"] <displacement> . ["(" <index> ")"] <newline>
|
||||
insn_ea_disp(ScanState, Name, AccOrDev, At, Displacement) ->
|
||||
insn_ea_disp(ScanState, Location, Name, AccOrDev, At, Displacement) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_LPAREN}} -> insn_ea_index(ScanState, Name, AccOrDev, At, Displacement);
|
||||
{ok, {_Location, ?T_NEWLINE}} -> make_insn(ScanState, Name, AccOrDev, At, Displacement, _Index = false);
|
||||
ScanRes -> badtok(ScanState, "junk after <displacement>", ScanRes)
|
||||
{ok, {_Location, ?T_LPAREN}} -> insn_ea_index(ScanState, Location, Name, AccOrDev, At, Displacement);
|
||||
{ok, {_Location, ?T_NEWLINE}} -> make_insn(Location, Name, AccOrDev, At, Displacement, _Index = false);
|
||||
ScanRes -> badtok("junk after <displacement>", ScanRes)
|
||||
end.
|
||||
|
||||
%% <symbol> [<accordev> ","] ["@"] <displacement> "(" . <index> ")" <newline>
|
||||
insn_ea_index(ScanState, Name, AccOrDev, At, Displacement) ->
|
||||
insn_ea_index(ScanState, Location, Name, AccOrDev, At, Displacement) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location1, {?T_UINTEGER, Index}}} when Index =< 8#17 ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location2, ?T_RPAREN}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location3, ?T_NEWLINE}} ->
|
||||
make_insn(ScanState, Name, AccOrDev, At, Displacement, Index);
|
||||
ScanRes -> badtok(ScanState, "junk after <index>", ScanRes)
|
||||
make_insn(Location, Name, AccOrDev, At, Displacement, Index);
|
||||
ScanRes -> badtok("junk after <index>", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk in <index>", ScanRes)
|
||||
ScanRes -> badtok("junk in <index>", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk in <index>", ScanRes)
|
||||
ScanRes -> badtok("junk in <index>", ScanRes)
|
||||
end.
|
||||
|
||||
make_insn(ScanState, Name, AccOrDev, At, Displacement, Index) ->
|
||||
make_insn(Location, Name, AccOrDev, At, Displacement, Index) ->
|
||||
Models = ?PDP10_KL10_271, % FIXME: make dynamic
|
||||
case pdp10_opcodes:insn_from_name(Models, Name, AccOrDev =/= false) of
|
||||
false -> badinsn(ScanState, "invalid mnemonic ~s", Name);
|
||||
false -> badinsn(Location, "invalid mnemonic ~s", Name);
|
||||
#pdp10_insn_desc{ high13 = High13
|
||||
, format = Format
|
||||
, e_unused = EUnused
|
||||
, extended = false % TODO: handle extended opcodes
|
||||
} ->
|
||||
case make_high13(ScanState, Name, AccOrDev, High13, Format) of
|
||||
case make_high13(Location, Name, AccOrDev, High13, Format) of
|
||||
{error, _Reason} = Error -> Error;
|
||||
{ok, FinalHigh13} ->
|
||||
case check_e(ScanState, Name, At, Displacement, Index, EUnused) of
|
||||
case check_e(Location, Name, At, Displacement, Index, EUnused) of
|
||||
{error, _Reason} = Error -> Error;
|
||||
ok -> {ok, #s_insn{ high13 = FinalHigh13
|
||||
, at = At
|
||||
@ -221,14 +221,14 @@ make_insn(ScanState, Name, AccOrDev, At, Displacement, Index) ->
|
||||
end
|
||||
end.
|
||||
|
||||
make_high13(ScanState, Name, AccOrDev, High13, Format) ->
|
||||
make_high13(Location, Name, AccOrDev, High13, Format) ->
|
||||
case {Format, AccOrDev} of
|
||||
{?PDP10_INSN_A_OPCODE, false} ->
|
||||
{ok, High13};
|
||||
{?PDP10_INSN_A_OPCODE, _} ->
|
||||
badinsn(ScanState, "~s: extraneous accumulator operand", Name);
|
||||
badinsn(Location, "~s: extraneous accumulator operand", Name);
|
||||
{?PDP10_INSN_IO, false} ->
|
||||
badinsn(ScanState, "~s: missing device operand", Name);
|
||||
badinsn(Location, "~s: missing device operand", Name);
|
||||
{?PDP10_INSN_IO, _} ->
|
||||
make_high13_io(High13, AccOrDev);
|
||||
{?PDP10_INSN_BASIC, false} ->
|
||||
@ -236,9 +236,9 @@ make_high13(ScanState, Name, AccOrDev, High13, Format) ->
|
||||
{?PDP10_INSN_BASIC, _} ->
|
||||
make_high13_basic(High13, AccOrDev);
|
||||
{?PDP10_INSN_A_NONZERO, false} ->
|
||||
badinsn(ScanState, "~s: missing accumulator operand", Name);
|
||||
badinsn(Location, "~s: missing accumulator operand", Name);
|
||||
{?PDP10_INSN_A_NONZERO, 0} ->
|
||||
badinsn(ScanState, "~s: accumulator must not be zero", Name);
|
||||
badinsn(Location, "~s: accumulator must not be zero", Name);
|
||||
{?PDP10_INSN_A_NONZERO, _} ->
|
||||
make_high13_basic(High13, AccOrDev)
|
||||
end.
|
||||
@ -251,17 +251,17 @@ make_high13_io(High13, Device) ->
|
||||
Mask = ((1 bsl 7) - 1),
|
||||
{ok, (High13 band bnot (Mask bsl 3)) bor ((Device band Mask) bsl 3)}.
|
||||
|
||||
check_e(ScanState, Name, At, Displacement, Index, EUnused) ->
|
||||
check_e(Location, Name, At, Displacement, Index, EUnused) ->
|
||||
HaveE = At orelse Displacement =/= false orelse Index =/= false,
|
||||
case {EUnused, HaveE} of
|
||||
{true, false} -> ok;
|
||||
{true, true} -> badinsn(ScanState, "~s: extraneous address operand", Name);
|
||||
{false, false} -> badinsn(ScanState, "~s: missing address operand", Name);
|
||||
{true, true} -> badinsn(Location, "~s: extraneous address operand", Name);
|
||||
{false, false} -> badinsn(Location, "~s: missing address operand", Name);
|
||||
{false, true} -> ok
|
||||
end.
|
||||
|
||||
badinsn(ScanState, Fmt, Mnemonic) ->
|
||||
fmterr(ScanState, Fmt, [Mnemonic]).
|
||||
badinsn(Location, Fmt, Mnemonic) ->
|
||||
fmterr(Location, Fmt, [Mnemonic]).
|
||||
|
||||
%% Directives ------------------------------------------------------------------
|
||||
|
||||
@ -271,9 +271,9 @@ dot_data(ScanState) ->
|
||||
{ok, {_Location1, {?T_UINTEGER, Nr}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_data{nr = Nr}};
|
||||
ScanRes -> badtok(ScanState, "junk after .data <nr>", ScanRes)
|
||||
ScanRes -> badtok("junk after .data <nr>", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .data", ScanRes)
|
||||
ScanRes -> badtok("junk after .data", ScanRes)
|
||||
end.
|
||||
|
||||
dot_file(ScanState) ->
|
||||
@ -289,9 +289,9 @@ dot_file_or_ident(ScanState, MkStmt, ErrMsg) ->
|
||||
{ok, {_Location1, {?T_STRING, String}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location2, ?T_NEWLINE}} -> {ok, MkStmt(String)};
|
||||
ScanRes -> badtok(ScanState, ErrMsg, ScanRes)
|
||||
ScanRes -> badtok(ErrMsg, ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, ErrMsg, ScanRes)
|
||||
ScanRes -> badtok(ErrMsg, ScanRes)
|
||||
end.
|
||||
|
||||
dot_globl(ScanState) ->
|
||||
@ -299,21 +299,21 @@ dot_globl(ScanState) ->
|
||||
{ok, {_Location1, {?T_SYMBOL, Name}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_globl{name = Name}};
|
||||
ScanRes -> badtok(ScanState, "junk after .globl", ScanRes)
|
||||
ScanRes -> badtok("junk after .globl", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .globl", ScanRes)
|
||||
ScanRes -> badtok("junk after .globl", ScanRes)
|
||||
end.
|
||||
|
||||
dot_popsection(ScanState) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_NEWLINE}} -> {ok, #s_dot_popsection{}};
|
||||
ScanRes -> badtok(ScanState, "junk after .popsection", ScanRes)
|
||||
ScanRes -> badtok("junk after .popsection", ScanRes)
|
||||
end.
|
||||
|
||||
dot_previous(ScanState) ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location, ?T_NEWLINE}} -> {ok, #s_dot_previous{}};
|
||||
ScanRes -> badtok(ScanState, "junk after .previous", ScanRes)
|
||||
ScanRes -> badtok("junk after .previous", ScanRes)
|
||||
end.
|
||||
|
||||
%% For now only accepts ".pushsection <name> [, <nr>]". TODO: extend
|
||||
@ -324,7 +324,7 @@ dot_pushsection(ScanState) ->
|
||||
%% TODO: do we need a general mapping from reserved to plain symbols?
|
||||
{ok, {_Location, ?T_DOT_DATA}} -> dot_pushsection(ScanState, _Name = ".data");
|
||||
{ok, {_Location, ?T_DOT_TEXT}} -> dot_pushsection(ScanState, _Name = ".text");
|
||||
ScanRes -> badtok(ScanState, "junk after .pushsection", ScanRes)
|
||||
ScanRes -> badtok("junk after .pushsection", ScanRes)
|
||||
end.
|
||||
|
||||
%% Seen ".pushsection <name>", expects "[, <nr>]".
|
||||
@ -336,11 +336,11 @@ dot_pushsection(ScanState, Name) ->
|
||||
{ok, {_Location2, {?T_UINTEGER, Nr}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location3, ?T_NEWLINE}} -> {ok, #s_dot_pushsection{name = Name, nr = Nr}};
|
||||
ScanRes -> badtok(ScanState, "junk after .pushsection <name>, <nr>", ScanRes)
|
||||
ScanRes -> badtok("junk after .pushsection <name>, <nr>", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .pushsection <name>,", ScanRes)
|
||||
ScanRes -> badtok("junk after .pushsection <name>,", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .pushsection <name>", ScanRes)
|
||||
ScanRes -> badtok("junk after .pushsection <name>", ScanRes)
|
||||
end.
|
||||
|
||||
%% For now only accepts ".size <sym>,.-<sym>". TODO: extend
|
||||
@ -357,17 +357,17 @@ dot_size(ScanState) ->
|
||||
{ok, {_Location5, {?T_SYMBOL, Name}}} -> % same Name as above
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location6, ?T_NEWLINE}} -> {ok, #s_dot_size{name = Name}};
|
||||
ScanRes -> badtok(ScanState, "junk after .size", ScanRes)
|
||||
ScanRes -> badtok("junk after .size", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .size", ScanRes)
|
||||
ScanRes -> badtok("junk after .size", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .size", ScanRes)
|
||||
ScanRes -> badtok("junk after .size", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .size", ScanRes)
|
||||
ScanRes -> badtok("junk after .size", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .size", ScanRes)
|
||||
ScanRes -> badtok("junk after .size", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .size", ScanRes)
|
||||
ScanRes -> badtok("junk after .size", ScanRes)
|
||||
end.
|
||||
|
||||
dot_subsection(ScanState) ->
|
||||
@ -375,9 +375,9 @@ dot_subsection(ScanState) ->
|
||||
{ok, {_Location1, {?T_UINTEGER, Nr}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_subsection{nr = Nr}};
|
||||
ScanRes -> badtok(ScanState, "junk after .subsection <nr>", ScanRes)
|
||||
ScanRes -> badtok("junk after .subsection <nr>", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .subsection", ScanRes)
|
||||
ScanRes -> badtok("junk after .subsection", ScanRes)
|
||||
end.
|
||||
|
||||
dot_text(ScanState) ->
|
||||
@ -386,9 +386,9 @@ dot_text(ScanState) ->
|
||||
{ok, {_Location1, {?T_UINTEGER, Nr}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_text{nr = Nr}};
|
||||
ScanRes -> badtok(ScanState, "junk after .text <nr>", ScanRes)
|
||||
ScanRes -> badtok("junk after .text <nr>", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .text", ScanRes)
|
||||
ScanRes -> badtok("junk after .text", ScanRes)
|
||||
end.
|
||||
|
||||
%% For now only accepts ".type <sym>,@function". TODO: extend
|
||||
@ -403,25 +403,24 @@ dot_type(ScanState) ->
|
||||
{ok, {_Location4, {?T_SYMBOL, "function"}}} ->
|
||||
case scan:token(ScanState) of
|
||||
{ok, {_Location5, ?T_NEWLINE}} -> {ok, #s_dot_type{name = Name}};
|
||||
ScanRes -> badtok(ScanState, "junk after .type", ScanRes)
|
||||
ScanRes -> badtok("junk after .type", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .type", ScanRes)
|
||||
ScanRes -> badtok("junk after .type", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .type", ScanRes)
|
||||
ScanRes -> badtok("junk after .type", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .type", ScanRes)
|
||||
ScanRes -> badtok("junk after .type", ScanRes)
|
||||
end;
|
||||
ScanRes -> badtok(ScanState, "junk after .type", ScanRes)
|
||||
ScanRes -> badtok("junk after .type", ScanRes)
|
||||
end.
|
||||
|
||||
%% Error reporting -------------------------------------------------------------
|
||||
|
||||
badtok(_ScanState, _ErrMsg, {error, _Reason} = Error) -> Error;
|
||||
badtok(ScanState, ErrMsg, {ok, {_Location, Token}}) ->
|
||||
fmterr(ScanState, ErrMsg ++ "; current token is ~s", [token:format(Token)]).
|
||||
badtok(_ErrMsg, {error, _Reason} = Error) -> Error;
|
||||
badtok(ErrMsg, {ok, {Location, Token}}) ->
|
||||
fmterr(Location, ErrMsg ++ "; current token is ~s", [token:format(Token)]).
|
||||
|
||||
fmterr(ScanState, Fmt, Args) ->
|
||||
{ok, {FileName, LineNr}} = scan_state:location(ScanState),
|
||||
fmterr({FileName, LineNr}, Fmt, Args) ->
|
||||
{error, {?MODULE, {FileName, LineNr, Fmt, Args}}}.
|
||||
|
||||
-spec format_error(term()) -> io_lib:chars().
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user