ISPP: Array variables declared with #dim can now be initialized directly, like #dim MyArray[3] {1, '2', 3} for example.

This commit is contained in:
Martijn Laan 2019-10-03 13:27:23 +02:00
parent 1a0e30d5e5
commit 5a938cdd20
4 changed files with 45 additions and 10 deletions

View File

@ -165,7 +165,7 @@
</keywords>
<syntax>
<define id="dim-directive">
<txt>dim</txt><opt><nt name="locality"/></opt><nt>ident</nt><nt name="index-spec"/>
<txt>dim</txt><opt><nt name="locality"/></opt><nt>ident</nt><nt name="index-spec"/><opt><nt name="initializers-spec"/></opt>
</define>
<define id="redim-directive">
<txt>redim</txt><opt><nt name="locality"/></opt><nt>ident</nt><nt name="index-spec"/>
@ -173,9 +173,12 @@
<define id="index-spec" inline="yes">
<txt>[</txt><nt>expr</nt><txt>]</txt>
</define>
<define id="initializers-spec" inline="yes">
<txt>{</txt><nt>expr</nt><opt repeated="yes"><txt>,</txt><nt>expr</nt></opt><txt>}</txt>
</define>
</syntax>
<description>
<para>Use &dim; to declare an array variable and set its dimension. All elements of the array are initialized to null (void). To assign an element value after declaring the array, use &define;. Instead of assigning element values with &define;, it is also possible to set an element value by using it as the left operand of an assignment.</para>
<para>Use &dim; to declare an array variable, set its dimension and optionally intialize it. All unitialized elements of the array are initialized to null (void). To assign an element value after declaring the array, use &define;. Instead of assigning element values with &define;, it is also possible to set an element value by using it as the left operand of an assignment.</para>
<para>Use &redim; to increase or decrease the dimension of an existing array variable. All new elements of the array are initialized to null (void) and existing elements are left unchanged. Identical to &dim; if <synel>ident</synel> isn't an existing array variable.</para>
</description>
<section title="Examples">
@ -185,6 +188,7 @@
<line>#redim MyArray[20]</line>
<line>#define MyArray[10] 30</line>
<line>#redim MyArray[10]</line>
<line>#dim MyArray2[3] {1, '2', 3}</line>
</pre>
</section>
<section title="See also">

View File

@ -95,7 +95,7 @@ type
procedure DefineVariable(const Name: string; Index: Integer;
const Value: TIsppVariant; Scope: TDefineScope);
procedure Delete(const Name: string; Scope: TDefineScope);
procedure DimVariable(const Name: string; Length: Integer; Scope: TDefineScope; ReDim: Boolean);
procedure DimVariable(const Name: string; Length: Integer; Scope: TDefineScope; var ReDim: Boolean);
function GetIdent(const Name: string; out CallContext: ICallContext): TIdentType;
function TypeOf(const Name: string): Byte;
function DimOf(const Name: String): Integer;
@ -830,7 +830,7 @@ begin
end;
procedure TIdentManager.DimVariable(const Name: string; Length: Integer;
Scope: TDefineScope; ReDim: Boolean);
Scope: TDefineScope; var ReDim: Boolean);
var
V, VOld: PVariable;
I, ReDimIndex: Integer;
@ -845,6 +845,7 @@ begin
((PIdent(FVarMan[ReDimIndex]).IdentType <> itVariable) or
(PVariable(FVarMan[ReDimIndex]).Dim = 0)) then
ReDimIndex := -1; //not a variable or not an array, #dim normally
ReDim := ReDimIndex <> -1;
end else
ReDimIndex := -1;

View File

@ -607,18 +607,41 @@ function TPreprocessor.ProcessPreprocCommand(Command: TPreprocessorCommand;
procedure ParseDim(Parser: TParserAccess; ReDim: Boolean);
var
V: string;
N: Integer;
Name: string;
N, NValues, I: Integer;
Scope: TDefineScope;
Values: array of TIsppVariant;
begin
with Parser do
try
Scope := GetScope(Parser);
V := CheckReservedIdent(TokenString);
Name := CheckReservedIdent(TokenString);
NextTokenExpect([tkOpenBracket]);
N := IntExpr(True);
NValues := 0;
NextTokenExpect([tkCloseBracket]);
FIdentManager.DimVariable(V, N, Scope, ReDim);
if PeekAtNextToken = tkOpenBrace then
begin
NextToken;
SetLength(Values, N);
NValues := 0;
while True do begin
if NValues >= N then
raise EIdentError.CreateFmt(SIndexIsOutOfArraySize, [NValues, Name]);
Values[NValues] := Expr(True);
MakeRValue(Values[NValues]);
Inc(NValues);
if PeekAtNextToken <> tkComma then
Break;
NextToken;
end;
NextTokenExpect([tkCloseBrace]);
end;
FIdentManager.DimVariable(Name, N, Scope, ReDim);
if ReDim and (NValues <> 0) then
Error('Initializers not allowed on #redim of existing array');
for I := 0 to NValues-1 do
FIdentManager.DefineVariable(Name, I, Values[I], Scope);
finally
//Free
end;
@ -1825,11 +1848,14 @@ begin
end;
procedure TProcCallContext.UpdateScope;
var
ReDim: Boolean;
begin
if not FScopeUpdated then
begin
FPreproc.FIdentManager.BeginLocal;
FPreproc.FIdentManager.DimVariable(SLocal, 16, dsPrivate, False);
ReDim := False;
FPreproc.FIdentManager.DimVariable(SLocal, 16, dsPrivate, ReDim);
FScopeUpdated := True;
end;
end;

View File

@ -38,7 +38,11 @@ For conditions of distribution and use, see <a href="http://www.jrsoftware.org/f
<li>When paused on a breakpoint in the [Code] section the new "Debug Call Stack" view now shows the call stack.</li>
</ul>
</li>
<li>Inno Setup Preprocessor (ISPP) change: Added new predefined variable <tt>Tab</tt>.</li>
<li>Inno Setup Preprocessor (ISPP) changes:
<ul>
<li>Array variables declared with <tt>#dim</tt> can now be initialized directly, like <tt>#dim MyArray[3] {1, &apos;2&apos;, 3}</tt> for example.</li>
<li>Added new predefined variable <tt>Tab</tt>.</li>
</ul>
<li>Pascal Scripting change: Added new <tt>Set8087CW</tt> and <tt>Get8087CW</tt> support functions.</li>
<li>Some messages have been added in this version: (<a href="https://github.com/jrsoftware/issrc/commit/dfdf02aef168be458b64e77afb20ae53a5b4f2ec">View differences in Default.isl</a>).
<ul>