;;; -*- mode:lisp;package:user;base:10.;fonts:(cptfontb) -*- ;;; $Header: /ct/interp/adas70.l,v 1.17 84/12/26 16:41:59 penny Exp $ ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; adas70.l ;;; ;;; Paul Robertson January 30, 1983 ;;; ;;; ;;; ;;; The C*T Ada Interpreters Syntax and Static Semantics ;;; ;;; ;;; ;;; This file is part of a proprietary software project. Source ;;; ;;; code and documentation describing implementation details are ;;; ;;; available on a confidential, non-disclosure basis only. These ;;; ;;; materials, including this file in particular, are trade secrets ;;; ;;; of Computer * Thought Corporation. ;;; ;;; ;;; ;;; (c) Copyright 1982 and 1983, Computer * Thought Corporation. ;;; ;;; All Rights Reserved. ;;; ;;; ;;; ;;; Reference materials: ;;; ;;; Miller, 1982. The C*T Ada Tutor: Guide to the Implementation. ;;; ;;; Charniak et al., 198?. Artificial Intelligence Programming. ;;; ;;; ;;; ;;; The following code assumes familiarity with the above. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Ensure presence of needed files. (eval-when (compile load eval) (ct_load 'aip)) ;AIP macros pkg. (eval-when (compile load eval) (ct_load 'compat)) ;Franz/LM compat pkg. (eval-when (compile load eval) (ct_load 'time)) ;Timing functions. (eval-when (compile load eval) (ct_load 'stdenv)) ; contains vital macro (eval-when (compile load eval) (ct_load 'sema)) ; contains vital MACRO (eval-when (compile load eval) (ct_load 'pser)) ; contains vital MACRO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Compiler Declarations and Global Variables -- #+franz (declare (macros t)) (declare (ct_includef 'intrpdcl)) ; get the specials (eval-when (compile load eval) (ct_load 'ferec)) ; get the macros etc. ;;;-- 6. Subprograms ;;;-- =============== ;;;-- 6.1 Subprogram Declarations ;;;-- Syntax 6.1.A ;;;-- subprogram_declaration ::= subprogram_specification ';' ;;;-- | generic_subprogram_declaration ;;;-- | generic_subprogram_instantiation ;;;-- ;;; ;;; SUBPROGRAM_DEF ::= void; ;;; ;;; subprogram_decl => as_designator : DESIGNATOR, -- one of 'entry_id', ;;; -- 'proc_id', 'function_id' ;;; -- or 'def_op' ;;; as_header : HEADER, ;;; as_subprogram_def : SUBPROGRAM_DEF; ;;; subprogram_decl => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; DEF_ID ::= proc_id; ;;; ;;; proc_id => lx_srcpos : source_position, ;;; lx_comments : comments, ;;; lx_symrep : symbol_rep; ;;; proc_id => sm_spec : HEADER, ;;; sm_body : SUBP_BODY_DESC, ;;; sm_location : LOCATION; ;;; ;;; DEF_ID ::= function_id; ;;; ;;; function_id => lx_srcpos : source_position, ;;; lx_comments : comments, ;;; lx_symrep : symbol_rep; ;;; function_id => sm_spec : HEADER, ;;; sm_body : SUBP_BODY_DESC, ;;; sm_location : LOCATION; ;;; ;;; DEF_OP ::= def_op; ;;; ;;; def_op => lx_srcpos : source_position, ;;; lx_comments : comments, ;;; lx_symrep : symbol_rep; ;;; def_op => sm_spec : HEADER, ;;; sm_body : SUBP_BODY_DESC, ;;; sm_location : LOCATION; ;;; ;;; LANGUAGE ::= argument_id; ;;; LOCATION ::= EXP_VOID | pragma_id; ;;; SUBP_BODY_DESC ::= block | stub | instantiation | ;;; FORMAL_SUBPROG_DEF | rename | LANGUAGE | void; ;;;-- 'pragma_id' and 'argument_id' only occur in the predefined environment ;;; ;;;-- Syntax 6.1.B ;;;-- subprogram_specification ::= ;;;-- 'procedure' identifier [formal_part] ;;;-- | 'function' designator [formal_part] ;;;-- 'return' subtype_indication ;;;-- designator ::= identifier | operator_symbol ;;;-- operator_symbol ::= character_string ;;;-- ;;; ;;; ;;; HEADER ::= procedure; ;;; HEADER ::= function; ;;; CONSTRAINED_VOID ::= CONSTRAINED | void; ;;; ;;; procedure => as_param_s : PARAM_S; ;;; procedure => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; function => as_param_s : PARAM_S, ;;; as_constrained_void : CONSTRAINED_VOID; ;;; -- void in case of instantiation ;;; function => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;;-- Syntax 6.1.C ;;;-- formal_part ::= ;;;-- '(' parameter_declaration {';' parameter_declaration} ')' ;;;-- parameter_declaration ::= ;;;-- identifier_list ':' mode subtype_indication ;;;-- [':=' expression] ;;;-- mode ::= ['in'] | 'out' | 'in' 'out' ;;;-- ;;; ;;; ;;; PARAM_S ::= param_s; ;;; ;;; param_s => as_list : Seq Of PARAM; ;;; param_s => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; ;;; PARAM ::= pragma; -- pragma allowed after ';' ;;; ;;; PARAM ::= in; ;;; ;;; in => as_id_s : ID_S, -- always a sequence ;;; -- of 'in_id' ;;; as_type_spec : TYPE_SPEC, ;;; as_exp_void : EXP_VOID; ;;; in => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; ;;; PARAM ::= in_out; ;;; PARAM ::= out; ;;; ;;; in_out => as_id_s : ID_S, -- always a sequence ;;; -- of 'in_out_id' ;;; as_type_spec : TYPE_SPEC, ;;; as_exp_void : EXP_VOID; -- always void ;;; in_out => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; out => as_id_s : ID_S, -- always a sequence ;;; -- of 'out_id' ;;; as_type_spec : TYPE_SPEC, ;;; as_exp_void : EXP_VOID; -- always void ;;; out => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; DEF_ID ::= in_id; ;;; ;;; in_id => lx_srcpos : source_position, ;;; lx_comments : comments, ;;; lx_symrep : symbol_rep; ;;; in_id => sm_obj_type : TYPE_SPEC, ;;; sm_init_exp : EXP_VOID; ;;; ;;; ;;; DEF_ID ::= in_out_id | out_id; ;;; ;;; in_out_id => lx_srcpos : source_position, ;;; lx_comments : comments, ;;; lx_symrep : symbol_rep; ;;; in_out_id => sm_obj_type : TYPE_SPEC; ;;; ;;; out_id => lx_srcpos : source_position, ;;; lx_comments : comments, ;;; lx_symrep : symbol_rep; ;;; out_id => sm_obj_type : TYPE_SPEC; ;;; ;;;;;;;;;;;;;;; (def_ada_syntax proc_param_decl ;;;;;;;;;;;;;;; (pr_and (lambda(as) (let ((identlist (cons (first as)(second as)))) (ct_selectq (first (fourth as)) (dn_in (sc_diana dn_in as_id_s (mapcar '(lambda(inid) ; formal in parameter. (add_name (diana_get inid 'lx_symrep) ; name 'formal_parameter (let ((id (sc_diana dn_in_id lx_symrep (diana_get inid 'lx_symrep) sm_obj_type (subtype_ind_init%sub_ind (second (fourth as))) ))) (diana_put id (diana_get inid 'lx_srcpos) 'lx_srcpos) (diana_put id id 'sm_defn) id) nil)) identlist) as_name (subtype_ind_init%sub_ind (second (fourth as))) as_exp_void (subtype_ind_init%initexp (second (fourth as))) )) (dn_in_out (sc_diana dn_in_out as_id_s (mapcar '(lambda(inid) ; formal in_out parameter. (add_name (diana_get inid 'lx_symrep) ; name 'formal_parameter (let ((id (sc_diana dn_in_out_id lx_symrep (diana_get inid 'lx_symrep) sm_obj_type (second (fourth as)) ))) (diana_put id (diana_get inid 'lx_srcpos) 'lx_srcpos) (diana_put id id 'sm_defn) id) nil)) identlist) as_name (second (fourth as)))) (dn_out (sc_diana dn_out as_id_s ; (mapcar '(lambda(inid); formal out parameter. (add_name (diana_get inid 'lx_symrep) ; name 'formal_parameter (let ((id (sc_diana dn_out_id lx_symrep (diana_get inid 'lx_symrep) sm_obj_type (second (fourth as)) ))) (diana_put id (diana_get inid 'lx_srcpos) 'lx_srcpos) (diana_put id id 'sm_defn) id) nil)) identlist) as_name (second (fourth as)))) (otherwise (lose 'fe_ppmode 'proc_formal_param `("Fatal error in frontend - proc_formal_param"))) ))) (pr_and (lambda (as) (let ((node (sc_diana dn_in_id lx_symrep (first as)))) (adjust_source_pos node -1 -1) node)) lex_ident) (pr_repeat nil (pr_or nil (pr_and (lambda(as) (gripe '("Probably comma omitted")) (first as)) (pr_and (lambda (as) (let ((node (sc_diana dn_in_id lx_symrep (first as)))) (adjust_source_pos node -1 -1) node)) lex_ident)) (pr_and cadr oper_comma (pr_and (lambda (as) (let ((node (sc_diana dn_in_id lx_symrep (first as)))) (adjust_source_pos node -1 -1) node)) lex_ident)))) (pr_or nil (pr_and (lambda(as) (gripe '("Probably colon omitted")) (putback_symbol (first as))) (pr_or nil symb_in symb_out)) oper_colon) (pr_or nil (pr_and (lambda(as) (cond ((and (first as) (null (extract_basetype (second as)))) (semgripe 'incomplete_type))) (list 'dn_out (second as))) symb_out subtype_indication) (pr_and cadr symb_in (pr_or nil (pr_and (lambda(as) (cond ((and (first as) (null (extract_basetype (second as)))) (semgripe 'incomplete_type))) (list 'dn_in_out (second as))) symb_out subtype_indication) (pr_and (lambda(as) (cond ((and (subtype_ind_init%sub_ind (first as)) (null (extract_basetype (subtype_ind_init%sub_ind (first as))))) (semgripe 'incomplete_type))) (list 'dn_in (first as))) subtype_indication_init))) (pr_and (lambda(as) (cond ((and (subtype_ind_init%sub_ind (first as)) (null (extract_basetype (subtype_ind_init%sub_ind (first as))))) (semgripe 'incomplete_type))) (list 'dn_in (first as))) subtype_indication_init)))) ;;;;;;;;;;;;;;;; (def_ada_syntax funct_param_decl ;;;;;;;;;;;;;;;; (pr_and (lambda(as) (let ((identlist (cons (first as)(second as)))) (sc_diana dn_in as_id_s (mapcar '(lambda(inid) ; formal in parameter. (add_name (diana_get inid 'lx_symrep) ; name 'formal_parameter (let ((id (sc_diana dn_in_id lx_symrep (diana_get inid 'lx_symrep) sm_obj_type (subtype_ind_init%sub_ind (fifth as)) ))) (diana_put id (diana_get inid 'lx_srcpos) 'lx_srcpos) (diana_put id id 'sm_defn) id) nil)) identlist) as_name (subtype_ind_init%sub_ind (fifth as)) as_exp_void (subtype_ind_init%initexp (fifth as))))) (pr_and (lambda (as) (let ((node (sc_diana dn_in_id lx_symrep (first as)))) (adjust_source_pos node -1 -1) node)) lex_ident) (pr_repeat nil (pr_or nil (pr_and (lambda(as) (gripe '("Probably comma omitted")) (first as)) (pr_and (lambda (as) (let ((node (sc_diana dn_in_id lx_symrep (first as)))) (adjust_source_pos node -1 -1) node)) lex_ident)) (pr_and cadr oper_comma (pr_and (lambda (as) (let ((node (sc_diana dn_in_id lx_symrep (first as)))) (adjust_source_pos node -1 -1) node)) lex_ident)))) oper_colon (pr_or nil symb_in nil) subtype_indication_init)) ;;;;;;;;;;;;;;;;; (def_ada_syntax funct_formal_part ;;;;;;;;;;;;;;;;; (pr_and (lambda(as) (sc_diana dn_function as_param_s (cons (second as)(third as)))) oper_lparen funct_param_decl (pr_repeat nil (pr_and cadr oper_semicolon funct_param_decl)) (pr_or nil (pr_and (lambda(as) (gripe '("A right parenthesis was expected")) (putback_symbol 'symb_is)) symb_is) oper_rparen))) ;;;;;;;;;;;;;;;; (def_ada_syntax proc_formal_part ;;;;;;;;;;;;;;;; (pr_and (lambda(as) ;(break in-proc-formal-part) (sc_diana dn_procedure as_param_s (cons (second as)(third as)))) oper_lparen proc_param_decl (pr_repeat nil (pr_and cadr oper_semicolon proc_param_decl)) (pr_or nil (pr_and (lambda(as) (gripe '("A right parenthesis was expected")) (putback_symbol 'symb_is)) symb_is) oper_rparen))) ;;;-- 6.3 Subprogram Bodies ;;; ;;;-- Syntax 6.3 ;;;-- subprogram_body ::= ;;;-- subprogram_specification 'is' ;;;-- declarative_part ;;;-- 'begin' ;;;-- sequence_of_statements ;;;-- ['exception' ;;;-- {exception_handler}] ;;;-- 'end' [designator] ';' ;;;-- ;;; ;;; ;;; BLOCK_STUB ::= block; ;;; ;;; subprogram_body => as_designator : DESIGNATOR, -- one of 'proc_id', ;;; -- 'function_id' or 'def_op' ;;; as_header : HEADER, ;;; as_block_stub : BLOCK_STUB; ;;; subprogram_body => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;;;;;;;; (def_ada_syntax body_part ;;;;;;;;; (pr_or nil (pr_and (lambda(as) (cond ((eq (second as) 'symb_end) (sc_diana dn_block as_item_s (first as) as_stm_s ())) (t (sc_diana dn_block as_item_s (first as) as_stm_s (car (second as)) as_alternative_s (cadr (second as)))))) declarative_part (pr_or nil (pr_in_block statement_part) symb_end)) (pr_and (lambda(as) (sc_diana dn_block as_item_s nil as_stm_s (car (first as)) as_alternative_s (cadr (first as)))) (pr_in_block statement_part)))) ;;;-- 6.4 Subprogram Calls ;;; ;;;-- Syntax 6.4 ;;;-- procedure_call ::= ;;;-- name [actual_parameter_part] ';' ;;;-- function_call ::= ;;;-- name actual_parameter_part ;;;-- actual_parameter_part ::= ;;;-- '(' parameter_association {',' parameter_association}')' ;;;-- parameter_association ::= ;;;-- [formal_parameter '=>'] actual_parameter ;;;-- formal_parameter ::= identifier ;;;-- actual_parameter ::= expression ;;;-- ;;; ;;; ;;; STM ::= procedure_call; ;;; ;;; procedure_call => as_name : NAME, ;;; as_param_assoc_s : PARAM_ASSOC_S; ;;; procedure_call => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; procedure_call => sm_normalized_param_s :EXP_S; ;;; ;;; NAME ::= function_call; ;;; ;;; function_call => as_name : NAME, ;;; as_param_assoc_s : PARAM_ASSOC_S; ;;; function_call => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; function_call => sm_exp_type : TYPE_SPEC, ;;; sm_value : value, ;;; sm_normalized_param_s :EXP_S; ;;; ;;; PARAM_ASSOC ::= EXP | assoc; ;;; ;;; assoc => as_designator : DESIGNATOR, ;;; as_actual : ACTUAL; ;;; assoc => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; ;;; ACTUAL ::= EXP; ;;; ;;;;;;;;;;;;;;;;;;;;; (def_ada_syntax actual_parameter_part ;;;;;;;;;;;;;;;;;;;;; (pr_or nil actual_parameter_part_formal (pr_and (lambda(as) ;(break in-actual_parameter_part) (cons (first as)(second as))) expression (pr_or nil (pr_and cadr oper_comma actual_parameter_part) nil)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def_ada_syntax actual_parameter_part_formal ;;;;;;;;;;;;;;;;;;;;;;;;;;;; (pr_and2 (lambda(as) ;(break in-actual_parameter_part_formal) (cons (sc_diana dn_assoc as_designator (first as) as_actual (third as)) (fourth as))) lex_ident ; (pr_restrict formal_parameter lex_ident) oper_goes expression (pr_or nil (pr_and cadr oper_comma actual_parameter_part_formal ) nil))) ;;;-- Syntax 9.5.B ;;;-- entry_call ::= name [actual_parameter_part] ';' ;;;-- ;;; ;;; ;;; STM ::= entry_call; ;;; ;;; entry_call => as_name : NAME, ;;; as_param_assoc_s : PARAM_ASSOC_S; ;;; entry_call => lx_srcpos : source_position, ;;; lx_comments : comments; ;;; entry_call => sm_normalized_param_s :EXP_S; ;;; ;;;;;;;;;;;;;;;;;;;;;;; (def_ada_syntax procedure_or_entry_call ;;;;;;;;;;;;;;;;;;;;;;; (pr_or nil (pr_and (lambda(as) ;(break in_proc_or_entry_call) (sc_diana dn_procedure_call as_name nil ; gets filled in later. as_param_assoc_s (sc_diana dn_param_assoc_s as_list (second as)) sm_normalized_param_s nil )) oper_lparen (pr_or nil (pr_and car procedure_or_entry_call_formal) ;; this one MUST be first. (pr_and (lambda(as) ;;(break in_procedure_or_entry_call_formal) ;; assume proc call for now. (cons (first as)(second as))) expression (pr_or nil (pr_and cadr oper_rparen (pr_or nil (pr_and cadr oper_lparen actual_parameter_part oper_rparen) nil) (pr_or nil oper_semicolon (pr_and (lambda (as) (semgripe 'illegal_assignment) (do nil ((eq la_current_symbol 'oper_semicolon) nil) (la_lex)) (la_lex)) oper_assign))) (pr_and cadr oper_comma actual_parameter_part oper_rparen (pr_or nil oper_semicolon (pr_and (lambda (as) (semgripe 'illegal_assignment) (do nil ((eq la_current_symbol 'oper_semicolon) nil) (la_lex)) (la_lex)) oper_assign))))) (pr_or nil (pr_and (lambda (as) (semgripe 'must_have_at_least_one_param) (do nil ((eq la_current_symbol 'oper_semicolon) nil) (la_lex)) (la_lex) nil) oper_rparen) nil) )) (pr_and (lambda(as) (sc_diana dn_procedure_call as_name nil ; gets filled in later. as_param_assoc_s nil ; no parameters. sm_normalized_param_s nil)) (pr_or nil oper_semicolon (pr_and (lambda (as) (semgripe 'illegal_assignment) (do nil ((eq la_current_symbol 'oper_semicolon) nil) (la_lex)) (la_lex)) oper_assign))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def_ada_syntax procedure_or_entry_call_formal ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (pr_and2 (lambda(as) ; build me a list of assocs. (cons ; first assoc (sc_diana dn_assoc as_designator (first as) as_actual (third as)) (fourth as))) ; and all the rest. lex_ident ; (pr_restrict formal_parameter lex_ident) oper_goes expression (pr_or nil (pr_and (lambda(as) nil) oper_rparen oper_semicolon) (pr_and cadr oper_comma procedure_or_entry_call_formal))))