{########################################################################## #### #### #### Full module name: TYPE_TABLE MODULE OF THE TYPE_CHECKER PROGRAM. #### #### File name: TYPE1TAB.PAS.(First of 3 files reqd for this module.)#### #### Support modules reqd: PASLIB.ERL, SCANNER. #### #### Run time environment: . #### #### Compile time environment: MT MicroSYSTEMS Pascal/MT+v5.25. #### #### Link time environment: MT MicroSYSTEMS Linkmt v5.1. #### #### Copyright (C) 1982 by Haldo Products, Inc. All rights reserved. #### #### 56 Camille Ln, E. Patchogue, NY 11772 #### #### Programmer: Lawrence Adkins. #### #### Module Development/Maintenance History: #### 6-NOV-81 Vers 1.0. File just created. 12-NOV-81 Development of this version completed. 9-JAN-82 Vers 2.0. development begins. 1-MAR-82 Development of this version complete. 6-MAR-82 Vers 2.1. Add conformant array stuff. 19-APR-82 Vers 2.2. No changes made. #### #### ##########################################################################} MODULE TYPE_TABLE_HANDLER; {$I B:TYPECHK.DEC } VAR last_tt_entry: integer; { index to last filled entry of type table } token: EXTERNAL tokentype; tokenbuf: EXTERNAL string132; exit_keywords: SET OF token_type; outfile: EXTERNAL text; record_parsing_status : t_record_parsing_status; last_entry_point_name: EXTERNAL string132; ttentry_types_where_base_types_wont_compare, rectype_expansion: SET OF tt_types; debug: EXTERNAL boolean; EXTERNAL PROCEDURE get_next_token; EXTERNAL PROCEDURE error (pascal_error_no: integer); EXTERNAL PROCEDURE @hlt; EXTERNAL PROCEDURE cmstore_scalar_type_values (VAR n_of_values: integer; VAR const_table: ARRAY [ctlobound..cthibound: natural] OF t_const_tab_rec); EXTERNAL PROCEDURE cmfinish_parsing_constant_value (VAR actual_value: integer; VAR const_table: ARRAY [ctlobound..cthibound: natural] OF t_const_tab_rec); {#############################################################################} {--- Initialize all of the variables private to this module } {#############################################################################} PROCEDURE tminit_type_table_module (VAR type_table: ARRAY [ttlobound..tthibound: natural] OF t_type_tab_rec); VAR i: integer; BEGIN FOR i:= 1 TO 9 DO WITH type_table[i] DO BEGIN entry_purpose:= predef_type; base_type_index := 0; lower_bound := 0; upper_bound := 0 END; WITH type_table[0] DO type_id := '0UNDEFIN'; WITH type_table[1] DO BEGIN type_id := 'CHAR'; upper_bound := 255 END; WITH type_table[2] DO BEGIN type_id := 'BYTE'; upper_bound := 255 END; WITH type_table[3] DO BEGIN type_id := 'INTEGER'; lower_bound := -32768; upper_bound := 32767 END; WITH type_table[4] DO BEGIN type_id := 'BOOLEAN'; upper_bound := 1 END; WITH type_table[5] DO BEGIN type_id := 'WORD'; lower_bound := -32768; upper_bound := 32767 END; WITH type_table[6] DO type_id := 'REAL'; WITH type_table[7] DO BEGIN type_id := 'STRING'; upper_bound := 255 END; WITH type_table[8] DO type_id := 'TEXT'; WITH type_table[9] DO type_id := 'FILE'; last_tt_entry := 9; rectype_expansion := [recfields, recfldnestedrecord, recvariant, recvarvalues]; ttentry_types_where_base_types_wont_compare := [array_type, file_type, record_type] END; {#############################################################################} (*-- Assuming that a Pascal keyword has been read in, we will parse the ---- folllowing Pascal/MT+ BNF productions: ---- ::= | ---- TYPE {; } ; ---- ---- ::= = ---- ::= ---- ::= ---- *) {#############################################################################} PROCEDURE tmadd_new_types_to_type_table (VAR const_table: ARRAY [ctlobound..cthibound: natural] OF t_const_tab_rec; VAR type_table : ARRAY [ttlobound..tthibound: natural] OF t_type_tab_rec); CONST action = 'Handling Types...'; BEGIN writeln; writeln (action); writeln (outfile); writeln (outfile, action); exit_keywords := [toktype, tokvar, tokproc, tokfunc, tokbegin, tokexternal]; record_parsing_status.got_rec_type := 0; WHILE token = toktype DO BEGIN get_next_token; { should be type identifier being defined } REPEAT last_entry_point_name := tokenbuf; tm1add_type_identifier_to_type_table (tokenbuf, type_table); get_next_token; { should be equal_sign } REPEAT tm0parse_rest_of_type_definition (const_table, type_table) UNTIL (record_parsing_status.got_rec_type= 0) AND (token= toksemicolon); get_next_token; { should be type_id or keyword } UNTIL (token IN exit_keywords) END END; {#############################################################################} {--- Place a type_id into a new slot of the type table. } {#############################################################################} PROCEDURE tm1add_type_identifier_to_type_table (new_id: alfa; VAR type_table : ARRAY [ttlobound..tthibound: natural] OF t_type_tab_rec); BEGIN tminc_last_tt_entry_index (tthibound); WITH type_table [last_tt_entry] DO BEGIN entry_purpose := undef_type; IF record_parsing_status. got_rec_type = 0 THEN type_id := new_id; lower_bound := 0; upper_bound := 0; base_type_index := 0 END; tmchange_any_refs_to_identical_type_id_with_undef_type (type_table) END; {#############################################################################} {--- Bump the index into the type table by 1, and error if overflow } {#############################################################################} PROCEDURE tminc_last_tt_entry_index (max_type_elements: natural); VAR i: integer; BEGIN IF last_tt_entry >= max_type_elements THEN BEGIN writeln; writeln ('Type Table overflow, last id: ', last_entry_point_name); close (outfile, i); @hlt END; last_tt_entry := last_tt_entry + 1 END; {#############################################################################} (*-- Parse the following Pascal/MT+ BNF productions: ---- ::= | | ---- ::= | ---- PACKED ---- ::= | | ---- | ---- ::= | ---- ::= ---- ::= ---- ::= ---- ::= ---- ::= ---- ::= ---- ::= FILE ---- ::= ---- *) {#############################################################################} PROCEDURE tm0parse_rest_of_type_definition (VAR const_table: ARRAY [ctlobound..cthibound: natural] OF t_const_tab_rec; VAR type_table : ARRAY [ttlobound..tthibound: natural] OF t_type_tab_rec); BEGIN get_next_token; { should be some type definition stuff } IF (token = tokidentifier) AND (tokenbuf = 'ABSOLUTE') THEN BEGIN { ignore [ ] syntax representing the address } get_next_token; get_next_token; get_next_token; get_next_token END ELSE IF token = tokexternal THEN get_next_token; IF token = tokpacked THEN get_next_token; { for sure now, we are at the type_id being defined } tm1init_new_type_table_entry (token, type_table); CASE token OF tokset : tm1parse_set (const_table, type_table); tokfile : tm2parse_tokof_and_beyond (const_table, type_table); tokstring : tm3parse_string (const_table, type_table); tokpointer: tm4parse_pointer (type_table); tokarray : tm5parse_array (const_table, type_table); tokrecord : tm6parse_record (const_table, type_table); ELSE tm9finish_parsing_simple_type (const_table, type_table) END; IF debug THEN error (0); tmremove_duplicate_type_declaration (type_table) END; {#############################################################################} {--- Assuming index has already been bumped and type_identifier entered, ---- initialize some of the other fields for that entry } {#############################################################################} PROCEDURE tm1init_new_type_table_entry (token: tokentype; VAR type_table : ARRAY [ttlobound..tthibound: natural] OF t_type_tab_rec); BEGIN WITH type_table [last_tt_entry] DO IF record_parsing_status.got_rec_type = 0 THEN entry_purpose := tok_class (token) ELSE BEGIN entry_purpose := tokrec_class (token); n_of_stacked_fields:= record_parsing_status.last_n_of_stacked_fields; record_nesting := record_parsing_status.got_rec_type; local_fieldlist_continues := true; field_entry_purpose := tok_class (token) END END; FUNCTION tokrec_class (token: tokentype): tt_types; BEGIN IF token = tokrecord THEN tokrec_class := recfldnestedrecord ELSE tokrec_class := recfields END; FUNCTION tok_class (token: tokentype): tt_types; BEGIN CASE token OF tokset : tok_class := set_type; tokfile : tok_class := file_type; tokstring : tok_class := string_type; tokpointer : tok_class := ptr_type; tokarray : tok_class := array_type; tokrecord : tok_class := record_type; notoken : tok_class := undef_type; ELSE tok_class := simple_type END END; {$I B:TYPE2TAB.PAS } {$I B:TYPE3TAB.PAS } MODEND.