;;; -*- mode:lisp;package:user;base:10.;fonts:(cptfontb) -*- ;;; $Header: /ct/interp/incd.l,v 1.68 84/12/04 18:54:13 penny Exp $ ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; incd ;;; ;;; Paul Robertson May-31-83 ;;; ;;; ;;; ;;; ;;; ;;; 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: ;;; ;;; Foderaro and Sklower, The FRANZ LISP Manual, September 1981. ;;; ;;; Weinreb and Moon, LISP MACHINE MANUAL, Symbolics, July 1981. ;;; ;;; Charniak et al., 1980. Artificial Intelligence Programming. ;;; ;;; Miller, 1982. The C*T Ada Tutor: Guide to the Implementation. ;;; ;;; The following code assumes familiarity with these materials. ;;; ;;; ;;; ;;; ASSUMES CT_LOAD AND SUITABLE FILEMAP ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Ensure presence of needed files. (eval-when (compile load eval) (ct_load 'charmac)) ;CT char set extensions. (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 'pser)) ;The Parser Driver (eval-when (compile load eval) (ct_load 'lana)) ;The lexical Anal. (eval-when (compile load eval) (ct_load 'sema)) ;The semantic support (eval-when (compile load eval) (ct_load 'eror)) ;The error handlers (eval-when (compile load eval) (ct_load 'adas)) ;The Ada Network ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Compiler Declarations and Global Variables -- #+franz (declare (macros t)) (declare (special *incremental_diana* *fe_timing*)) (declare (ct_includef 'intrpdcl)) (eval-when (compile load eval) (ct_load 'ferec)) ; get the macros etc. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Externally Call-able Functions/Macros -- ;;; copied from fe_infc ;;; This will perform the initialization of the ;;; interpreter environment, This should only be ;;; invoked once if separate compilation is taking ;;; place ;;;;;;;;;;;;;;;;; (defun create_time_stamp () ;;;;;;;;;;;;;;;;; (multiple-value-bind (a b c d e f g) (time:get-time) (plus (times a (fix 1e2)) (times b (fix 1e4)) (times c (fix 1e6)) (times d (fix 1e8)) (times e (fix 1e10)) (times f (fix 1e12))))) ;;;;;;;;;;;;;;;;;;;;;;;; (defun diana_node_integer_array() ;;;;;;;;;;;;;;;;;;;;;;;; (do ((i *diana_nodetypes* (cdr i)) (n 0 (1+ n)) (r (make-array (length *diana_nodetypes*)))) ((null i) (setq *index_diana_nodes* r)) (putprop (car i) n 'index_node) (aset (car i) r n)) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun incremental_build_diana_init() ;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq ; initialize all the specials!! *time_stamp* (create_time_stamp) *disc_not_allowed* nil *disc_list* nil *disc_used* nil *in_record* nil *function_name_only* nil *infrontend* t *debugdriver* nil *debugscheduler* nil *debugparser* nil *not_inside_debug_ta* t *range_checking* t *incremental_diana* nil *current_generic_nestitude* nil *generic_nestitude_stack* nil *return_stmt_stack* nil *in_attribute_value* nil *exception_handler_stack* nil *named_stm_stack* nil *exception_name* nil *exception_reason* nil *current_non_terminal* nil *symbolstack* nil *original_context* nil *name_communication* nil *seen_assistance_1* nil *seen_assistance_2* nil *seen_assistance_3* nil *pnl* 0 ; The procedure nesting level. *bnl* 0 ; The Block nesting level. *path* "wazzoo" ; sets the path for the wazzoo la_comments nil *charcount* 0 *pcharcount* 0 *ppcharcount* 0 la_plinpos 0 la_psrcpos 0 la_pplinpos 0 la_ppsrcpos 0 la_srcpos 0 la_linpos 0 *srcposbeg* 0 *linposbeg* 0 *preparsecc* 0 *postparsecc* 0 res nil la_this_symbols_pos 0 *identstack* nil ; the stack used for comparing tags. *returntypestack* nil ; stack of func return types *goto_count* 0 *awaiting_parameter_normalization* nil *awaiting_aggregate_normalization* nil *awaiting_aggregate_disambiguation* nil *awaiting_deferred_value* nil *awaiting_disambiguation* nil *awaiting_incomplete_type* nil *awaiting_label_fixup* nil *produce_listing* t *tracedfunctions* nil ; a list of functions being traced. *class_restriction* nil *no_function* nil ; if t, don't allow a function call. *eof_count* 0 ; How many times has the end of file been ; read? *parse_errors* 0 ; how many syntax errors were there? *semantic_errors* 0 ; how many semantic errors were there? *error_status* 0 ; how many semantic errors were there? **text_file_list** (list nil nil) ;; list of the text opened by user **text_file_num** 3 ; next file descriptor ; the first position will be reserved for ; the default standard input and output **standard_input** 1 **default_input** 1 **standard_output** 2 **default_output** 2 **sequen_file_list** nil ; list of the sequen files opened ; by user **sequen_file_num** 1 ; next file descriptor **direct_file_list** nil ; list of the direct files opened ; by user **direct_file_num** 1 ; next file descriptor *textio_temp_file_list* nil *seqio_temp_file_list* nil *dirio_temp_file_list* nil *io_get_integer* nil *io_get_float* nil *io_get_fixed* nil *io_get_enum* nil ) (cond ((status feature fe_initialized) (setq *diana_internp* nil)) ; initialization already done! ;turn off intern gensym (t ; Initialize the code (sstatus feature fe_initialized) (setq *diana_internp* t) ; turn on intern gensym (la_init) ; initialize the lexical analyser. (diana_node_integer_array) (initialize_nonterminals) (init_syntax) ; initialise the syntax network. (init_ssemantics))) ; initialize the error handlers. (setq **current_block** **standard_env**) (setq **current_block** (new_block)));new block which inherits the standard env. ;;; This builds the diana tree, does not use initialization ;;;;;;;;;;;;; (defun different_pnl(label goto) ;;;;;;;;;;;;; (cond ((equal (diana_get label 'ct_pnl) (diana_get goto 'ct_pnl)) t) (t nil))) ;;;;;;;;;;;;;;;;;;;;;;; (defun incremental_build_diana (*srcin* *listout* *errin* *errout* *userin* *userout*) ;;;;;;;;;;;;;;;;;;;;;;; (la_startup) ; Do the work. (let ((*diana_tree* (*catch nil (parserd 'compilation)))) ; (freshline *listout*) ; (print_gripes) ;;now check that all the labels are fixed up. (mapc #'(lambda(fix) (let* ((**current_block** (gotorec%context fix)) (label (ada_declared (gotorec%labelname fix) nil 'label t))) ;(break what-have-I-got) (cond ((null label) (semgripe 'missing_label_for_goto (implode (cadr (gotorec%labelname fix))) (diana_get (gotorec%gotonode fix) 'lx_srcpos))) ((> (length label) 1) (semgripe 'ambiguous_label_for_goto (implode (cadr (gotorec%labelname fix))) (diana_get (gotorec%gotonode fix) 'lx_srcpos))) #| ((not (strictly_enclosing (first label)(gotorec%gotonode fix))) (semgripe 'structure_entering_goto (implode (cadr (gotorec%labelname fix))) (diana_get (gotorec%gotonode fix) 'lx_srcpos)))|# ;;jumps out of procs and accepts not allowed ((not (different_pnl (first label)(gotorec%gotonode fix))) (semgripe 'goto_inside_a_program_unit (implode (cadr (gotorec%labelname fix))) (diana_get (gotorec%gotonode fix) 'lx_srcpos))) (t (diana_put (gotorec%gotonode fix) (sc_diana dn_used_name_id sm_defn (first label) lx_symrep (gotorec%labelname fix)) 'sm_name)))));ct_change was as_name *awaiting_label_fixup*) (setq *awaiting_label_fixup* nil) (la_finale) (cond ((eq *diana_tree* 'cant_continue) (generic_gripe '("~%Your program's analysis has been terminated.~%~ The interpreter is unable to continue its analysis."))) ((eq *diana_tree* 'too_many_errors) (generic_gripe '("~%Your program's analysis has been terminated.~%~ Too many errors have occurred for the analysis to continue.")) nil) ((eq *diana_tree* 'lex_eof) (generic_gripe '("Unexpected end of file encountered")) nil) ((and (not (diana_nodep *diana_tree*)) *diana_tree*) (generic_gripe '("The interpreter is unable to begin executing your program.~%~ A complete representation of your program could not be constructed."))) (t (cond (*incremental_diana* ;;merge compilation units to make a single tree. (%= *incremental_diana* (merge_diana_trees *_* *diana_tree*))) (t (%= *incremental_diana* *diana_tree*))) *incremental_diana*)))) ;;; This is not used at this time. ;;;;;;;;; (defun adafe_int (srcin listout errin errout userin userout) ;;;;;;;;; (let ((*diana_tree* (incremental_build_diana ;Do the REAL work. srcin listout ; source => listing errin errout ; errors and correction userin userout))) ; standard interaction (cond ((greaterp *parse_errors* 0) ;Cleanup after FE. (greaterp *semantic_errors* 0) (skipline listout))) (fe_result (and *diana_tree* ;Run-p Flag. (lessp *parse_errors* 1.) (lessp *semantic_errors* 1.)) *parse_errors* *semantic_errors* *diana_tree*))) ;;;S-IF-PLURAL: Returns "s" if N is zero or > 1. Useful for messages ;;;involving numbers of items. (defun s-if-plural (n) (if (or (zerop n) (> n 1)) "s" "")) ;;; This is used instead of ada_int, since it contains two extra ;;; lines of code (setq *incremental_diana* nil) on errors ;;;;;;;;;;; (defun ada_int_inc (srcin listout errin errout userin userout) ;;;;;;;;;;; " The C*T Ada Interpreter Top Level. " ;(time_line listout) (ada_version_msg listout) (*catch 'lossage (let* ((base 10.) (ibase 10.) (*nopoint t) (*lossage* t) (t1 #+lispm (multiple-value-bind (a b c d e f g)(time:get-time) (list a b c d e f g)) #+franz (status localtime)) ;;Start FE timing. (*function_name_only* nil) (*in_record* nil) (*disc_not_allowed* nil) (*disc_list* nil) (*disc_used* nil) (*produce_listing* t) (*generic_nestitude_stack* nil) (*exception_handler_stack* nil) (*named_stm_stack* nil) (*return_stmt_stack* nil) (*current_generic_nestitude* nil) (*parse_errors* 0) (*semantic_errors* 0) (*error_statustmp* 0) (*eof_count* 0) (fe_res (adafe_int srcin listout ;;Run the Front End. errin errout userin userout)) (t2 #+lispm (multiple-value-bind (a b c d e f g)(time:get-time) (list a b c d e f g)) #+franz (status localtime)) ;;Stop FE timing. (runflg (fe_result%runflg fe_res)) ;;Extract FE results. (synerrs (fe_result%synerrs fe_res)) (semerrs (fe_result%semerrs fe_res)) (diana (fe_result%diana fe_res)) (fe_timing (elapsed_time t2 t1)) (be_result nil) (*infrontend* nil)) (setq be_result diana) (freshline listout) (cond ((or runflg (> synerrs 0) (> semerrs 0)) (ct_format listout "A total of ~a syntax error~a and ~a static semantic error~a were detected.~%" synerrs (s-if-plural synerrs) semerrs (s-if-plural semerrs)) (cond ((and (status feature debugging) (> *goto_count* 0)) (ct_format listout "Warning: Your program uses ~A 'goto' ~A~%" *goto_count* (cond ((= *goto_count* 1) "statement.") (t "statements."))) (ct_format listout "Warning: 'goto' is an obsolete statement. Use structured constructs if possible.~%"))))) (setq *fe_timing* fe_timing) (cond ((status feature qawimps) (print_elapsed listout "Elapsed time = " fe_timing))) (cond (runflg) ((greaterp synerrs 0) (skipline listout) (setq *incremental_diana* nil) (ct_format userout "Your program's execution has been cancelled due to syntax errors. ~%") (%= *error_statustmp* 2) #+franz (%= *error_status* (boole 7 *error_statustmp* *error_status*))) ((greaterp semerrs 0) (setq *incremental_diana* nil) (skipline listout) (ct_format userout "Your program's execution has been cancelled due to static semantic errors. ~%") (%= *error_statustmp* 4) #+franz (%= *error_status* (boole 7 *error_statustmp* *error_status*))) (t (ct_format listout "~%Your input was probably not an Ada program.~%") (ct_format listout "Program execution has ended.~%") (%= *error_statustmp* 8) #+franz (%= *error_status* (boole 7 *error_statustmp* *error_status*)))) (cond (runflg (time_line listout) be_result) ;;; if the runflg is false then the compilation ;;; will not be run, however wish to continue compiling ;;; any other segments. If the diana-tree is in a bad ;;; state then the compilation must be abandon. (t (ct_format listout "~%Code will not be generated for ~S.~%" *path*) (cond ((not (diana_nodep be_result)) (setq *not_wffp_diana* nil) (%= *error_statustmp* 16) #+franz (%= *error_status* (boole 7 *error_statustmp* *error_status*)) (*throw '*not_wffp_diana* *not_wffp_diana*)) (t (%= *error_statustmp* 32) #+franz (%= *error_status* (boole 7 *error_statustmp* *error_status*)) (setq *continue_inc_diana* nil)))))) )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Internal Use Only Functions/Macros -- ;;; This is used to merge two diana trees ;;;;;;;;;;;;;;;;; (defun merge_diana_trees(previous_tree latest_tree) ;;;;;;;;;;;;;;;;; (cond ((null previous_tree) latest_tree) ((null latest_tree) previous_tree) (t (diana_put previous_tree (append (diana_get previous_tree 'as_list) (diana_get latest_tree 'as_list)) 'as_list) previous_tree))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Edit History: ;;; ;;; o 17-May-83, MLM: Add edit history page to templates. ;;; ;;; eof ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;