;;; -*- mode:lisp;package:user;base:10.;fonts:(cptfontb) -*- ;;; $Header: /ct/interp/adas44.l,v 1.59 84/10/23 17:41:23 penny Exp $ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; adas44.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. (defun stub_p(dn)(eq (diana_nodetype_get dn) 'dn_stub)) ;;;;;;;;;;;;;;;;; (def_ada_syntax program_component ;;;;;;;;;;;;;;;;; (pr_or nil pragma ; allow pragmas as program components. (pr_and car ; throw away the semicolon. (pr_or nil (pr_and (lambda(as) (matching_ident (diana_get (second as) 'lx_symrep) (ct_pop *identstack*)) (setq *current_generic_nestitude* (ct_pop *generic_nestitude_stack*)) (ct_pop *identstack*) ;pop off the id node. (sc_diana dn_subprogram_decl as_designator (let ((nod (second as)) (others (diana_get (second as) 'sm_first))) ; (break in-program-component) (cond ((third (third as)) (cond ((eq (diana_nodetype_get (third (third as))) 'dn_instantiation) ; (break instantiating) (let ((instantiation (instantiated_spec (third (third as))))) (cond (instantiation (diana_put nod (diana_get instantiation 'sm_spec) 'sm_spec) (diana_put nod (diana_get instantiation 'ct_spec) 'ct_spec) (diana_put nod (diana_get instantiation 'sm_body) 'sm_body))))) (t (diana_put nod (first (third as)) 'sm_spec) (diana_put nod (third (third as)) 'sm_body))) (cond (others (diana_put others (first (third as)) 'ct_spec))) (cond ((and others (diana_get others 'sm_body) (not (stub_p (diana_get others 'sm_body))))) (others (cond ((eq (diana_nodetype_get (third (third as))) 'dn_instantiation) (let ((instantiation (instantiated_spec (third (third as))))) (cond (instantiation (diana_put others (diana_get instantiation 'ct_spec) 'ct_spec) (diana_put others (diana_get instantiation 'sm_body) 'sm_body))))) (t (diana_put others (first (third as)) 'ct_spec) (diana_put others (third (third as)) 'sm_body))) ; (break installed-body-and-spec) )))) nod) as_header nil as_subprogram_def (or (third (third as)) (sc_diana dn_void))); procedure defn. ) symb_procedure (pr_and (lambda(as) (ct_push nil *returntypestack*) (let* ((stub (ada_declared (first as) nil '(procedure generic_unit) t)) (this (add_name (first as) ; name (cond ((generic_defo_p stub) 'generic_unit); class (t 'procedure)) (sc_diana dn_proc_id lx_symrep (first as) sm_spec nil sm_body nil sm_location nil sm_stub nil sm_first nil) nil))) ; (break look-at=stub) (diana_put this (pushproccontext) 'ct_named_context) (cond ((generic_defo_p stub) (diana_put **current_block** (list (diana_get (car stub) 'ct_named_context)) 'ct_mixin_s))) (ct_push this *identstack*);communicate with others. (ct_push *current_generic_nestitude* *generic_nestitude_stack*) (diana_put this stub 'sm_first) this)) ;we always return the current one! lex_ident) (pr_and (lambda (as) (list (first as);formal_part (first (second as));symb_is (cond ((null (second as)) (popcontext) (ct_push nil *identstack*) (sc_diana dn_stub)) (t (second (second as))))));body (pr_and (lambda(as) (diana_put (first *identstack*) (first as) 'sm_spec) (first as)) (pr_or nil proc_formal_part nil)) (pr_or nil (pr_and nil (pr_and (lambda(as) (let* ((this (first *identstack*)) (stub (with_same_type_profile this (diana_get this 'sm_first)))) (cond (stub ;;if any of these have matching specs and come ;;from either here of the corresponding package ;;declaration, we have the def_occurence. (let* ((defo (mapcan #'(lambda(fun) (cond ((eq (diana_nodetype_get (diana_get fun 'sm_body)) 'dn_stub) (list fun)) (t nil))) stub)) (defo (find_defo defo))) (cond (defo (diana_put **current_block** (list (diana_get defo 'ct_named_context)) 'ct_mixin_s) (setq *current_generic_nestitude* (diana_get defo 'ct_generic_membership)) (change_generic_membership (diana_get this 'sm_spec) *current_generic_nestitude*))) (diana_put this defo 'sm_first))) (t (diana_put this nil 'sm_first))))) symb_is) (pr_or nil (pr_and (lambda(as) (ct_push nil *identstack*) (popcontext) ;leave proc context before decl. (sc_diana dn_stub)) symb_separate) (pr_and (lambda(as) (ct_push nil *identstack*) (popcontext) (first as)) generic_instantiation) (pr_and (lambda(as) (ct_push (second as) *identstack*) (first as)) (pr_and (lambda(as) (popcontext) ;;leave procedure context before decl. (first as)) body_part) (pr_or nil lex_ident nil)))) (pr_and (lambda(as) (let* ((this (first *identstack*)) (that (sc_diana dn_rename as_name nil)) (stub (with_same_type_profile this (second as)))) (ct_push nil *identstack*) (popcontext) (cond (stub ;;if any of these have matching specs and come ;;from either here of the corresponding package ;;declaration, we have the def_occurence. (let ((defo (find_defo stub))) (cond (defo (diana_put that defo 'as_name) (diana_put **current_block** (list (diana_get defo 'ct_named_context)) 'ct_mixin_s) (setq *current_generic_nestitude* (diana_get defo 'ct_generic_membership)) (change_generic_membership (diana_get this 'sm_spec) *current_generic_nestitude*)) (t (semgripe 'not_the_same_profile_in_rename (implode (uplowlist (cadr (diana_get this 'lx_symrep))))))) (diana_put this that 'sm_body))) (t (semgripe 'not_the_same_profile_in_rename (implode (uplowlist (cadr (diana_get this 'lx_symrep))))))) (list that)) ) symb_renames (pr_restrict proc_or_entry name) (pr_or nil (pr_and nil oper_lparen expression oper_rparen) nil)) nil))) (pr_and (lambda(as) (ct_pop *returntypestack*) ;(ct_pop *returntypestack*)??? (cond ((null (ct_pop *return_stmt_stack*)) (semgripe 'no_return_statement_in_function (implode (lowuplist (cadr (diana_get (second as) 'lx_symrep))))))) (setq *current_generic_nestitude* (ct_pop *generic_nestitude_stack*)) (matching_ident (diana_get (second as) 'lx_symrep) (ct_pop *identstack*)) (ct_pop *identstack*) ;pop off the id node. (sc_diana dn_subprogram_decl as_designator (let ((nod (second as)) (others (diana_get (second as) 'sm_first))) (cond ((fifth (third as)) (cond ((eq (diana_nodetype_get (fifth (third as))) 'dn_instantiation) ; (break about-to-instantiate) (let ((instantiation (instantiated_spec (fifth (third as))))) (cond (instantiation (diana_put nod (diana_get instantiation 'sm_spec) 'sm_spec) (diana_put nod (diana_get instantiation 'ct_spec) 'ct_spec) (diana_put nod (diana_get instantiation 'sm_body) 'sm_body))))) (t (diana_put nod (first (third as)) 'sm_spec) (diana_put (first (third as)) ;a dn_function (third (third as)) ;a subtypeind 'as_name_void) (diana_put nod (fifth (third as)) 'sm_body) )) (cond ((and others (diana_get others 'sm_body) (not (stub_p (diana_get others 'sm_body)))) (cond ((fifth (third as)) ;body suplied? #| (semgripe 'body_already_spec (implode (uplowlist (cadr (diana_get nod 'lx_symrep)))) )|#))) (others (cond ((eq (diana_nodetype_get (fifth (third as))) 'dn_instantiation) (let ((instantiation (instantiated_spec (fifth (third as))))) (cond (instantiation (diana_put others (diana_get instantiation 'ct_spec) 'ct_spec) (diana_put others (diana_get instantiation 'sm_body) 'sm_body))))) (t (diana_put others (first (third as)) 'ct_spec) (diana_put others (fifth (third as)) 'sm_body))))))) nod) as_header nil as_subprogram_def (or (fifth (third as)) (sc_diana dn_stub))) ) symb_function (pr_and (lambda(as) (ct_push nil *returntypestack*) (ct_push nil *return_stmt_stack*) (rplacd (first as) (list (uplowlist (cadr (first as))))) (let* ((stub (ada_declared `(lex_ident ,(cadr (first as))) nil '(function generic_unit) t)) (this (add_name `(lex_ident ,(cadr (first as))) ; name (cond ((generic_defo_p stub) 'generic_unit); class (t 'function)) (sc_diana dn_function_id lx_symrep (first as) sm_spec nil sm_body nil sm_location nil sm_stub nil sm_first nil) nil))) (ct_push *current_generic_nestitude* *generic_nestitude_stack*) (diana_put this stub 'sm_first) (diana_put this (pushproccontext) 'ct_named_context) (cond ((generic_defo_p stub) (diana_put **current_block** (list (diana_get (car stub) 'ct_named_context)) 'ct_mixin_s))) (ct_push this *identstack*);communicate with others. this) ;we always return the current one! ) (pr_or nil (pr_and (lambda(as) (cond ((not (user_definable_function_p as)) (semgripe 'not_user_definable_operator (implode (cadr (first as)))))) (first as)) lex_string) lex_ident)) (pr_and (lambda(as) (list (first as);formal-part (second as);symb_return (third as);return type (first (fourth as));symb is (cond ((null (fourth as)) (ct_push nil *identstack*) (rplaca *return_stmt_stack* t) (popcontext) (sc_diana dn_stub)) (t (second (fourth as))))));body (pr_and (lambda(as) (let ((spc (cond ((first as)(first as)) (t (sc_diana dn_function))))) (diana_put (first *identstack*) spc 'sm_spec) spc)) (pr_or nil funct_formal_part nil)) (pr_or nil symb_return nil) (pr_and (lambda(as) (diana_put (diana_get (first *identstack*) 'sm_spec) (cond ((first as)(first as)) (t (sc_diana dn_void))) 'as_name_void) (first as)) (pr_or nil (pr_and (lambda (as) (rplaca *returntypestack* (first as)) (first as)) subtype_indication) nil)) (pr_or nil (pr_and nil (pr_and (lambda(as) (let* ((this (first *identstack*)) (stub (with_same_type_profile this (diana_get this 'sm_first)))) (cond (stub ;;if any of these have matching specs and come ;;from either here of the corresponding package ;;declaration, we have the def_occurence. (let* ((defo (mapcan #'(lambda(fun) (cond ((eq (diana_nodetype_get (diana_get fun 'sm_body)) 'dn_stub) (list fun)) (t nil))) stub)) (defo (find_defo defo))) (cond (defo (diana_put **current_block** (list (diana_get defo 'ct_named_context)) 'ct_mixin_s) (setq *current_generic_nestitude* (diana_get defo 'ct_generic_membership)) (change_generic_membership (diana_get this 'sm_spec) *current_generic_nestitude*))) (diana_put this defo 'sm_first))) (t (diana_put this nil 'sm_first))))) symb_is) (pr_or nil (pr_and (lambda(as) (rplaca *return_stmt_stack* t) (ct_push nil *identstack*) (popcontext) (sc_diana dn_stub)) symb_separate) (pr_and (lambda(as) (rplaca *return_stmt_stack* t) (ct_push nil *identstack*) (popcontext) (first as)) generic_instantiation) (pr_and (lambda(as) (ct_push (second as) *identstack*) (first as)) (pr_and (lambda(as) (popcontext) (first as)) body_part) (pr_or nil lex_ident operator_symbol nil)))) (pr_and (lambda (as) (setq *function_name_only* nil) (let* ((this (first *identstack*)) (that (sc_diana dn_rename as_name nil)) (stub (with_same_type_profile this (second as)))) (ct_push nil *identstack*) (popcontext) (cond (stub ;;if any of these have matching specs and come ;;from either here of the corresponding package ;;declaration, we have the def_occurence. (let ((defo (find_defo stub))) (cond (defo (diana_put that defo 'as_name) (diana_put **current_block** (list (diana_get defo 'ct_named_context)) 'ct_mixin_s) (setq *current_generic_nestitude* (diana_get defo 'ct_generic_membership)) (change_generic_membership (diana_get this 'sm_spec) *current_generic_nestitude*)) (t (semgripe 'not_the_same_profile_in_rename (implode (uplowlist (cadr (diana_get this 'lx_symrep))))))) (diana_put this that 'sm_body))) (t (semgripe 'not_the_same_profile_in_rename (implode (uplowlist (cadr (diana_get this 'lx_symrep))))))) (list that))) (pr_and (lambda (as) (rplaca *return_stmt_stack* t) (setq *function_name_only* t) (car as)) symb_renames) (pr_restrict function name)) nil))) (pr_and (lambda(as) (ct_pop *returntypestack*) (second as)) (pr_and (lambda (as) (ct_push 'package *returntypestack*) (first as)) symb_package) (pr_or nil (pr_and (lambda(as) (let ((pkg_id (first as))) (cond ((eq (diana_nodetype_get (second as)) 'dn_rename) (diana_put pkg_id (let* ((smdef (diana_get (diana_get (second as) 'as_name) 'sm_defn)) (ctn1 (and smdef (diana_get smdef 'ct_named_context)))) ctn1) 'ct_named_context))) (cond ((eq (diana_nodetype_get (second as)) 'dn_instantiation) (let ((instantiation (instantiated_spec (second as)))) (cond (instantiation (diana_put pkg_id (diana_get instantiation 'sm_spec) 'sm_spec) (diana_put pkg_id (diana_get instantiation 'sm_body) 'sm_body) (let ((**current_block** (diana_get pkg_id 'ct_named_context))) (redeclare_package_declarations (diana_get instantiation 'sm_spec))))) ; (break redeclare-instantiated-declarations) )) (t (diana_put pkg_id (second as) 'sm_spec) (diana_put pkg_id (sc_diana dn_void) 'sm_body))) (popcontext) (sc_diana dn_package_decl as_id pkg_id as_package_def (second as)))) (pr_and (lambda(as) (let ((this_pkg (sc_diana dn_package_id lx_symrep (first as)))) (add_name (first as) 'package this_pkg nil) (pushcontext) (diana_put this_pkg **current_block** 'ct_named_context) this_pkg)) lex_ident) (pr_or nil (pr_and cadr symb_is (pr_or nil (pr_and car package_spec_part (pr_or nil lex_ident nil)) generic_instantiation)) (pr_and (lambda(as) ;(break look-at-secondas) (sc_diana dn_rename as_name (second as))) symb_renames (pr_restrict package name) ))) (pr_and (lambda(as) (popcontext) (setq *current_generic_nestitude* (ct_pop *generic_nestitude_stack*)) (matching_ident (ct_pop *identstack*) (diana_get (ct_pop *identstack*) 'lx_symrep)) (let ((pkg_id (second as))) (diana_put pkg_id (fourth as) 'sm_body) (let ((nu_pkg (sc_diana dn_package_id sm_spec (diana_get pkg_id 'sm_spec) sm_body (fourth as)))) (sc_diana dn_package_body as_id nu_pkg as_block_stub (fourth as))))) symb_body (pr_and (lambda(as) (let* ((pkg_id (let ((pid (ada_declared (first as) nil '(package generic_unit)))) (cond ((eq (diana_nodetype_get pid) 'dn_used_name_id) (semgripe 'cant_find_matching_spec_for_package_body) (sc_diana dn_package_id lx_symrep (first as))) (t pid)))) (spec_context (diana_get pkg_id 'ct_named_context)) (spec_mixins (and spec_context (diana_get (diana_get spec_context 'ct_is_enclosed_by) 'ct_mixin_s))) (mycontext (diana_get **current_block** 'ct_mixin_s)) (hidden_context (and spec_context (diana_get spec_context 'ct_hidden_context)))) (savecontext) ;(break look-at-hid-con) (setq **current_block** (or hidden_context spec_context)) (setq **current_block** (new_block)) (ct_push *current_generic_nestitude* *generic_nestitude_stack*) (setq *current_generic_nestitude* (diana_get pkg_id 'ct_generic_membership)) (diana_put **current_block** (cons hidden_context (append spec_mixins mycontext)) 'ct_mixin_s) (diana_put **current_block** hidden_context 'ct_hidden_context) (diana_put pkg_id **current_block** 'ct_package_inner_environment) (ct_push pkg_id *identstack*) pkg_id)) lex_ident) symb_is (pr_or nil (pr_and (lambda(as) (ct_push nil *identstack*) (sc_diana dn_stub)) symb_separate) (pr_and (lambda(as) (ct_push (second as) *identstack*) (first as)) body_part (pr_or nil lex_ident nil))))) ) ;oper_semicolon) (pr_and nil symb_body lex_ident symb_is (pr_or nil (pr_and (lambda(as) (sc_diana dn_stub)) symb_separate) (pr_and car body_part (pr_or nil lex_ident nil)))) (pr_and (lambda (as) (ct_pop *returntypestack*) (second as)) ;task++ (pr_and (lambda (as) (ct_push 'task *returntypestack*) (first as)) symb_task) (pr_or nil (pr_and (lambda(as) (matching_ident (first as)(fourth as)) (popcontext) ;;first fill in the body field of the sm_obj_spec ;;field of the var_id, to point to the spec. (diana_put (first as) (cond ((second as) (second as)) (t (sc_diana dn_task_spec))) 'sm_obj_type) (sc_diana dn_task_decl as_id (first as) as_task_def (diana_get (first as) 'sm_obj_type))) (pr_and (lambda(as) (let ((vid (add_name (first as) 'task (sc_diana dn_var_id lx_symrep (first as)) nil))) (diana_put vid (pushcontext) 'ct_named_context) vid)) lex_ident) (pr_or nil (pr_and cadr symb_is task_spec_part (pr_or nil lex_ident nil)) (pr_and cadr symb_renames (pr_restrict task name)) nil)) (pr_and (lambda (as) (let* ((ttd (sc_diana dn_type_id lx_symrep (second as) sm_type_spec (third as))) (td (sc_diana dn_type as_id ttd as_type_spec (third as)))) (add_name (second as) 'type ttd nil) td)) symb_type lex_ident symb_is task_spec_part (pr_or nil lex_ident nil)) (pr_and (lambda(as) ;;put the body into the task_body_id (diana_put (second as) (fourth as) 'sm_body) ;;and into the spec's body. (let ((sts (diana_get (second as) 'sm_type_spec))) (and sts (diana_put sts (fourth as) 'sm_body))) (sc_diana dn_task_body as_id (second as) as_block_stub (fourth as))) symb_body (pr_and (lambda(as) (pushproccontext) (let ((ts (ada_declared (first as) nil '(task type)))) (install_mixins (list (diana_get ts 'ct_named_context))) (add_name (first as) 'task (sc_diana dn_task_body_id lx_symrep (first as) sm_type_spec (cond ((eq (diana_nodetype_get ts) 'dn_var_id) (diana_get ts 'sm_obj_type)) (t (diana_get ts 'sm_type_spec))) sm_body nil ;later! sm_first ts) nil))) lex_ident) symb_is (pr_and (lambda(as) (popcontext) (first as)) (pr_or nil (pr_and (lambda(as) (sc_diana dn_stub)) symb_separate) (pr_and car body_part (pr_or nil lex_ident nil))))) #| (pr_and (lambda(as) (popcontext) (break pc_task-body) (sc_diana dn_task_body as_id (second as) as_block_stub (fourth as))) symb_body (pr_and (lambda(as) (let ((ts (ada_declared (first as) nil 'task))) (pushproccontext) (install_mixins (list (diana_get ts 'ct_named_context))) ts)) lex_ident) symb_is (pr_or nil (pr_and (lambda(as) (sc_diana dn_stub)) symb_separate) (pr_and (lambda(as) (first as)) body_part (pr_or nil lex_ident nil)))) |# )) (pr_and (lambda(as) (matching_ident (fourth as)(seventh as)) (prog1 (sc_diana dn_generic as_id (add_name (fourth as) 'generic (sc_diana dn_generic_id lx_symrep (fourth as) sm_generic_param_s (second as) sm_body (sc_diana dn_void) ) nil) as_generic_param_s (second as) as_generic_header (sixth as)) (ct_pop *current_generic_nestitude*))) (pr_and (lambda(as) (ct_push (gensym) *current_generic_nestitude*) (first as)) symb_generic) generic_formal_parameter symb_package lex_ident symb_is package_spec_part (pr_or nil lex_ident nil)) (pr_and (lambda(as) ; build up into a list. (putback_symbol 'oper_semicolon) ;what a crock! (first as)) use_clause)) oper_semicolon)))