From 34202b2e2f8fa26208b9f4567d77132831b3c8a3 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Thu, 26 Dec 2019 17:51:38 +0100 Subject: [PATCH] as: scan: tag returned tokens with start locations; parse: ignore them --- erlang/apps/as/src/parse.erl | 142 +++++++++++++++++------------------ erlang/apps/as/src/scan.erl | 76 ++++++++++--------- 2 files changed, 111 insertions(+), 107 deletions(-) diff --git a/erlang/apps/as/src/parse.erl b/erlang/apps/as/src/parse.erl index 6507af1..f950a2b 100644 --- a/erlang/apps/as/src/parse.erl +++ b/erlang/apps/as/src/parse.erl @@ -32,21 +32,21 @@ -> {ok, stmt()} | eof | {error, {module(), term()}}. stmt(ScanState) -> case scan:token(ScanState) of - {ok, ?T_DOT_DATA} -> dot_data(ScanState); - {ok, ?T_DOT_FILE} -> dot_file(ScanState); - {ok, ?T_DOT_GLOBL} -> dot_globl(ScanState); - {ok, ?T_DOT_IDENT} -> dot_ident(ScanState); - {ok, ?T_DOT_POPSECTION} -> dot_popsection(ScanState); - {ok, ?T_DOT_PREVIOUS} -> dot_previous(ScanState); - {ok, ?T_DOT_PUSHSECTION} -> dot_pushsection(ScanState); - {ok, ?T_DOT_SIZE} -> dot_size(ScanState); - {ok, ?T_DOT_SUBSECTION} -> dot_subsection(ScanState); - {ok, ?T_DOT_TEXT} -> dot_text(ScanState); - {ok, ?T_DOT_TYPE} -> dot_type(ScanState); - {ok, {?T_SYMBOL, Name}} -> stmt_after_symbol(ScanState, Name); - {ok, {?T_UINTEGER, UInt}} -> stmt_after_uinteger(ScanState, UInt); - {ok, ?T_NEWLINE} -> stmt(ScanState); - {ok, ?T_EOF} -> eof; + {ok, {_Location, ?T_DOT_DATA}} -> dot_data(ScanState); + {ok, {_Location, ?T_DOT_FILE}} -> dot_file(ScanState); + {ok, {_Location, ?T_DOT_GLOBL}} -> dot_globl(ScanState); + {ok, {_Location, ?T_DOT_IDENT}} -> dot_ident(ScanState); + {ok, {_Location, ?T_DOT_POPSECTION}} -> dot_popsection(ScanState); + {ok, {_Location, ?T_DOT_PREVIOUS}} -> dot_previous(ScanState); + {ok, {_Location, ?T_DOT_PUSHSECTION}} -> dot_pushsection(ScanState); + {ok, {_Location, ?T_DOT_SIZE}} -> dot_size(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_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) end. @@ -96,11 +96,11 @@ stmt(ScanState) -> stmt_after_symbol(ScanState, Name) -> case scan:token(ScanState) of - {ok, ?T_COLON} -> {ok, #s_label{name = Name}}; - {ok, ?T_NEWLINE} -> make_insn(ScanState, Name, false, false, false, false); - {ok, {?T_UINTEGER, UInt}} -> insn_uint(ScanState, Name, UInt); - {ok, {?T_SYMBOL, Symbol}} -> insn_symbol(ScanState, Name, Symbol); - {ok, {?T_LOCAL_LABEL, Number, Direction}} -> + {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_LOCAL_LABEL, Number, Direction}}} -> insn_local_label(ScanState, Name, Number, Direction); ScanRes -> badtok(ScanState, "junk after symbol", ScanRes) end. @@ -108,7 +108,7 @@ stmt_after_symbol(ScanState, Name) -> %% ::= . ":" stmt_after_uinteger(ScanState, UInt) -> case scan:token(ScanState) of - {ok, ?T_COLON} -> {ok, #s_local_label{number = UInt}}; + {ok, {_Location, ?T_COLON}} -> {ok, #s_local_label{number = UInt}}; ScanRes -> badtok(ScanState, "junk after symbol", ScanRes) end. @@ -116,12 +116,12 @@ stmt_after_uinteger(ScanState, UInt) -> %% by ",", otherwise (the start of) the . insn_uint(ScanState, Name, UInt) -> case scan:token(ScanState) of - {ok, ?T_COMMA} -> % the Uint is the Accumulator, parse EA next + {ok, {_Location, ?T_COMMA}} -> % the Uint is the Accumulator, parse EA next insn_ea(ScanState, Name, _AccOrDev = UInt); - {ok, ?T_LPAREN} -> % the Uint is the Displacement, parse Index next + {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); - {ok, ?T_NEWLINE} -> % the Uint is the 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 ", ScanRes) @@ -141,16 +141,16 @@ insn_local_label(ScanState, Name, Number, Direction) -> %% "," . [ ["@"] ["(" ")"] ] insn_ea(ScanState, Name, AccOrDev) -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> + {ok, {_Location, ?T_NEWLINE}} -> make_insn(ScanState, Name, AccOrDev, _At = false, _Displacement = false, _Index = false); - {ok, ?T_AT} -> insn_ea_at(ScanState, Name, AccOrDev); - {ok, {?T_UINTEGER, UInt}} -> + {ok, {_Location, ?T_AT}} -> insn_ea_at(ScanState, Name, AccOrDev); + {ok, {_Lcation, {?T_UINTEGER, UInt}}} -> Displacement = #e_integer{value = UInt}, insn_ea_disp(ScanState, Name, AccOrDev, _At = false, Displacement); - {ok, {?T_SYMBOL, Symbol}} -> + {ok, {_Location, {?T_SYMBOL, Symbol}}} -> Displacement = #e_symbol{name = Symbol}, insn_ea_disp(ScanState, Name, AccOrDev, _At = false, Displacement); - {ok, {?T_LOCAL_LABEL, Number, Direction}} -> + {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) @@ -159,13 +159,13 @@ insn_ea(ScanState, Name, AccOrDev) -> %% [ ","] "@" . ["(" ")"] insn_ea_at(ScanState, Name, AccOrDev) -> case scan:token(ScanState) of - {ok, {?T_UINTEGER, UInt}} -> + {ok, {_Location, {?T_UINTEGER, UInt}}} -> Displacement = #e_integer{value = UInt}, insn_ea_disp(ScanState, Name, AccOrDev, _At = true, Displacement); - {ok, {?T_SYMBOL, Symbol}} -> + {ok, {_Location, {?T_SYMBOL, Symbol}}} -> Displacement = #e_symbol{name = Symbol}, insn_ea_disp(ScanState, Name, AccOrDev, _At = true, Displacement); - {ok, {?T_LOCAL_LABEL, Number, Direction}} -> + {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) @@ -174,19 +174,19 @@ insn_ea_at(ScanState, Name, AccOrDev) -> %% [ ","] ["@"] . ["(" ")"] insn_ea_disp(ScanState, Name, AccOrDev, At, Displacement) -> case scan:token(ScanState) of - {ok, ?T_LPAREN} -> insn_ea_index(ScanState, Name, AccOrDev, At, Displacement); - {ok, ?T_NEWLINE} -> make_insn(ScanState, Name, AccOrDev, At, Displacement, _Index = false); + {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 ", ScanRes) end. %% [ ","] ["@"] "(" . ")" insn_ea_index(ScanState, Name, AccOrDev, At, Displacement) -> case scan:token(ScanState) of - {ok, {?T_UINTEGER, Index}} when Index =< 8#17 -> + {ok, {_Location1, {?T_UINTEGER, Index}}} when Index =< 8#17 -> case scan:token(ScanState) of - {ok, ?T_RPAREN} -> + {ok, {_Location2, ?T_RPAREN}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> + {ok, {_Location3, ?T_NEWLINE}} -> make_insn(ScanState, Name, AccOrDev, At, Displacement, Index); ScanRes -> badtok(ScanState, "junk after ", ScanRes) end; @@ -267,10 +267,10 @@ badinsn(ScanState, Fmt, Mnemonic) -> dot_data(ScanState) -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_data{nr = 0}}; - {ok, {?T_UINTEGER, Nr}} -> + {ok, {_Location1, ?T_NEWLINE}} -> {ok, #s_dot_data{nr = 0}}; + {ok, {_Location1, {?T_UINTEGER, Nr}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_data{nr = Nr}}; + {ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_data{nr = Nr}}; ScanRes -> badtok(ScanState, "junk after .data ", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .data", ScanRes) @@ -286,9 +286,9 @@ dot_ident(ScanState) -> dot_file_or_ident(ScanState, MkStmt, ErrMsg) -> case scan:token(ScanState) of - {ok, {?T_STRING, String}} -> + {ok, {_Location1, {?T_STRING, String}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, MkStmt(String)}; + {ok, {_Location2, ?T_NEWLINE}} -> {ok, MkStmt(String)}; ScanRes -> badtok(ScanState, ErrMsg, ScanRes) end; ScanRes -> badtok(ScanState, ErrMsg, ScanRes) @@ -296,9 +296,9 @@ dot_file_or_ident(ScanState, MkStmt, ErrMsg) -> dot_globl(ScanState) -> case scan:token(ScanState) of - {ok, {?T_SYMBOL, Name}} -> + {ok, {_Location1, {?T_SYMBOL, Name}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_globl{name = Name}}; + {ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_globl{name = Name}}; ScanRes -> badtok(ScanState, "junk after .globl", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .globl", ScanRes) @@ -306,36 +306,36 @@ dot_globl(ScanState) -> dot_popsection(ScanState) -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_popsection{}}; + {ok, {_Location, ?T_NEWLINE}} -> {ok, #s_dot_popsection{}}; ScanRes -> badtok(ScanState, "junk after .popsection", ScanRes) end. dot_previous(ScanState) -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_previous{}}; + {ok, {_Location, ?T_NEWLINE}} -> {ok, #s_dot_previous{}}; ScanRes -> badtok(ScanState, "junk after .previous", ScanRes) end. %% For now only accepts ".pushsection [, ]". TODO: extend dot_pushsection(ScanState) -> case scan:token(ScanState) of - {ok, {?T_STRING, Name}} -> dot_pushsection(ScanState, Name); - {ok, {?T_SYMBOL, Name}} -> dot_pushsection(ScanState, Name); + {ok, {_Location, {?T_STRING, Name}}} -> dot_pushsection(ScanState, Name); + {ok, {_Location, {?T_SYMBOL, Name}}} -> dot_pushsection(ScanState, Name); %% TODO: do we need a general mapping from reserved to plain symbols? - {ok, ?T_DOT_DATA} -> dot_pushsection(ScanState, _Name = ".data"); - {ok, ?T_DOT_TEXT} -> dot_pushsection(ScanState, _Name = ".text"); + {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) end. %% Seen ".pushsection ", expects "[, ]". dot_pushsection(ScanState, Name) -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_pushsection{name = Name, nr = 0}}; - {ok, ?T_COMMA} -> + {ok, {_Location1, ?T_NEWLINE}} -> {ok, #s_dot_pushsection{name = Name, nr = 0}}; + {ok, {_Location1, ?T_COMMA}} -> case scan:token(ScanState) of - {ok, {?T_UINTEGER, Nr}} -> + {ok, {_Location2, {?T_UINTEGER, Nr}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_pushsection{name = Name, nr = Nr}}; + {ok, {_Location3, ?T_NEWLINE}} -> {ok, #s_dot_pushsection{name = Name, nr = Nr}}; ScanRes -> badtok(ScanState, "junk after .pushsection , ", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .pushsection ,", ScanRes) @@ -346,17 +346,17 @@ dot_pushsection(ScanState, Name) -> %% For now only accepts ".size ,.-". TODO: extend dot_size(ScanState) -> case scan:token(ScanState) of - {ok, {?T_SYMBOL, Name}} -> + {ok, {_Location1, {?T_SYMBOL, Name}}} -> case scan:token(ScanState) of - {ok, ?T_COMMA} -> + {ok, {_Location2, ?T_COMMA}} -> case scan:token(ScanState) of - {ok, ?T_DOT} -> + {ok, {_Location3, ?T_DOT}} -> case scan:token(ScanState) of - {ok, ?T_MINUS} -> + {ok, {_Location4, ?T_MINUS}} -> case scan:token(ScanState) of - {ok, {?T_SYMBOL, Name}} -> % same Name as above + {ok, {_Location5, {?T_SYMBOL, Name}}} -> % same Name as above case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_size{name = Name}}; + {ok, {_Location6, ?T_NEWLINE}} -> {ok, #s_dot_size{name = Name}}; ScanRes -> badtok(ScanState, "junk after .size", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .size", ScanRes) @@ -372,9 +372,9 @@ dot_size(ScanState) -> dot_subsection(ScanState) -> case scan:token(ScanState) of - {ok, {?T_UINTEGER, Nr}} -> + {ok, {_Location1, {?T_UINTEGER, Nr}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_subsection{nr = Nr}}; + {ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_subsection{nr = Nr}}; ScanRes -> badtok(ScanState, "junk after .subsection ", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .subsection", ScanRes) @@ -382,10 +382,10 @@ dot_subsection(ScanState) -> dot_text(ScanState) -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_text{nr = 0}}; - {ok, {?T_UINTEGER, Nr}} -> + {ok, {_Location1, ?T_NEWLINE}} -> {ok, #s_dot_text{nr = 0}}; + {ok, {_Location1, {?T_UINTEGER, Nr}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_text{nr = Nr}}; + {ok, {_Location2, ?T_NEWLINE}} -> {ok, #s_dot_text{nr = Nr}}; ScanRes -> badtok(ScanState, "junk after .text ", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .text", ScanRes) @@ -394,15 +394,15 @@ dot_text(ScanState) -> %% For now only accepts ".type ,@function". TODO: extend dot_type(ScanState) -> case scan:token(ScanState) of - {ok, {?T_SYMBOL, Name}} -> + {ok, {_Location1, {?T_SYMBOL, Name}}} -> case scan:token(ScanState) of - {ok, ?T_COMMA} -> + {ok, {_Location2, ?T_COMMA}} -> case scan:token(ScanState) of - {ok, ?T_AT} -> + {ok, {_Location3, ?T_AT}} -> case scan:token(ScanState) of - {ok, {?T_SYMBOL, "function"}} -> + {ok, {_Location4, {?T_SYMBOL, "function"}}} -> case scan:token(ScanState) of - {ok, ?T_NEWLINE} -> {ok, #s_dot_type{name = Name}}; + {ok, {_Location5, ?T_NEWLINE}} -> {ok, #s_dot_type{name = Name}}; ScanRes -> badtok(ScanState, "junk after .type", ScanRes) end; ScanRes -> badtok(ScanState, "junk after .type", ScanRes) @@ -417,7 +417,7 @@ dot_type(ScanState) -> %% Error reporting ------------------------------------------------------------- badtok(_ScanState, _ErrMsg, {error, _Reason} = Error) -> Error; -badtok(ScanState, ErrMsg, {ok, Token}) -> +badtok(ScanState, ErrMsg, {ok, {_Location, Token}}) -> fmterr(ScanState, ErrMsg ++ "; current token is ~s", [token:format(Token)]). fmterr(ScanState, Fmt, Args) -> diff --git a/erlang/apps/as/src/scan.erl b/erlang/apps/as/src/scan.erl index e58b98f..330d874 100644 --- a/erlang/apps/as/src/scan.erl +++ b/erlang/apps/as/src/scan.erl @@ -26,36 +26,40 @@ -include("token.hrl"). +-type location() :: scan_state:location(). + -spec token(scan_state:scan_state()) - -> {ok, token()} | {error, {module(), term()}}. + -> {ok, {location(), token()}} | {error, {module(), term()}}. token(ScanState) -> + %% TODO: optimize + {ok, Location} = scan_state:location(ScanState), case scan_state:fgetc(ScanState) of {error, _Reason} = Error -> Error; - eof -> {ok, ?T_EOF}; + eof -> {ok, {Location, ?T_EOF}}; {ok, Ch} -> case Ch of $\s -> token(ScanState); $\t -> token(ScanState); $\r -> token(ScanState); $\f -> token(ScanState); - $\n -> {ok, ?T_NEWLINE}; + $\n -> {ok, {Location, ?T_NEWLINE}}; $# -> do_line_comment(ScanState); - $@ -> {ok, ?T_AT}; - $: -> {ok, ?T_COLON}; - $; -> {ok, ?T_NEWLINE}; - $, -> {ok, ?T_COMMA}; - $( -> {ok, ?T_LPAREN}; - $) -> {ok, ?T_RPAREN}; + $@ -> {ok, {Location, ?T_AT}}; + $: -> {ok, {Location, ?T_COLON}}; + $; -> {ok, {Location, ?T_NEWLINE}}; + $, -> {ok, {Location, ?T_COMMA}}; + $( -> {ok, {Location, ?T_LPAREN}}; + $) -> {ok, {Location, ?T_RPAREN}}; $/ -> do_slash(ScanState); - $\" -> do_string(ScanState, []); - $- -> {ok, ?T_MINUS}; + $\" -> do_string(ScanState, Location, []); + $- -> {ok, {Location, ?T_MINUS}}; _ -> - if $0 =< Ch, Ch =< $9 -> do_number(ScanState, Ch); + if $0 =< Ch, Ch =< $9 -> do_number(ScanState, Location, Ch); ($A =< Ch andalso Ch =< $Z) orelse ($a =< Ch andalso Ch =< $z) orelse Ch =:= $. orelse Ch =:= $$ orelse - Ch =:= $_ -> do_symbol(ScanState, [Ch]); + Ch =:= $_ -> do_symbol(ScanState, Location, [Ch]); true -> badchar(ScanState, Ch, "") end end @@ -66,7 +70,7 @@ do_line_comment(ScanState) -> case scan_state:fgetc(ScanState) of {error, _Reason} = Error -> Error; eof -> badchar(ScanState, eof, "in line comment"); - {ok, $\n} -> {ok, ?T_NEWLINE}; + {ok, $\n} -> {ok, {scan_state:location(ScanState), ?T_NEWLINE}}; {ok, _Ch} -> do_line_comment(ScanState) end. @@ -93,18 +97,18 @@ do_c_comment(ScanState, PrevWasStar) -> end. %% Scan after seeing '"'. -do_string(ScanState, Chars) -> +do_string(ScanState, Location, Chars) -> case scan_state:fgetc(ScanState) of {error, _Reason} = Error -> Error; eof -> badchar(ScanState, eof, "in string literal"); {ok, $\n} -> badchar(ScanState, $\n, "in string literal"); - {ok, $\"} -> {ok, {?T_STRING, lists:reverse(Chars)}}; + {ok, $\"} -> {ok, {Location, {?T_STRING, lists:reverse(Chars)}}}; {ok, $\\} -> case do_escape(ScanState) of {error, _Reason} = Error -> Error; - {ok, Ch} -> do_string(ScanState, [Ch | Chars]) + {ok, Ch} -> do_string(ScanState, Location, [Ch | Chars]) end; - {ok, Ch} -> do_string(ScanState, [Ch | Chars]) + {ok, Ch} -> do_string(ScanState, Location, [Ch | Chars]) end. %% Scan after seeing '\' in a string literal. @@ -144,38 +148,38 @@ do_octal_escape(ScanState, Val, N) -> end end. -do_symbol(ScanState, Chars) -> +do_symbol(ScanState, Location, Chars) -> case scan_state:fgetc(ScanState) of {error, _Reason} = Error -> Error; - eof -> do_symbol(lists:reverse(Chars)); + eof -> do_symbol(Location, lists:reverse(Chars)); {ok, Ch} -> if ($A =< Ch andalso Ch =< $Z) orelse ($a =< Ch andalso Ch =< $z) orelse ($0 =< Ch andalso Ch =< $9) orelse Ch =:= $. orelse Ch =:= $$ orelse - Ch =:= $_ -> do_symbol(ScanState, [Ch | Chars]); + Ch =:= $_ -> do_symbol(ScanState, Location, [Ch | Chars]); true -> case scan_state:ungetc(Ch, ScanState) of {error, _Reason} = Error -> Error; - ok -> do_symbol(lists:reverse(Chars)) + ok -> do_symbol(Location, lists:reverse(Chars)) end end end. -do_symbol(Chars) -> +do_symbol(Location, Chars) -> case Chars of - [$.] -> {ok, ?T_DOT}; - [$. | _] -> {ok, token:from_symbol(Chars)}; - _ -> {ok, {?T_SYMBOL, Chars}} + [$.] -> {ok, {Location, ?T_DOT}}; + [$. | _] -> {ok, {Location, token:from_symbol(Chars)}}; + _ -> {ok, {Location, {?T_SYMBOL, Chars}}} end. -do_number(ScanState, Dig0) -> +do_number(ScanState, Location, Dig0) -> case Dig0 of $0 -> case scan_state:fgetc(ScanState) of {error, _Reason} = Error -> Error; - eof -> {ok, {?T_UINTEGER, Dig0 - $0}}; + eof -> {ok, {Location, {?T_UINTEGER, Dig0 - $0}}}; {ok, Ch} -> if Ch =:= $x; Ch =:= $X -> %% must have hex digit after 0x @@ -185,34 +189,34 @@ do_number(ScanState, Dig0) -> {ok, Ch} -> case chval(Ch) of ChVal when ChVal < 16 -> - do_number(ScanState, _Base = 16, ChVal); + do_number(ScanState, Location, _Base = 16, ChVal); _Val -> badchar(ScanState, Ch, "after 0x in number") end end; true -> case scan_state:ungetc(Ch, ScanState) of {error, _Reason} = Error -> Error; - ok -> do_number(ScanState, _Base = 8, _Val = 0) + ok -> do_number(ScanState, Location, _Base = 8, _Val = 0) end end end; - _ -> do_number(ScanState, _Base = 10, _Val = Dig0 - $0) + _ -> do_number(ScanState, Location, _Base = 10, _Val = Dig0 - $0) end. -do_number(ScanState, Base, Val) -> +do_number(ScanState, Location, Base, Val) -> case scan_state:fgetc(ScanState) of {error, _Reason} = Error -> Error; - eof -> {ok, {?T_UINTEGER, Val}}; + eof -> {ok, {Location, {?T_UINTEGER, Val}}}; {ok, Ch} -> case chval(Ch) of ChVal when ChVal < Base -> - do_number(ScanState, Base, Val * Base + ChVal); + do_number(ScanState, Location, Base, Val * Base + ChVal); _ChVal when Base =< 10 andalso (Ch =:= $b orelse Ch =:= $f) -> - {ok, {?T_LOCAL_LABEL, Val, Ch}}; + {ok, {Location, {?T_LOCAL_LABEL, Val, Ch}}}; _ChVal -> case scan_state:ungetc(Ch, ScanState) of {error, _Reason} = Error -> Error; - ok -> {ok, {?T_UINTEGER, Val}} + ok -> {ok, {Location, {?T_UINTEGER, Val}}} end end end.