-- This program introduces basic features of Ada: -- Standard types, i/o, operators, strong typing, control structures with ada.text_io; use ada.text_io; -- IO of characters and strings with ada.integer_text_io; use ada.integer_text_io; -- IO of integers -- Case insensitive: with ada.float_text_io; use ADA.FLOAT_TEXT_IO; -- IO of floats procedure intro_all is -- All of these types are automatically available from package Standard -- SIMPLE NUMERIC TYPES - Unitialized i, j, k, int_sum, int_avg: Integer; f, g, flt_sum, flt_avg: Float; -- NUMERIC SUBTYPES - Initialized m, n: Natural := 1; -- 0 .. Integer'last. Same operations as integer. p, q: Positive := 2; -- 1 .. Integer'last. Same operations as integer. -- CONSTANT (of a specified type) c: constant Integer := 3; -- NAMED NUMBERS - no type! pi: constant := 3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37510; two_pi: constant := 2 * pi; one_third: constant := 1 / 3; -- Really 1/3! one: constant := 3 * one_third; -- Really one! -- TYPE BOOLEAN: true or false less: Boolean; -- ENUMERATED Type type Color is (red, blue, green); my_car_color: Color := red; type Days is (Sun, Mon, Tues, Wed, Thu, Fri, Sat); today, tomorrow: Days := Fri; package Days_IO is new Ada.Text_IO.Enumeration_IO(Days); use Days_IO; -- Type for a single 8-bit CHARACTER a_char: Character := 's'; -- FIXED LENGTH STRINGS: A String is an array of Characters -- Include lengths in name for later reference s3: String := "bat"; -- initialized, size 3 s5: String(1 .. 5); -- not initialized s6: String(1 .. 6); s8: String(1 .. 8); s10: String(1 .. 10); s12: String(1 .. 12); -- UNBOUNDED LENGTH STRINGS: see package Ada.Strings.Unbounded begin -- NUMERIC, STRING, and CHARACTER INPUT: -- values from Standard Input are returned in the parameter! -- numeric skips white space, looking for a number -- character and string skip newline but not spaces put("Enter an int, a nat, a string, a float, a string, a float and a character: "); get(i); -- next integer, skips white space get(j); -- next integer, skips white space get(s5); -- 5 characters, skips end of line get(f); -- next float, skips white space get(s6); -- 6 characters, skips end of line get(g); -- next float, skips white space get(a_char); -- 1 character, skips end of line -- Strings are arrays of characters: s3(2) := 'i'; -- s3 is now "bit". Index starts at 1. -- FIXED LENGTH STRING OPERATIONS: String lengths must match s8 := s3 & s5; s10 := s3 & s6 & a_char; s12 := s3 & s6 & a_char & "!!"; put_line(s8); put_line(s10); put_line(s12); -- ARITHMETIC OPERATIONS k := i + j; k := i - j; k := i * j; k := i / j; -- truncates k := 2 ** 10; -- 1024 k := 13 mod 10; -- 3 -- Mod and rem identical for positives k := 13 rem 10; -- 3 k := (-2) mod 12; -- 10 Useful for clock arithmetic k := (-2) rem 12; -- -2 Like Java % operator put("AREA: "); put(pi * f ** 2); new_line; -- STRONG TYPING: ASSIGNMENT, EXPRESSIONS, PUT -- Cannot mix types! These are all okay. flt_sum := f + g; int_sum := i + j; int_avg := int_sum / 2; flt_avg := flt_sum / 2.0; flt_avg := float(int_sum) / 2.0; -- TYPE CONVERSION flt_avg := float(int_sum / 2); -- TYPE CHECKING FOR SUBTYPES get(n); i := n; -- Can mix parent types and subtypes. Where can errors occur? get(i); n := i; p := i; p := n; n := p; -- OUTPUT INTEGERS and FLOATS - No put_line for numeric put(i); new_line; -- Default width: 11 put(i, 4); new_line; -- Minimum width 4 -- KEYWORD PARAMETERS put(item => i, width => 4); new_line; put(f, 4, 5, 0); new_line; -- Put is OVERLOADED put(item => f, fore => 4, aft => 5, exp => 0); new_line; -- 'IMG AND TYPE'IMAGE CONVERT TO A STRING, LIKE to_string put_line(i'img); -- 'img is not standard: provided by GNAT put_line(f'img); put_line(integer'image(i)); put_line(float'image(f)); -- ENUMERATED TYPE if my_car_color = red then put_line("It's red!"); else put_line("It's not red!"); end if; if today in sat | sun then put("Weekend!"); end if; if today not in mon .. fri then -- Another way put("Weekend!"); end if; tomorrow := (if today = sat then sun else Days'Succ(today)); for d in Days loop Days_IO.put(d); put(Days'pos(d)); Days_IO.put(Days'val(Days'pos(d))); new_line; end loop; for c in Color loop if c = my_car_color then put(c'img); end if; end loop; -- Can also instantiate Ada.Text_IO.Enumeration_IO for get and put for colors -- BOOLEAN less := i < j; -- assign a boolean variable put_line(less'img); -- CONTROL STRUCTURES, BOOLEAN OPERATIONS: AND, OR, NOT, XOR if less then put_line(i'img & " < " & j'img); elsif NOT (i = j) OR f > g then put(i); put(" /= "); put_line(j'img & "OR f > g"); -- IN operator and a range -- () required when mixing and, or elsif i in 1 .. 10 and (j not in 1 .. 10 xor i * j /= 25) then put_line("Interesting"); elsif f in 1.1 .. 2.1 then -- Ranges work for floats, too put_line("Great, floats too"); else put_line(i'img & " > " & j'img); end if; -- SHORT CIRCUIT EVALUATION: AND THEN, OR ELSE if j /= 0 AND THEN i > 5 then -- Stop if NOT j/=0 put(i / j); new_line; elsif i = 0 OR ELSE j = 0 then -- Stop if i=0 put_line("One or the other is 0"); end if; -- CASE MUST ACCOUNT FOR ALL VALUES. -- All branches must be disjoint case i is when 1 => put_line("It's one"); when 5 | 3 => put_line("It's three or five"); when 20 .. 29 => put_line("It's in the 20's"); when 7 | 30 .. 39 | 9 => put_line("It's 7 or 9 or in the 30's"); when others => put_line("It's neither odd <= 10,"); put_line("or in 20's or 30's"); end case; int_sum := 0; for k in i .. j loop -- RANGE ALLOWED TO BE EMPTY! int_sum := int_sum + k; end loop; for k in reverse 1 .. 10 loop put(k); -- Prints 10 to 1 end loop; flt_sum := 0.0; while i < 2 * j loop flt_sum := flt_sum + f; i := i + 1; end loop; put(f, 2, 2, 0); new_line; loop -- loop and a half get(f); exit when f < 0.0; put(f, 2, 2, 0); end loop; new_line(2); -- two newlines put_line("DONE"); end intro_all;