;;; -*- mode:lisp;package:user;base:10.;fonts:(cptfontb) -*- 
;;;  $Header: /ct/interp/adas42.l,v 1.72 84/12/04 18:48:32 penny Exp $
;;;
;;;  

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;                            adas42.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.


;;;-- 4.  Names and Expressions
;;;-- =========================
;;;-- 4.1  Names
;;;
;;;-- Syntax 4.1
;;;--  name ::= identifier
;;;--   | indexed_component  | slice
;;;--   | selected_component | attribute
;;;--   | function_call      | operator_symbol
;;;--
;;;
;;;
;;;    NAME ::=             DESIGNATOR;
;;;    -- see 2.3, 4.1.1, 4.1.2, 4.1.3, 4.1.4,
;;;
;;;    USED_ID ::=          used_object_id | used_name_id | used_bltn_id;
;;;
;;;    used_object_id =>    lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    used_object_id =>    sm_exp_type      : TYPE_SPEC,
;;;                         sm_defn          : DEF_OCCURRENCE,
;;;                         sm_value         : value;
;;;
;;;    used_name_id =>      lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    used_name_id =>      sm_defn          : DEF_OCCURRENCE;
;;;
;;;    used_bltn_id =>      lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    used_bltn_id =>      sm_operator      : operator;
;;;    -- see the rationale for a discussion of built-in subprograms
;;;
;;;    USED_OP ::=          used_op | used_bltn_op;
;;;
;;;    used_op =>           lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    used_op =>           sm_defn          : DEF_OCCURRENCE;
;;;
;;;    used_bltn_op =>      lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    used_bltn_op =>      sm_operator      : operator;
;;;
;;; Name is a bit hairy.
;;; A function eats its parameters.
;;; Variuos named objects  may have parameter sequences for array indexing
;;; etc. Procedures DO NOT eat their parameters, they are eaten by 
;;; procedure_or_entry_call. Same for entry calls.

(def_ada_syntax name
		(pr_and
		  (lambda (as)
		    (setq *original_context* nil)
		    (first as))
		  name_aux))

		;;;;;;;;
