as: handle .ascii and .asciz directives

This commit is contained in:
Mikael Pettersson 2019-12-31 13:55:45 +01:00
parent 9f51730200
commit 72df4dc2b3
7 changed files with 104 additions and 2 deletions

View File

@ -0,0 +1,23 @@
/*
* test6.s
* Copyright (C) 2019 Mikael Pettersson
*
* This file is part of pdp10-tools.
*
* pdp10-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* pdp10-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with pdp10-tools. If not, see <http://www.gnu.org/licenses/>.
*/
.text
.ascii "bar"
.asciz "foo", "fie", "fum"

View File

@ -100,12 +100,21 @@ stmts_image([Stmt | Stmts], Tunit, Acc) ->
stmt_image(Stmt, Tunit) ->
case Stmt of
#s_dot_ascii{} -> dot_ascii_image(Stmt, Tunit);
#s_dot_byte{} -> dot_byte_image(Stmt, Tunit);
#s_dot_long{} -> dot_long_image(Stmt, Tunit);
#s_dot_short{} -> dot_short_image(Stmt, Tunit);
#s_insn{} -> insn_image(Stmt, Tunit)
end.
dot_ascii_image(#s_dot_ascii{z = Z, strings = Strings}, _Tunit) ->
Image =
case Z of
true -> [String ++ [0] || String <- Strings];
false -> Strings
end,
{ok, Image}.
dot_byte_image(#s_dot_byte{exprs = Exprs}, Tunit) ->
integer_data_directive(Exprs, Tunit, fun(Value) -> Value band ?PDP10_UINT9_MAX end).

View File

@ -313,6 +313,7 @@ pass2_stmts([{Location, Stmt} | Stmts], Tunit) ->
pass2_stmt(Location, Tunit, Stmt) ->
case Stmt of
#s_dot_ascii{} -> dot_ascii(Location, Tunit, Stmt);
#s_dot_byte{} -> dot_byte(Location, Tunit, Stmt);
#s_dot_file{} -> dot_file(Location, Tunit, Stmt);
#s_dot_globl{} -> dot_globl(Location, Tunit, Stmt);
@ -326,6 +327,21 @@ pass2_stmt(Location, Tunit, Stmt) ->
#s_insn{} -> insn(Location, Tunit, Stmt)
end.
dot_ascii(_Location, Tunit, #s_dot_ascii{z = Z, strings = Strings} = Stmt) ->
#tunit{cursect = Cursect} = Tunit,
#section{data = {stmts, Stmts}, dot = Dot} = Section = tunit:get_section(Tunit, Cursect),
Size0 = lists:sum(lists:map(fun erlang:length/1, Strings)),
Size =
case Z of
true -> Size0 + length(Strings);
false -> Size0
end,
NewSection =
Section#section{ data = {stmts, [Stmt | Stmts]}
, dot = Dot + Size
},
{ok, tunit:put_section(Tunit, NewSection)}.
dot_byte(Location, Tunit, #s_dot_byte{} = Stmt0) ->
integer_data_directive(Location, Tunit, Stmt0, 1, ".byte",
fun(Stmt) -> Stmt#s_dot_byte.exprs end,

View File

@ -34,6 +34,8 @@
-> {ok, {location(), stmt()}} | eof | {error, {module(), term()}}.
stmt(ScanState) ->
case scan:token(ScanState) of
{ok, {Location, ?T_DOT_ASCII}} -> dot_ascii(ScanState, Location);
{ok, {Location, ?T_DOT_ASCIZ}} -> dot_asciz(ScanState, Location);
{ok, {Location, ?T_DOT_BYTE}} -> dot_byte(ScanState, Location);
{ok, {Location, ?T_DOT_DATA}} -> dot_data(ScanState, Location);
{ok, {Location, ?T_DOT_FILE}} -> dot_file(ScanState, Location);
@ -274,6 +276,23 @@ badinsn(Location, Fmt, Mnemonic) ->
%% Directives ------------------------------------------------------------------
dot_ascii(ScanState, Location) ->
dot_ascii(ScanState, Location, ".ascii", _Z = false).
dot_asciz(ScanState, Location) ->
dot_ascii(ScanState, Location, ".asciz", _Z = true).
dot_ascii(ScanState, Location, Lexeme, Z) ->
case string_list(ScanState) of
{ok, {Strings, Follow}} ->
case Follow of
{_Location, ?T_NEWLINE} ->
{ok, {Location, #s_dot_ascii{z = Z, strings = Strings}}};
_ -> badtok("junk after " ++ Lexeme ++ " <strings>", {ok, Follow})
end;
{error, _Reason} = Error -> Error
end.
dot_byte(ScanState, Location) ->
integer_data_directive(ScanState, Location, ".byte",
fun(Exprs) -> #s_dot_byte{exprs = Exprs} end).
@ -500,6 +519,29 @@ expr_opt(ScanState) ->
Error
end.
%% String Lists ----------------------------------------------------------------
%% <string_list> ::= (<string> ("," <string>)*)?
string_list(ScanState) ->
case scan:token(ScanState) of
{ok, {_Location, {?T_STRING, String}}} -> string_list(ScanState, [String]);
{ok, Follow} -> {ok, {[], Follow}};
{error, _Reason} = Error -> Error
end.
string_list(ScanState, Strings) ->
case scan:token(ScanState) of
{ok, {_Location1, ?T_COMMA}} ->
case scan:token(ScanState) of
{ok, {_Location2, {?T_STRING, String}}} ->
string_list(ScanState, [String | Strings]);
{ok, First} -> badtok("expected string literal", {ok, First});
{error, _Reason} = Error -> Error
end;
{ok, Follow} -> {ok, {lists:reverse(Strings), Follow}};
{error, _Reason} = Error -> Error
end.
%% Error reporting -------------------------------------------------------------
badtok(_ErrMsg, {error, _Reason} = Error) -> Error;

View File

@ -29,6 +29,8 @@
-spec from_symbol(string()) -> token().
from_symbol(Name) ->
case Name of
".ascii" -> ?T_DOT_ASCII;
".asciz" -> ?T_DOT_ASCIZ;
".byte" -> ?T_DOT_BYTE;
".data" -> ?T_DOT_DATA;
".file" -> ?T_DOT_FILE;
@ -51,6 +53,8 @@ from_symbol(Name) ->
-spec format(token()) -> io_lib:chars().
format(Token) ->
case Token of
?T_DOT_ASCII -> ".ascii";
?T_DOT_ASCIZ -> ".asciz";
?T_DOT_BYTE -> ".byte";
?T_DOT_DATA -> ".data";
?T_DOT_FILE -> ".file";

View File

@ -26,6 +26,8 @@
%% with attributes (ordinary symbols, literals, errors).
%% reserved symbols including directives
-define(T_DOT_ASCII, 'T_DOT_ASCII'). % .ascii
-define(T_DOT_ASCIZ, 'T_DOT_ASCIZ'). % .asciz
-define(T_DOT_BYTE, 'T_DOT_BYTE'). % .byte
-define(T_DOT_DATA, 'T_DOT_DATA'). % .data
-define(T_DOT_FILE, 'T_DOT_FILE'). % .file
@ -64,7 +66,9 @@
-define(T_NEWLINE, 'T_NEWLINE'). % <end-of-line>
-define(T_EOF, 'T_EOF'). % <end-of-file>
-type token() :: ?T_DOT_BYTE
-type token() :: ?T_DOT_ASCII
| ?T_DOT_ASCIZ
| ?T_DOT_BYTE
| ?T_DOT_DATA
| ?T_DOT_FILE
| ?T_DOT_GLOBL

View File

@ -36,6 +36,9 @@
%% either interpreted immediately or appended to the representation of the
%% current section.
%% .asci{i,z} [string (, string)*]
-record(s_dot_ascii, {z :: boolean(), strings :: [string()]}).
%% .byte [expr (, expr)*]
-record(s_dot_byte, {exprs :: [expr()]}).
@ -90,7 +93,8 @@
, index :: 0..((1 bsl 4) - 1)
}).
-type stmt() :: #s_dot_data{}
-type stmt() :: #s_dot_ascii{}
| #s_dot_data{}
| #s_dot_file{}
| #s_dot_globl{}
| #s_dot_ident{}