Pascal to Ada95 Translator Ada95 (and its predecessor Ada83) uses a syntax very similar to the Pascal language, and provides a number of features that are also found in Pascal. This makes it farily easy for Pascal programmers to read and write Ada95 programs that involve common features. This translator describes the Ada95 constructs which implement features found in both languages. Since the two languages were developed for different purposes (Pascal as a simple yet explicative language intended for teaching programming, and Ada95 as a language for developing [possibly very large] embedded programs) and many years apart, it is not surprising that Ada95 includes many features that are not found in Pascal. This translator makes no attempt to describe those additional Ada95 features. Fundamentals Topic Pascal Ada95 semicolon Uses the ; as a statement separator. No ; is needed after statements that appear before end or else Uses the ; as a statement terminator. This means ; must appear at the end of every statement, regardless of any reserved words that may follow the statement. comments Begin with a { or (* and continue until a matching } or *) is encountered. Comments may continue across several lines. Begin with -- and continue to the end of the current line. Multiline comments must begin each line with -- compound statement Syntax is described in terms of single statements as targets of control structures. Begin - end pairs are used group two or more statements together to allow them to be treated as a single statement for control purposes. Thus: if condition then statement; or if condition then begin statement; statement end; Control structure syntax is designed with reserved words to terminate each construct. Targets of control statements may be statement sequences without use of Begin - end pairs. Thus: if condition then statement; statement; end if; Begin - end pairs act as blocks, and can scope identifiers within code sections. declare declaration statements begin one or more executable statements, including null end; Identifiers and Literals Topic Pascal Ada95 identifiers Any length. Begin with letter, contain letters and digits. Same, except can also contain the underscore ( _ ) character except as the first character. numeric literals Begin with a digit (except for optional leading + or - sign). Integer literals contain only digits. Real literals must contain a decimal point followed by one or more digits, or a scale factor (E followed by optional sign and an integer). -40579 3.141592 12E-04 Same, except can contain underscore characters (to group digits). The underscore cannot appear next to the decimal point in a real literal, nor at the beginning or end of the literal. -40_579 3.141_592 12E-04 character literals Use single quotes to contain the character. Use 2 single quotes to represent the quote character. 'a' '''' Same. string literals No separate string literals. Use character literals containing multiple characters. 'This is a string!' Use double quotes to represent a multicharacter string. Use two double quotes to represent the double quote character. "This is a string!" "Type ""string"" now." Operators and Expressions Topic Pascal Ada95 arithmetic operators +, -, *, / (real and mixed mode division), div (integer division with truncation), mod M mod N is undefined if N is not positive +, -, *, / (Float and Integer division), ** (exponentiation), mod, rem, abs Division between two Integers truncates. In A ** B, B must be an Integer and may not be negative if A is an Integer M mod N and M rem N both allow N to be negative. Mod gives result the sign of the second operand, rem gives result the sign of the first operand. relational operators <, <=, =, <>, >=, >, in (set inclusion test) <, <=, =, /=, >=, >, in (range membership and subtype membership test) logical operators not, and, or not, and, or, xor, and then, or else and and or always evaluate both operands. A and then B only evaluates B if A is True. A or else B only evaluates B if A is False. mixed mode expressions Allows mixing integer and real values in expressions (except assignment of real value to integer variable). Promotes integer values to real before performing operation. Both operands of an operator must be of same type; no mixed mode expressions allowed. Can explicitly convert between numeric types by specifiying result type name followed by source type variable or value in parentheses. intvar := Integer (floatvar); precedence not *, /, div, mod, and +, -, or <, <=, =, <>, >=, >, in Operators of equal precedence are evaluated left to right, or as specified by parentheses **, abs, not *, /, mod, rem +, - (unary) +, - (binary) <, <=, =, /=, >=, > and, or, xor Operators of equal precedence are evaluated left to right, or as specified by parentheses. Successive ** operators must be clarified by parentheses: A ** B ** C is illegal Declarations Both Pascal and Ada95 follow a "declare before use" paradigm. Both are strong type checking languages, although Ada95 is significantly more thorough about type checking. Topic Pascal Ada95 predefined types integer, real, Boolean, char Integer (and subtypes Natural, Positive), Float, Boolean, Character, and several others declaring labels label list of unsigned integers; don't need to be declared declaring constants const sequence of identifier = constant_value; identifier: constant type := constant_value; declaring variables var sequence of list of identifiers: type; list of identifiers: type; identifiers may be initialized by specifying assignment value: A: Float := 0.0; declaring types type sequence of identifier = type_definition; type identifier is type_definition; array types type name = array [lower..upper] of component_type; type name is array (lower..upper) of component_type; record types type name = record sequence of field_identifier: type; end; Use variable_name.field_identifier to specifiy a field of a variable of record type. type name is record sequence of field_identifier: type; end record; Use variable_name.field_identifier to specifiy a field of a variable of record type. Ada95 has no equivalent of Pascal's with statement to avoid specifying the variable identifier for each field reference. enumerated types type name = (list of element identifiers); type name is (list of element identifiers); Pointers and Node Structures Topic Pascal Ada95 pointer to nothing nil null declaring pointer types type name = ­type; type name is access type; declaring node structure type ptr = ­Listnode; Listnode = record datum: datumtype; link: ptr end; type Listnode; type ptr is access Listnode; type Listnode = record datum: datumtype; link: ptr end record; declaring pointer variables var p: ptr; p: ptr; creating new nodes new(p); p := new Listnode; freeing unused nodes dispose(p); you may: 1. rely on garbage collector (if provided by the compiler); 2. define an instance of the generic deallocator (unchecked_deallocation): procedure free is new unchecked_deallocation (Listnode, ptr); 3. define your own procedure access fields p­.datum p.datum access entire node p­ p.all Control Structures Ada95 provides a special statement to cause termination of a loop, which may be used in either of the loop control structures specified below. exit [when Boolean_expression] causes control to move to the statement following the loop (unconditionally, or when Boolean_expression is True, if specified). Topic Pascal Ada95 if - then - else if Boolean_expression then statement else statement; no ; allowed before else if Boolean_expression then statements else statements end if; ; required before else and end if case case case_expression of choice: statement; choice: statement end; case_expression must have ordinal value. choices must have constant values. specify alternative choices for same action by choice1, choice2: statement; case case_expression is when choice => statements; when choice => statements; when others => statements; end case; case_expression must have discrete value. choices must have static values. Specify alternatives for same action by when choice1 | choice2 => statement; Specify range of choices for same action by when start..stop => statement; Every possible value of case_expression must have an action specified. when others indicates action to take when case_expression has value not covered by choices. This action may be null statement. counting loop for index := initial_value to | downto final_value do statement; index must be ordinal variable. for index in [reverse] discrete_range loop statements end loop; index is implicitly declared, with a type determined by discrete_range. Within the scope of the loop, index hides other identifiers with the same name. index is not accessible outside of loop. logical pretest loop while Boolean_expression do statement; while Boolean_expression loop statements end loop; logical posttest loop repeat statements until Boolean_expression; loop statements end when Boolean expression; end loop; Parameters, Procedures, and Functions Topic Pascal Ada95 parameter passing mechanisms var parameters cause any changes in the parameter to be reflected in the corresponding argument value in the invoking program. Without var designator, parameters are value parameters only, and changes to them do not cause a change to the corresponding argument.. out and in out mode parameters reflect any changes to them in the corresponding argument in the invoking program. The argument must represent a memory location that can hold a value of the relevant type. out mode parameters can only be "written to" (assigned to), until initialized within the subprogram in mode parameters are value parameters, and may not have a value "written to" them. This is the default mode if not specified otherwise. parameter list [var] identifier {, identifier} : type {; [var] identifier {, identifier} : type} identifier{, identifier}: [in | out | in out] type {; identifier{, identifier}: [in | out | in out] type} procedures procedure name (parameter_list); local declarations begin statements end; procedure name (parameter_list) is local declarations begin statements end name; functions function name (parameter_list): return_type; local declarations begin statements end; Return value by assigning to function name. Returned value may be of predefined, enumerated, or pointer type. function name (parameter_list) return return_type is local declarations begin statements end name; Return value by executing return statement: return expression; Returned value may be discrete, real, access, array, or record type. declaration of mutually recursive subprograms procedure name (parameter_list); forward; procedure name2 (parameter_list); begin . . . name(. . .); . . . end name2; procedure name (parameter_list); begin . . . name2(. . .); . . . end name2; procedure name (parameter_list); procedure name2 (parameter_list) is begin . . . name(. . .); . . . end name2; procedure name (parameter_list) is begin . . . name2(. . .); . . . end name2; Text Input-Output A major difference between Pascal and Ada95 is that the I/O statements in Ada95 only allow specifying a single value to be read or written each time. The standard packages Ada.text_io and Ada.sequential_io provide a variety of input/output procedures and functions. If we assume that we are reading and writing character variables, then the following equivalences hold. Topic Pascal Ada95 keyboard input read (identifier_list); readln(identifier_list); Get (identifier); Get (identifier); Skip_Line; screen output write (identifier_list); writeln (identifier_list); Put (identifier); Put (identifier); New_Line; declaring files type file_type = file of text; var file_variable: file_type; file_variable: File_Type; opening files compiler dependent Open (file_variable, In_File | Out_File | Append_File, "physical_filename"); Open positions the file to the beginning (In_File and Out_File) or to the end (Append_File) reading files read (file_variable, identifier_list); readln (file_variable, identifier_list); Get (file_variable, identifier); Get (file_variable, identifier); Skip_Line; writing files write (file_variable, identifier_list); writeln (file_variable, identifier_list); Put (file_variable, identifier); Put (file_variable, identifier); New_Line; end of line test eoln eoln (file_variable) End_Of_Line End_Of_Line (file_variable) end of file test eof eof (file_variable) End_Of_File End_Of_File (file_variable) closing files compiler dependent Close (file_variable);