(def_ada_syntax name_aux
		;;;;;;;;

	(pr_and
	  (lambda (as)
	    (ct_pop *name_communication*)
	    (first as))
	  (pr_or nil 
	       (pr_and
		 (lambda(as)
		   (let ((nam
			   (ada_declared (first as) nil 'function t)))
		     (cond
		       ((and *function_name_only* (null (second as)))
			nam)
		       ((null (second as))
			(let ((func   (sc_diana dn_function_call lx_prefix t)))
			  (diana_put func nam 'tp_vfuns)
			  (normalize_params   ;in case of defaults.
			    (dissambiguate_function_reference func))))
		       ((eq (diana_nodetype_get
				   (name_cdr_bits%thisname (second as)))
				 'dn_selected)
			(diana_put (name_cdr_bits%thisname (second as))
				   (car nam)
				   'as_name)
			(name_cdr_bits%destname (second as)))
		       (t (diana_put
			    (name_cdr_bits%thisname (second as))
			    nam
			    'tp_vfuns)
			  ;;now, if its a function call, we have to
			  ;;normalize the parameters.
			  (cond
			    ((eq (diana_nodetype_get
				   (name_cdr_bits%thisname (second as)))
				 'dn_function_call)
			     (normalize_params
			       (dissambiguate_function_reference 
			       (name_cdr_bits%thisname (second as))))))
			  (name_cdr_bits%destname (second as))))))
		 (pr_and
		   (lambda(as);(break found-function)
		     (ct_push  (first as) *name_communication*)
		     (first as))
		   (pr_or nil 
			  (pr_and
			    (lambda(as)
			      ;;if its a string, check that its not an
			      ;;enumeration literal.
			      ;;need to beware of strings that are operators
			      ;;and do the right thing
			      (let ((deff
				      (ada_declared (first as) nil 'function t)))
				(setq deff
				      (mapcan
					#'(lambda(id)
					    (cond ((eq (diana_nodetype_get id)
						       'dn_enum_id)
						   nil)
						  (t (list id))))
					deff))
				(cond (deff (first as))
				      (t (putback_symbol (first as)) ;undo parse.
					 (rplaca (first as) 'lex_string)
					 'fail))))
			    (pr_or
			      nil			      
			      (pr_and2c
				(lambda(as)
				  (first as))
				lex_string
				oper_lparen
				(pr_restrict function lex_string))
			      (pr_and
				(lambda(as)
				  (cond (*function_name_only*
					 (first as))
					(t (putback_symbol (first as))
					   (rplaca (first as) 'lex_string)
					   'fail)))
				(pr_restrict function lex_string))))
			  (pr_restrict function lex_ident)
			  ))
		 (pr_or nil 
			(pr_and
			  (lambda(as)
			    (popcontext)
			    (let* ((selid (filter_non_visible_selected
					    (second as)
					       (ada_declared
						(strip_index *name_communication*) 
						nil
						'(package function named
							  constant
							  record task
							  formal_parameter
							  procedure entry object))
					      ))
				   (nam
;				     (break above-the-dudelle)
				    (sc_diana dn_selected
					      as_name nil ; maybe later..
					      as_designator_char selid)))
;			      (break look-at-nam)
			      (ct_push nil *name_communication*) 
			      (name_cdr_bits nam nam)))
			  (pr_and
			    (lambda(as)
			      (cond ((null *original_context*)
				     (setq *original_context* **current_block**)))
			      (savecontext)	  ;remember the current context.
			      (setq **current_block**
				    (diana_get
				      (ada_declared
					(strip_index *name_communication*) 
				 	nil
					'(package function named constant
						  record task
						  formal_parameter
						  procedure entry object))
				      'ct_named_context))
;			      (break look-at-context)
			      )
			    oper_period )
			  name_aux)
			(pr_and 
			  (lambda(as)
			    (let ((nam
				    (sc_diana dn_attribute_call
					      as_name nil ;see below
					      )))
			      (diana_put
				nam
				(sc_diana
				  dn_attribute
				  as_name nil	  ; gets put in later.
				  as_id 
				  (sc_diana dn_used_name_id
					    lx_symrep (second as)
					    sm_defn
					    (ada_declared 
					      (second as)
					      nil
					      '(not_indexable_attribute
						 indexable_attribute))))
				'as_name)
			      (cond
				((null (third as))
				 (name_cdr_bits (diana_get nam 'as_name)
						nam))
				(t  
				    (diana_put
				      (name_cdr_bits%thisname 
					(third as))
				      nam
				      'as_name)
				    (name_cdr_bits 
				      nam
				      (name_cdr_bits%destname (third as)))))))
			  oper_quote
			  (pr_or nil
			    (pr_restrict indexable_attribute lex_ident)
			    (pr_restrict not_indexable_attribute lex_ident))
			  (pr_or nil
				 (pr_and
				   (lambda (as)
				     (ct_push nil  *name_communication*)
				     (first as))
				   name_cdr)
				 nil))
			(pr_and 
			  (lambda(as)
			    (let ((nam 
				    (sc_diana dn_function_call
					      as_name nil ; gets filled in later.
					      lx_prefix t
					      as_param_assoc_s
					      (sc_diana dn_param_assoc_s
							as_list (second as)))))
			      nam	  ;this will get normalized in name.
			      (cond
				((null (fifth as)); ?why not fourth?
				 (name_cdr_bits nam nam))
				(t  (diana_put 
				      (name_cdr_bits%thisname 
					(fifth as))
				      nam
				      'as_name)
				    (name_cdr_bits 
				      nam
				      (name_cdr_bits%destname
					(fifth as)))))
			      ))
			  (pr_and
			    (lambda (as)
			      (savecontext)
			      (cond (*original_context*
				     (setq **current_block** *original_context*)
				     ))
			      (rplaca *name_communication* nil);+++
			      (first as))
			    oper_lparen)
			  (pr_or nil actual_parameter_part nil)
			  (pr_and
			    (lambda (as)
			      (popcontext)
			      (first as))
			    oper_rparen)
			  (pr_or nil name_cdr nil))
			nil))
	       
	       (pr_and 
		 (lambda(as)		  ;  case for a proc or entry.
;		  (break in-name-proc-or-entry)
		   (let
		     ((this_id
			(ada_declared (first as) nil '(procedure entry) t)))
		     (cond
		       ((null (second as)) this_id)
		       (t (diana_put
			    (name_cdr_bits%thisname (second as))
			    this_id
			    'tp_vfuns)
			  (cond
			    ((eq (length this_id) 1)
			     (diana_put
			       (name_cdr_bits%thisname (second as))
			       (sc_diana dn_used_name_id
					 sm_defn (car this_id))
			       'as_name)))
			  (name_cdr_bits%destname (second as))))))
		 (pr_or nil
			(pr_and
			  (lambda(as)
			    (ct_push (first as) *name_communication*)
			    (first as))
			  (pr_restrict procedure lex_ident))
			(pr_and
			  (lambda(as)
			    (ct_push (first as) *name_communication*)
			    (first as))
			  (pr_restrict entry lex_ident))
			)
		 (pr_or nil
			(pr_and  
			  (lambda(as)(second as))
			  (pr_and
			    (lambda(as)
			      (putback_symbol 'oper_period))
			    oper_period)
			  (pr_or nil name_cdr nil))
			nil)
		 )
	       
	       (pr_and 
		 (lambda(as)	  ; last case for a  type, var.
		   (let* ((vnam
			    (first	  ;++
			      (ada_declared
				(first as)
				nil
				(or *class_restriction*
				    '(object formal_parameter number
					     constant package named
					     pragma_parameter
					     generic_unit
					     library_unit
					     task procedure entry))
				t)))
			  (tnam
			    (first	  ;++
			      (ada_declared
				(first as)
				nil
				(or *class_restriction*
				    '(type))
				t)))
			  (namdef (or vnam tnam))
			  (nam
			    (sc_diana dn_used_name_id
				      lx_symrep (first as)
				      sm_defn (or vnam tnam))))
		     (cond
		       ((and *in_record*
			     namdef
			     (eq (diana_nodetype_get namdef) 'dn_dscrmt_id))
			(setq *disc_used* t)))
		     (cond
		       ((and *disc_not_allowed*
			     namdef
			     (eq (diana_nodetype_get namdef) 'dn_dscrmt_id))
			(semgripe 'illegal_use_of_disc )))
		     (cond
		       ((null (second as)) nam)
		       (t (diana_put
			    (name_cdr_bits%thisname (second as))
			    nam
			    'as_name)
			  (name_cdr_bits%destname (second as))))
		     ))
		 (pr_and
		   (lambda(as)
		     (ct_push (first as) *name_communication*)
		     (first as))
		   lex_ident)		  ;if all else fails!
		 (pr_or nil name_cdr nil ))
	       ))
	  )

;;; find enclosed context. move this function to sema.l ++
       ;;;;;;;;;;;;;;;;;;;;;
(defun find_enclosed_context(id &optional override)
       ;;;;;;;;;;;;;;;;;;;;;
 (cond ((null id)
	nil)
       (t
     (ct_selectq
	(or override (diana_nodetype_get id))
	(dn_indexed
	  (find_enclosed_context
	    (extract_basetype
	      (diana_get
		(extract_basetype id t)
		'as_constrained))))
	((dn_used_name_id  dn_in_id dn_in_out_id dn_out_id dn_comp_id)
	 ;;dn_var_id was 'ere
	    (find_enclosed_context (extract_basetype id)))
	(dn_var_id
	  (let ((btid (extract_basetype id)))
	    (cond
	    ((and btid (eq (diana_nodetype_get btid) 'dn_record))
	     (find_enclosed_context btid))
	    ((and btid (eq (diana_nodetype_get btid) 'dn_access))
	     ;(break look-at-btid)
	     (find_enclosed_context btid))
	    ((and btid (eq (diana_nodetype_get btid) 'dn_task_spec))
	     ;(break look-at-task)
	     (find_enclosed_context btid))
	    (t (and (diana_node_accepts_attributep id 'ct_named_context)
		    (diana_get id 'ct_named_context))))))
	(dn_access
	    (find_enclosed_context
	      (extract_basetype (diana_get id 'as_constrained))))
	(dn_task_spec
	  (let ((entry (car (diana_get id 'as_decl_s))))
	       (and entry
		    (diana_get
		      (diana_get
			entry
			'as_designator)
		      'ct_st_defining_block))))
	(otherwise		; case for procedures, functions tasks
				; and packages.
	    (and (diana_node_accepts_attributep id 'ct_named_context)
		 (diana_get id 'ct_named_context)))))))

       ;;;;;;;;;;;
(defun strip_index(name_stack)
       ;;;;;;;;;;;
  (strip_index_aux (car name_stack)))

       ;;;;;;;;;;;;;;;
(defun strip_index_aux(name)
       ;;;;;;;;;;;;;;;
  (cond
    ((eq (car  name)
	 'index)
     (strip_index_aux  (cadr  name)))
    (t name)))

		;;;;;;;;
(def_ada_syntax name_cdr	;should return a name_cdr_bits
		;;;;;;;;

	(pr_and
	  (lambda (as)
	    (ct_pop  *name_communication*)
	    (first as))
	  (pr_or nil 
	       (pr_and  
		 (lambda(as)
		   ;(setq *original_context* nil)
		   (popcontext)
		   (let ((nam
			   (cond	  ; choose between selected and all.
			     ((and
				(diana_nodep (second as))
				(eq (diana_nodetype_get (second as)) 'dn_all))
			      (second as))
			     ((and (consp (second as))
				   (neq (first (second as))
					'*subprog*))
			      (second as))
			     ((and
				(diana_nodep (second as))
				(eq (diana_nodetype_get
				      (second as))
				    'dn_attribute_call))
			      (sc_diana
				dn_selected
				as_name nil	  ; gets put in by name (above).
				as_designator_char
				  (diana_get
				    (diana_get (second as) 'as_name)
					     'as_name)
				  ))
			     (t
			      (sc_diana
				dn_selected
				as_name nil	  ; gets put in by name (above).
				as_designator_char
				(filter_non_visible_selected
				  (cond ((and (consp (second as))
					      (eq (car (second as))
						  '*subprog*))
					 (second (second as)))
					(t (second as)))
				  (ada_declared 
				    (strip_index *name_communication*)
				    nil
				    '(package function record task constant
					      formal_parameter named
					      procedure entry object))
				  ))))))
		     (cond
		       ((and (consp (second as))
			     (neq (first (second as))
					   '*subprog*))
			(second as))
		       ((consp (second as)) (name_cdr_bits nam nam))
		       ((and (diana_nodep (second as))
			     (memq (diana_nodetype_get (second as))
			      '(dn_indexed dn_selected)))
			;;transform tree to get the indexed on top of the
			;;selected.
			(diana_put nam
				   (diana_get (second as)
					      'as_name)
				   'as_designator_char)
			(diana_put (second as)
				   nam
				   'as_name)
			(name_cdr_bits nam (second as))
			)
		       ((and (diana_nodep (second as))
			     (eq (diana_nodetype_get (second as))
			      'dn_attribute_call))
			(diana_put (diana_get (second as)
					      'as_name)
				   nam
				   'as_name)
			(name_cdr_bits nam (second as))
			)
		       (t (name_cdr_bits nam nam)))))
		 (pr_and
		   (lambda(as)
		     (cond ((null *original_context*)
			    (setq *original_context* **current_block**)))
		     (savecontext)	  ;save the current context
		     (ct_push (car  *name_communication*)  *name_communication*)
		     (setq **current_block** 
			   (or
			     (find_enclosed_context
			       (ada_declared 
				 (strip_index *name_communication*)
				 nil
				 '(package function record task formal_parameter
					   procedure entry object named constant))
			       (cond ((eq (caar  *name_communication*)
					  'index)
				      'dn_indexed)
				     (t nil))
			       )
			     **current_block**)))
		   oper_period)
		 (pr_or nil
			(pr_and
			  (lambda (as)
;			    (break mumble)
			    (cond ((consp (first as))
				   (list '*subprog* (first as)))
#|				  ((and (diana_nodep (first as))
					(eq (diana_nodetype_get (first as))
					    'dn_selected)
					(null
					  (diana_get (first as)
						     'as_designator_char)))
				   (diana_get (first as) 'as_name)) |#
				  (t (cond
				       ((and
					  (eq (diana_nodetype_get (first as))
					      'dn_used_name_id)
					  (null (diana_get (first as)
							   'sm_defn)))
					(semgripe
					  'undecl_id
					  (implode
					    (lowuplist
					      (cadr (diana_get
						      (first as)
						    'lx_symrep)))))))
				     (first as))))
			  name_aux)
			(pr_and
			  (lambda(as)
			    (cond ((null (second as))
				   (sc_diana dn_all
					     as_name nil)); gets filled in by name
				  (t (let ((dnall (sc_diana dn_all
							    as_name nil)))
				       (diana_put
					 (name_cdr_bits%thisname (second as))
				 	 dnall
					 'as_name)
				       (name_cdr_bits
					 dnall
					 (name_cdr_bits%destname (second as)))))))
			  symb_all
			  (pr_or nil
				 name_cdr
				 nil))))
	       (pr_and 
		 (lambda(as)
		   (let ((nam 
			   (cond
			     ((null (third as))	  ; single indexed.
			      (cond ((and
				       (diana_nodep (second as))
				       (eq (diana_nodetype_get (second as))
					   'dn_used_name_id)
				       (diana_get (second as)
							  'sm_defn)
				       (memq (diana_nodetype_get
					       (diana_get (second as)
							  'sm_defn))
					     '(dn_type_id dn_subtype_id)))
				     (semgripe
				       'array_index_cannot_be_a_type
				       (implode
					 (lowuplist
					   (cadr
					     (diana_get (second as)
							'lx_symrep)))))))
			      ;;this could be a typemark to represent a slice ++
			      (let*
				((us_id (and (diana_nodep (second  as))
					     (eq (diana_nodetype_get (second as))
					   'dn_used_name_id)
					     (second as)))
				 (sm_def (and us_id
					      (diana_get (second as)
							  'sm_defn)))
				 (discp (and sm_def
					     (eq (diana_nodetype_get sm_def)
						 'dn_dscrmt_id))))
				 (cond ((and *in_record*
					     discp)
				    (semgripe 'illegal_use_of_disc))))
			      (sc_diana dn_indexed
					as_name nil	  ; filled in by name.
					as_exp_s
					(sc_diana dn_exp_s
						  as_list (list (second as)))))
			     ((eq (car (third as)) 'oper_dotdot)  ; slice6
			      (cond ((and
				       (eq (diana_nodetype_get (second as))
					   'dn_used_name_id)
				       (diana_get (second as)
							  'sm_defn)
				       (memq (diana_nodetype_get
					       (diana_get (second as)
							  'sm_defn))
					     '(dn_type_id dn_subtype_id)))
				     (semgripe
				       'array_index_cannot_be_a_type
				       (implode
					 (lowuplist
					   (cadr
					     (diana_get (second as)
							'lx_symrep)))))))
			      (cond ((and
				       (eq (diana_nodetype_get (second (third as)))
					   'dn_used_name_id)
				       (diana_get (second (third as))
							  'sm_defn)
				       (memq (diana_nodetype_get
					       (diana_get (second (third as))
							  'sm_defn))
					     '(dn_type_id dn_subtype_id)))
				     (semgripe
				       'array_index_cannot_be_a_type
				       (implode
					 (lowuplist
					   (cadr
					     (diana_get (second as)
							'lx_symrep)))))))
			      (sc_diana dn_slice
					as_name nil	  ; filled in by name.
					as_dscrt_range
					(sc_diana dn_range
						  as_exp1 (second as)
						  as_exp2 (second (third
								    as)))))
			     ((eq (car (third as)) 'oper_comma)	  ; indexed
			      (cond ((and
				       (eq (diana_nodetype_get (second as))
					   'dn_used_name_id)
				       (diana_get (second as)
							  'sm_defn)
				       (memq (diana_nodetype_get
					       (diana_get (second as)
							  'sm_defn))
					     '(dn_type_id dn_subtype_id)))
				     (semgripe
				       'array_index_cannot_be_a_type
				       (implode
					 (lowuplist
					   (cadr
					     (diana_get (second as)
							'lx_symrep)))))))
			      (sc_diana dn_indexed
					as_name nil	  ; filled in by name.
					as_exp_s
					(sc_diana dn_exp_s
						  as_list
						  (cons (second as)
							(cons (second (third
									as))
							      (third (third
								       as)))))))
			     (t (sc_diana dn_foo)); ++
			     ) ))
		     (cond
		       ((null  (fifth as))
			(name_cdr_bits nam nam))
		       (t  (diana_put 
			     (name_cdr_bits%thisname (fifth as))
			     nam
			     'as_name)
			   (name_cdr_bits
			     nam
			     (name_cdr_bits%destname (fifth as)))))))
		 ;;dont allow success if tm ++
		 (pr_and
		   (lambda(as)
		     (let ((name
			     (first
			       (ada_declared
				 (strip_index *name_communication*)
				 nil
				 '(object formal_parameter constant
					  procedure function)
				 t))))
		     (cond
		       ((null name);(break name-not-an-array)
			(putback_symbol (first as))	  ;undo parse.
			'fail)		  ;and return nil... noparse
		      (t (savecontext)
			 (ct_push
			   (list 'index (car  *name_communication*))
			   *name_communication*)
			 (cond (*original_context*
				(setq **current_block**
				      *original_context*)
				))
			 (first as)))))
		   (pr_or pascal_bracket_check oper_lparen))
		 expression
		 (pr_or nil 
			range_constraint  ; not dotdot or comma signifies slice.
			(pr_and nil	  ; dotdot signifies slice.
				oper_dotdot
				simple_expression)
			(pr_and nil	  ; comma signifies indexed.
				oper_comma
				expression
				(pr_repeat nil
					   (pr_and cadr
						   oper_comma
						   expression)))
			nil)
		 (pr_or pascal_bracket_check
			(pr_and
			  (lambda (as)
			    (setq *original_context* **current_block**)
			    (popcontext)
			    (first as))
			  oper_rparen))
		 (pr_or nil name_cdr nil))
	       (pr_and2c
		 (lambda(as)
;		   (break in-name_cdr)
		   (second as))
		 oper_quote
		 (pr_or nil lex_ident symb_range symb_delta symb_digits)
		 ;these are the ll2 symbols.

		 oper_quote
		 (pr_or
		   nil 
		   (pr_and 
		     (lambda(as)
		       (let ((nam
			       (sc_diana dn_attribute_call
					 as_name nil	  ; see below
					 as_exp (second as))))
			 (ct_push (car  *name_communication*) *name_communication*)
			 (diana_put
			   nam
			   (sc_diana
			     dn_attribute
			     as_name nil  ; gets filled in by name
			     as_id
			     (sc_diana
			       dn_used_name_id
			       lx_symrep (first as)
			       sm_defn (ada_declared 
					 (first as)
					 nil
					 '(indexable_attribute
					    not_indexable_attribute))))
			   'as_name)
			 (cond
			   ((null (third as))
			    ;(break look-at-foo) 
			    (name_cdr_bits (diana_get nam 'as_name)
					   nam))
			   (t  
			       (cond
				 ((eq (diana_nodetype_get
					(name_cdr_bits%destname (third as)))
				      'dn_attribute_call)
				  (diana_put
				    (name_cdr_bits%thisname (third as))
				    nam
				    'as_name)
				  (let ((frob
					  (name_cdr_bits 
					    (diana_get nam 'as_name)
					    (name_cdr_bits%destname (third as)))))
				     frob))
				 (t (diana_put 
				      (name_cdr_bits%thisname (third as))
				      nam 
				      'as_name)
				    (name_cdr_bits 
				      nam 
				      (name_cdr_bits%destname
					(third as)))))))))
		     (pr_or nil
			    (pr_restrict indexable_attribute lex_ident)
			    (pr_restrict not_indexable_attribute lex_ident)
;;; This is unbelievable! range is a reserved word and also an attribute.
;;; only context can tell which. even worse so are delta and digits.
			    (pr_and
			      (lambda(as)
				(ada_ident digits))
			      symb_digits)
			    (pr_and
			      (lambda(as)
				(ada_ident delta))
			      symb_delta)
			    (pr_and
			      (lambda(as)
				(ada_ident range))
			      symb_range));crock crock 
		     (pr_or nil 
			    (pr_and cadr
				    (pr_and
				      (lambda (as)
					(savecontext)
					(cond (*original_context*
					       (setq **current_block**
						     *original_context*)
					       ))
					(first as))
				      oper_lparen)
				    expression
				    (pr_and
				      (lambda (as)
					(popcontext)
					(first as))
				      oper_rparen))
			    nil)
		     (pr_or nil name_cdr nil))
		   ))
	       nil))) 
    
		;;;;;;;;;;;;;;;
(def_ada_syntax operator_symbol
		;;;;;;;;;;;;;;;

   (pr_and
     (lambda(as)
       `(lex_ident ,(cadr (first as))))
     lex_string))

;;;-- 4.2  Literals
;;;
;;;-- Syntax 4.2
;;;--  literal  ::=
;;;--     numeric_literal | enumeration_literal | character_string
;;;--   | 'null'
;;;    -- The xcenumeration_literal is represented as a 'used_object_id' or a
;;;    --  'used_char' whose attributes point to an 'enum_id' or a 'def_char'.
;;;    -- See 2.3.
;;;--
;;;
;;;
;;;    EXP ::=              numeric_literal;
;;;
;;;    numeric_literal =>   lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_numrep        : number_rep;
;;;    numeric_literal =>   sm_exp_type      : TYPE_SPEC,
;;;                         sm_value         : value;
;;;    -- if there is implicit conversion sm_exp_type reflects conversion;
;;;    -- otherwise it references a universal type
;;;
;;;    EXP ::=              used_char;
;;;
;;;    used_char =>         lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    used_char =>         sm_defn          : DEF_OCCURRENCE,
;;;                         sm_exp_type      : TYPE_SPEC,
;;;                         sm_value         : value;
;;;
;;;
;;;    EXP ::=              null_access;
;;;
;;;    null_access =>       lx_srcpos        : source_position,
;;;                         lx_comments      : comments;
;;;    null_access =>       sm_exp_type      : TYPE_SPEC,
;;;                         sm_value         : value;
;;;
;;;
;;;    EXP ::=              string_literal;
;;;
;;;    string_literal =>    lx_srcpos        : source_position,
;;;                         lx_comments      : comments,
;;;                         lx_symrep        : symbol_rep;
;;;    string_literal =>    sm_exp_type      : TYPE_SPEC,
;;;                         sm_constraint    : CONSTRAINT,
;;;                         sm_value         : value;
;;;
		;;;;;;;
(def_ada_syntax literal
		;;;;;;;

	(pr_or nil 
	       (pr_and 
		 (lambda(as)
		   (sc_diana dn_null_access))
		 symb_null)
	       (pr_and
		 (lambda(as)
		   (sc_diana dn_string_literal
			     lx_symrep (first as)))
		 lex_string)
		(pr_and
		  (lambda(as)
		    (do
		      ((chz la_current_symbol (la_lex)))
		      ((and (consp chz)(eq (car chz) 'oper_quote))
		       (la_lex)))
		    (cond
		      ((= (length (cadr (first as))) 1)
		       (dissambiguate_function_reference
			 (sc_diana dn_function_call
			      lx_symrep
			      `(lex_char (#/' ,(caadr (first as)) #/'))
			      tp_vfuns
			      (ada_declared
				`(lex_char (#/' ,(caadr (first as)) #/'))
				nil 'function t))))
		      (t (semgripe
			   'character_literal_has_funny_length
			    (implode (append (list '#/') 
					     (cadr (first as)) (list '#/'))))
			 (sc_diana dn_character_literal
			      lx_symrep
			      `(lex_char `(#/' ,(caadr (first as)) #/')))))
		    )
		  oper_quote)
					  ;	    int_const
					  ;	    real_const
	       (pr_and
		 (lambda(as)
		   (sc_diana dn_numeric_literal
			     lx_numrep (first as)))
		 lex_number)))		  ; {other_number_const}
    
