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> </keywords>
<syntax> <syntax>
<define id="dim-directive"> <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>
<define id="redim-directive"> <define id="redim-directive">
<txt>redim</txt><opt><nt name="locality"/></opt><nt>ident</nt><nt name="index-spec"/> <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"> <define id="index-spec" inline="yes">
<txt>[</txt><nt>expr</nt><txt>]</txt> <txt>[</txt><nt>expr</nt><txt>]</txt>
</define> </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> </syntax>
<description> <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> <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> </description>
<section title="Examples"> <section title="Examples">
@ -185,6 +188,7 @@
<line>#redim MyArray[20]</line> <line>#redim MyArray[20]</line>
<line>#define MyArray[10] 30</line> <line>#define MyArray[10] 30</line>
<line>#redim MyArray[10]</line> <line>#redim MyArray[10]</line>
<line>#dim MyArray2[3] {1, '2', 3}</line>
</pre> </pre>
</section> </section>
<section title="See also"> <section title="See also">

View File

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

View File

@ -607,18 +607,41 @@ function TPreprocessor.ProcessPreprocCommand(Command: TPreprocessorCommand;
procedure ParseDim(Parser: TParserAccess; ReDim: Boolean); procedure ParseDim(Parser: TParserAccess; ReDim: Boolean);
var var
V: string; Name: string;
N: Integer; N, NValues, I: Integer;
Scope: TDefineScope; Scope: TDefineScope;
Values: array of TIsppVariant;
begin begin
with Parser do with Parser do
try try
Scope := GetScope(Parser); Scope := GetScope(Parser);
V := CheckReservedIdent(TokenString); Name := CheckReservedIdent(TokenString);
NextTokenExpect([tkOpenBracket]); NextTokenExpect([tkOpenBracket]);
N := IntExpr(True); N := IntExpr(True);
NValues := 0;
NextTokenExpect([tkCloseBracket]); 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 finally
//Free //Free
end; end;
@ -1825,11 +1848,14 @@ begin
end; end;
procedure TProcCallContext.UpdateScope; procedure TProcCallContext.UpdateScope;
var
ReDim: Boolean;
begin begin
if not FScopeUpdated then if not FScopeUpdated then
begin begin
FPreproc.FIdentManager.BeginLocal; FPreproc.FIdentManager.BeginLocal;
FPreproc.FIdentManager.DimVariable(SLocal, 16, dsPrivate, False); ReDim := False;
FPreproc.FIdentManager.DimVariable(SLocal, 16, dsPrivate, ReDim);
FScopeUpdated := True; FScopeUpdated := True;
end; end;
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> <li>When paused on a breakpoint in the [Code] section the new "Debug Call Stack" view now shows the call stack.</li>
</ul> </ul>
</li> </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>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>). <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> <ul>