Differences

This shows you the differences between two versions of the page.

Link to this comparison view

the_hello_world_program [2011/12/15 20:58]
thomaslocke [The project file]
the_hello_world_program [2012/03/06 22:09] (current)
cvanvliet fixed a few grammar erros
Line 1: Line 1:
 =====  Introduction ​ ===== =====  Introduction ​ =====
-The worlds ​most famous program is probably the [[http://​en.wikibooks.org/​wiki/​Computer_Programming/​Hello_world|Hello,​ world!]] program. It is often the first program programmers write when starting on a new language, so it is only natural that we have an entire page dedicated to greeting the world in Ada.+The world'​s ​most famous program is probably the [[http://​en.wikibooks.org/​wiki/​Computer_Programming/​Hello_world|Hello,​ world!]] program. It is often the first program programmers write when starting on a new language, so it is only natural that we have an entire page dedicated to greeting the world in Ada.
  
 There are literally hundreds of ways to create a **Hello, world!** program in Ada. I'm going to show you a few of these, not because it's necessary to have more than one version, but because it allows me to demonstrate a few Ada basics. There are literally hundreds of ways to create a **Hello, world!** program in Ada. I'm going to show you a few of these, not because it's necessary to have more than one version, but because it allows me to demonstrate a few Ada basics.
Line 7: Line 7:
  
 =====  The simple, no frills version ​ ===== =====  The simple, no frills version ​ =====
-Put the following in a file named ''​helloworld.adb''​+Put the following in a file named //helloworld.adb//
  
 <code ada> <code ada>
Line 18: Line 18:
 </​code>​ </​code>​
  
-In the first line we notice the ''​with Ada.Text_IO;​ use Ada.Text_IO'' ​clause. This is called a **with** clause and it gives the name of the library unit required by this program. We could have done without declaring the ''​use Ada.Text_IO'' ​part, in which case the call to ''​Put_Line'' ​at line 5 would'​ve looked like this:+In the first line we notice the //with Ada.Text_IO;​ use Ada.Text_IO// clause. This is called a **with** clause and it gives the name of the library unit required by this program. We could have done without declaring the //use Ada.Text_IO// part, in which case the call to //Put_Line// at line 5 would'​ve looked like this:
  
 <code ada> <code ada>
Line 24: Line 24:
 </​code>​ </​code>​
  
-Without the ''​use Ada.Text_IO'' ​declaration ​''​Put_Line'' ​is no longer directly visible in the ''​HelloWorld'' ​procedure, so we have to specify where the procedure is to be found.+Without the //use Ada.Text_IO// declaration ​//Put_Line// is no longer directly visible in the //HelloWorld// procedure, so we have to specify where the procedure is to be found.
  
-On line 3 the main procedure of the program begins. This procedure is aptly named ''​HelloWorld''​. This is comparable to C'​s ​''​main()'' ​function, except that in Ada you can name the main procedure as you wish.+On line 3 the main procedure of the program begins. This procedure is aptly named //HelloWorld//. This is comparable to C'​s ​//main()// function, except that in Ada you can name the main procedure as you wish.
  
-Between the ''​is'' ​and ''​begin'' ​keywords we can declare objects, such as variables, constants and arrays, although we do not have any for this example. Between ​''​begin'' ​and ''​end'' ​we write statements, in this case the lone call to the ''​Put_Line'' ​procedure.+Between the //is// and //begin// keywords we can declare objects, such as variables, constants and arrays, although we do not have any for this example. Between ​//begin// and //end// we write statements, in this case the lone call to the //Put_Line// procedure.
  
 And that's all there'​s to it. Now, to compile the program, execute this command: And that's all there'​s to it. Now, to compile the program, execute this command:
Line 34: Line 34:
   $ gnatmake helloworld.adb   $ gnatmake helloworld.adb
  
-You should now have 4 files in the directory where you placed the ''​helloworld.adb'' ​file:+You should now have 4 files in the directory where you placed the //helloworld.adb// file:
  
   helloworld   helloworld
Line 41: Line 41:
   helloworld.o   helloworld.o
  
-The first of these is the executable. The ''​.ali'' ​and ''​.o'' ​files are output generated by the compiler. Lets ignore those for now. Executing the ''​helloworld'' ​program should result in this:+The first of these is the executable. The //.ali// and //.o// files are output generated by the compiler. Lets ignore those for now. Executing the //helloworld// program should result in this:
  
   $ ./​helloworld   $ ./​helloworld
Line 63: Line 63:
   hellowworld.gpr   hellowworld.gpr
  
-This all seems a bit "​much"​ for a simple **Hello, world!** program and it isn't absolutely necessary, but as this is Ada, we might as well do things properly from the beginningand that means keeping object files, executables,​ and source files separated.+This all seems a bit "​much"​ for a simple **Hello, world!** program and it isn't absolutely necessary, but as this is Ada, we might as well do things properly from the beginning and that means keeping object files, executables,​ and source files separated.
  
 Here's a quick overview of what we've got: Here's a quick overview of what we've got:
  
-  * **exe/** This is the directory where the ''​helloworld'' ​executable is placed when compiling the program+  * **exe/** This is the directory where the //helloworld// executable is placed when compiling the program
   * **objects/​** When compiling a program, the compiler creates ALI files, object files and tree files. These files are placed in this directory.   * **objects/​** When compiling a program, the compiler creates ALI files, object files and tree files. These files are placed in this directory.
   * **helloworld.adb** The main Ada source file for the **Hello, world!** program.   * **helloworld.adb** The main Ada source file for the **Hello, world!** program.
-  * **helloworld.gpr** This is an Ada [[http://​gcc.gnu.org/​onlinedocs/​gcc-4.4.3/​gnat_ugn_unw/​Project-Files.html|project file]]. This file controls various properties of the program, such as how to compile it, what sources to include, where to put thingsand so on.+  * **helloworld.gpr** This is an Ada [[http://​gcc.gnu.org/​onlinedocs/​gcc-4.4.3/​gnat_ugn_unw/​Project-Files.html|project file]]. This file controls various properties of the program, such as how to compile it, what sources to include, where to put things and so on.
  
 =====  The project file  ===== =====  The project file  =====
-The ''​helloworld.gpr'' ​file is, as stated earlier, not strictly necessary for compiling an Ada program. Consider it instead as a means to simplify things when programming in Ada. When doing small programs it might seem a bit "over the top", but you might as well get used to it, because it will become crucial as your programs increase in complexity.+The //helloworld.gpr// file is, as stated earlier, not strictly necessary for compiling an Ada program. Consider it instead as a means to simplify things when programming in Ada. When doing small programs it might seem a bit "over the top", but you might as well get used to it, because it will become crucial as your programs increase in complexity.
  
 The project file for our **Hello, world!** program, in spite of being well over twice the size of the program itself, is very simple. What it contains is this: The project file for our **Hello, world!** program, in spite of being well over twice the size of the program itself, is very simple. What it contains is this:
Line 100: Line 100:
 As you can see, the syntax of a project file looks very much like a regular Ada program. In this project file we define where the compiler is to look for source files, in which Ada source file the main procedure is found, where to put the resulting executable, and where to put compiler objects. As you can see, the syntax of a project file looks very much like a regular Ada program. In this project file we define where the compiler is to look for source files, in which Ada source file the main procedure is found, where to put the resulting executable, and where to put compiler objects.
  
-If you use the [[http://​libre.adacore.com/​libre/​tools/​gps/​|GPS IDE]] (you really should - it's very good) or another IDE that supports project files, then the "''​package Ide is''​" block tells the IDE which compiler to use. You should of course change the path ''​/​usr/​gnat/​bin/​gnatmake'' ​to where you've installed the GNAT compiler. And finally, in the ''​package Compiler is'' ​block, we define the options used when compiling the program. There'​s a whole slew of options available. Just do:+If you use the [[http://​libre.adacore.com/​libre/​tools/​gps/​|GPS IDE]] (you really should - it's very good) or another IDE that supports project files, then the "//package Ide is//" block tells the IDE which compiler to use. You should of course change the path ///​usr/​gnat/​bin/​gnatmake// to where you've installed the GNAT compiler. And finally, in the "//package Compiler is//" ​block, we define the options used when compiling the program. There'​s a whole slew of options available. Just do:
  
   $ gnatmake -h   $ gnatmake -h
Line 108: Line 108:
 =====  Compiling with a project file  ===== =====  Compiling with a project file  =====
 Either use your IDE, or this command: Either use your IDE, or this command:
- 
-  $ /​usr/​gnat/​bin/​gnatmake -P helloworld.gpr 
- 
-Or if you want to use the [[http://​gcc.gnu.org/​|GNU GCC]] compiler, do this instead: 
  
   $ gnatmake -P helloworld.gpr   $ gnatmake -P helloworld.gpr
Line 121: Line 117:
   gnatlink /​home/​thomas/​HelloWorld/​objects/​helloworld.ali -o /​home/​thomas/​HelloWorld/​exe/​helloworld   gnatlink /​home/​thomas/​HelloWorld/​objects/​helloworld.ali -o /​home/​thomas/​HelloWorld/​exe/​helloworld
  
-And after that you should have an executable in the ''​exe'' ​directory and a few object files in the ''​objects'' ​directory. This is the method you should use to compile the following **Hello, world!** examples.+And after that you should have an executable in the //exe// directory and a few object files in the //objects// directory. This is the method you should use to compile the following **Hello, world!** examples.
  
 =====  Some alternative Hello, world! examples ​ ===== =====  Some alternative Hello, world! examples ​ =====
-In the first example we included the ''​Ada.Text_IO'' ​package using a ''​with'' ​clause. But we also declared that we wanted to ''​use Ada.Text_IO'' ​on the same line. The ''​use Ada.Text_IO'' ​declaration could have been moved into the declarative part of the ''​HelloWorld'' ​procedure:+In the first example we included the //Ada.Text_IO// package using a //with// clause. But we also declared that we wanted to //use Ada.Text_IO// on the same line. The //use Ada.Text_IO// declaration could have been moved into the declarative part of the //HelloWorld// procedure:
  
 <code ada> <code ada>
Line 136: Line 132:
 </​code>​ </​code>​
  
-In this version, the procedures, functions, and types of ''​Ada.Text_IO'' ​are directly available inside the ''​HelloWorld'' ​procedure. Outside the block in which ''​use Ada.Text_IO'' ​is declared, we would have to use the dotted notation to invoke, for example, the ''​Put_Line''​ procedure. Let me show you, using two Put functions, the first does not do a linefeed, the second does, so we get "​Hello,​ world!"​ all on one line, but anything coming afterwards will go on a new line:+In this version, the procedures, functions, and types of //Ada.Text_IO// are directly available inside the //HelloWorld// procedure. Outside the block in which //use Ada.Text_IO// is declared, we would have to use the dotted notation to invoke, for example:
  
 <code ada> <code ada>
Line 152: Line 148:
 </​code>​ </​code>​
  
-This enables us to isolate the ''​use ...'' ​declarations to where they are necessary. But ''​use ...'' ​is not the only method to lessen the pain of having to write long package names. How about this one:+This enables us to isolate the //use ...// declarations to where they are necessary. But //use ...// is not the only method to lessen the pain of having to write long package names. How about this one:
  
 <code ada> <code ada>
Line 164: Line 160:
 </​code>​ </​code>​
  
-Here we've renamed the entire ​''​Ada.Text_IO'' ​package to the much shorter ​''​IO''​. We then proceed using the normal dotted notation to use the ''​Put_Line'' ​procedure. How does this fit in with the ''​use ...'' ​declaration?​+Here we've renamed the entire ​//Ada.Text_IO// package to the much shorter ​//IO//. We then proceed using the normal dotted notation to use the //Put_Line// procedure. How does this fit in with the //use ...// declaration?​
  
 <code ada> <code ada>
Line 186: Line 182:
  
 ====  Hello, world! using variables and constants ​ ==== ====  Hello, world! using variables and constants ​ ====
-So far we've called ​''​Put_Line'' ​and ''​Put'' ​with the **Hello, world!** string literal as the parameter, but it's of course also possible to instead use a constant:+So far we've called ​//Put_Line// and //Put// with the **Hello, world!** string literal as the parameter, but it's of course also possible to instead use a constant:
  
 <code ada> <code ada>
Line 192: Line 188:
  
 procedure HelloWorld is procedure HelloWorld is
-   Hello : constant String := "​Hello,​ world!";​+   Hello : constant String ​(1 .. 13) := "​Hello,​ world!";​
 begin begin
    ​Put_Line (Hello);    ​Put_Line (Hello);
Line 198: Line 194:
 </​code>​ </​code>​
  
-On line 4 we declare the constant ​''​Hello''​, which is immediately assigned the value ''​Hello, world!''​. Constants should obviously always be initialized when declared, unless the constant is [[http://​www.adaic.com/​standards/​05rm/​html/​RM-7-4.html|deferred]].+On line 4 we declare the constant ​//Hello//, which is immediately assigned the value //Hello, world!//. Constants should obviously always be initialized when declared, unless the constant is [[http://​www.adaic.com/​standards/​05rm/​html/​RM-7-4.html|deferred]].
  
 Using a regular variable, the program looks like this: Using a regular variable, the program looks like this:
Line 225: Line 221:
 </​code>​ </​code>​
  
-On line 4 we declare the variable ​''​Hello'' ​to be of the type ''​String (1 .. 13)''​. That one line there tells us something important about the ''​String'' ​type: It is really just an ordinary ​array of characters, in this case an array with room for 13 characters. The ''​String'' ​type is [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-6-3.html|declared]] like this:+On line 4 we declare the variable ​//Hello// to be of the type //String (1 .. 13)//. That one line there tells us something important about the //String// type: It is really just an array of characters, in this case an array with room for 13 characters. The //String// type is [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-6-3.html|declared]] like this:
  
 <code ada> <code ada>
Line 231: Line 227:
 </​code>​ </​code>​
  
-This means that all the tools Ada makes available for handling [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-6.html|arrays]],​ can also be used to manage ​''​String'' ​objects.+This means that all the tools Ada makes available for handling [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-6.html|arrays]],​ can also be used to manage ​//String// objects.
  
-On line 6 we assign the string literal ​''​Hello, world!'' ​to the ''​Hello'' ​variable, and then we output the contents of ''​Hello'' ​using ''​Put_Line''​, as usual.+On line 6 we assign the string literal ​//Hello, world!// to the //Hello// variable, and then we output the contents of //Hello// using //Put_Line//, as usual.
  
-In the above examples we have specifically declared the ''​Hello'' ​object to be of the type ''​String (1 .. 13)''​. This is not strictly necessary, as the length of the array is implied when the ''​Hello, world!'' ​string literal is assigned:+In the above examples we have specifically declared the //Hello// object to be of the type //String (1 .. 13)//. This is not strictly necessary, as the length of the array is implied when the //Hello, world!// string literal is assigned:
  
 <code ada> <code ada>
Line 247: Line 243:
 </​code>​ </​code>​
  
-This will of course only work if the ''​Hello'' ​object is initialized when it is declared. You cannot do this:+This will of course only work if the //Hello// object is initialized when it is declared. You cannot do this:
  
 <code ada> <code ada>
Line 268: Line 264:
  
 ====  Hello, world! is really just an array  ==== ====  Hello, world! is really just an array  ====
-Now that we know that the ''​String'' ​type is really just an array of characters, it's easy to do various "​fun"​ things with the **Hello, world!** string literal. How about reversing it?+Now that we know that the //String// type is really just an array of characters, it's easy to do various "​fun"​ things with the **Hello, world!** string literal. How about reversing it?
  
 <code ada> <code ada>
Line 287: Line 283:
   !dlrow ,olleH   !dlrow ,olleH
  
-Lets go vertical:+Let'​s ​go vertical:
  
 <code ada> <code ada>
Line 320: Line 316:
 Neat! Neat!
  
-Lets take a closer look at the two programs. In both of them we have a ''​for'' ​statement. This is a loop which allows for a specific number of iterations, here given by the ''​Hello'​Range'' ​discrete range. ​''​Hello'​Range'' ​is just a short/​convenient way of saying ​''​Hello'​First .. Hello'​Last''​, which would'​ve worked just as well.+Let'​s ​take a closer look at the two programs. In both of them we have a //for// statement. This is a loop which allows for a specific number of iterations, here given by the //Hello'​Range// discrete range. ​//Hello'​Range// is just a short/​convenient way of saying ​//Hello'​First .. Hello'​Last//, which would'​ve worked just as well.
  
-We know that the ''​String'' ​type is an array of characters, with an index value of the type ''​Positive''>​+We know that the //String// type is an array of characters, with an index value of the type //Positive//
  
 <code ada> <code ada>
Line 328: Line 324:
 </​code>​ </​code>​
  
-According to the above, a ''​Positive'' ​is an integer ranging from 1 to the highest available integer on the platform. Because of this, the first index of a ''​String'' ​defaults to 1. On the first iteration of the loop ''​i'' ​equals 1, so the line ''​Put (Hello (i));'' ​outputs the first character in the ''​Hello, world!'' ​string, and on the final iteration of the loop it outputs the 13th. index of the string, the character **!**.+According to the above, a //Positive// is an integer ranging from 1 to the highest available integer on the platform. Because of this, the first index of a //String// defaults to 1. On the first iteration of the loop //i// equals 1, so the line //Put (Hello (i));// outputs the first character in the //Hello, world!// string, and on the final iteration of the loop it outputs the 13th. index of the string, the character **!**.
  
-Since we know that the ''​String'' ​type is merely an array of characters, we can do weird stuff like this:+Since we know that the //String// type is merely an array of characters, we can do weird stuff like this:
  
 <code ada> <code ada>
Line 350: Line 346:
   Ifmmp-!xpsme"​   Ifmmp-!xpsme"​
  
-What just happened there? Remember the ''​'Range'' ​attribute we used in the ''​for .. loop''​? Well, there are lots of such [[http://​www.adaic.com/​standards/​05rm/​html/​RM-K.html|attributes in Ada]], and ''​'Succ'' ​is one such:+What just happened there? Remember the //'Range// attribute we used in the //for .. loop//? Well, there are lots of such [[http://​www.adaic.com/​standards/​05rm/​html/​RM-K.html|attributes in Ada]], and //'Succ// is one such:
  
 <code ada> <code ada>
Line 358: Line 354:
 Looks a bit odd eh'? Here's the formal explanation:​ Looks a bit odd eh'? Here's the formal explanation:​
  
-<​blockquote> +>For an enumeration type, the function returns the value whose position number is one more than that of the value of Arg; Constraint_Error is raised if there is no such value of the type. For an integer type, the function returns ​>the result of adding one to the value of Arg. For a fixed point type, the function returns the result of adding small to the value of Arg. For a floating point type, the function returns the machine number (as defined in 3.5.7) ​>immediately above the value of Arg; Constraint_Error is raised if there is no such machine number.  
-For an enumeration type, the function returns the value whose position number is one more than that of the value of Arg; Constraint_Error is raised if there is no such value of the type. For an integer type, the function returns the result of adding one to the value of Arg. For a fixed point type, the function returns the result of adding small to the value of Arg. For a floating point type, the function returns the machine number (as defined in 3.5.7) immediately above the value of Arg; Constraint_Error is raised if there is no such machine number.  +
-</​blockquote>​+
  
-In Ada the [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-5-2.html|Character type]] is an [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-5-1.html|enumeration type]]. The ''​'Succ'' ​attribute give the successor of an enumeration value, so the value ''​H'' ​becomes an ''​I'' ​instead. The ''​'Pre'' ​attribute gives the predecessor.+In Ada the [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-5-2.html|Character type]] is an [[http://​www.adaic.com/​standards/​05rm/​html/​RM-3-5-1.html|enumeration type]]. The //'Succ// attribute give the successor of an enumeration value, so the value //H// becomes an //I// instead. The //'Pre// attribute gives the predecessor.
  
-====  Going UP or down  ====+====  Going up or down  ====
 Adding the package [[http://​www.adaic.com/​standards/​05rm/​html/​RM-A-3-2.html|Ada.Characters.Handling]] gives us a few tools to handle characters and strings, for example the ever useful ability to either change a string to uppercase or lowercase: Adding the package [[http://​www.adaic.com/​standards/​05rm/​html/​RM-A-3-2.html|Ada.Characters.Handling]] gives us a few tools to handle characters and strings, for example the ever useful ability to either change a string to uppercase or lowercase:
  
Line 386: Line 381:
   hello, world!   hello, world!
  
-In this package there are also useful functions like ''​Is_Letter (Item : Character) return Boolean''​''​function Is_Digit (Item : Character) return Boolean''​''​function Is_Alphanumeric (Item : Character) return Boolean'' ​and so on.+In this package there are also useful functions like //Is_Letter (Item : Character) return Boolean////function Is_Digit (Item : Character) return Boolean////function Is_Alphanumeric (Item : Character) return Boolean// and so on.
  
 ====  Concatenate ​ ==== ====  Concatenate ​ ====
-One dimensional arrays can be concatenated using the ''​&'' ​operator:+One-dimensional arrays can be concatenated using the //&// operator:
  
 <code ada> <code ada>
Line 414: Line 409:
 </​code>​ </​code>​
  
-Both of which yield the expected output. This next one perhaps demonstrates the use of the ''​&'' ​operator even better:+Both of which yield the expected output. This next one perhaps demonstrates the use of the //&// operator even better:
  
 <code ada> <code ada>
Line 433: Line 428:
 </​code>​ </​code>​
  
-Note how we at line 6 initialize the value of the ''​HelloWorld'' ​string to whitespace using the ''​others'' ​aggregate. What ''​others'' ​enables us to do is fill the remaining part of an array with the given value. In our case, the remaining part of the ''​HelloWorld'' ​array is the entire array, as we have not assigned a single character to the string.+Note how at line 6 initialize the value of the //HelloWorld// string to whitespace using the //others// aggregate. What //others// enables us to do is fill the remaining part of an array with the given value. In our case, the remaining part of the //HelloWorld// array is the entire array, as we have not assigned a single character to the string.
  
 Running this we get: Running this we get:
Line 444: Line 439:
 </​code>​ </​code>​
  
-We can even avoid the ''​String (1 .. 13)'' ​declaration:​+We can even avoid the //String (1 .. 13)// declaration:​
  
 <code ada> <code ada>
Line 463: Line 458:
 </​code>​ </​code>​
  
-Using the ''​'​Length'' ​attribute, we can initialize the ''​H'' ​and ''​W'' ​arrays whatever we feel like, and the ''​HW'' ​array will adjust itself accordingly. The output is the same as the previous example.+Using the //'​Length// attribute, we can initialize the //H// and //W// arrays whatever we feel like, and the //HW// array will adjust itself accordingly. The output is the same as the previous example.
  
 =====  Goodbye, world! ​ ===== =====  Goodbye, world! ​ =====
 These few examples are obviously just scratching the surface of Ada, yet I hope you got a little taste of what Ada is. At least you should be capable of writing your own **Hello, world!** program in Ada. These few examples are obviously just scratching the surface of Ada, yet I hope you got a little taste of what Ada is. At least you should be capable of writing your own **Hello, world!** program in Ada.
  

Navigation