comp.lang.ada
 help / color / mirror / Atom feed
* type String_Type array(Integer range <>) of Character;
@ 2010-04-16 19:52 Warren
  2010-04-16 21:09 ` stefan-lucks
  0 siblings, 1 reply; 6+ messages in thread
From: Warren @ 2010-04-16 19:52 UTC (permalink / raw)


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



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: type String_Type array(Integer range <>) of Character;
  2010-04-16 21:09 ` stefan-lucks
@ 2010-04-16 20:29   ` J-P. Rosen
  2010-04-16 20:53     ` Charmed Snark
  2010-04-16 20:56     ` Adam Beneschan
  0 siblings, 2 replies; 6+ messages in thread
From: J-P. Rosen @ 2010-04-16 20:29 UTC (permalink / raw)


stefan-lucks@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@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: type String_Type array(Integer range <>) of Character;
  2010-04-16 20:29   ` J-P. Rosen
@ 2010-04-16 20:53     ` Charmed Snark
  2010-04-16 20:56     ` Adam Beneschan
  1 sibling, 0 replies; 6+ messages in thread
From: Charmed Snark @ 2010-04-16 20:53 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 698 bytes --]

J-P. Rosen expounded in news:hqahb1$tnm$1@news.eternal-september.org:

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



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: type String_Type array(Integer range <>) of Character;
  2010-04-16 20:29   ` J-P. Rosen
  2010-04-16 20:53     ` Charmed Snark
@ 2010-04-16 20:56     ` Adam Beneschan
  2010-04-19 15:27       ` Warren
  1 sibling, 1 reply; 6+ messages in thread
From: Adam Beneschan @ 2010-04-16 20:56 UTC (permalink / raw)


On Apr 16, 1:29 pm, "J-P. Rosen" <ro...@adalog.fr> wrote:
> stefan-lu...@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




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: type String_Type array(Integer range <>) of Character;
  2010-04-16 19:52 type String_Type array(Integer range <>) of Character; Warren
@ 2010-04-16 21:09 ` stefan-lucks
  2010-04-16 20:29   ` J-P. Rosen
  0 siblings, 1 reply; 6+ messages in thread
From: stefan-lucks @ 2010-04-16 21:09 UTC (permalink / raw)


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




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: type String_Type array(Integer range <>) of Character;
  2010-04-16 20:56     ` Adam Beneschan
@ 2010-04-19 15:27       ` Warren
  0 siblings, 0 replies; 6+ messages in thread
From: Warren @ 2010-04-19 15:27 UTC (permalink / raw)


Adam Beneschan expounded in news:2dab1630-4abd-4d5b-a286-
6fdbd18ce19c@b33g2000yqc.googlegroups.com:

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

Even better, thanks.

Warren



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-04-19 15:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-16 19:52 type String_Type array(Integer range <>) of Character; Warren
2010-04-16 21:09 ` stefan-lucks
2010-04-16 20:29   ` J-P. Rosen
2010-04-16 20:53     ` Charmed Snark
2010-04-16 20:56     ` Adam Beneschan
2010-04-19 15:27       ` Warren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox