From: Warren on 16 Apr 2010 15:52 I am looking for some sound Ada ('05) advice on a design issue, concerning strings. In my basic interpreter, I permit the end user to choose the array subscript ranges just like in Ada. But this includes strings, whereas in Ada one generally just uses the String type, with its positive subscript values. I would find it convenient in the interpreter to use a string type with an Integer range for Basic string variables instead: type String_Type is array(Integer range <>) of Character; This allows subscripts to range negative to positive. The reason for this approach is that any dynamically allocated string would also carry this "bounds" info with it, saving me from having to manage it separately. However, I'll need to convert them back to normal Ada Strings in order to manipulate and print them etc. The following snippet highlights the challenge: with Ada.Text_IO; use Ada.Text_IO; procedure M is type String_Type is array(Integer range <>) of Character; S : String_Type := "Abc."; T : String(1..4); begin T := String(S); Put_Line(T); end M; $ gnatmake -Wall m.adb gcc -c -Wall m.adb m.adb:11:17: warning: value out of range of type "Standard.String" m.adb:11:17: warning: "Constraint_Error" will be raised at run time gnatbind -x m.ali gnatlink m.ali Is there a simple way to "slide" my String_Type into a normal Ada String array? Or must I do this in a custom function for the purpose, character by character? Warren
From: stefan-lucks on 16 Apr 2010 17:09 On Fri, 16 Apr 2010, Warren wrote: > procedure M is > > type String_Type is array(Integer range <>) of Character; > > S : String_Type := "Abc."; > T : String(1..4); > begin > T := String(S); -- this raises Constraint_Error > Put_Line(T); > > end M; Convert S into a variable of type String_Type with String-compatible bounds, and then convert that variable into a String: S : String_Type := "Abc."; T : String_Type(1 .. S'Length) := S; U : String(1 .. S'Length); begin U := String(T); Put_Line(U); -- or just Put_Line(String(T)); If you have to do that frequently, use an appropriate function (without any need to copy the String-like thing character by character): function To_String(S: String_Type) return String is X: String_Type(1 .. S'Length) := S; begin return String(X); end To_String; I hope that helps! Stefan -- ------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------ Stefan dot Lucks at uni minus weimar dot de ------ I love the taste of Cryptanalysis in the morning! ------
From: J-P. Rosen on 16 Apr 2010 16:29 stefan-lucks(a)see-the.signature a �crit : > Convert S into a variable of type String_Type with String-compatible > bounds, and then convert that variable into a String: > > S : String_Type := "Abc."; > T : String_Type(1 .. S'Length) := S; > U : String(1 .. S'Length); > begin > U := String(T); Put_Line(U); -- or just Put_Line(String(T)); > No need for intermediate copy, just use an appropriate subtype: S : String_Type := "Abc."; T : String(1..4); subtype Slide is String_type (T'Range); begin T := String(Slide(S)); -- --------------------------------------------------------- J-P. Rosen (rosen(a)adalog.fr) Visit Adalog's web site at http://www.adalog.fr
From: Charmed Snark on 16 Apr 2010 16:53 J-P. Rosen expounded in news:hqahb1$tnm$1(a)news.eternal-september.org: > stefan-lucks(a)see-the.signature a �crit : >> Convert S into a variable of type String_Type with String-compatible >> bounds, and then convert that variable into a String: >> >> S : String_Type := "Abc."; >> T : String_Type(1 .. S'Length) := S; >> U : String(1 .. S'Length); >> begin >> U := String(T); Put_Line(U); -- or just Put_Line(String(T)); >> > No need for intermediate copy, just use an appropriate subtype: > > S : String_Type := "Abc."; > T : String(1..4); > subtype Slide is String_type (T'Range); > begin > T := String(Slide(S)); Great- thanks. Fast service too :) Warren
From: Adam Beneschan on 16 Apr 2010 16:56 On Apr 16, 1:29 pm, "J-P. Rosen" <ro...(a)adalog.fr> wrote: > stefan-lu...(a)see-the.signature a écrit :> Convert S into a variable of type String_Type with String-compatible > > bounds, and then convert that variable into a String: > > > S : String_Type := "Abc."; > > T : String_Type(1 .. S'Length) := S; > > U : String(1 .. S'Length); > > begin > > U := String(T); Put_Line(U); -- or just Put_Line(String(T)); > > No need for intermediate copy, just use an appropriate subtype: > > S : String_Type := "Abc."; > T : String(1..4); > subtype Slide is String_type (T'Range); > begin > T := String(Slide(S)); You don't even need two type conversions: S : String_Type := "Abc."; subtype String_Subtype is String(1..S'Length); T : String_Subtype; -- T : String(1..4); -- this works too begin T := String_Subtype(S); Sometimes reading the manual helps (especially if you know where to look). 4.6(37-38) says about array type conversions: * If the target subtype is a constrained array subtype, then a check is made that the length of each dimension of the value of the operand equals the length of the corresponding dimension of the target subtype. The bounds of the result are those of the target subtype. * If the target subtype is an unconstrained array subtype, then the bounds of the result are obtained by converting each bound of the value of the operand to the corresponding index type of the target type. For each nonnull index range, a check is made that the bounds of the range belong to the corresponding index subtype. So if we're converting to a constrained subtype (like String_Subtype), it just makes sure the length is the same on each dimension; while if we're converting to an unconstrained subtype (like String), then each bound is expected to be the same. So we solve the problem by making the type conversion target a constrained subtype. -- Adam
|
Next
|
Last
Pages: 1 2 Prev: ANN: Interval Arithmetic for Ada v1.8 Next: confusion with string initialization |