Forráskód Böngészése

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

Martijn Laan 6 éve
szülő
commit
5a938cdd20

+ 6 - 2
Projects/ISPP/Help/ispp.xml

@@ -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">

+ 3 - 2
Projects/ISPP/IsppIdentMan.pas

@@ -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;
 
 

+ 31 - 5
Projects/ISPP/IsppTranslate.pas

@@ -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;
-    N: Integer;
+    Name: string;
+    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;

+ 5 - 1
whatsnew.htm

@@ -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>