2015-06-12 Basile Starynkevitch <basile@starynkevitch.net>
[official-gcc.git] / gcc / melt / warmelt-normal.melt
blob94dced5bfd059648e9ca64acbedc03fa9da00eb7
1 ;; file warmelt-normal.melt -*- Lisp -*-
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 (comment "***
4     Copyright 2008 - 2014  Free Software Foundation, Inc.
5     Contributed by Basile Starynkevitch <basile@starynkevitch.net>
7     This file is part of GCC.
9     GCC is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 3, or (at your option)
12     any later version.
14     GCC is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
19     You should have received a copy of the GNU General Public License
20     along with GCC; see the file COPYING3.  If not see
21     <http://www.gnu.org/licenses/>.
22 ***")
24 ;; the copyright notice above apply both to warmelt-normal.melt and 
25 ;; to the generated file  warmelt-normal*.c
28 ;; This MELT module is GPL compatible since it is GPLv3+ licensed.
29 (module_is_gpl_compatible "GPLv3+")
31 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33 ;;    This file is part of a bootstrapping compiler for the MELT lisp
34 ;;    dialect, compiler which should be able to compile itself (into
35 ;;    generated C file[s])
36 ;;    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39 ;;;; ================ normalized representations
42 ;; basically, the normalized representation of (f a (g x)) 
43 ;; is let y=(g x) in (f a y)
44 ;; etc... where y is a cloned symbol
46 ;;; common superclass for normalized representations
47 (defclass class_nrep
48   :super class_root
49   :doc #{The $CLASS_NREP is the common super class of normalized
50 representations. Its $NREP_LOC field gives the location in source,
51 if any.}#
52   :fields (nrep_loc                     ;location in source
53            ))
56 ;;; the discriminant for normalizing closures
57 (definstance discr_normalizing_closure class_discriminant
58   :doc #{The $DISCR_NORMALIZING_CLOSURE is the discriminant of MELT debug
59   functions. Use $CLONE_WITH_DISCRIMINANT on a closure, e.g. with
60   $LAMBDA, to make it a normalizing function. For gurus.}#
61   :obj_num MELTOBMAG_CLOSURE
62   :disc_super discr_closure
63   :named_name '"DISCR_NORMALIZING_CLOSURE")
65 (defclass class_normal_magic_binding
66   :doc #{The $CLASS_NORMAL_MAGIC_BINDING is tricky, rarely
67   used (e.g. for @code{code_chunk} tags): the $NMAGIC_VALUE is the
68   returned value of its $BINDER. If it is a closure of
69   DICR_NORMALIZING_CLOSURE, that closure is applied to normalize.}#
70   :super class_any_binding
71   :fields (nmagic_value)
74 ;; a simple stuff is a non-object, a symbol (or keyword or clonedsym),
75 ;; ...
76 (defclass class_nrep_simple
77   :doc #{The $CLASS_NREP_SIMPLE is for simple normal things -e.g. normal
78   symbols.}#
79   :super class_nrep
80   :fields ( ))
82 ;; a normalized expression should never be the result of normal_exp;
83 ;; it should only appear in bindings!
84 (defclass class_nrep_expression
85   :doc #{Common superclass $CLASS_NREP_EXPRESSION of normalized expressions
86   which can only appear in normal bindings.}#
87   :super class_nrep
88   :fields ( ))
90 ;; normalized typed expressions also have a ctype
91 (defclass class_nrep_typed_expression
92   :doc #{Common super-class $CLASS_NREP_TYPED_EXPRESSION of typed normalized
93   expressions. $NEXPR_CTYP gives its c-type.}#
94   :super class_nrep_expression
95   :fields (nexpr_ctyp                   ;the ctype
96            ))
98 ;; normalized typed expressions with arguments
99 (defclass class_nrep_typed_expression_with_arguments
100   :doc #{Common super-class
101 $CLASS_NREP_TYPED_EXPRESSION_WITH_ARGUMENTS of typed normalized
102 expressions with normalized arguments. $NEXPR_ARGS is the tuple of
103 normalized arguments.}#
104   :super class_nrep_typed_expression
105   :fields (nexpr_args))
107 ;; normal applications have simple functions & arguments
108 (defclass class_nrep_apply
109   :super class_nrep_typed_expression_with_arguments
110   :doc #{The $CLASS_NREP_APPLY class is for normal
111 applications. $NAPP_FUN is the simple function to apply to $NEXPR_ARGS.}#
112   :fields (napp_fun                     ;simple function to apply
113            ))
115 ;; normal hook calls
116 (defclass class_nrep_hook_call
117   :super class_nrep_typed_expression_with_arguments
118   :doc #{The $CLASS_NREP_HOOK_CALL is for normal hook calls.
119   $NHOOK_CALLED is the called hook. $NHOOK_OUTS it the actual output
120   arguments to the hook. $NHOOK_DESCR is the descriptor.}#
121   :fields (nhook_name
122            nhook_called
123            nhook_outs
124            nhook_descr
125            ))
127 ;; normalized multiresult apply
128 (defclass class_nrep_multiapply
129   :doc #{The $CLASS_NREP_MULTIAPPLY is for normal applications of
130 functions with several results within $MULTICALL. $NMULAPP_BINDINGS is
131 the tuple of formal result bindings. $NMULAPP_BODY is the normal
132 body.}#
133   :super class_nrep_apply
134   :fields (nmulapp_bindings             ;a tuple of formal result bindings
135            nmulapp_body                 ;body normexp
136            ))
138 ;;; normal message sending
139 (defclass class_nrep_msend
140   :doc #{The $CLASS_NREP_SEND is for normal message send (or message
141 passing), with a single result. $NSEND_SEL is the normalized selector,
142 $NSEND_RECV the normalized receiver, with $NEXPR_ARGS giving the
143 normalized arguments.}#
144   :super class_nrep_typed_expression_with_arguments
145   :fields (nsend_sel               ;the normalized selector occurrence
146            nsend_recv              ;the receiver
147            ))
151 ;; normalized multiresult message send
152 (defclass class_nrep_multimsend
153   :doc #{The $CLASS_NREP_MULTIMSEND is for normal message sends with
154 multiple results thru $MULTICALL. $NMULSEND_BINDINGS is the tuple of
155 formal result bindings, and $NMULSEND_BODY is the normalized body.}#
156   :super class_nrep_msend
157   :fields (nmulsend_bindings            ;tuple of formal bindings
158            nmulsend_body                ;body normexp
159            ))
161 ;; normal chunk is a normalized expansion of primitive
162 (defclass class_nrep_chunk
163   :doc #{The $CLASS_NREP_CHUNK is for normalized expansion of
164 primitive or cmatcher expressions. Field $NCHUNK_EXPANSION is the
165 expansion - where strings of $DISCR_VERBATIM_STRING are handled
166 specifically. Field $NCHUNK_OPER is the operator.}#
167   :super class_nrep_typed_expression
168   :fields (nchunk_expansion             ;the expansion
169            nchunk_oper                  ;the operator (primitive or cmatcher)
170            ))
172 ;; normal comment is a normalized comment
173 (defclass class_nrep_comment
174   :doc #{The $CLASS_NREP_COMMENT if for normalized comments in the
175 generated C code. The field $NCOMM_STRING gives the comment.}#
176   :super class_nrep_expression
177   :fields (ncomm_string ;the comment
178            ))
180 ;; normal lets have simple binding & body subexpressions
181 (defclass class_nrep_let
182   :doc #{The $CLASS_NREP_LET is for normalized lets. The
183 $NLET_BINDINGS field is a tuple of $CLASS_NORMAL_LET_BINDING
184 instances. The $NLET_BODY field is the normal body. The normalization
185 process introduce many such normal lets.}#
186   :super class_nrep_expression
187   :fields (nlet_bindings                ;a tuple of class_normal_let_binding-s
188            nlet_body
189            ))
191 ;; normal letrec 
192 (defclass class_nrep_letrec
193   :doc #{The $CLASS_NREP_LETREC is for normalized letrec. The field
194 $NLETREC_FILL_BINDINGS is the list of internal normal bindings to fill
195 the letrec-ed constructions. The field $NLETREC_BODY_BINDINGS is the
196 tuple of internal normal bindings for the body.  The field
197 $NLETREC_LOCSYMS is the tuple of local symbol occurrences.}#
198   :super class_nrep_let
199   :fields (
200            ;; the nlet_bindings is a tuple of constructive bindings
201            nletrec_fill_bindings 
202            nletrec_body_bindings 
203            nletrec_locsyms
206 ;; normal return have a main & supplementary subexpressions
207 (defclass class_nrep_return
208   :doc #{The $CLASS_NREP_RETURN is for normalized returns. The primary
209 returned value is given thru $NRET_MAIN field. The secondary
210 returned things are thru $NRET_REST tuple.}#
211   :super class_nrep_expression
212   :fields (nret_main                    ;main normal expression to return
213            nret_rest                    ;tuple of normal expr...
214            ))
216 ;; common normal for if, ifisa ...
217 (defclass class_nrep_ifcommon
218   :doc #{The $CLASS_NREP_IFCOMMON is the common superclass for
219 normalized if-like tests. $NIF_THEN gives the then branch, and
220 $NIF_ELSE gives the else branch.}#
221   :super class_nrep_typed_expression
222   :fields (nif_then
223            nif_else
224            ))
226 ;;; common normal for testing some value
227 (defclass class_nrep_iftestvalue
228   :doc #{The $CLASS_NREP_IFTESTVALUE is a common superclass for
229   testing about some given value $NIF_TESTVAL}# 
230   :super class_nrep_ifcommon
231   :fields (nif_testval
234 ;; normal if is_a(value,class) then else
235 (defclass class_nrep_ifisa
236   :doc #{The $CLASS_NREP_IFISA is for normalized $IS_A
237   tests. Inherited $NIF_TESTVAL gives the value to be tested, and
238   $NIFA_CLASS gives the normalized class data in which the value is
239   tested for membership.}#
240   :super class_nrep_iftestvalue
241   :fields (nifa_class                   ;normal class 
244 (defclass class_nrep_iftuplesized
245   :doc #{The $CLASS_NREP_IFTUPLESIZED is for normalized tests of
246   multiple of given size. Inherited $NIF_TESTVAL gives the value to be tested (if
247   it is multiple), and $NIF_TUPSIZ gives the size to be tested (if it
248   has that size).}#
249   :super class_nrep_iftestvalue
250   :fields (nif_tupsiz))
252 ;; normal if_variadic(variadic,typetuple) then ..
253 (defclass class_nrep_ifvariadic
254   :doc #{The $CLASS_NREP_IFVARIADIC is for normalized $VARIADIC
255   tests. $NIFV_VARIADIC gives the variadic name, and $NIFV_CTYPES
256   gives the tuple of ctypes.}#
257   :super class_nrep_ifcommon
258   :fields (nifv_variadic
259            nifv_ctypes))
261 ;; normal consume_variadic 
262 (defclass class_nrep_consume_variadic
263   :super class_nrep_expression
264   :doc #{The $CLASS_NREP_CONSUME_VARIADIC is for $VARIADIC argument
265 consumption.  Field $NCONSVA_VARIADIC gives the variadic, and
266 $NCONSVA_CTYPES the consumed types of arguments.  }#
267   :fields (
268            nconsva_variadic
269            nconsva_ctypes
272 ;; normal if same (t1,t2) then else
273 (defclass class_nrep_ifsame
274   :doc #{The $CLASS_NREP_IFSAME is for normalized identity tests for matching. $NIFS_LEFT and $NIFS_RIGHT are the simple stuff to compare for identity.}#
275   :super class_nrep_ifcommon
276   :fields (nifs_left 
277            nifs_right))
279 ;; normal if have simple test, then, else clauses & a ctype
280 (defclass class_nrep_if
281   :doc #{The $CLASS_NREP_IF is for usual normalized if-test. $NIF_TEST
282 gives the tested thing.}#
283   :super class_nrep_ifcommon
284   :fields (nif_test
285            ))
287 ;; normal ifcpp have a symbol and a ctyp. Perhaps it should be
288 ;; refactored using class_nrep_ifcommon?
289 (defclass class_nrep_cppif
290   :doc #{The $CLASS_NREP_CPPIF is for cppif compile-time
291 tests. $NIFP_COND is the tested cpp symbol. $NIFP_THEN the then
292 part, $NIFP_ELSE the else part, $NIFP_CTYP the ctype.}#
293   :super class_nrep_expression
294   :fields (nifp_cond
295            nifp_then
296            nifp_else
297            nifp_ctyp
298            ))
300 ;; normal progn has a distingished last
301 (defclass class_nrep_progn
302   :doc #{The $CLASS_NREP_PROGN is for normalized $PROGN sequences. The
303   $NPROGN_SEQ field is the tuple of all-but-last subexpressions, and
304   the last one is given in $NPROGN_LAST.}#
305   :super class_nrep_expression
306   :fields (nprogn_seq                   ;tuple of all but last
307            nprogn_last
308            ))
310 (defclass class_nrep_checksignal
311   :doc #{The $CLASS_NREP_CHECKSIGNAL is an internal expression to check interrupts, 
312   corresponding to emission of the melt_check_interrupt() C macro. 
313   It is emitted at safe places.}#
314   :super class_nrep_expression
315   :fields ()
318 (defclass class_nrep_putmodulevar
319   :super class_nrep_expression
320   :fields (nputmod_destvar
321           nputmod_value))
323 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
324 (compile_warning ":doc missing below")
325 ;; normalized unsafe get field
326 (defclass class_nrep_unsafe_get_field
327   :super class_nrep_expression
328   :fields (nuget_obj
329            nuget_field))
334 ;; normalized unsafe_put_field
335 (defclass class_nrep_unsafe_put_fields
336   :super class_nrep_expression
337   :fields (nuput_obj
338            nuput_fields))
340 ;; normalized unsafe nth_component
341 (defclass class_nrep_unsafe_nth_component
342   :super class_nrep_expression
343   :fields (nunth_tuple
344            nunth_index))
346 ;; normalized setq
347 (defclass class_nrep_setq
348   :super class_nrep_expression
349   :fields (nstq_var
350            nstq_exp
351            ))
353 ;; normalized forever
354 (defclass class_nrep_forever
355   :super class_nrep_expression
356   :fields (nforever_bind                ;the label binding
357            nforever_body                ;a tuple
358            nforever_result              ;cloned symbol for result
359            ))
361 ;; normalized exit
362 (defclass class_nrep_exit
363   :super class_nrep_expression
364   :fields (nexit_bind                   ;the label binding
365            nexit_val                    ;the exited value
366            ))
368 ;; normalized again
369 (defclass class_nrep_again
370   :super class_nrep_expression
371   :fields (nagain_bind                  ;the label binding
372            ))
374 ;; normalized field assign (in make instance)
375 (defclass class_nrep_fieldassign
376   :super class_nrep
377   :fields (nfla_field                   ;the field
378            nfla_val                     ;its normalized value
379            ))
381 ;; normalized make instance
382 (defclass class_nrep_instance
383   :super class_nrep_expression
384   :fields (nmins_class                  ;the instanciated class
385            nmins_cladata                ;its data
386            nmins_fields                 ;the tuple of field assignments
387            ))
389 ;; normalized variadic argument retrieval
390 (defclass class_nrep_variadic_argument
391   :super class_nrep_expression
392   :fields (nvarg_variadic ;variadic symbol for index
393            nvarg_ctyp     ;ctype of argument
394            nvarg_offset   ;boxed integer offset
395            ))
397 ;; normalized lambda
398 (defclass class_nrep_lambda 
399   :super class_nrep_expression
400   :fields (nlambda_proc                 ;the procedure
401            nlambda_constrout            ;the constant routine
402            nlambda_closedv              ;the tuple of closed normal values
403            ))
405 ;; normalized lambda for :macro binding
406 (defclass class_nrep_macrolambda
407   :super class_nrep_lambda
408   :fields ()
411 ;; normalized citeration
412 (defclass class_nrep_citeration
413   :super class_nrep_expression
414   :fields (nciter_citerator             ;the citerator
415            nciter_chunkbefore           ;the expansed chunk before
416            nciter_chunkafter            ;the expansed chunk after
417            nciter_body                  ;the normalized body
418            nciter_statocc               ;the state local occurrence
419            nciter_locbindings           ;the local bindings
420            nciter_bodbindings           ;normalized body bindings
421            ))
423 ;; normalized tests sequence, used for matches
424 (defclass class_nrep_tests
425   :super class_nrep_expression
426   :fields (ntests_testseq               ;the tuples of normal tests
427            ;;;; see file warmelt-normatch.melt
430 ;;;;;;;;;;;;;;;;
431 (defclass class_normal_constructor_binding
432   :doc #{The internal $CLASS_NORMAL_CONSTRUCTOR_BINDING is the common
433 super-class of constructor bindings in LETREC... Field $NCONSB_LOC
434 gives the optional location, field $NCONSB_DISCR gives the normalized
435 discriminant, and field $NCONSB_NLETREC gives the normal letrec containing it..}#
436   :super class_any_binding
437   :fields (nconsb_loc nconsb_discr nconsb_nletrec)
440 (defclass class_normal_constructed_tuple_binding
441   :doc #{The internal $CLASS_NORMAL_CONSTRUCTED_TUPLE_BINDING is the
442 class of tuple constructor bindings. Field $NTUPB_COMP gives the tuple
443 of initial normalized components.}#
444   :super class_normal_constructor_binding
445   :fields (ntupb_comp))
447 (defclass class_normal_constructed_pair_binding
448   :doc #{The internal $CLASS_NORMAL_CONSTRUCTED_PAIR_BINDING is the
449   class of pair constructor bindings. Field $NPAIRB_HEAD gives the
450   normalized head, and $NPAIRB_TAIL gives the normalized tail.}#
451   :super class_normal_constructor_binding
452   :fields (npairb_head npairb_tail))
454 (defclass class_normal_constructed_list_binding
455   :doc #{The internal $CLASS_NORMAL_CONSTRUCTED_LIST_BINDING is the
456 class of list constructor bindings. Field $NLISTB_FIRST gives the
457 initial normalized first pair, and field $NLISTB_LAST gives the last
458 one. Field $NLISTB_PAIRSB gives the tuple of constructed pair bindings}#
459   :super  class_normal_constructor_binding
460   :fields (nlistb_first nlistb_last nlistb_pairsb))
462 (defclass class_normal_constructed_lambda_binding
463   :doc #{The internal $CLASS_NORMAL_CONSTRUCTED_LAMBDA_BINDING is the
464 class of lambda constructor bindings. Field $NLAMBDAB_NCLOSED gives
465 the normalized closed values, and $NLAMBDAB_DATAROUT gives the normalized routine data, and $NLAMBDAB_CONSTROUT its constant.}#
466   :super  class_normal_constructor_binding
467   :fields (nlambdab_nclosed nlambdab_constrout nlambdab_datarout))
469 (defclass class_normal_constructed_instance_binding
470   :doc #{The internal $CLASS_NORMAL_CONSTRUCTED_INSTANCE_BINDING is
471 the class of instance constructor bindings. Field $NINSTB_SLOTS is the
472 tuple of the normalized slots, and $NINSTB_CLABIND is the class binding.}#
473   :super  class_normal_constructor_binding
474   :fields (ninstb_slots ninstb_clabind))
476 (defclass class_normal_module_variable_binding
477   :doc #{The internal $CLASS_NORMAL_MODULE_VARIABLE_BINDING is the
478 class of module variable bindings. }#
479   :super class_variable_binding
480   :fields (nvarb_num))
482 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
483 ;;; procedures
484 (defclass class_nrep_anyproc
485   :doc #{The $CLASS_NREP_ANYPROC is the common super-class for
486 procedures. Field $NPROC_BODY is the normalized body.}#
487   :super class_nrep
488   :fields (
489            nproc_body
490            ))
493 ;; the class of the initial procedure
494 (defclass class_nrep_initproc
495   :super class_nrep_anyproc
496   :doc #{The $CLASS_NREP_INITPROC is the class for the initial
497 procedure in a module. Field $NINIT_TOPL is the list of top-level
498 normalized expressions. Field $NINIT_DEFBINDS is the list of $DEFINE-d
499 bindings. Field $NINIT_IMPORTS is the list of imports.}#
500   :fields (ninit_topl                   ;list of toplevel nrep
501            ninit_defbinds               ;list of define-d bindings
502            ninit_imports                ;list of imports
503            ninit_importexprs            ;tuple of import assignments
504            ))
506 ;; the class of the initial procedure when extending a module
507 (defclass class_nrep_initextendproc
508   :super class_nrep_initproc
509   :doc #{The $CLASS_NREP_INITEXTENDPROC is the class for the initial
510 extending procedure for an existing module. Field ninitextend_modenv
511 is the extended environment.}#
512   :fields (ninitextend_modenv
513            ))
516 (defclass class_nrep_closproc
517   :super class_nrep_anyproc
518   :doc #{The internal $CLASS_NREP_CLOSPROC is the super-class for
519   closing procedures with optional name $NRCLOP_NAME, [input]
520   arguments bindings tuplz $NRCLOP_ARGBINDTUPLE, closed bindings list
521   $NRCLOP_CLOBINDLIST, constant list $NRCLOP_CONSTLIST, and object
522   const cache map $NRCLOP_OBJCONSTCACHEMAP}#
523   :fields (nrclop_name
524            nrclop_argbindtuple
525            nrclop_clobindlist
526            nrclop_constlist
527            nrclop_objconstcachemap
528            ))
532 ;; the class of the normalized hook procedure
533 (defclass class_nrep_hookproc
534   :super class_nrep_closproc
535   :doc #{The $CLASS_NREP_HOOKPROC is the class for a hook
536 procedure in a module, defined with $DEFHOOK. }#
537   :fields (nrhook_outb                  ;output arguments binding tuple
538            nrhook_ctype                 ;ctype of result
539            nrhook_datahook              ;hook data object
540            ))
542 ;; normal routine procedure
543 (defclass class_nrep_routproc
544   :super class_nrep_closproc
545   :doc #{The $CLASS_NREP_ROUTPROC is the class for normal routine
546 procedures, representing $DEFUN or $LAMBDA code. Field $NRPRO_DATAROUT
547 is the routine data object. Field $NRPRO_DATACLOS is the closure data
548 object. Field $NRPRO_THUNKLIST is the list of thunks to be called when
549 compiling it. Field $NRPRO_VARIADIC is non-null if the routine is
550 variadic.}#
551   :fields (
552            nrpro_datarout               ;routine data object
553            nrpro_dataclos               ;closure data object
554            nrpro_thunklist              ;list of thunks to be called when compiling it
555            nrpro_variadic               ;non null iff variadic
556            ))
558 (defclass class_nrep_lambdaroutproc
559   :super class_nrep_routproc
560   :doc #{The $CLASS_NREP_LAMBDAROUTPROC is the class for $LAMBDA
561 related routine procedures.}#
562   :fields ())
564 (defclass class_nrep_macrolambdaroutproc
565   :super class_nrep_routproc
566   :doc #{The $CLASS_NREP_LAMBDAROUTPROC is the class for :macro lambda
567 related routine procedures.}#
568   :fields ())
570 (defclass class_nrep_defunroutproc
571   :super class_nrep_routproc
572   :doc #{The $CLASS_NREP_DEFUNROUTPROC is the class for $DEFUN related
573 routine procedures.}#
574   :fields ())
579 ;;; static normalized predef
580 (defclass class_nrep_predef
581   :doc #{The $CLASS_NREP_PREDEF is for normalized predefined
582   values. $NRPREDEF gives the symbolic or integer number.}#
583   :super class_nrep_simple
584   :fields (
585            nrpredef                     ;the predef is a symbol or a boxed integer
586            ))
588 ;; normalized nil
589 (defclass class_nrep_nil
590   :doc #{The $CLASS_NREP_NIL is for normalized nil occurrences.}#
591   :super class_nrep_simple
592   :fields (
593            ))
596 ;; give the normal import of some imported value or literal named value
597 (defun normal_import (nimpval env ncx psloc)
598   (debug "normal_import nimpval=" nimpval "\n.. ncx=" ncx)
599   (let ( (nsymb ())
600          (nsymbname ())
601          )
602     (cond ( (is_a nimpval class_nrep_importedval)
603             (setq nsymb (get_field :nimport_symb  nimpval))
604             (setq nsymbname (get_field :named_name nsymb))
605             (debug "normal_import importedval nsymb=" nsymb "\n.. nsymbname=" nsymbname)
606             )
607           ( (is_a nimpval class_nrep_literalvalue)
608             (setq nsymb (get_field :nlitval_symbol nimpval))
609             (setq nsymbname (get_field :named_name nsymb))
610             (debug "normal_import literalvalue nsymb=" nsymb "\n.. nsymbname=" nsymbname)
611             )
612           (:else
613            (debug "normal_import bad nimpval=" nimpval)
614            (assert_msg "normal_import with unepxected nimpval" () nimpval)
615            (return)
616            )
617           )
618     (assert_msg "check nsymb" (is_a nsymb class_symbol) nsymb)
619     (let (
620           (modctx (get_field :nctx_modulcontext ncx))
621           (curproc (get_field :nctx_curproc ncx))
622           (ndataparenv (get_field :nctx_qdatparmodenv ncx))
623           (modname (get_field :mocx_modulename modctx))
624           (sloc (or (get_field :nrep_loc nimpval) psloc))
625           (nimphc
626            (instance class_nrep_hook_call
627                      :nrep_loc sloc
628                      :nexpr_ctyp ctype_value
629                      :nhook_name '"HOOK_SYMBOL_IMPORTER"
630                      :nexpr_args (tuple nsymbname modname ndataparenv)
631                      :nhook_called (normal_predef hook_symbol_importer ncx
632                                                   sloc "hook_symbol_importer")
633                       
634                      :nhook_outs (tuple)
635                      :nhook_descr (hook_data hook_symbol_importer)
636                      )
637            )
638           (nsetimp (instance class_nrep_setq
639                              :nrep_loc sloc
640                              :nstq_var nimpval
641                              :nstq_exp nimphc
642                              ))
643           )
644       (debug "normal_import nimphc=" nimphc "\n.. nimpval=" nimpval "\n.. nsetimp=" nsetimp)
645       (return nsetimp)
646       )))
648 ;;; quasidata are stuff to be computed inside the initial routine;
649 ;;; most of them are plain data, but current_module_environment_reference &
650 ;;; parent_module_environment need specific stuff
652 (defclass class_nrep_quasidata
653   :doc #{The $CLASS_NREP_QUASIDATA is an abstract super-class for data
654   computed during initialization.}#
655   :super class_nrep
656   :fields (
657            ))
659 (defclass class_nrep_bound_data
660   :super class_nrep_quasidata
661   :doc #{The internal $CLASS_NREP_BOUND_DATA is for normalized defined and
662   bound data. The objnum of its instance is the predefined rank if
663   any.}#
664   ;; the objnum is the predefined rank if any
665   :fields  (ndata_name                ;name if any of the data
666             ndata_rank                ;boxed integer rank of the data 
667 ;;; we box the integer and don't use the objnum bzcause we
668 ;;; might have a lot (>30000) of data
669             ndata_locbind        ;local binding tuple to fill the data
670             )
671   )
673 (defclass class_nrep_discriminated_data
674   :doc #{The internal $CLASS_NREP_DISCRIMINATED_DATA is for defined
675   data with a static disciminant.}#
676   :super class_nrep_bound_data
677   :fields (
678            ndata_discrx               ;discriminant normal expression 
679            ))
681 ;; normal "static" instance - built at modules initialization
682 (defclass class_nrep_datainstance
683   :super class_nrep_discriminated_data
684   :fields (ninst_objnum         ;object number (a number or a symbol)
685            ninst_predef         ;predefined rank (number or symbol)
686            ninst_hash           ;integer hash
687            ninst_slots          ;tuple of normalized slots expressions
688            ))
690 ;; normal "static" string
691 (defclass class_nrep_datastring
692   :super class_nrep_discriminated_data
693   :fields ( nstr_string                 ;the string
694             ))
696 ;; normal "static" boxed integer
697 (defclass class_nrep_databoxedinteger
698   :super class_nrep_discriminated_data
699   :fields ( nboxint_num                 ;the numerical integer
700             ))
702 ;; normal "static" tuple
703 (defclass class_nrep_datatuple
704   :super class_nrep_discriminated_data
705   :fields ( ntup_comp       ;the tuple of component values expressions
706             ))
708 ;; normal interned static symbol
709 (defclass class_nrep_datasymbol
710   :super class_nrep_datainstance
711   :fields ( ndsy_namestr
712             ))
714 ;; normal interned static keyword
715 (defclass class_nrep_datakeyword
716   :super class_nrep_datasymbol
717   :fields ( 
718            ))
720 ;; normal static routine data
721 (defclass class_nrep_dataroutine
722   :super class_nrep_discriminated_data
723   :fields (ndrou_proc                   ;associated procedure
724            ))
726 ;; normal static hook data
727 (defclass class_nrep_datahook
728   :super class_nrep_discriminated_data
729   :fields (ndhook_proc             ;associated procedure
730            ndhook_data             ;the data
731            ndhook_closv            ;tuple of closed values
732            ndhook_predef           ;the predefined, if any
733            ndhook_modvarbind       ;the module variable binding if any
734            ))
736 ;; normal static closure data
737 (defclass class_nrep_dataclosure
738   :super class_nrep_discriminated_data
739   :fields (ndclo_proc                   ;associated procedure
740            ndclo_closv                  ;tuple of closed values
741            ))
743 ;; normal static start value
744 ;; obtained from an initial binding, imported from parent environment
745 (defclass class_nrep_importedval
746   :super class_nrep_simple
747   :fields (nimport_symb                 ;the symbol
748            nimport_sydata               ;the symbol data
749            ))
751 ;; normal literal value
752 (defclass class_nrep_literalvalue
753   :super class_nrep_simple
754   :fields (nlitval_regval
755            ))
757 ;; normal literal named values
758 (defclass class_nrep_literalnamedvalue
759   :super class_nrep_literalvalue
760   :fields (nlitval_symbol
761            ))
763 ;; normal static variable occurrence
764 (defclass class_nrep_modulevarocc
765   :super class_nrep_simple
766   :fields (nmodvar_bind ;the normal variable binding, containing the index
767            ))
769 ;; normal  occurrence of a symbol 
770 (defclass class_nrep_symocc
771   :super class_nrep_simple
772   :fields (nocc_symb
773            nocc_ctyp          ;the ctype of the symbol, eg ctype_value
774            nocc_bind          ;the binding of the symbol
775            ))
777 ;; normal local occurrence of a symbol
778 (defclass class_nrep_locsymocc
779   :super class_nrep_symocc
780   :fields (
781            ))
783 ;; normal closed occurrence of a symbol
784 (defclass class_nrep_closedocc
785   :super class_nrep_symocc
786   :fields (ncloc_procs                  ;list of enclosing procedures
787            ))
789 ;; normal constant occurrence of a symbol
790 (defclass class_nrep_constocc
791   :super class_nrep_closedocc
792   )
794 ;;; normal quasi constants for current_module_environment_reference &
795 ;;; parent_module_environment & constants
796 (defclass class_nrep_quasiconstant
797   :super class_nrep_simple
798   :fields (nconst_sval        ;source value
799            nconst_proc        ;containing proc
800            nconst_data        ;normalized data or stuff inside iniproc
801            ))
803 ;; normal constant (.e.g a quoted symbol, a keyword, a define-d value ...)
804 (defclass class_nrep_constant
805   :super class_nrep_quasiconstant
806   :fields (
807            ))
809 (defclass class_nrep_defined_constant
810   :super class_nrep_quasiconstant
811   :fields (nconst_defbind
812            )
813   )
815 ;; noormal current_module_environment_reference quasiconst
816 (defclass class_nrep_quasiconst_current_module_environment_reference
817   :super class_nrep_quasiconstant
818   :fields ( nqcmec_comment
819             ))
822 ;; normal current_module_environment_reference quasidata
823 (defclass class_nrep_quasidata_current_module_environment_reference
824   :super class_nrep_quasidata
825   :fields (
826            ))
828 ;; noormal parent_module_environment quasiconst
829 (defclass class_nrep_quasiconst_parent_module_environment
830   :super class_nrep_quasiconstant
831   :fields (
832            ))
834 ;; normal parent_module_environment quasidata
835 (defclass class_nrep_quasidata_parent_module_environment
836   :super class_nrep_quasidata
837   :fields (
838            ))
840 ;; data field accessor (mostly used for defclass initialization) this
841 ;; translates into melt_field_object(<obj>,<off>) of obj is not a
842 ;; datainstance and directly to the field if it is a datainstance
843 (defclass class_nrep_fieldacc
844   :super class_nrep_expression
845   :fields (naccf_obj              ;data for the object to be accessed 
846            naccf_fld              ;rank or field to be accessoed
847            ))
849 ;;; data multiple accessor (mostly used for defclass initialization)
850 ;; this translates into melt_multiple_nth(<mul>,<ix>) if mul is not
851 ;; a datatuple and directly to the component if it is a datatuple
852 (defclass class_nrep_multacc
853   :super class_nrep_expression
854   :fields (naccm_mul           ;data for the multiple to be accessed
855            naccm_ix            ;index to be accessed (a boxed integer)
856            ))
858 ;; normalized store predefined
859 (defclass class_nrep_store_predefined
860   :super class_nrep_expression
861   :fields (nstpd_predef
862            nstpd_value
863            ))
865 ;; normalized update current module environment box
866 (defclass class_nrep_update_current_module_environment_reference
867   :super class_nrep_expression
868   :fields (
869            nucmeb_expr          ;the normalized expression
870                                         ;computing the box
871            ncumeb_comment               ;optional comment
872            ))
874 ;; normalized check of current running module environment box
875 (defclass class_nrep_check_running_module_environment_container
876   :super class_nrep_expression
877   :fields (nchrumod_comment             ;optional comment
878            ))
880 ;;; export all the normalized representations classes
881 (export_class ;; normal representations classes in alphabetical order
883  class_normal_constructed_instance_binding
884  class_normal_constructed_lambda_binding
885  class_normal_constructed_list_binding
886  class_normal_constructed_pair_binding
887  class_normal_constructed_tuple_binding
888  class_normal_constructor_binding
889  class_normal_magic_binding
890  class_normal_module_variable_binding
891  class_nrep
892  class_nrep_again
893  class_nrep_anyproc
894  class_nrep_apply
895  class_nrep_bound_data
896  class_nrep_check_running_module_environment_container
897  class_nrep_checksignal
898  class_nrep_chunk
899  class_nrep_citeration
900  class_nrep_closedocc
901  class_nrep_closproc
902  class_nrep_comment 
903  class_nrep_constant
904  class_nrep_constocc
905  class_nrep_consume_variadic
906  class_nrep_cppif
907  class_nrep_databoxedinteger
908  class_nrep_dataclosure
909  class_nrep_datahook
910  class_nrep_datainstance
911  class_nrep_datakeyword
912  class_nrep_dataroutine
913  class_nrep_datastring
914  class_nrep_datasymbol
915  class_nrep_datatuple
916  class_nrep_defined_constant
917  class_nrep_defunroutproc
918  class_nrep_discriminated_data
919  class_nrep_exit
920  class_nrep_expression
921  class_nrep_fieldacc
922  class_nrep_fieldassign
923  class_nrep_forever
924  class_nrep_hookproc
925  class_nrep_hook_call
926  class_nrep_if
927  class_nrep_ifcommon
928  class_nrep_ifisa
929  class_nrep_ifsame
930  class_nrep_iftestvalue
931  class_nrep_iftuplesized
932  class_nrep_ifvariadic
933  class_nrep_importedval
934  class_nrep_initextendproc
935  class_nrep_initproc
936  class_nrep_instance
937  class_nrep_lambda
938  class_nrep_lambdaroutproc
939  class_nrep_let
940  class_nrep_letrec
941  class_nrep_literalnamedvalue
942  class_nrep_literalvalue
943  class_nrep_locsymocc
944  class_nrep_macrolambda
945  class_nrep_macrolambdaroutproc
946  class_nrep_msend
947  class_nrep_multacc
948  class_nrep_multiapply
949  class_nrep_multimsend
950  class_nrep_nil
951  class_nrep_predef
952  class_nrep_progn
953  class_nrep_putmodulevar
954  class_nrep_quasiconst_current_module_environment_reference
955  class_nrep_quasiconst_parent_module_environment
956  class_nrep_quasiconstant
957  class_nrep_quasidata
958  class_nrep_quasidata_current_module_environment_reference
959  class_nrep_quasidata_parent_module_environment
960  class_nrep_return
961  class_nrep_routproc
962  class_nrep_setq
963  class_nrep_simple
964  class_nrep_modulevarocc
965  class_nrep_store_predefined
966  class_nrep_symocc
967  class_nrep_typed_expression
968  class_nrep_typed_expression_with_arguments
969  class_nrep_unsafe_get_field
970  class_nrep_unsafe_nth_component
971  class_nrep_unsafe_put_fields
972  class_nrep_update_current_module_environment_reference
973  class_nrep_variadic_argument
974  )                                      ;end of export normal classes
978 ;;;;;;; primitive for extra warnings
979 (defprimitive has_extra_warnings () :long "(extra_warnings)")
983 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
985 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
987 ;;; add some data to a normalization context and return it
988 (defun add_nctx_data (nctx ndata)
989   (debug "add_nctx_data nctx=" nctx)
990   (debug "add_nctx_data ndata=" ndata "\n")
991   (shortbacktrace_dbg "add_nctx_data" 16)
992   (assert_msg "check nctx" (is_a nctx class_normalization_context) nctx)
993   (assert_msg "check ndata" (is_a ndata class_nrep_bound_data) ndata)
994   (assert_msg "fresh ndata" (null (unsafe_get_field :ndata_rank ndata)) ndata)
995   (let ( (datlis (unsafe_get_field :nctx_datalist nctx)) 
996          (ncurproc (unsafe_get_field :nctx_curproc nctx))
997          )
998     (debug "add_nctx_data ncurproc=" ncurproc)
999     (debug "add_nctx_data datlis=" datlis)
1000     (assert_msg "check datlis" (is_list datlis) datlis)
1001     (let ( (lastdat (pair_head (list_last datlis)))  )
1002       (if (is_a lastdat class_nrep_bound_data)
1003           (let ( (:long lastrk (get_int (unsafe_get_field :ndata_rank lastdat))) )
1004             (assert_msg "check lastrk" (>i lastrk 0) lastrk)
1005             (let ( (rkbox (make_integerbox discr_integer (+i 1 lastrk))) )
1006               (unsafe_put_fields ndata :ndata_rank rkbox)
1007               ))
1008         (let ( (rkbox1 (make_integerbox discr_integer 1)) )
1009           (unsafe_put_fields ndata :ndata_rank rkbox1)
1010           )))
1011     (list_append datlis ndata)
1012     (debug "add_nctx_data updated datlis=" datlis "\n result ndata=" ndata)
1013     ndata
1014     ))
1016   ;; the automatically generated _warmelt-predef.melt file defines a
1017   ;; fill_initial_predefmap function
1018 (load "_warmelt-predef.melt")
1020   ;; internal primitive to return the last predefined index
1021 (defprimitive last_globpredef_index () :long
1022   "BGLOB__LASTGLOB")
1026 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1027 (defclass class_literal_value 
1028   :super class_proped
1029   :fields (litv_value
1030            litv_rank
1031            litv_loc)
1032   :doc #{$CLASS_LITERAL_VALUE is the class managing literal values in runtime extension modules.
1033   $LITV_VALUE is the literal value itself
1034   $LITV_RANK is its unique rank in the extension module
1035   $LITV_LOC may contain its stack location}#
1036   )
1037 (export_class class_literal_value)
1039 (defun register_literal_value (val modctx)
1040   (debug "register_literal_value val=" val "\n in modctx=" modctx)
1041   (assert_msg "check modctx" (is_a modctx class_running_extension_module_context) modctx)
1042   (let ( (litvalist (get_field :morcx_litervalist modctx))
1043          (litobjmap (get_field :morcx_literobjmap modctx))
1044          (countlit (get_field :morcx_countlitval modctx))
1045          (:long count (get_int countlit))
1046          )
1047     (assert_msg "check litvalist" (is_list litvalist) litvalist)
1048     (assert_msg "check litobjmap" (is_mapobject litobjmap) litobjmap)
1049     (assert_msg "check countlit" (is_integerbox countlit) countlit)
1050     ;; check once in a while that the counter is the list length
1051     (assert_msg "check count" (or (%iraw count 8) (==i count (list_length litvalist))) count)
1052     (cond ( (null val)
1053             (assert_msg "null literal value" ())
1054             (return))
1055           ( (is_integerbox val)
1056             (assert_msg "integer literal value" () val)
1057             (return))
1058           ( (is_string val)
1059             (assert_msg "string literal value" () val)
1060             (return))
1061           ( (is_object val)
1062             (let ( (litv (mapobject_get litobjmap val))
1063                    )
1064               (cond
1065                (litv 
1066                 (debug "register_literal_value found litv=" litv)
1067                 (assert_msg "check litv" (is_a litv class_literal_value) litv)
1068                 (assert_msg "check old found value" (== (get_field :litv_value litv) val) litv val)
1069                 )
1070                (:else
1071                 (setq litv (instance class_literal_value
1072                                      :litv_value val
1073                                      :litv_rank (make_integerbox discr_constant_integer count)
1074                                      :litv_loc ()
1075                                      ))
1076                 (list_append litvalist litv)
1077                 (put_int countlit (+i count 1))
1078                 (mapobject_put litobjmap val litv)
1079                 (debug "register_literal_value new litv=" litv "\n updated litobjmap=" litobjmap)
1080                 )
1081                )
1082               (return litv)
1083               ))
1084           (:else
1085            ;; non-object value
1086            (let ( (litv (instance class_literal_value
1087                                   :litv_value val
1088                                   :litv_rank (make_integerbox discr_constant_integer count)
1089                                   :litv_loc ()
1090                                   ))
1091                   )
1092              (list_append litvalist litv)
1093              (put_int countlit (+i count 1))
1094              (debug "register_literal_value nonobject value litv=" litv)
1095              (return litv)
1096              ))
1097           )))
1100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1101 ;;; create a normalization context
1102 (defun create_normcontext (modctx)
1103   :doc #{Internal routine to reate a normalization context for module
1104   context $MODCTX, used to compile modules.}#
1105   (debug "create_normcontext modctx=" modctx)
1106   (shortbacktrace_dbg "create_normcontext" 12)
1107   (let ( (:long maxpredefix (last_globpredef_index))
1108          (:long ix 1)
1109          (predefmap (make_mapobject discr_map_objects (+i 19 (*i 2 maxpredefix))))
1110          (valmap (make_mapobject discr_map_objects 350))
1111          )
1112     (assert_msg "check modctx" (is_a modctx class_any_module_context) modctx)
1113     (forever predefloop
1114              (if (>=i ix maxpredefix) (exit predefloop))
1115              (let ( (curpredef (get_globpredef ix)) )
1116                (if (is_object curpredef)
1117                    (mapobject_put predefmap curpredef (make_integerbox discr_integer ix)))
1118                )
1119              (setq ix (+i ix 1)))
1120     (fill_initial_predefmap predefmap)
1121     (let ( (inipro  (instance class_nrep_initproc
1122                               :ninit_topl (make_list discr_list)
1123                               :ninit_defbinds (make_list discr_list)
1124                               :nrep_loc ()
1125                               )) 
1126            (ncx (instance class_normalization_context
1127                           :nctx_initproc inipro
1128                           :nctx_proclist (make_list discr_list)
1129                           :nctx_datalist (make_list discr_list)
1130                           :nctx_valuelist (make_list discr_list)
1131                           :nctx_symbmap  (make_mapstring discr_map_strings 50)
1132                           :nctx_keywmap  (make_mapstring discr_map_strings 40)
1133                           :nctx_predefmap predefmap
1134                           :nctx_valmap valmap
1135                           :nctx_valbindmap (make_mapobject discr_map_objects 20)
1136                           ;; we need a symbcachemap for the toplevel expressions
1137                           :nctx_symbcachemap (make_mapobject discr_map_objects 30)
1138                           :nctx_curproc inipro
1139                           :nctx_modulcontext modctx
1140                           :nctx_qdatcurmodenvbox (instance class_nrep_quasidata_current_module_environment_reference
1141                                                            )
1142                           :nctx_qdatparmodenv (instance class_nrep_quasidata_parent_module_environment
1143                                                         )
1144                           :nctx_procurmodenvlist (make_list discr_list)
1145                           ))
1146            )
1147       (debug "create_normcontext make ncx=" ncx)
1148       (return ncx)
1149       )))
1153 ;;;;;;;;;;;;;;;;
1154 (defun create_normal_extending_context (modctx modenv)
1155   :doc #{Internal routine to create a normalization context for module
1156   context $MODCTX, used to compile, e.g. for running, the extension of a module environment $MODENV.}#
1157   (debug "create_normal_extending_context start modctx=" modctx
1158          "\n* modenv=" modenv "\n")
1159   (shortbacktrace_dbg "create_normal_extending_context" 12)
1160   (let ( (:long maxpredefix (last_globpredef_index))
1161          (:long ix 1)
1162          (predefmap (make_mapobject discr_map_objects (+i 11 (*i 2 maxpredefix))))
1163          (valmap (make_mapobject discr_map_objects 91))
1164          )
1165     (assert_msg "check modctx" (is_a modctx class_running_extension_module_context) modctx)
1166     (assert_msg "check modenv" (is_a modenv class_environment) modenv)
1167     (forever predefloop
1168              (if (>=i ix maxpredefix) (exit predefloop))
1169              (let ( (curpredef (get_globpredef ix)) )
1170                (if (is_object curpredef)
1171                    (mapobject_put predefmap curpredef (make_integerbox discr_integer ix)))
1172                )
1173              (setq ix (+i ix 1)))
1174     (fill_initial_predefmap predefmap)
1175     (let ( (inipro  (instance class_nrep_initextendproc
1176                               :ninit_topl (make_list discr_list)
1177                               :ninit_defbinds (make_list discr_list)
1178                               :nrep_loc ()
1179                               :ninitextend_modenv modenv
1180                               )) 
1181            (ncx (instance class_normalization_context
1182                           :nctx_initproc inipro
1183                           :nctx_proclist (make_list discr_list)
1184                           :nctx_datalist (make_list discr_list)
1185                           :nctx_valuelist (make_list discr_list)
1186                           :nctx_symbmap  (make_mapstring discr_map_strings 30)
1187                           :nctx_keywmap  (make_mapstring discr_map_strings 20)
1188                           :nctx_predefmap predefmap
1189                           :nctx_valmap valmap
1190                           :nctx_valbindmap (make_mapobject discr_map_objects 20)
1191                           ;; we need a symbcachemap for the toplevel expressions
1192                           :nctx_symbcachemap (make_mapobject discr_map_objects 10)
1193                           :nctx_curproc inipro
1194                           :nctx_modulcontext modctx
1195                           :nctx_qdatcurmodenvbox (instance class_nrep_quasidata_current_module_environment_reference
1196                                                            )
1197                           :nctx_qdatparmodenv (instance class_nrep_quasidata_parent_module_environment
1198                                                         )
1199                           :nctx_procurmodenvlist (make_list discr_list)
1200                           ))
1201            )
1202       (debug "create_normal_extending_context make inipro=" inipro "\n.. result ncx=" ncx "\n")
1203       (return ncx)
1204       )))
1207 ;;; the normal_exp selector 
1208 ;;;;; expected arguments: 
1209 ;;;   recv = the receiver, eg a sexpr
1210 ;;;   env = the environment 
1211 ;;;   ncx = the normalization context 
1212 ;;;   psloc = (parent) source location
1213 ;;;;; expected results: normalized + binding list 
1214 ;;; IMPORTANT NOTICE: even for simple expressions [like side-effecting
1215 ;;; expressions returning void, e.g. RETURN, EXIT, ... other simple
1216 ;;; side-effecting expressions like SETQ], the normalized should
1217 ;;; always be a simple occurrence, and the work being done in the
1218 ;;; bindings list.
1219 (defselector normal_exp class_selector
1220   :doc #{Normalize an expression, often an S-expr or a literal
1221   constant. $RECV is the reciever, $ENV the environment of
1222   $CLASS_ENVIRONMENT, $NCX the normalization context of
1223   $CLASS_NORMALIZATION_CONTEXT and $PSLOC the parent source
1224   location. Should return a normalized thing, often an instance of
1225   $CLASS_NREP_LOCSYMOCC, and as a secondary result a list of
1226   bindings.)}#
1227   :formals (recv env ncx psloc)
1228                                         ;  :named_name (stringconst2val discr_namestring "NORMAL_EXP")
1229   )
1231 ;; many stuff, e.g. constant literal strings or numbers, are already normalized 
1232 (defun normexp_identical (recv env ncx psloc)
1233   (assert_msg "check env" (is_a env class_environment) env)
1234   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1235   ;; is a no-op
1236   (debug "normexp_identical recv" recv)
1237   (return recv ()))
1239 (install_method discr_string normal_exp  normexp_identical)
1240 (install_method discr_integer normal_exp  normexp_identical)
1242 (defun normexp_null (recv env ncx psloc)
1243   (assert_msg "check env" (is_a env class_environment) env)
1244   (assert_msg "check nctxt" (is_a ncx class_normalization_context) ncx)
1245   (let ( (normnull (instance class_nrep_nil :nrep_loc psloc)) )
1246     (debug "normexp_null normnull" normnull)
1247     (return normnull ())
1248     ))
1249 (install_method discr_null_receiver normal_exp normexp_null)
1252 ;;; an object or a value may have to be normalized only when inside a
1253 ;;; constructed s-expression. The reader is not able to give such
1254 ;;; values.  So it practically happens only when running an
1255 ;;; evaluation.
1256 ;;;;;;;;;;;;;;;;
1257 (defun normexp_any_object (recv env ncx psloc)
1258   (debug "normexp_any_object" " recv=" recv)
1259   (assert_msg "check env" (is_a env class_environment) env)
1260   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1261   ;; we should normalize arbitrary objects into themselves. However,
1262   ;; we should collect all these objects, so that the runtime
1263   ;; evaluator gets them all, so the normalized expression would be an
1264   ;; access to some constant offset inside a tuple
1265   (let ( (cla (discrim recv))
1266          (claname (get_field :named_name cla))
1267          (recname (get_field :named_name recv))
1268          )
1269     (if (is_string recname)
1270         (error_at psloc 
1271                   "unimplemented normalization for literal object named $1"_ recname))
1272     (error_at psloc 
1273                 "unimplemented normalization for literal object of $1"_ claname)
1274     (assert_msg "@$@ unimplemented normexp_any_object" () recv)))
1275 (install_method class_root normal_exp normexp_any_object)
1278 (defun normexp_mixed_location (recv env ncx psloc)
1279   (debug "normexp_mixed_location" " recv=" recv)
1280   (let ( (filev ())
1281          (:long linenum 0)
1282          (:long colnum 0)
1283          )
1284     (code_chunk 
1285      normixloc_chk
1286      #{ /* normexp_mixed_location start $NORMIXLOC_CHK */
1287      source_location loc_$NORMIXLOC_CHK = melt_location_mixloc((melt_ptr_t)$RECV) ;
1288      $FILEV = meltgc_cached_string_path_of_source_location (loc_$NORMIXLOC_CHK) ;
1289      $LINENUM = LOCATION_LINE(loc_$NORMIXLOC_CHK)  ;
1290      $COLNUM = LOCATION_COLUMN(loc_$NORMIXLOC_CHK) ;
1291      /* normexp_mixed_location end $NORMIXLOC_CHK */}#)
1292     (debug "normexp_mixed_location" " filev=" filev "; linenum=" linenum "; colnum=" colnum)
1293     (let (
1294           (sloc (or psloc recv))
1295           (sdiscr (instance class_source_fetch_predefined
1296                             :loca_location sloc
1297                             :sfepd_predef 'discr_mixed_integer))
1298           (squofil (instance class_source_quote
1299                              :loca_location sloc
1300                              :squoted filev))
1301           (sprim (instance class_source_primitive
1302                             :loca_location sloc
1303                             :sprim_oper make_mixint
1304                             :sargop_args (tuple sdiscr squofil (constant_box linenum))))
1305            )
1306       (debug "normexp_mixed_location" " sprim=" sprim)
1307       (multicall
1308        (nres nbind)
1309        (normexp_primitive sprim env ncx psloc)
1310        (debug "normexp_mixed_location" " result nres=" nres "\n.. nbind=" nbind)
1311        (return nres nbind)
1312        )         
1313       )
1314     )
1315   )
1316 (install_method discr_mixed_location normal_exp normexp_mixed_location)
1318 (defun normexp_any_value (recv env ncx psloc)
1319   (assert_msg "check env" (is_a env class_environment) env)
1320   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1321   ;; we should normalize arbitrary values into themselves, unless when
1322   ;; they are containers for stuff like DISCR_TREE etc..., then we
1323   ;; should unbox that stuff.  so the normalized expression would be
1324   ;; an access to some constant offset inside a tuple or its unboxing
1325   (debug "normexp_any_value recv=" recv)
1326   (let ( (cla (discrim recv))
1327          (claname (get_field :named_name cla))
1328          )
1329     (error_at psloc 
1330               "unimplemented normalization for literal value of $1"_ claname)
1331     (warning_at psloc
1332                 "unnormalizable literal value is $1" recv)
1333     (assert_msg "@$@ unimplemented normexp_any_value" () recv)))
1334 (install_method discr_any_receiver normal_exp  normexp_any_value)
1336 ;;; catchall for src
1337 (defun normexp_src_catchall (recv env ncx psloc)
1338   (debug "normexp_src_catchall recv=" recv)
1339   (assert_msg "check env" (is_a env class_environment) env)
1340   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1341   (let ( (myclass (discrim recv))
1342          (myclassname (unsafe_get_field :named_name myclass)) )
1343     (error_at (unsafe_get_field :loca_location recv) 
1344                 "unimplemented normalization for value of $1" myclassname)
1345     (assert_msg "normexp_src_catchall unimplemented normexp for src" () recv)
1346     ))
1347 (install_method class_source normal_exp normexp_src_catchall)
1350 ;; normalization of lazy macro expansion
1351 (defun normexp_lazymacroexp (recv env ncx psloc)
1352   (assert_msg "check env" (is_a env class_environment) env)
1353   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1354   (let (
1355         (sloc (get_field :loca_location recv))
1356         (lazymacfun (get_field :slazymacro_fun recv))
1357         (lazymacoper (get_field :slazymacro_oper recv))
1358         )
1359     (multicall 
1360      (mexp mresexp)
1361      (lazymacfun)
1362      (debug "normexp_lazymacroexp mexp" mexp)
1363      (if mresexp
1364          ;;; this happens in the pathological case when the lazy macro
1365          ;;; macro-expands to more than one result
1366          (error_at sloc "delayed lazy macro expansion cannot macro expand multiply"_))
1367      (if (is_a mexp class_source_lazy_macro_expansion)
1368          ;;; this happens in the pathological case when a macro
1369          ;;; operator is not defined
1370          (progn 
1371            (if (is_a lazymacoper class_symbol)
1372                (error_at sloc "undefined operator; unknown name $1"
1373                            (get_field :named_name lazymacoper))
1374              (error_at sloc "undefined macro; delayed lazy macro expansion too lazy"))
1375            (return)
1376            ))
1377      (multicall
1378       (nrep nbind)
1379       (normal_exp mexp env ncx psloc)
1380       (debug "normexp_lazymacroexp nrep=" nrep " nbind=" nbind)
1381       (return nrep nbind)
1382       )
1383      )))
1384 (install_method class_source_lazy_macro_expansion normal_exp normexp_lazymacroexp)
1386 ;; the selector to compute the ctype of a value in an environment
1387 ;;; argument: environment
1388 ;;;; sometimes this selector is used with a null environment, for
1389 ;;;; instance in the code generation phase
1390 (defselector get_ctype class_selector
1391   )
1393 ;;; selector to compile a normalized stuff into an object
1394 ;;; receiver: the normalized stuff
1395 ;;; arguments: 
1396 ;;;; * GCX the code generation context
1397 ;;; result = the obj instruction or value
1399 (defselector compile_obj class_selector
1400   )
1402 ;;; most stuff are really ctype_value
1403 (defun gectyp_anyrecv (recv env) ctype_value)
1404 (install_method discr_any_receiver get_ctype gectyp_anyrecv)
1406 (defun gectyp_root (recv env) ctype_value)
1407 (install_method class_root get_ctype gectyp_root)
1409 ;; integers are ctype_long
1410 (defun gectyp_integer (recv env) 
1411   (debug "gectyp_integer recv" recv)
1412   ctype_long)
1413 (install_method discr_integer get_ctype gectyp_integer)
1415 ;; strings are ctype_cstring
1416 (defun gectyp_string (recv env)
1417   ctype_cstring)
1418 (install_method discr_string get_ctype gectyp_string)
1422 ;;; normalize a tuple - returning a tuple & a bindinglist
1423 (defun normalize_tuple (tup env ncx psloc)
1424   (debug "normalize_tuple start tup=" tup " psloc=" psloc)
1425   (shortbacktrace_dbg "normalize_tuple" 16)
1426   (assert_msg "check env" (is_a env class_environment) env)
1427   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1428   (if (null tup) 
1429       (return () ()))
1430   (assert_msg "check tup" (is_multiple tup) tup)
1431   (let ( (bindlist (make_list discr_list)) 
1432          (:long tuplen (multiple_length tup))
1433          (res (make_multiple discr_multiple tuplen))
1434          )
1435     (foreach_in_multiple
1436      (tup)
1437      (comp :long ix)
1438      (debug "normalize_tuple comp=" comp "\n ix=" ix)
1439      (multicall 
1440       (norcomp nbinds)
1441       (normal_exp comp env ncx psloc)
1442       (debug "normalize_tuple norcomp=" norcomp 
1443              "\n of discrim=" (discrim norcomp)
1444              "\n* nbinds=" nbinds 
1445              "\n* for comp=" comp 
1446              "\n ix=" ix)
1447       (assert_msg "check nbinds" (is_list_or_null nbinds) nbinds)
1448       ;; Shameful dirty hack for module variables; notably for
1449       ;; application, we need to put them into a local
1450       ;; binding, because meltgc_apply is passing argument
1451       ;; by references, and melt_module_var_fetch returns
1452       ;; a pointer value, not a reference. 
1453       (if (is_a norcomp class_nrep_modulevarocc)
1454           (let ( (nvarbind (unsafe_get_field :nmodvar_bind norcomp))
1455                  )
1456             (debug "normalize_tuple modulevarocc norcomp=" norcomp " ix#" ix)
1457             (if (null nbinds) 
1458                 (setq nbinds (make_list discr_list)))
1459             (assert_msg "check nvarbind" (is_a nvarbind class_normal_module_variable_binding) nvarbind)
1460             (let ( (nvbinder (get_field :binder nvarbind))
1461                    (clonsym (clone_symbol nvbinder))
1462                    (clonbind (instance class_normal_let_binding
1463                                        :letbind_loc ()
1464                                        :binder clonsym
1465                                        :letbind_type ctype_value
1466                                        :letbind_expr norcomp))
1467                    (clonocc (instance class_nrep_locsymocc
1468                                       :nrep_loc ()
1469                                       :nocc_ctyp ctype_value
1470                                       :nocc_symb clonsym
1471                                       :nocc_bind clonbind))
1472                    )
1473               (when (!= (get_ctype norcomp env) ctype_value)
1474                   (error_at psloc "incompatible type of module variable $1 - needs a value" nvbinder))
1475               (list_append nbinds clonbind)
1476               (setq norcomp clonocc)
1477               )))
1478       ;;
1479       (assert_msg "check norcomp not class_nrep_expression" 
1480                   (is_not_a norcomp class_nrep_expression) norcomp)
1481       (if (is_list nbinds)
1482           (foreach_pair_component_in_list 
1483            (nbinds)
1484            (curpair bnd)
1485            (assert_msg "check bnd" (is_a bnd class_any_binding) bnd)
1486            (assert_msg "check bindlist" (is_list bindlist) bindlist)
1487            (list_append bindlist bnd)
1488            )
1489         )
1490       (debug "normalize_tuple ix#" ix " norcomp=" norcomp)
1491       (multiple_put_nth res ix norcomp)
1492       ))
1493     (if (not (is_pair (list_first bindlist)))
1494         (setq bindlist ()))
1495     (debug "normalize_tuple final res=" res "\n.. bindlist=" bindlist)
1496     (return res bindlist)
1497     ))
1500 ;; wrap a normal let around a single normalized expression & a bindinglist
1501 (defun wrap_normal_let1 (nexp bindlist loc)
1502   (debug "wrap_normal_let1 nexp=" nexp " bindlist=" bindlist)
1503   (assert_msg "check bindlist" (is_list_or_null bindlist) bindlist)
1504   (list_every
1505    bindlist 
1506    (lambda (cbind) 
1507      (if (not (is_a cbind class_normal_let_binding))
1508            (debug "wrap_normal_let1 nexp=" nexp
1509                   " bindlist=" bindlist
1510                   " cbind" cbind))
1511      (assert_msg "check cbind wrapnormlet1" (is_a cbind class_normal_let_binding) cbind)))
1512   (if 
1513       (and (is_list bindlist)
1514            (is_pair (list_first bindlist)))
1515       (let ( (wnlet 
1516               (instance class_nrep_let
1517                         :nrep_loc loc
1518                         :nlet_bindings (list_to_multiple bindlist)
1519                         :nlet_body (tuple nexp)))
1520              )
1521         wnlet)
1522     nexp
1523     ))
1525 ;; wrap a normal let around a tuple of normalized expressions and a bindinglist
1526 ;; add an interrupt check
1527 (defun wrap_normal_letseq (tupnexp bindlist loc)
1528   (debug "wrap_normal_letseq tupnexp=" tupnexp " bindlist=" bindlist " loc=" loc)
1529   (shortbacktrace_dbg "wrap_normal_letseq" 10)
1530   (assert_msg "check tupnexp" (is_multiple_or_null tupnexp) tupnexp)
1531   (assert_msg "check bindlist" (is_list_or_null bindlist) bindlist)
1532   (let ( (:long nbnexp (multiple_length tupnexp))
1533          )
1534     (cond
1535      ( (not (is_multiple tupnexp))
1536        (let ( (wnletn (wrap_normal_let1 tupnexp bindlist loc))
1537               )
1538        (debug "wrap_normal_letseq non-tuple tupnexp=" tupnexp 
1539               "\n return wnletn=" wnletn)
1540        (return wnletn)))
1541      ( (==i nbnexp 0)
1542        (assert_msg "check impossible nbnexp" () tupnexp))
1543      ( (==i nbnexp 1)
1544        (let ( (subnexp (multiple_nth tupnexp 0))
1545               (wnlet1 (wrap_normal_let1 subnexp bindlist loc))
1546               )
1547          ;; single subexpression
1548          (debug "wrap_normal_letseq return wnlet1=" wnlet1)
1549          (return wnlet1)
1550          ))
1551      ( :else                            ;more than one sub-expression
1552        (let (
1553              (ncheckint (instance class_nrep_checksignal
1554                                   :nrep_loc loc))
1555              (growntup (make_multiple discr_multiple (+i nbnexp 1)))
1556              )
1557          (multiple_put_nth growntup 0 ncheckint)
1558          (foreach_in_multiple 
1559           (tupnexp)
1560           (curnexp :long nix)
1561           (assert_msg "check curnexp" (or (is_not_object curnexp) (is_a curnexp class_nrep)) curnexp)
1562           (multiple_put_nth growntup (+i nix 1) curnexp))
1563          (list_every
1564           bindlist 
1565           (lambda (cbind) 
1566             (if (not (is_a cbind class_normal_let_binding))
1567                 (debug "wrap_normal_letseq tuplexp=" tupnexp
1568                        " bindlist=" bindlist
1569                        " cbind=" cbind))
1570             (assert_msg "check cbind wrapnormletseq" 
1571                         (is_a cbind class_normal_let_binding) cbind)))
1572          (let ( (wnlet
1573                  (instance class_nrep_let
1574                            :nrep_loc loc
1575                            :nlet_bindings (list_to_multiple bindlist)
1576                            :nlet_body growntup))
1577                 )
1578            (debug "wrap_normal_letseq return wnlet=" wnlet)
1579            (return wnlet)))))))
1582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1583 ;;; utility to check that every normalized argument has a passable ctype
1584 (defun check_ctype_nargs (nargs env sloc)
1585   (foreach_in_multiple 
1586    (nargs)
1587    (cnarg :long ix) 
1588    (let ( (ctyp (get_ctype cnarg env))
1589           (ctypname (get_field :named_name ctyp))
1590           )
1591      (assert_msg "check_ctype_nargs ctyp" (is_a ctyp class_ctype) ctyp)
1592      (when (not (is_string (unsafe_get_field :ctype_parstring ctyp)))
1593        (debug "check_ctype_nargs" " ix#" ix " cnarg=" cnarg
1594               "\n.. ctyp=" ctyp)
1595        (cond
1596         ( (is_a cnarg class_nrep_locsymocc)
1597           (error_at sloc "symbol $1 occurrence argument #$2 has invalid type $3"
1598                     (get_field :nocc_symb cnarg)
1599                     ix
1600                     ctypname))
1601         ( (or (is_string cnarg) (is_integerbox cnarg))
1602           (error_at sloc "literal $1 argument #$2 has invalid type $3"
1603                     cnarg ix ctypname)
1604           )
1605         (:else
1606          (error_at sloc "argument #$1 has invalid type $2"_ ix ctypname)
1607          )))
1608      )))
1611 (defselector normalize_binding class_selector
1612   :doc #{Normalize a locally bound symbol. $RECV is the binding, $ENV
1613 is the environment, $NCX is the normal context, $PSLOC the parent
1614 source location.}#
1615   :formals (recv env ncx procs psloc))
1617 (defun normbind_failany (recv env ncx procs psloc)
1618   (debug "normbind_failany recv" recv)
1619   (let ( (dis (discrim recv))
1620          )
1621     (debug "normbind_failany dis" dis)
1622     (error_at psloc "unexpected binding normalization of instance of $1" (get_field :named_name dis))
1623     (assert_msg "@$@unexpected normalize binding" () recv)
1625 (install_method discr_any_receiver normalize_binding normbind_failany)
1627 (defun normbind_anybind (bind env ncx procs psloc)
1628   (debug "normbind_anybind bind=" bind)
1629   (let ( (dis (discrim bind))
1630          (symb (unsafe_get_field :binder bind)) 
1631          (sycmap  (unsafe_get_field :nctx_symbcachemap ncx))
1632          )
1633     (warning_strv psloc "bizarre?? constant reference to"
1634                   (unsafe_get_field :named_name symb))
1635     (debug "normbind_anybind bind=" bind "\n of dis=" dis)
1636     (warning_strv psloc "bizarre binding normalization for " (get_field :named_name dis))
1637     (let ( (kocc
1638             (instance class_nrep_constocc
1639                       :nrep_loc psloc
1640                       :nocc_ctyp ctype_value
1641                       :nocc_symb symb
1642                       :nocc_bind bind) ) )
1643       (debug "normbind_anybind kocc=" kocc)
1644       ;; cache the result & return it
1645       (mapobject_put sycmap symb kocc)
1646       (debug "normbind_anybind updated sycmap=" sycmap)
1647       ;; put the const occurrence if needed in the const list of each proc
1648       (foreach_pair_component_in_list
1649        (procs)
1650        (curpair curproc)
1651        (debug "normbind_anybind const curproc=" curproc)
1652        (assert_msg "check curproc" (is_a curproc class_nrep_anyproc) curproc)
1653        (let ( (clcont (instance class_reference :referenced_value kocc))
1654               (constlist (get_field :nrclop_constlist curproc)) )
1655          (debug "normbind_anybind constlist=" constlist)
1656          (foreach_pair_component_in_list
1657           (constlist)
1658           (curpaircl curcl)
1659           (if (== curcl kocc)
1660               (put_fields clcont :referenced_value ())))
1661          (let ( (newcl (get_field :referenced_value clcont)) )
1662            (when newcl 
1663              (debug "normbind_anybind newcl=" newcl)
1664              (list_append constlist newcl))) 
1665          ))
1666       (return kocc)
1667       )))
1668 (install_method class_any_binding normalize_binding normbind_anybind)
1671 ;; normalize local formal bindings
1672 (defun normbind_formalbind (bind env ncx procs psloc)
1673   (assert_msg "check bind" (is_a bind class_formal_binding) bind)
1674   (assert_msg "check env" (is_a env class_environment) env)
1675   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1676   (let ( (sycmap (unsafe_get_field :nctx_symbcachemap ncx))
1677          (symb (unsafe_get_field :binder bind))
1678          (syocc
1679                 (instance class_nrep_locsymocc
1680                           :nrep_loc psloc
1681                           :nocc_ctyp (unsafe_get_field :fbind_type bind) 
1682                           :nocc_symb symb
1683                           :nocc_bind bind) ) 
1684          )
1685           ;; cache the result & return it
1686     (mapobject_put sycmap symb syocc)
1687     (debug "normbind_formalbind updated sycmap=" sycmap 
1688            "\n.. syocc=" syocc "\n.. psloc=" psloc)
1689     syocc
1690     ))
1691 (install_method class_formal_binding  normalize_binding normbind_formalbind)
1693 ;; normalize local let binding
1695 (defun normbind_letbind (bind env ncx procs psloc)
1696   (assert_msg "check bind" (is_a bind class_let_binding) bind)
1697   (assert_msg "check env" (is_a env class_environment) env)
1698   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1699   (let ( (sycmap (unsafe_get_field :nctx_symbcachemap ncx))
1700          (symb (unsafe_get_field :binder bind))
1701          (syocc
1702                 (instance class_nrep_locsymocc
1703                           :nrep_loc psloc
1704                           :nocc_ctyp (unsafe_get_field :fbind_type bind) 
1705                           :nocc_symb symb
1706                           :nocc_bind bind) ) 
1707          )
1708     ;; cache the result & return it
1709     (debug "normbind_letbind bind=" bind "\n.. syocc=" syocc "\n.. psloc=" psloc)
1710     (shortbacktrace_dbg "normbind_letbind" 20)
1711     (mapobject_put sycmap symb syocc)
1712     (debug "normbind_letbind updated sycmap=" sycmap "\n.. syocc=" syocc)
1713     syocc
1714     ))
1715 (install_method class_let_binding  normalize_binding normbind_letbind)
1718 ;;; normalize local fixed binding
1719 (defun normbind_fixbind (bind env ncx procs psloc)
1720   (debug "normbind_fixbind bind=" bind)
1721   (assert_msg "check bind" (is_a bind class_fixed_binding) bind)
1722   (assert_msg "check env" (is_a env class_environment) env)
1723   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1724   (let ( (sycmap  (unsafe_get_field :nctx_symbcachemap ncx))
1725          (symb (unsafe_get_field :binder bind))
1726          (fixdat (unsafe_get_field :fixbind_data bind))
1727          )
1728     (debug "normbind_fixbind fixdat=" fixdat "\n.. psloc=" psloc)
1729     (when (null fixdat)
1730       (debug "normbind_fixbind strange bind=" bind)
1731       (error_at psloc "unresolved forward fixed reference to $1"
1732                   (unsafe_get_field :named_name symb)
1733                   )
1734       )
1735     (assert_msg "normbind_fixbind check fixdat" (is_a fixdat class_nrep_bound_data) fixdat)
1736     ;; cache the result & return it
1737     (mapobject_put sycmap symb fixdat)
1738     (debug "normbind_fixbind updated sycmap=" sycmap " symb=" symb " fixdat=" fixdat "\n.. psloc=" psloc)
1739     fixdat))
1740 (install_method class_fixed_binding  normalize_binding normbind_fixbind)
1743 ;; normalize a define-d binding
1744 (defun normbind_definedvalbind (bind env ncx procs psloc)
1745   (debug "normbind_definedvalbind bind=" bind " psloc=" psloc)
1746   (assert_msg "check bind" (is_a bind class_defined_value_binding) bind)
1747   (assert_msg "check env" (is_a env class_environment) env)
1748   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1749   (let ( (sycmap  (unsafe_get_field :nctx_symbcachemap ncx))
1750          (symb (unsafe_get_field :binder bind))
1751          (curproc (get_field :nctx_curproc ncx))
1752          (syconst (instance class_nrep_defined_constant
1753                             :nrep_loc psloc
1754                             :nconst_sval symb
1755                             :nconst_data ()
1756                             :nconst_proc curproc
1757                             :nconst_defbind bind
1758                             ))
1759          )
1760     (debug "normbind_definedvalbind ncx=" ncx
1761            "\n env=" env " procs=" procs)
1762     ;; cache the result & return it
1763     (mapobject_put sycmap symb syconst)
1764     (put_fields bind :fixbind_data syconst)
1765     (debug "normbind_definedvalbind updated sycmap=" sycmap " syconst=" syconst 
1766            "\n.. bind=" bind "\n.. psloc=" psloc)
1767     (if (is_non_empty_list procs)
1768         (assert_msg "normbind_definedvalbind check no procs" () procs)
1769     (return syconst)
1770     )))
1771 (install_method class_defined_value_binding normalize_binding normbind_definedvalbind)
1775 ;; normalize defined macro binding
1776 (defun normbind_defmacrobind (bind env ncx procs psloc)
1777   (debug "normbind_defmacrobind bind=" bind "\n.. env=" env "\n.. ncx=" debug_less ncx 
1778          "\n.. procs=" debug_less procs "\n.. psloc=" psloc)
1779   (shortbacktrace_dbg "normbind_defmacrobind" 12)
1780   (assert_msg "check bind" (is_a bind class_defined_macro_binding) bind)
1781   (assert_msg "check env" (is_a env class_environment) env)
1782   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1783   (let ( (sycmap  (unsafe_get_field :nctx_symbcachemap ncx))
1784          (symb (unsafe_get_field :binder bind))
1785          (curproc (get_field :nctx_curproc ncx))
1786          (modctx (get_field :nctx_modulcontext ncx))
1787          (mdata (get_field :mbind_data bind))
1788          )
1789     (debug "normbind_defmacrobind mdata=" mdata)
1790     (when (is_non_empty_list procs)
1791       (assert_msg "normbind_defmacrobind bad procs" () procs))
1792     (when (is_not_a mdata class_nrep_dataclosure)
1793       (error_at psloc "insane use of undefined or ill-defined macro $1; macro uses should be operator-like." (get_field :named_name symb))
1794       (assert_msg "normbind_defmacrobind bad macro data while bootstrapping" 
1795                   (not (melt_is_bootstrapping)) 
1796                   mdata bind (discrim bind))
1797       (return)
1798       )
1799     (mapobject_put sycmap symb mdata)
1800     (return mdata)
1801     ))
1802 (install_method class_defined_macro_binding normalize_binding normbind_defmacrobind)
1806 ;; normalize local constructed binding
1807 (defun normbind_constructbind (bind env ncx procs psloc)
1808   (assert_msg "check bind" (is_a bind class_normal_constructor_binding) bind)
1809   (assert_msg "check env" (is_a env class_environment) env)
1810   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1811   (let ( (sycmap  (unsafe_get_field :nctx_symbcachemap ncx))
1812          (symb (unsafe_get_field :binder bind))
1813          (nletrec (get_field :nconsb_nletrec bind))
1814          )
1815           (debug "normbind_constructbind nletrec" nletrec)
1816           (assert_msg "normbind_constructbind  check nletrec" (is_a nletrec class_nrep_letrec) nletrec)
1817           (let ( (nlocsyms (get_field :nletrec_locsyms nletrec))
1818                  (ourlocsym ())
1819                  )
1820             (debug "normbind_constructbind nlocsyms" nlocsyms)
1821             ;; find the right locsym in nlocsyms and cache it
1822             (foreach_in_multiple
1823              (nlocsyms)
1824              (curlocsym :long syix)
1825              (when (== (get_field :nocc_bind curlocsym) bind)
1826                    (setq syix -9999)    ;to exit the loop [-1 don't work!]
1827                    (setq ourlocsym curlocsym))
1828              )
1829             (debug "normbind_constructbind ourlocsym" ourlocsym)
1830             (assert_msg "normbind_constructbind should have ourlocsym"
1831                         (is_a ourlocsym class_nrep_locsymocc) ourlocsym)
1832             ;; cache the result & return it
1833             (mapobject_put sycmap symb ourlocsym)
1834             (debug "normbind_constructbind updated sycmap=" sycmap " symb=" symb " ourlocsym=" ourlocsym)
1835             (return ourlocsym)
1837 (install_method class_normal_constructor_binding normalize_binding normbind_constructbind)
1840 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1841 ;; For symbols which are imported from a previous environment we
1842 ;; should detect them and generate some special data to fetch them, in
1843 ;; the start routine, from the given environment (which is the only
1844 ;; argument to the start routine). Detecting such symbols is easy:
1845 ;; their binding is a class_value_binding
1847 ;;;; normalize a symbol occurrence
1848 (defun normexp_symbol (recv env ncx psloc)
1849   (debug "normexp_symbol recv=" recv 
1850          "\n.. env=" debug_more env
1851          "\n.. ncx=" ncx
1852          "\n.. psloc=" psloc 
1853          )
1854   (shortbacktrace_dbg "normexp_symbol" 32)
1855   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
1856   (assert_msg "check recv" (is_a recv class_symbol) recv)
1857   (multicall
1858    (bind procs gotenv)
1859    (find_enclosing_env env recv)
1860    (debug "normexp_symbol after find_enclosing_env bind=" debug_more bind 
1861           "\n.. procs=" debug_less procs "\n.. gotenv=" debug_more gotenv
1862           "\n.. env=" debug_more env "\n.. recv=" recv)
1863    (assert_msg "normexp_symbol check recv" (is_a recv class_symbol) recv)
1864    (let ( (modctx  (unsafe_get_field :nctx_modulcontext ncx))
1865           (valbindmap (unsafe_get_field :nctx_valbindmap ncx))
1866           (valuelist (unsafe_get_field :nctx_valuelist ncx))
1867           (symbname (get_field :named_name recv))
1868           )
1869      (if (null psloc)
1870          (shortbacktrace_dbg "normex_symbol null psloc" 10)
1871        )
1872      (when (null bind)
1873        (error_at psloc "unknown name $1; symbol is not bound"
1874                    symbname)
1875        (shortbacktrace_dbg "normexp_symbol null bind" 15)
1876        (debug "normexp_symbol bad name recv=" recv "\n.. env=" debug_more env)
1877        (debug "normexp_symbol bad name envprev=" debug_more (get_field :env_prev env))
1878        (debug "normexp_symbol bad name envprev2=" debug_more (get_field :env_prev (get_field :env_prev env)))
1879        (debug "normexp_symbol bad name envprev3=" (get_field :env_prev  (get_field :env_prev (get_field :env_prev env))))
1880        (if (melt_is_bootstrapping)
1881            (assert_msg "@$@normexp_symbol is failing while bootstrapping" () recv env))
1882        (return () ()))
1883      ;;
1884      (if (is_a bind class_normal_magic_binding)
1885          (let ( (magval (get_field :nmagic_value bind))
1886                )
1887            (debug "normexp_symbol magicbind magval=" magval)
1888            (if (is_a magval discr_normalizing_closure)
1889                (multicall
1890                 (nval nbind)
1891                 (magval env ncx psloc)
1892                 (debug "normexp_symbol magicbind nval=" nval " nbind=" nbind)
1893                 (return nval nbind))
1894              (progn
1895                (debug "normexp_symbol magicbind bind=" bind "\n gives magval=" magval)
1896                (return magval ())
1897              ))
1898            ))
1899      ;;
1900      (let ( (sycmap (unsafe_get_field :nctx_symbcachemap ncx))
1901             (syca (mapobject_get sycmap recv)) )
1902        (assert_msg "check sycmap" (is_mapobject sycmap) sycmap)
1903        (debug "normexp_symbol syca=" syca "\n.. for recv=" recv "\n.. bind=" bind)
1904        (cond 
1905         ;; check if in the cache
1906         (syca 
1907          (return syca ()))   ;already cached
1908         ;;
1909         ;; value binding, get/put it into the map
1910         ( (is_a bind class_value_binding)
1911           (let ( (bvar (mapobject_get valbindmap bind)) 
1912                  (val (get_field :vbind_value bind))
1913                  )
1914             (debug "normexp_symbol value bind=" bind 
1915                    "\n.. procs=" procs "\n.. bvar=" bvar "\n.. val=" val)
1916             (if (null bvar)
1917                 (let ( (newbvar 
1918                         (cond ( (is_a modctx class_running_extension_module_context)
1919                                 (let
1920                                     ( (reglitval (register_literal_value val  modctx))
1921                                       (nlitval (instance class_nrep_literalnamedvalue
1922                                                          :nlitval_regval reglitval
1923                                                          :nlitval_symbol recv))
1924                                       )
1925                                   (debug "normexp_symbol nlitval=" nlitval)
1926                                   nlitval
1927                                   )
1928                                 )
1929                               (:else
1930                                (instance class_nrep_importedval
1931                                          :nrep_loc psloc
1932                                          :nimport_symb recv
1933                                          :nimport_sydata (normal_symbol_data recv ncx psloc)))))
1934                        )
1935                   (mapobject_put valbindmap bind newbvar)
1936                   (setq bvar newbvar)
1937                   (list_append valuelist newbvar)
1938                   (debug "normexp_symbol newbvar=" newbvar "\n.. valuelist=" valuelist)
1939                   ))
1940             ;; if procs is a non-empty list, symbol is a "closed"
1941             ;; constant for the value
1942             (debug "normexp_symbol recv=" recv "\n.. procs=" procs)
1943             (if (and (is_list procs)
1944                      (is_pair (list_first procs)))
1945                 (let ( (fxocc
1946                         (instance class_nrep_constocc
1947                                   :nrep_loc psloc
1948                                   :nocc_symb recv
1949                                   :nocc_bind bind
1950                                   :nocc_ctyp ctype_value
1951                                   :ncloc_procs procs))
1952                        )
1953                   ;; cache the result
1954                   (mapobject_put sycmap recv fxocc)
1955                   (debug "normexp_symbol const value fxocc=" fxocc "\n.. recv=" recv
1956                          "\n.. updated sycmap=" sycmap "\n.. procs=" debug_less procs "\n.. for symbname=" symbname)
1957                   ;; put the const occurrence if needed in the const
1958                   ;; list of each proc
1959                   (foreach_pair_component_in_list
1960                    (procs)
1961                    (curpairpro pr)
1962                    (debug "normexp_symbol const symbname=" debug_less symbname " pr=" debug_less pr)
1963                    (assert_msg "check pr" (is_a pr class_nrep_anyproc) pr)
1964                    (cond ( (is_a pr class_nrep_routproc)
1965                            (let ( (clcont
1966                                    (instance class_reference :referenced_value fxocc))
1967                                   (cnstlist (get_field :nrclop_constlist pr)) )
1968                              (debug "normexp_symbol cnstlist=" cnstlist "\n.. pr=" pr "\n.. recv=" recv)
1969                              (foreach_pair_component_in_list
1970                               (cnstlist)
1971                               (curpaircx cx) 
1972                               (when (== cx fxocc)
1973                                 (put_fields clcont :referenced_value ())))
1974                              (let ( (newcl (get_field :referenced_value clcont)) )
1975                                (when newcl 
1976                                  (debug "normexp_symbol newcl=" newcl)
1977                                  (list_append cnstlist newcl))) 
1978                              ))
1979                          ( (is_a pr class_nrep_hookproc)
1980                            (let ( (hkclobindlist (get_field :nrclop_clobindlist pr))
1981                                   (foundbind ())
1982                                   )
1983                              (debug "normexp_symbol hkclobindlist=" hkclobindlist)
1984                              (assert_msg "check hkclobindlist" (is_list hkclobindlist) hkclobindlist)
1985                              (foreach_pair_component_in_list 
1986                               (hkclobindlist)
1987                               (curpairbndhc curbnd)
1988                               (assert_msg "check curbnd" (is_a curbnd class_any_binding) curbnd)
1989                               (if (== curbnd bind) (setq foundbind curbnd)))
1990                              ;; append the new binding if not found
1991                              (when (null foundbind) 
1992                                (list_append hkclobindlist bind)
1993                                (debug "normexp_symbol recv=" recv
1994                                       "\n.. updated hkclobindlist=" hkclobindlist)
1995                                )
1996                              ))
1997                          (:else
1998                           (debug "normexp_symbol unexpected pr=" pr "\n... of discrim: " (discrim pr))
1999                           (assert_msg "normexp_symbol unexpected closing procedure" () pr)
2000                           )
2001                          )
2002                    )                    ;end foreach in procs
2003                   (return fxocc ())
2004                   )
2005               ;; otherwise symbol is the direct value
2006               (progn
2007                 ;; cache the result
2008                 (mapobject_put sycmap recv bvar)
2009                 (debug "normexp_symbol local value bvar=" bvar "\n.. updated sycmap=" sycmap "\n.. symbname=" symbname)
2010                 (return bvar ())
2011                 )
2012               )))
2013         ;;
2014         ;; module variables
2015         ( (is_a bind class_normal_module_variable_binding)
2016           (debug "normexp_symbol variable binding bind=" bind)
2017           (let ( (nmodvar (instance class_nrep_modulevarocc
2018                                    :nmodvar_bind bind))
2019                  )
2020             ;; cache the result
2021             (mapobject_put sycmap recv nmodvar)
2022             (debug "normexp_symbol module variable occurrence nmodvar=" nmodvar  
2023                    "\n.. updated sycmap=" sycmap)
2024             (return nmodvar ())
2025           ))
2026         ;;
2027         ;; the procs is a non-empty list, so the symbol is closed
2028         ( (and (is_list procs)
2029                (is_pair (list_first procs)))
2030           (debug "normexp_symbol closed procs=" procs "\n.. bind=" bind)
2031           ;; check that a closed symbol is always a value
2032           (let ( (bty
2033                   (cond ( (is_a bind class_formal_binding)
2034                           (unsafe_get_field :fbind_type bind) )
2035                         ( (is_a bind class_let_binding)
2036                           (unsafe_get_field :letbind_type bind))
2037                         (:else ()))) 
2038                  )
2039             (if bty 
2040                 (if (!= bty ctype_value)
2041                     (error_at psloc
2042                                 "closed variable $1 has non value ctype $2 (boxing required)"
2043                                 (unsafe_get_field :named_name recv)
2044                                 (get_field :named_name bty)
2045                                 )))
2046             (setq bty ctype_value)
2047             (if (is_a bind class_fixed_binding)
2048                 (let ( (fxocc
2049                         (instance class_nrep_constocc
2050                                   :nrep_loc psloc
2051                                   :nocc_symb recv
2052                                   :nocc_bind bind
2053                                   :nocc_ctyp ctype_value
2054                                   :ncloc_procs procs)) )
2055                   ;; cache the result
2056                   (mapobject_put sycmap recv fxocc)
2057                   (debug "normexp_symbol fxocc=" fxocc " updated sycmap=" sycmap)
2058                   ;; put the const occurrence if needed in the const list of each proc
2059                   (foreach_pair_component_in_list
2060                    (procs)
2061                    (curpairproc curproc)
2062                    (debug "normexp_symbol curproc=" curproc)
2063                    (assert_msg "check curproc" (is_a curproc class_nrep_anyproc) curproc)
2064                    (cond 
2065                     ( (is_a curproc class_nrep_routproc)
2066                       (let ( (clcont
2067                               (instance class_reference :referenced_value fxocc))
2068                              (cnstprocl (get_field :nrclop_constlist curproc)) )
2069                         (foreach_pair_component_in_list
2070                          (cnstprocl)
2071                          (curpairprocl cx) 
2072                          (when (== cx fxocc)
2073                            (put_fields clcont :referenced_value ()) ()))
2074                         (let ( (newcl (get_field :referenced_value clcont)) )
2075                           (when newcl 
2076                             (debug "normexp_symbol newcl=" newcl)
2077                             (list_append cnstprocl newcl))) 
2078                         ))
2079                     ( (is_a curproc class_nrep_hookproc)
2080                       (debug "normexp_symbol curproc=" curproc "\n recv=" recv "\n bind=" bind 
2081                              "\n fxocc=" fxocc)
2082                       (let ( (hkclobindlist (get_field :nrclop_clobindlist curproc))
2083                              (foundbind ())
2084                              )
2085                         (debug "normexp_symbol hkclobindlist=" hkclobindlist)
2086                         (assert_msg "check hkclobindlist" (is_list hkclobindlist) hkclobindlist)
2087                         (foreach_pair_component_in_list 
2088                          (hkclobindlist)
2089                          (curpairbndhc curbnd)
2090                          (assert_msg "check curbnd" (is_a curbnd class_any_binding) curbnd)
2091                          (if (== curbnd bind) (setq foundbind curbnd)))
2092                         (when (null foundbind)
2093                           (list_append hkclobindlist bind)
2094                           (debug "normexp_symbol updated hkclobindlist=" hkclobindlist))
2095                         ))
2096                     ;;
2097                     (:else
2098                      (debug "normexp_symbol bad curproc=" curproc)
2099                      (assert_msg "normexp_symbol unexpected curproc" () curproc)
2100                      ))
2101                    )                    ;end foreach_pair_component_in_list
2102                   (debug "normexp_symbol return fxocc=" fxocc)
2103                   (return fxocc ())
2104                   )
2105               ;; else bind is not a class_fixed_binding
2106               (let ( (clocc 
2107                       (instance class_nrep_closedocc
2108                                 :nrep_loc psloc
2109                                 :nocc_symb recv
2110                                 :nocc_ctyp ctype_value
2111                                 :nocc_bind bind
2112                                 :ncloc_procs procs)) 
2113                      )
2114                 ;; cache the result
2115                 (mapobject_put sycmap recv clocc)
2116                 (debug "normexp_symbol updated sycmap=" sycmap " clocc=" clocc)
2117                 ;; put the closed occurrence if needed in the closed list of each proc
2118                 (foreach_pair_component_in_list  
2119                  (procs)
2120                  (curpair curproc)
2121                  (assert_msg "check curproc" (is_a curproc class_nrep_anyproc) curproc)
2122                  (let ( (clcont (instance class_reference :referenced_value clocc))
2123                         (clobindl (get_field :nrclop_clobindlist curproc)) )
2124                    (foreach_pair_component_in_list 
2125                     (clobindl)
2126                     (curbndpair clbnd) 
2127                     (when (== clbnd bind)
2128                       (put_fields clcont :referenced_value ())))
2129                    (let ( (newcl (get_field :referenced_value clcont)) )
2130                      (if newcl (list_append clobindl bind))) 
2131                    ))
2132                 (return clocc ())
2133                 )))) 
2134         ;;
2135         ;; dispatch the binding
2136         (:else 
2137          (debug "normexp_symbol before normalize_binding bind=" bind " for recv=" recv " psloc=" psloc)
2138          (let ( (resnormbind 
2139                  (normalize_binding bind env ncx procs psloc))
2140                 )
2141            (debug "normexp_symbol after normalize_binding resnormbind=" resnormbind
2142                   " for bind=" bind " recv=" recv " psloc=" psloc)
2143            (return resnormbind ())
2144            )))))))
2146 (install_method class_symbol normal_exp normexp_symbol)
2150 (defun gectyp_symocc (recv env)
2151   (assert_msg "check recv" (is_a recv class_nrep_symocc) recv)
2152   (unsafe_get_field :nocc_ctyp recv)
2153   )
2154 (install_method class_nrep_symocc get_ctype gectyp_symocc)
2158 (defun gectyp_modvarocc (recv env)
2159   (assert_msg "check recv" (is_a recv class_nrep_modulevarocc) recv)
2160   (return ctype_value)
2161   )
2162 (install_method class_nrep_modulevarocc get_ctype gectyp_modvarocc)
2165 ;;; normalize a class - used in particular in normalization of get_field
2166 ;; this does not work well when the class's name is locally rebound,
2167 ;; which rarely happens in practice
2168 (defun normexp_class (recv env ncx psloc)
2169   (debug "normexp_class recv" recv)
2170   (assert_msg "check recv" (is_a recv class_class) recv)
2171   (assert_msg "check env" (is_a env class_environment) env)
2172   (assert_msg "check nctxt" (is_a ncx class_normalization_context) ncx)
2173   (let ( (clasymb (get_symbolstr (unsafe_get_field :named_name recv))) 
2174          (clabind (find_env env clasymb))
2175          )
2176     (debug "normexp_class clabind" clabind)
2177     (cond ( (is_a clabind class_class_binding)
2178             (let ( (normcla (normexp_symbol clasymb env ncx psloc)) )
2179               (debug "normexp_class normcla class data inst" normcla)
2180               (assert_msg "check normcla" 
2181                           (or 
2182                            (is_a normcla class_nrep_datainstance)
2183                            (is_a normcla class_nrep_constocc)
2184                            )
2185                           normcla
2186                           )
2187               (return normcla)
2188               ))
2189           ( (is_a clabind class_value_binding)
2190             (assert_msg "check clabind value" (== recv (unsafe_get_field :vbind_value clabind)) clabind recv)
2191             (let ( (normcla (normexp_symbol clasymb env ncx psloc)) )
2192               (debug "normexp_class normcla class value" normcla)
2193               ;; normcla can be a class_nrep_constocc or a class_nrep_importedval ...
2194               (assert_msg "check normcla" (is_a normcla class_nrep) normcla)
2195               (return normcla)
2196               ))
2197           (:else
2198            ;; this could happen if the class's name has been locally
2199            ;; rebound, But we don't really handle that. We might scan
2200            ;; the environment stack to find the real class binding and
2201            ;; normalize accordingly, but this won't happen often...
2202            (error_at psloc "class $1 incorrectly bound, perhaps locally rebound"_
2203                        (unsafe_get_field :named_name recv))
2204            (debug "normexp_class failed")
2205            (return)
2206            ))
2207     ))
2209 (install_method class_class normal_exp normexp_class)
2212 ;;;;;;;;;;;;;;;;
2213 ;;; normalize a primitive invocation
2214 (defun normexp_primitive (recv env ncx psloc)
2215   (debug "normexp_primitive recv" recv)
2216   (assert_msg "check prim recv" (is_a recv class_source_primitive) recv)
2217   (assert_msg "check env" (is_a env class_environment) env)
2218   (assert_msg "check nctxt" (is_a ncx class_normalization_context) ncx)
2219   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2220          (soper (unsafe_get_field :sprim_oper recv))
2221          (sargs (unsafe_get_field :sargop_args recv)) 
2222          )
2223     (assert_msg "check soper" (is_a soper class_primitive) soper)
2224     (multicall 
2225      (nargs nbind)
2226      (normalize_tuple sargs env ncx sloc)
2227      (let ( (sopnamstr (unsafe_get_field :named_name soper))
2228             (sopformals (unsafe_get_field :prim_formals soper))
2229             (soptype (unsafe_get_field :prim_type soper))
2230             (sopexp (unsafe_get_field :prim_expansion soper)) 
2231             (:long nbarg (multiple_length nargs))
2232             (:long nbexp (multiple_length sopexp))
2233             )
2234        (assert_msg "check soptype" (is_a soptype class_ctype) soptype)
2235        (when (!=i nbarg (multiple_length sopformals))
2236              (error_at sloc "length mismatch between formals & actuals in primitive $1, got $2 arguments for $3 formals"_
2237                          sopnamstr nbarg (multiple_length sopformals))
2238              (return ()))
2239        (let ( (bmap (make_mapobject  discr_map_objects (+i 5 (/iraw (*i 3 nbarg) 2))))
2240               (expargs (make_multiple discr_multiple nbexp))
2241               )
2242          (foreach_in_multiple
2243           (sopformals)
2244           (forb :long ix)
2245           (assert_msg "check forb" (is_a forb class_formal_binding) forb)
2246           (debug "normexp_primitive forb" forb)
2247           (let ( (forarg (unsafe_get_field :binder forb))
2248                  (actarg (multiple_nth nargs ix)) 
2249                  (fortype (unsafe_get_field :fbind_type forb))
2250                  (actype (get_ctype actarg env))
2251                  )
2252             (debug "normexp_primitive actarg=" actarg " actype=" actype)
2253             (when (and (is_a fortype class_ctype)
2254                        (is_a actype class_ctype)
2255                        (!= fortype actype))
2256               (error_at sloc "type mismatch between formal $1 of ctype $2 and argument #$3 of ctype $4 in primitive $5"_
2257                         forarg (get_field :named_name fortype) ix (get_field :named_name actype) sopnamstr)
2258               )
2259             (mapobject_put bmap forarg actarg)
2260             ))
2261          (debug "normexp_primitive bmap in sopexp" bmap)
2262          (foreach_in_multiple
2263           (sopexp)
2264           (excu :long jx)
2265           (let ( (exval
2266                   (if (is_a excu class_symbol)
2267                       (let ( (bval (mapobject_get bmap excu)) )
2268                         (if (null bval) 
2269                             (progn 
2270                               ;; we could perhaps handle symbols which are not primitive arguments
2271                               ;; as some kind of closed constants, but this is rarely needed and
2272                               ;; requires a lot of work: the excu should then be the constant
2273                               ;; itself, and code should be generated to fill the primitive with
2274                               ;; non-symbol values.
2275                               (debug "normexp_primitive recv unexpected symbol in expansion recv=" recv "excu=" excu)
2276                               (error_at sloc "unexpected symbol $1 in primitive $2 expansion"_ 
2277                                         (unsafe_get_field  :named_name excu) sopnamstr)
2278                               ))
2279                         bval)
2280                     excu)) )
2281             (if (null exval)
2282                 (progn
2283                   (warning_strv sloc "null expansion of primitive argument for"
2284                                 sopnamstr)
2285                   (if (is_a excu class_named) 
2286                       (warning_strv sloc "null primitive original piece is"
2287                                     (unsafe_get_field :named_name excu)))
2288                   ))
2289             (multiple_put_nth expargs jx exval))
2290           )
2292          (debug "normexp_primitive soper" soper)
2293          (assert_msg "check soper is named" (is_a soper class_named) soper)
2294          (let ( (csym (clone_symbol soper))
2295                 (nchunk (instance class_nrep_chunk
2296                                            :nrep_loc sloc
2297                                            :nchunk_expansion expargs
2298                                            :nchunk_oper soper
2299                                            :nexpr_ctyp soptype
2300                                            ))
2301                 (cbind (instance class_normal_let_binding
2302                                  :letbind_loc sloc
2303                                  :binder csym
2304                                  :letbind_type soptype 
2305                                  :letbind_expr nchunk
2306                                  )) 
2307                 (clocc (instance class_nrep_locsymocc
2308                                  :nrep_loc sloc
2309                                  :nocc_ctyp soptype
2310                                  :nocc_symb csym
2311                                  :nocc_bind cbind)) 
2312                 )
2313            (debug "normexp_primitive nchunk=" nchunk)
2314            (if (is_list nbind) 
2315                (list_append nbind cbind)
2316              (progn
2317                (setq nbind (make_list discr_list))
2318                (list_append nbind cbind)
2319                ))
2320            (debug "normexp_primitive result clocc" clocc)
2321            (return
2322             clocc
2323             nbind
2324             )))))))
2326 (install_method class_source_primitive normal_exp normexp_primitive)
2328 ;;;;;;;;;;;;;;;;
2329 ;;; normalize a hook call
2330 (defun normexp_hook_call (recv env ncx psloc)
2331   (debug "normexp_hook_call recv=" recv)
2332   (shortbacktrace_dbg "normexp_hook_call" 15)
2333   (assert_msg "check recv" (is_a recv class_source_hook_call) recv)
2334   (assert_msg "check env" (is_a env class_environment) env)
2335   (assert_msg "check nctxt" (is_a ncx class_normalization_context) ncx)
2336   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2337          (shook (unsafe_get_field :shook_called recv))
2338          (sargs (unsafe_get_field :sargop_args recv))
2339          (hkname ())
2340          (hksymb ())
2341          (hkins ())
2342          (hkouts ())
2343          (hkctype ())
2344          (hkdescr ())
2345          (:long errorflag 0)
2346          (newenv (fresh_env env))
2347          )
2348     (debug "normexp_hook_call shook=" shook " sargs=" sargs)
2349     (match shook
2350            (?(instance class_source_defhook
2351                        :sdef_name ?shksymb
2352                        :sformal_args ?shkins
2353                        :shook_ctype ?shctype
2354                        :shook_out_formals ?shkouts)
2355              (setq hksymb shksymb)
2356              (assert_msg "check hksymb" (is_a hksymb class_symbol) hksymb)
2357              (setq hkname (get_field :named_name shksymb))
2358              (setq hkins shkins)
2359              (setq hkouts shkouts)
2360              (setq hkctype shctype)
2361              (debug "normexp_hook_call sourcedefhook hkname=" hkname
2362                     "\n hkins=" hkins "\n hkouts=" hkouts)
2363              )
2364            (?(some_hook_with_data
2365               ?(and ?dhkdescr 
2366                     ?(instance class_hook_descriptor
2367                                :named_name ?dhkname
2368                                :hookdesc_in_formals ?dhkins
2369                                :hookdesc_out_formals ?dhkouts
2370                                :hookdesc_ctype ?dhkctype)))
2371              (assert_msg "check dhkname" (is_string dhkname) dhkname)
2372              (setq hksymb (get_symbolstr dhkname))
2373              (setq hkname dhkname)
2374              (setq hkdescr dhkdescr)
2375              (setq hkins dhkins)
2376              (setq hkouts dhkouts)
2377              (setq hkctype dhkctype)
2378              (debug "normexp_hook_call valuehook hkname=" hkname
2379                     "\n.. hkins=" hkins
2380                     "\n.. hkouts=" hkouts
2381                     "\n.. hkctype=" hkctype)
2382              )
2383            (?_
2384             (error_at sloc "invalid hook call")
2385             (setq errorflag 1)
2386             (assert_msg "@$@unexpected hook, unimplemented" () shook)
2387             ))
2388     (assert_msg "check hkname" (is_string hkname) hkname)
2389     (assert_msg "check hkins" (is_multiple hkins) hkins)
2390     (assert_msg "check hkouts" (is_multiple hkouts) hkouts)
2391     (assert_msg "check hkctype" (is_a hkctype class_ctype) hkctype)
2392     (debug "normexp_hook_call hkname=" hkname " hksymb=" hksymb 
2393            "\n.. hkins=" hkins 
2394            "\n.. hkouts=" hkouts "\n.. hkctype=" hkctype)
2395     (assert_msg "check hkctype" (is_a hkctype class_ctype) hkctype)
2396     (let ( (:long nbins (multiple_length hkins))
2397            (:long nbouts (multiple_length hkouts))
2398            (hnamestr (get_field :named_name hkname))
2399            (sins (make_multiple discr_multiple nbins))
2400            (souts (make_multiple discr_multiple nbouts))
2401            (nouts (make_multiple discr_multiple nbouts))
2402            (hkbind (find_env env hksymb))
2403            )
2404       (debug "normexp_hook_call hkbind=" hkbind "\n hksymb=" hksymb)
2405       (assert_msg "check hkbind" (is_object hkbind) hkbind)
2406       (when (!=i (multiple_length sargs) (+i nbins nbouts))
2407         (error_at sloc "invalid operand arity $1 for hook call '$2' wanting #$3 inputs and #$4 outputs"_ 
2408                   (multiple_length sargs) hnamestr nbins nbouts)
2409         (return () ()))
2410       ;; extract and normalize the inputs
2411       (foreach_long_upto
2412        (0 (-i nbins 1))
2413        (:long inix)
2414        (multiple_put_nth sins inix (multiple_nth sargs inix))
2415        )
2416       (debug "normexp_hook_call sins=" sins)
2417       (multicall 
2418        (ninargs ninbinds)
2419        (normalize_tuple sins env ncx sloc)
2420        (debug "normexp_hook_call ninargs=" ninargs " ninbinds=" ninbinds)
2421        (if (null ninbinds)
2422            (setq ninbinds (make_list discr_list)))
2423        (foreach_pair_component_in_list
2424         (ninbinds)
2425         (curpair curinbind)
2426         (put_env newenv curinbind)
2427         )
2428        ;; check type compatibility of inputs
2429        (foreach_in_multiple
2430         (ninargs)
2431         (curinarg :long inix)
2432         (let ( (curinbind (multiple_nth hkins inix))
2433                (inbctyp (get_field :fbind_type curinbind))
2434                (inbinder (get_field :binder curinbind))
2435                (curinctyp (get_ctype curinarg newenv))
2436                )
2437           (debug "normexp_hook_call curinbind=" curinbind 
2438                  "\n curinarg=" curinarg "\n inix#" inix 
2439                  "\n inbctyp=" inbctyp "\n curinctyp=" curinctyp)
2440           (assert_msg "check inbctyp" (is_a inbctyp class_ctype) inbctyp)
2441           (assert_msg "check curinctyp" (is_a curinctyp class_ctype) curinctyp)
2442           (when (!= inbctyp curinctyp)
2443             (error_at sloc "type mismatch between input formal $1 of ctype $2 & argument #$3 of ctype $4 in hook call $5"
2444                         (get_field :named_name inbinder) (get_field :named_name inbctyp) 
2445                         inix (get_field :named_name curinctyp) hnamestr)
2446             (setq errorflag 1)
2447             )
2448           ))
2449        (debug "normexp_hook_call errorflag=" errorflag " after checking ninargs=" ninargs)
2450        ;;
2451        ;; extract and normalize the outputs
2452        (foreach_long_upto
2453         (0 (-i nbouts 1))
2454         (:long outix)
2455         (let ( (curoutarg (multiple_nth sargs (+i outix nbins)))
2456                (curoutbind (multiple_nth hkouts outix))
2457                (outbctyp (get_field :fbind_type curoutbind))
2458                (outbinder (get_field :binder curoutbind))
2459                )
2460           (debug "normexp_hook_call curoutarg=" curoutarg
2461                  "\n curoutbind=" curoutbind "\n outix#" outix)
2462           (multiple_put_nth souts outix curoutarg)
2463           (cond 
2464            ( (is_a curoutarg class_symbol)
2465              (let ( (noutvar (normexp_symbol curoutarg env ncx sloc)) 
2466                     (varoutctyp (get_ctype noutvar env))
2467                     )
2468                (debug "normexp_hook_call noutvar=" noutvar " varoutctyp=" varoutctyp)
2469                (when (is_not_a noutvar class_nrep_locsymocc)
2470                  (error_at sloc "invalid output variable $1 for hook $2"_ (get_field :named_name curoutarg) hnamestr)
2471                  (setq errorflag 1))             
2472                (assert_msg "check varoutctyp" (is_a varoutctyp class_ctype) varoutctyp)
2473                (when (!= varoutctyp outbctyp)
2474                  (error_at sloc "incompatible output formal $1 ctype $2 expecting $3 for hook $4"_ 
2475                            (get_field :named_name outbinder) 
2476                            (get_field :named_name varoutctyp) 
2477                            (get_field :named_name outbctyp) hnamestr)
2478                  (setq errorflag 1)
2479                  )
2480                (multiple_put_nth nouts outix noutvar)
2481                ))
2482            (:else
2483             (error_at sloc "hook output argument is not a symbol for formal output $1 of hook $2" (unsafe_get_field :named_name outbinder) hnamestr)
2484             (setq errorflag 1)
2485             ))
2486           ))
2487        (debug "normexp_hook_call  errorflag=" errorflag " souts=" souts " nouts=" nouts)
2488        (if errorflag 
2489            (return () ()))
2490        ;;
2491        (debug "normexp_hook_call hksymb=" hksymb "\n hkbind=" hkbind)
2492        (let (
2493              (nhook (normexp_symbol hksymb env ncx sloc))
2494              (nhkcall (instance class_nrep_hook_call
2495                                 :nrep_loc sloc
2496                                 :nexpr_ctyp hkctype
2497                                 :nhook_name hkname
2498                                 :nhook_called nhook
2499                                 :nexpr_args ninargs
2500                                 :nhook_outs nouts
2501                                 :nhook_descr hkdescr
2502                                 ))
2503              )
2504          (debug "normexp_hook_call nhkcall=" nhkcall "\n.. nhook=" nhook 
2505                 "\n.. hksymb=" hksymb "\n .. hkdescr=" hkdescr)
2506          (let ( (csym (clone_symbol hksymb))
2507                 (cbind (instance class_normal_let_binding
2508                                  :letbind_loc sloc
2509                                  :binder csym
2510                                  :letbind_type hkctype
2511                                  :letbind_expr nhkcall
2512                                  )) 
2513                 (clocc (instance class_nrep_locsymocc
2514                                  :nrep_loc sloc
2515                                  :nocc_ctyp hkctype
2516                                  :nocc_symb csym
2517                                  :nocc_bind cbind)) 
2518                 )
2519            (debug "normexp_hook_call cbind=" cbind " clocc=" clocc)
2520            (list_append ninbinds cbind)
2521            (debug "normexp_hook_call result clocc=" clocc 
2522                   " ninbinds=" ninbinds)
2523            (return clocc ninbinds)
2524            ))))))
2525 (install_method class_source_hook_call normal_exp normexp_hook_call)
2528 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2529 ;;;; normalize boxes
2532 ;;; mutable boxes
2533 (defun normexp_box (recv env ncx psloc)
2534   (debug "normexp_box recv" recv)
2535   (assert_msg "check box recv" (is_a recv class_source_box) recv)
2536   (assert_msg "check env" (is_a env class_environment) env)
2537   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
2538   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2539          (sboxed (get_field :sboxed recv))
2540          )
2541     (multicall 
2542      (nboxed nbind)
2543      (normal_exp sboxed env ncx sloc)
2544      (debug "normexp_box nboxed=" nboxed " nbind=" nbind)
2545      (when (not (is_list nbind))
2546        (setq nbind (list))
2547        (debug "normexp_box set nbind=" nbind))
2548      (let ( (nctyp (get_ctype nboxed env))
2549             (autoboxdiscr (get_field :ctype_autoboxdiscr nctyp))
2550             )
2551        (assert_msg "normexp_box check nctyp" (is_a nctyp class_ctype) nctyp)
2552        (debug "normexp_box nctyp=" nctyp " autoboxdiscr=" autoboxdiscr)
2553        (when (is_not_a autoboxdiscr class_discriminant)
2554          (error_at sloc "non-BOX-able stuff of ctype $1"
2555                      (get_field :named_name nctyp))
2556          (return))
2557        (let (
2558              (boxer
2559               (cond
2560                ( (== nctyp ctype_value)
2561                  (setq autoboxdiscr ())
2562                  '"/*boxvalue*/ meltgc_new_reference"
2563                  )
2564                ( (is_a nctyp class_ctype_plain)
2565                  (let ( (boxing (get_field :ctypp_boxing nctyp))
2566                         )
2567                    boxing
2568                    ))
2569                ( (is_a nctyp class_ctype_gty)
2570                  (let ( (boxfun (get_field :ctypg_boxfun nctyp))
2571                         )
2572                    boxfun
2573                    ))
2574                (:else
2575                 (error_at sloc "unexpected ctype $1 for BOX"
2576                             (get_field :named_name nctyp))))
2577               )
2578              )
2579          (debug "normexp_box boxer=" boxer)
2580          (let ( 
2581                (csym (clone_symbol 'box))
2582                (nchunk (instance class_nrep_chunk
2583                                  :nrep_loc sloc
2584                                  :nchunk_oper 'box
2585                                  :nexpr_ctyp ctype_value
2586                                  :nchunk_expansion
2587                                  (if autoboxdiscr
2588                                      (let 
2589                                          ( (predefdiscr
2590                                             (normal_predef autoboxdiscr ncx sloc
2591                                                            "autoboxing discriminant"))
2592                                            )
2593                                        (tuple
2594                                         (clone_with_discriminant '"/*full boxing*/ " discr_verbatim_string)
2595                                         (clone_with_discriminant boxer discr_verbatim_string)
2596                                         (clone_with_discriminant '"((meltobject_ptr_t) (" discr_verbatim_string)
2597                                         predefdiscr
2598                                         (clone_with_discriminant '"), (" discr_verbatim_string)
2599                                         nboxed
2600                                         (clone_with_discriminant '"))" discr_verbatim_string)
2601                                         ))
2602                                    (tuple
2603                                         (clone_with_discriminant '"/*short boxing*/ " discr_verbatim_string)
2604                                     (clone_with_discriminant boxer discr_verbatim_string)
2605                                     (clone_with_discriminant '"(" discr_verbatim_string)
2606                                     nboxed
2607                                     (clone_with_discriminant '")" discr_verbatim_string)
2608                                     )
2609                                    )))
2610                (cbind (instance class_normal_let_binding
2611                                 :letbind_loc sloc
2612                                 :binder csym
2613                                 :letbind_type ctype_value
2614                                 :letbind_expr nchunk
2615                                 ))
2616                (clocc (instance class_nrep_locsymocc
2617                                 :nrep_loc sloc
2618                                 :nocc_ctyp ctype_value
2619                                 :nocc_symb csym
2620                                 :nocc_bind cbind))
2621                )
2622            (debug "normexp_box nchunk=" nchunk " clocc="  clocc)
2623            (list_append nbind cbind)
2624            (debug "normexp_box return clocc=" clocc " nbind=" nbind)
2625            (return clocc nbind)
2626            ))))))
2627 (install_method class_source_box normal_exp normexp_box)
2630 ;;; constant boxes
2631 (defun normexp_constbox (recv env ncx psloc)
2632   (debug "normexp_box recv" recv)
2633   (assert_msg "check box recv" (is_a recv class_source_constant_box) recv)
2634   (assert_msg "check env" (is_a env class_environment) env)
2635   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
2636   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2637          (sboxed (get_field :sboxed recv))
2638          )
2639     (multicall 
2640      (nboxed nbind)
2641      (normal_exp sboxed env ncx sloc)
2642      (debug "normexp_constbox nboxed=" nboxed " nbind=" nbind)
2643      (when (not (is_list nbind))
2644        (setq nbind (list))
2645        (debug "normexp_constbox set nbind=" nbind))
2646      (let ( (nctyp (get_ctype nboxed env))
2647             (autoboxdiscr (get_field :ctype_autoconstboxdiscr nctyp))
2648             )
2649        (assert_msg "normexp_constbox check nctyp" (is_a nctyp class_ctype) nctyp)
2650        (debug "normexp_constbox nctyp=" nctyp " autoboxdiscr=" autoboxdiscr)
2651        (when (is_not_a autoboxdiscr class_discriminant)
2652          (error_at sloc "non-CONSTANT_BOX-able stuff of ctype $1"
2653                      (get_field :named_name nctyp))
2654          (return))
2655        (let (
2656              (boxer
2657               (cond
2658                ( (is_a nctyp class_ctype_plain)
2659                  (let ( (boxing (get_field :ctypp_boxing nctyp))
2660                         )
2661                    boxing
2662                    ))
2663                ( (is_a nctyp class_ctype_gty)
2664                  (let ( (boxfun (get_field :ctypg_boxfun nctyp))
2665                         )
2666                    boxfun
2667                    ))
2668                (:else
2669                 (error_at sloc "unexpected ctype $1 for BOX"_
2670                             (get_field :named_name nctyp))))
2671               )
2672              )
2673          (debug "normexp_box boxer=" boxer)
2674          (let ( 
2675                (csym (clone_symbol 'box))
2676                (nchunk (instance class_nrep_chunk
2677                                  :nrep_loc sloc
2678                                  :nchunk_oper 'box
2679                                  :nexpr_ctyp ctype_value
2680                                  :nchunk_expansion
2681                                  (if autoboxdiscr
2682                                      (let 
2683                                          ( (predefdiscr
2684                                             (normal_predef autoboxdiscr ncx sloc
2685                                                            "autoconstboxing discriminant"))
2686                                            )
2687                                        (tuple
2688                                         (clone_with_discriminant '"/*full constboxing*/ " discr_verbatim_string)
2689                                         (clone_with_discriminant boxer discr_verbatim_string)
2690                                         (clone_with_discriminant '"((meltobject_ptr_t) (" discr_verbatim_string)
2691                                         predefdiscr
2692                                         (clone_with_discriminant '"), (" discr_verbatim_string)
2693                                         nboxed
2694                                         (clone_with_discriminant '"))" discr_verbatim_string)
2695                                         ))
2696                                    (tuple
2697                                         (clone_with_discriminant '"/*short constboxing*/ " discr_verbatim_string)
2698                                     (clone_with_discriminant boxer discr_verbatim_string)
2699                                     (clone_with_discriminant '"(" discr_verbatim_string)
2700                                     nboxed
2701                                     (clone_with_discriminant '")" discr_verbatim_string)
2702                                     )
2703                                    )))
2704                (cbind (instance class_normal_let_binding
2705                                 :letbind_loc sloc
2706                                 :binder csym
2707                                 :letbind_type ctype_value
2708                                 :letbind_expr nchunk
2709                                 ))
2710                (clocc (instance class_nrep_locsymocc
2711                                 :nrep_loc sloc
2712                                 :nocc_ctyp ctype_value
2713                                 :nocc_symb csym
2714                                 :nocc_bind cbind))
2715                )
2716            (debug "normexp_constbox nchunk=" nchunk " clocc="  clocc)
2717            (list_append nbind cbind)
2718            (debug "normexp_constbox return clocc=" clocc " nbind=" nbind)
2719            (return clocc nbind)
2720            ))))))
2721 (install_method class_source_constant_box normal_exp normexp_constbox)
2725 ;;;  unboxing
2726 (defun normexp_unbox (recv env ncx psloc)
2727   (debug "normexp_unbox recv" recv)
2728   (assert_msg "check unbox recv" (is_a recv class_source_unbox) recv)
2729   (assert_msg "check env" (is_a env class_environment) env)
2730   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
2731   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2732          (sexp (get_field :sunbox_expr recv))
2733          (ctyp (get_field :sunbox_ctype recv))
2734          (cname (get_field :ctype_cname ctyp))
2735          )
2736     (debug "normexp_unbox ctyp=" ctyp)
2737     (assert_msg "check ctyp" (is_a ctyp class_ctype) ctyp)
2738     (let ( (unboxer 
2739             (cond ( (is_a ctyp class_ctype_plain)
2740                     (get_field :ctypp_unboxing ctyp))
2741                   ( (is_a ctyp class_ctype_gty)
2742                     (get_field :ctypg_unboxfun ctyp))
2743                   (:else
2744                    (error_at sloc "unexpected ctype $1 for UNBOX" 
2745                              (get_field :named_name ctyp))
2746                    (return))))
2747            )
2748       (debug "normexp_unbox unboxer=" unboxer " cname=" cname)
2749       (multicall 
2750        (nexp nbind)
2751        (normal_exp sexp env ncx sloc)
2752        (debug "normexp_unbox nexp=" nexp " nbind=" nbind)
2753        (when (not (is_list nbind))
2754          (setq nbind (list))
2755          (debug "normexp_unbox set nbind=" nbind))
2756        (let (
2757              (csym (clone_symbol 'unbox))
2758              (nchunk 
2759               (instance class_nrep_chunk
2760                         :nrep_loc sloc
2761                         :nchunk_oper 'unbox
2762                         :nexpr_ctyp ctyp
2763                         :nchunk_expansion
2764                         (tuple
2765                          (clone_with_discriminant '"/*unboxing*/ " discr_verbatim_string)
2766                          (clone_with_discriminant unboxer discr_verbatim_string)
2767                          (clone_with_discriminant '" ((melt_ptr_t)" discr_verbatim_string)
2768                          nexp
2769                          (clone_with_discriminant '")" discr_verbatim_string)
2770                          )))
2771              (cbind (instance class_normal_let_binding
2772                               :letbind_loc sloc
2773                               :binder csym
2774                               :letbind_type ctyp
2775                               :letbind_expr nchunk
2776                               ))
2777              (clocc (instance class_nrep_locsymocc
2778                               :nrep_loc sloc
2779                               :nocc_ctyp ctyp
2780                               :nocc_symb csym
2781                               :nocc_bind cbind))
2782              )
2783          (debug "normexp_unbox nchunk=" nchunk " clocc="  clocc)
2784          (list_append nbind cbind)
2785          (debug "normexp_unbox return clocc=" clocc " nbind=" nbind)
2786          (return clocc nbind)
2787          )))))
2788 (install_method class_source_unbox normal_exp normexp_unbox)
2791 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2792 ;;; normalize a code_chunk
2793 (defun normexp_code_chunk (recv env ncx psloc)
2794   (debug "normexp_code_chunk recv=" recv)
2795   (assert_msg "check code_chunk recv" (is_a recv class_source_codechunk) recv)
2796   (assert_msg "check env" (is_a env class_environment) env)
2797   (assert_msg "check nctxt" (is_a ncx class_normalization_context) ncx)
2798   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2799          (schk (unsafe_get_field :sch_chunks recv))
2800          (gsym (unsafe_get_field :sch_gensym recv))
2801          (csym (clone_symbol gsym))
2802          (bindlist (make_list discr_list))
2803          (newenv (fresh_env env))
2804          (csymstr 
2805           (let ( (sbuf (make_strbuf discr_strbuf)) )
2806             (add2sbuf_cident sbuf (get_field :named_name csym))
2807             (add2sbuf_strconst sbuf "__")
2808             (add2sbuf_longdec sbuf (get_int (get_field :csym_urank csym)))
2809             (strbuf2string discr_verbatim_string sbuf)
2810             ))
2811          (magicbind (let ( (mb (instance class_normal_magic_binding
2812                                          :binder gsym
2813                                          :nmagic_value csymstr))
2814                            )
2815                       (put_env newenv mb)
2816                       (debug "normexp_code_chunk magicbind=" mb)
2817                       mb))
2818          (nchk (let ( (nc 
2819                        (multiple_map 
2820                         schk
2821                         (lambda (curcomp :long curix)
2822                           (cond
2823                            ( (is_string curcomp)
2824                              (clone_with_discriminant curcomp discr_verbatim_string))
2825                            ( (is_a curcomp class_symbol)
2826                              (normal_exp curcomp newenv ncx sloc))
2827                            (:else
2828                             (debug "normexp_code_chunk curcomp=" curcomp " curix#" curix)
2829                             (multicall
2830                              (nexp nbind)
2831                              (normal_exp curcomp newenv ncx sloc)
2832                              (debug "normexp_code_chunk nexp=" nexp "\n.. nbind=" nbind)
2833                              (assert_msg "check nbind" (is_list_or_null nbind) nbind)
2834                              (let ( (compctyp (get_ctype nexp newenv))
2835                                     (cloc (or (get_field :loca_location curcomp) sloc))
2836                                     )
2837                                (debug "normexp_code_chunk compctyp=" compctyp)
2838                                (when (!= compctyp ctype_void)
2839                                  (error_at cloc
2840                                              "composite CODE_CHUNK element should be :void, got $1"
2841                                              (get_field :named_name compctyp))
2842                                  (return ())
2843                                  )
2844                                (let ( (wl (wrap_normal_let1 nexp nbind sloc))
2845                                       )
2846                                  (debug "normexp_code_chunk wl=" wl " curix#" curix)
2847                                  wl)))))))))
2848                  (debug "normexp_code_chunk nchk=" nc)
2849                  nc))
2850          (cbind (instance class_normal_let_binding
2851                           :letbind_loc sloc
2852                           :binder csym
2853                           :letbind_type ctype_void
2854                           :letbind_expr 
2855                           (instance class_nrep_chunk
2856                                     :nrep_loc sloc
2857                                     :nchunk_expansion nchk
2858                                     :nchunk_oper csym
2859                                     :nexpr_ctyp ctype_void
2860                                     ))) 
2861          (clocc (instance class_nrep_locsymocc
2862                           :nrep_loc sloc
2863                           :nocc_ctyp ctype_void
2864                           :nocc_symb csym
2865                           :nocc_bind cbind)) 
2866          )
2867     (debug "normexp_code_chunk schk=" schk "\n.. nchk=" nchk)
2868     (debug "normexp_code_chunk clocc=" clocc)
2869     (assert_msg "check nchk" (is_multiple nchk) nchk)
2870     (debug "normexp_code_chunk return clocc=" clocc " cbind=" cbind)
2871     (return clocc (list cbind))
2872     ))
2873 (install_method class_source_codechunk normal_exp normexp_code_chunk)
2875 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2876 ;;; normalize an expr_chunk
2877 (defun normexp_expr_chunk (recv env ncx psloc)
2878   (debug "normexp_expr_chunk recv=" recv)
2879   (assert_msg "check expr_chunk recv" (is_a recv class_source_exprchunk) recv)
2880   (assert_msg "check env" (is_a env class_environment) env)
2881   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
2882   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2883          (schk (unsafe_get_field :sch_chunks recv))
2884          (gsym (unsafe_get_field :sch_gensym recv))
2885          (ctyp (unsafe_get_field :sxch_ctype recv))
2886          (csym (clone_symbol gsym))
2887          (bindlist (make_list discr_list))
2888          (newenv (fresh_env env))
2889          (csymstr 
2890           (let ( (sbuf (make_strbuf discr_strbuf)) )
2891             (add2sbuf_cident sbuf (get_field :named_name csym))
2892             (add2sbuf_strconst sbuf "__")
2893             (add2sbuf_longdec sbuf (get_int (get_field :csym_urank csym)))
2894             (strbuf2string discr_verbatim_string sbuf)
2895             ))
2896          (magicbind (let ( (mb (instance class_normal_magic_binding
2897                                          :binder gsym
2898                                          :nmagic_value csymstr))
2899                            )
2900                       (put_env newenv mb)
2901                       (debug "normexp_expr_chunk magicbind=" mb)
2902                       mb))
2903          (listbinds (make_list discr_list))
2904          (listnchunks (make_list discr_list))
2905          (nchk (make_multiple discr_multiple (multiple_length schk)))
2906          )
2907     (debug "normexp_expr_chunk ctyp=" ctyp "\n schk=" schk)
2908     (assert_msg "check schk" (is_multiple schk) schk)
2909     (assert_msg "check ctyp" (is_a ctyp class_ctype) ctyp)
2910     (foreach_in_multiple 
2911      (schk)
2912      (srcomp :long six)
2913      (debug "normexp_expr_chunk six#" six " srcomp=" srcomp)
2914      (cond ( (is_a srcomp class_source)
2915              (multicall 
2916               (ncomp ncbind)
2917               (normal_exp srcomp newenv ncx sloc)
2918               (debug "normexp_expr_chunk six#" six " ncomp=" ncomp "\n.. ncbind=" ncbind)
2919               (assert_msg "check ncbind" (is_list_or_null ncbind) ncbind)
2920               (if ncbind (list_append2list listbinds ncbind))
2921               (if (is_list ncomp)
2922                   (list_append2list listnchunks ncomp)
2923                 (list_append listnchunks ncomp))
2924               ))
2925            ( (is_a srcomp class_symbol)
2926              (multicall 
2927               (nsymb nsbind)
2928               (normal_exp srcomp newenv ncx sloc)
2929               (debug "normexp_expr_chunk nsymb=" nsymb " nsbind=" nsbind)
2930               (assert_msg "nsbind null" (null nsbind) nsbind)
2931               (list_append listnchunks nsymb)
2932              ))
2933            ( (is_string srcomp)
2934              (list_append listnchunks (make_string discr_verbatim_string srcomp))
2935              )
2936            (:else
2937             (list_append listnchunks srcomp)
2938             ))
2939      (debug "normexp_expr_chunk six#" six "\n updated listbinds=" listbinds
2940             "\n updated listnchunks=" listnchunks)
2941      )
2942     ;; end foreach_in_multiple
2943     (let ( (tupnchunk (list_to_multiple listnchunks discr_multiple))
2944            (nchunk (instance class_nrep_chunk
2945                              :nrep_loc sloc
2946                              :nchunk_expansion tupnchunk
2947                              :nchunk_oper csym
2948                              :nexpr_ctyp ctyp))
2949            (cbind  (instance class_normal_let_binding
2950                              :letbind_loc sloc
2951                              :binder csym
2952                              :letbind_type ctyp
2953                              :letbind_expr nchunk))
2954            (clocc (instance class_nrep_locsymocc
2955                             :nrep_loc sloc
2956                             :nocc_ctyp ctyp
2957                             :nocc_symb csym
2958                             :nocc_bind cbind)) 
2959            )
2960       (list_append listbinds cbind)
2961       (debug "normexp_expr_chunk with nchunk=" nchunk " gives clocc=" clocc " listbinds=" listbinds)
2962       (return clocc listbinds)
2963       ))) 
2964 (install_method class_source_exprchunk normal_exp normexp_expr_chunk)
2966 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2967 ;;; normalize a cmatchexpr
2968 (defun normexp_cmatchexpr (recv env ncx psloc)
2969   (debug "normexp_cmatchexpr recv" recv)
2970   (assert_msg "check recv" (is_a recv class_source_cmatchexpr) recv)
2971   (assert_msg "check env" (is_a env class_environment) env)
2972   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
2973   (let ( (sloc (unsafe_get_field :loca_location recv)) 
2974          (scmat (unsafe_get_field :scmatx_cmatcher recv))
2975          (sargs (unsafe_get_field :sargop_args recv)) 
2976          )
2977     (assert_msg "check scmat" (is_a scmat class_cmatcher) scmat)
2978     (multicall 
2979      (nargs nbind)
2980      (normalize_tuple sargs env ncx sloc)
2981      (let ( (cmanamstr (unsafe_get_field :named_name scmat))
2982             ;; the outformals are really the "input" arguments for cmatchexpr
2983             (oformals (unsafe_get_field :amatch_out scmat))
2984             ;; the matchbind gives the result of the cmatchexpr
2985             (mabind (let ( (mb (unsafe_get_field :amatch_matchbind scmat)) )
2986                       (assert_msg "check mabind" (is_a mb class_formal_binding) mb)
2987                       mb))
2988             ;; the type of the cmatchexpr
2989             (otype (unsafe_get_field :fbind_type mabind))
2990             (sopexp (unsafe_get_field :cmatch_expoper scmat)) 
2991             (:long nbarg (multiple_length nargs))
2992             (:long nbexp (multiple_length sopexp))
2993             )
2994        (assert_msg "check otype" (is_a otype class_ctype) otype)
2995        (if (!=i nbarg (multiple_length oformals))
2996            (progn
2997              (error_at sloc "length mismatch between formals & actuals in cmatch $1 expr" 
2998                          cmanamstr)
2999              (return))
3000          )
3001        (let ( (bmap (make_mapobject  discr_map_objects (+i 5 (/iraw (*i 3 nbarg) 2))))
3002               (expargs (make_multiple discr_multiple nbexp))
3003               )
3004          (multiple_every
3005           oformals
3006           (lambda (forb :long ix)
3007             (assert_msg "check forb" (is_a forb class_formal_binding) forb)
3008             (debug "normexp_cmatchexpr forb" forb)
3009             (let ( (forarg (unsafe_get_field :binder forb))
3010                    (actarg (multiple_nth nargs ix)) 
3011                    (fortype (unsafe_get_field :fbind_type forb))
3012                    (actype (get_ctype actarg env))
3013                    )
3014               (debug "normexp_cmatchexpr actarg=" actarg " actype=" actype)
3015               (if (and (is_a fortype class_ctype)
3016                        (is_a actype class_ctype)
3017                        (!= fortype actype))
3018                   (progn
3019                     (error_at sloc 
3020                               "type mismatch between formals & actuals in cmatch $1 operator formal $2 actual ctype $3 expected ctype $4"_
3021                                   cmanamstr
3022                                   (unsafe_get_field :named_name forarg) 
3023                                   (unsafe_get_field :named_name actype) 
3024                                   (unsafe_get_field :named_name fortype))
3025                     ))
3026               (mapobject_put bmap forarg actarg)
3027               )))
3028          (debug "normexp_cmatchexpr bmap in sopexp" bmap)
3029          (multiple_every
3030           sopexp
3031           (lambda (excu :long jx)
3032             ;;(debug "normexp_cmatchexpr excu in sopexp" excu)
3033             (let ( (exval
3034                     (if (is_a excu class_symbol)
3035                         (let ( (bval (mapobject_get bmap excu)) )
3036                           (if (null bval) 
3037                               (progn 
3038 ;; we could perhaps handle symbols which are not primitive arguments
3039 ;; as some kind of closed constants, but this is rarely needed and
3040 ;; requires a lot of work: the excu should then be the constant
3041 ;; itself, and code should be generated to fill the primitive with
3042 ;; non-symbol values.
3043                                 (debug "normexp_cmatchexpr unexpected symbol in expansion recv=" recv " excu=" excu)
3044                                 (error_at sloc 
3045                                           "unexpected symbol in cmatch expression expansion $1 for $2"_
3046                                           (unsafe_get_field  :named_name excu)
3047                                           cmanamstr)
3048                                 ))
3049                           bval)
3050                       excu)) )
3051               (if (null exval)
3052                   (progn
3053                     (warning_strv sloc "null expansion of cmatch expression argument for"
3054                                   cmanamstr)
3055                     (if (is_a excu class_named) 
3056                         (warning_strv sloc "null cmatch expression original piece is"
3057                                       (unsafe_get_field :named_name excu)))
3058                     ))
3059                                         ;(debug "normexp_cmatchexpr exval in sopexp" exval)
3060               (multiple_put_nth expargs jx exval))
3061             ))
3062          (let ( (csym (clone_symbol cmanamstr)) 
3063                 (cbind (instance class_normal_let_binding
3064                                  :letbind_loc sloc
3065                                  :binder csym
3066                                  :letbind_type otype 
3067                                  :letbind_expr 
3068                                  (instance class_nrep_chunk
3069                                            :nrep_loc sloc
3070                                            :nchunk_expansion expargs
3071                                            :nchunk_oper scmat
3072                                            :nexpr_ctyp otype
3073                                            ))) 
3074                 (clocc (instance class_nrep_locsymocc
3075                                  :nrep_loc sloc
3076                                  :nocc_ctyp otype
3077                                  :nocc_symb csym
3078                                  :nocc_bind cbind)) 
3079                 )
3080            (if (is_list nbind) 
3081                (list_append nbind cbind)
3082              (progn
3083                (setq nbind (make_list discr_list))
3084                (list_append nbind cbind)
3085                ))
3086            (debug "normexp_cmatchexpr result clocc" clocc)
3087            (return
3088             clocc
3089             nbind
3090             )))))))
3092 (install_method class_source_cmatchexpr normal_exp normexp_cmatchexpr)
3095 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3096 ;;; normalize a funmatchexpr
3097 (defun normexp_funmatchexpr (recv env ncx psloc)
3098   (debug "normexp_funmatchexpr recv" recv)
3099   (assert_msg "check recv" (is_a recv class_source_funmatchexpr) recv)
3100   (assert_msg "check env" (is_a env class_environment) env)
3101   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3102   (let ( (sloc (unsafe_get_field :loca_location recv)) 
3103          (sfmat (unsafe_get_field :sfmatx_fmatcher recv))
3104          (sfbind (unsafe_get_field :sfmatx_fmatbind recv))
3105          (sargs (unsafe_get_field :sargop_args recv)) 
3106          (nbind (make_list discr_list))
3107          )
3108     (assert_msg "check sfmat" (is_a sfmat class_funmatcher) sfmat)
3109     (assert_msg "check sfbind" (is_a sfbind class_any_binding) sfbind)
3110     (debug "normexp_funmatchexpr sfbind" sfbind)
3111     (let ( (fmatsym (unsafe_get_field :binder sfbind)) )
3112       (assert_msg "check fmatsym" (is_a fmatsym class_symbol) fmatsym)
3113       (assert_msg "check good sfbind" (== sfbind (find_env env fmatsym)) sfbind fmatsym)
3114       (let ( (nfmat (normal_exp fmatsym env ncx psloc)) )
3115         (debug "normexp_funmatchexpr nfmat" nfmat)
3116         ;; should create a normlet binding to hold the nfmat's
3117         ;; fmatch_applyf field
3118         (let ( (csym (clone_symbol fmatsym))
3119                (cbind (instance class_normal_let_binding
3120                                 :letbind_loc sloc
3121                                 :binder csym
3122                                 :letbind_type ctype_value 
3123                                 :letbind_expr 
3124                                 (instance class_nrep_unsafe_get_field
3125                                           :nrep_loc sloc
3126                                           :nuget_obj nfmat
3127                                           :nuget_field fmatch_applyf)
3128                                 ))
3129                (clocc (instance  class_nrep_locsymocc
3130                                  :nrep_loc sloc
3131                                  :nocc_ctyp ctype_value
3132                                  :nocc_symb csym
3133                                  :nocc_bind cbind))
3134                )
3135           (list_append nbind cbind)
3136           (multicall 
3137            (nargs nargbind)
3138            (normalize_tuple sargs env ncx sloc)
3139            (debug "normexp_funmatchexpr nargs=" nargs " nargbind=" nargbind)
3140            (list_append2list nbind nargbind)
3141            (let (
3142                  (asym (clone_symbol fmatsym))
3143                  (abind  (instance class_normal_let_binding
3144                                    :letbind_loc sloc
3145                                    :binder asym
3146                                    :letbind_type ctype_value 
3147                                    :letbind_expr 
3148                                    (instance class_nrep_apply
3149                                              :nexpr_ctyp ctype_value
3150                                              :nrep_loc sloc
3151                                              :napp_fun clocc
3152                                              :nexpr_args nargs
3153                                              ))) 
3154                  (calocc  (instance  class_nrep_locsymocc
3155                                      :nrep_loc sloc
3156                                      :nocc_ctyp ctype_value
3157                                      :nocc_symb asym
3158                                      :nocc_bind abind
3159                                      )) 
3160                  )
3161              (list_append nbind abind)
3162              (debug "normexp_funmatchexpr final calocc=" calocc " nbind=" nbind)
3163              (return calocc nbind)
3164              )))))))
3165 (install_method class_source_funmatchexpr normal_exp normexp_funmatchexpr)
3167 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3168 ;;; normalize an application
3169 (defun normexp_apply (recv env ncx psloc)
3170   (debug "normexp_apply" " recv=" recv "\n.. env=" env "\n.. ncx=" ncx "\n.. psloc=" psloc)
3171   (shortbacktrace_dbg "normexp_apply" 18)
3172   (assert_msg "check apply recv" (is_a recv class_source_apply) recv)
3173   (assert_msg "check env" (is_a env class_environment) env)
3174   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3175   (let ( (sloc (unsafe_get_field :loca_location recv)) 
3176          (sfun (unsafe_get_field :sapp_fun recv))
3177          (sargs (unsafe_get_field :sargop_args recv))
3178          (sfusymb (if (is_a sfun class_symbol) sfun '_fun_))
3179          )
3180     (debug "normexp_apply sloc=" sloc "; sfun=" sfun)
3181     (multicall 
3182      (nfun nbindfun)
3183      (normal_exp sfun env ncx sloc)
3184      (debug "normexp_apply nfun=" nfun "\n nbindfun=" nbindfun)
3185      (assert_msg "check nbindfun" (is_list_or_null nbindfun) nbindfun)
3186      (let ( (nfunctyp (get_ctype nfun env)) 
3187             )
3188        (debug "normexp_apply nfunctyp" nfunctyp)
3189        (if (!= nfunctyp ctype_value)
3190            (progn 
3191              (debug "normexp_apply bad nfun=" nfun " sfun=" sfun " nfunctyp=" nfunctyp " recv=" recv)
3192              (error_at sloc "applied function should be a value, but has bad ctype $1" 
3193                          (get_field :named_name nfunctyp))
3194              (cond 
3195               ( (is_string sfun)
3196                 (error_at sloc "bad applied string '$1', not a function"_ sfun))
3197               ( (is_a sfun class_named)
3198                 (error_at sloc "bad applied function, named $1"_ 
3199                             (get_field :named_name sfun)))
3200               ( (is_a sfun class_located)
3201                 (error_at (get_field :loca_location sfun) 
3202                           "here is the wrong applied function")))
3203              )))
3204      (debug "normexp_apply sloc=" sloc "; sargs=" sargs)
3205      (multicall
3206       (nargs nbindargs)
3207       (normalize_tuple sargs env ncx sloc)
3208       (debug "normexp_apply" " nargs=" nargs "\n.. nbindargs=" nbindargs
3209              "\n.. sargs=" sargs "\n.. sloc=" sloc)
3210       (assert_msg "check nbindargs" (is_list_or_null nbindargs) nbindargs)
3211       ;; if given the first argument should be a value
3212       (let ( (nargfirst (multiple_nth nargs 0)) 
3213              )
3214         (debug "normexp_apply nargfirst" nargfirst)
3215         (if nargfirst 
3216             (let ( (nargfirstctype (get_ctype nargfirst env)) 
3217                    )
3218               (debug "normexp_apply nargfirstctype=" nargfirstctype)
3219               (if (!= nargfirstctype ctype_value)
3220                   (error_at sloc
3221                             "first argument of function application should be a value not a $1" (get_field :named_name nargfirstctype))
3222                 ))
3223           ))
3224       ;;
3225       (debug "normexp_apply" " before check_ctype_nargs, nargs=" nargs
3226              "\n.. env=" debug_less env "\n.. sloc=" sloc)
3227       (check_ctype_nargs nargs env sloc)
3228       (debug "normexp_apply" " after check_ctype_nargs sloc=" sloc)
3229       (setq nbindargs (list_append2list nbindargs nbindfun))
3230       ;; add a void binding to check interrupts
3231       (let ( (cintsym (clone_symbol sfusymb))
3232              (nchint (instance class_nrep_checksignal
3233                                :nrep_loc sloc))
3234              (cintbind (instance class_normal_let_binding
3235                                  :letbind_loc sloc
3236                                  :binder cintsym
3237                                  :letbind_type ctype_void
3238                                  :letbind_expr nchint))
3239              )
3240         (if (null nbindargs)
3241             (setq nbindargs (list cintbind))
3242           (list_append nbindargs cintbind))
3243         )
3244       (assert_msg "check nbindargs" (is_list nbindargs) nbindargs)
3245       ;;
3246       (let ( (csym (clone_symbol sfusymb))
3247              (cbind (instance class_normal_let_binding
3248                               :letbind_loc sloc
3249                               :binder csym
3250                               :letbind_type ctype_value 
3251                               :letbind_expr 
3252                               (instance class_nrep_apply
3253                                         :nrep_loc sloc
3254                                         :nexpr_ctyp ctype_value
3255                                         :napp_fun nfun
3256                                         :nexpr_args nargs
3257                                         ))) 
3258              (clocc  (instance  class_nrep_locsymocc
3259                                 :nrep_loc sloc
3260                                 :nocc_ctyp ctype_value
3261                                 :nocc_symb csym
3262                                 :nocc_bind cbind
3263                                 )) 
3264              )
3265         (list_append nbindargs cbind)
3266         (return clocc nbindargs)
3267         )))))
3268 (install_method class_source_apply normal_exp normexp_apply)
3270 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3271 ;;; normalize a message send
3272 (defun normexp_msend (msnd env ncx psloc)
3273   (debug "normexp_msend msnd=" msnd)
3274   (assert_msg "check msnd" (is_a msnd class_source_msend) msnd)
3275   (assert_msg "check env" (is_a env class_environment) env)
3276   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3277   (let ( (msrecv (unsafe_get_field :msend_recv msnd))
3278          (msargs (unsafe_get_field :sargop_args msnd))
3279          (selnam (unsafe_get_field :msend_selsymb msnd))
3280          (curproc (unsafe_get_field :nctx_curproc ncx))
3281          (sloc (unsafe_get_field :loca_location msnd))
3282          (nsel (normexp_symbol selnam env ncx sloc))
3283          (selbind (find_env env selnam))
3284          )
3285     (debug "normexp_msend curproc=" curproc " selbind=" selbind)
3286 ;;;; we should add the constant selector into the current routine's constant pool
3287     (multicall
3288      (nrecv nbindrecv)
3289      (normal_exp msrecv env ncx sloc)
3290      (assert_msg "check nbindrecv" (is_list_or_null nbindrecv) nbindrecv)
3291      ;; check that receiver is a value
3292      (let ( (ctypr (get_ctype nrecv env)) )
3293        (assert_msg "normexp_msend check ctypr " (is_a ctypr class_ctype) ctypr)
3294        (if (!= ctypr ctype_value)
3295            (error_at sloc "non value receiver for message send of selector $1"
3296                      (unsafe_get_field :named_name selnam)))
3297        )
3298      (multicall
3299       (nargs nbindargs)
3300       (normalize_tuple msargs env ncx sloc)
3301       (assert_msg "check nbindargs" (is_list_or_null nbindargs) nbindargs)
3302       ;; add a void binding to check interrupts
3303       (let ( 
3304              (cintsym (clone_symbol selnam))
3305              (nint (instance class_nrep_checksignal
3306                              :nrep_loc sloc))
3307              (cintbind (instance class_normal_let_binding
3308                                  :letbind_loc sloc
3309                                  :binder cintsym
3310                                  :letbind_type ctype_void
3311                                  :letbind_expr nint))
3312             )
3313         (if (is_list nbindargs)
3314             (list_append nbindargs cintbind)
3315           (setq nbindargs (list cintbind)))
3316         )
3317       ;;
3318       (setq nbindrecv (list_append2list nbindrecv nbindargs))
3319       (check_ctype_nargs nargs env sloc)
3320       (let ( (selformals
3321               (cond ( (is_a selbind class_selector_binding)
3322                       (get_field  :sdefsel_formals (get_field :sbind_selectordef selbind) 
3323                                   )
3324                       )
3325                     ( (is_a selbind class_value_binding)
3326                       (let ( (valsel (get_field :vbind_value selbind)) )
3327                         (assert_msg "check valsel" (is_a valsel class_selector) valsel)
3328                         (get_field  :sel_signature valsel))
3329                       )
3330                     (:else 
3331                      (assert_msg "invalid selbind" () selbind)
3332                      ())))
3333              (csym (clone_symbol selnam)) 
3334              (nsend (instance class_nrep_msend
3335                               :nrep_loc sloc
3336                               :nexpr_ctyp ctype_value
3337                               :nsend_sel nsel
3338                               :nsend_recv nrecv
3339                               :nexpr_args nargs
3340                               )) 
3341              (cbind (instance class_normal_let_binding
3342                               :letbind_loc sloc
3343                               :binder csym
3344                               :letbind_type ctype_value 
3345                               :letbind_expr nsend))
3346              (clocc  (instance  class_nrep_locsymocc
3347                                 :nrep_loc sloc
3348                                 :nocc_ctyp ctype_value
3349                                 :nocc_symb csym
3350                                 :nocc_bind cbind)) 
3351              )
3352         (debug "normexp_msend nsend middle" nsend)
3353         (assert_msg "check nrecv" (is_object nrecv) nrecv)
3354         (if (is_multiple selformals)
3355             (let ( (recvformal (multiple_nth selformals 0))
3356                    (:long nbformals (multiple_length selformals))
3357                    )
3358               (debug "normexp_msend" selformals)
3359               (assert_msg "check recvformal" (== (get_field :fbind_type recvformal) ctype_value) recvformal)
3360               (if (!=i nbformals (+i 1 (multiple_length nargs)))
3361                   (error_at sloc "unexpected number of arguments for method $1 with $2 formals"
3362                             (get_field :named_name selnam) nbformals)
3363                 )
3364               (foreach_in_multiple 
3365                (nargs)
3366                (curnarg :long nix)
3367                (let ( (curformal (multiple_nth selformals (+i nix 1)))
3368                       (curctyp (get_ctype curnarg env))
3369                       (formctyp (get_field :fbind_type curformal))
3370                       (formbinder (get_field :binder curformal))
3371                       )
3372                  (assert_msg "check curformal" (is_a curformal class_formal_binding) curformal)
3373                  (if (!= curctyp formctyp)
3374                      (progn
3375                        (warning_strv sloc "c-type mismatch in method send argument"
3376                                      (get_field :named_name selnam))
3377                        (inform_strv sloc "mismatched method formal name"
3378                                     (get_field :named_name formbinder))
3379                        (inform_strv sloc "mismatched method actual type"
3380                                     (get_field :named_name curctyp))
3381                        (inform_strv sloc "mismatched method expected type"
3382                                     (get_field :named_name formctyp))
3383                        )
3384                    )
3385                  ))))
3386         (unsafe_put_fields clocc :nocc_bind cbind)
3387         (if (not (is_list nbindrecv))
3388             (setq nbindrecv (make_list discr_list)))
3389         (list_append nbindrecv cbind)
3390         (debug "normexp_msend final nbindrecv=" nbindrecv " clocc=" clocc)
3391         (return clocc nbindrecv)
3392         )))))
3393 (install_method class_source_msend normal_exp normexp_msend)
3397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3398 ;;; normalize a return
3399 (defun normexp_return (recv env ncx psloc)
3400   (debug "normexp_return recv=" recv "\n ncx=" ncx)
3401   (assert_msg "check return recv" (is_a recv class_source_return) recv)
3402   (assert_msg "check env" (is_a env class_environment) env)
3403   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3404   (let ( (sloc (or (get_field :loca_location recv) psloc))
3405          (srets (unsafe_get_field :sargop_args recv))
3406          (:long nbrets (multiple_length srets))
3407          (csym (clone_symbol 'return_))
3408          (curproc (get_field :nctx_curproc ncx))
3409          (restype (cond ( (is_a curproc class_nrep_routproc)
3410                           ctype_value)
3411                         ( (is_a curproc class_nrep_hookproc)
3412                           (get_field :nrhook_ctype curproc))
3413                         ( :else
3414                           (error_at sloc 
3415                                     "RETURN outside of LAMBDA or DEFUN procedure or DEFHOOK")
3416                           (return))))
3417          ;; while the return effectively go out, it is preferable to give it a value type
3418          ;; to avoid make warning on code like (if (p x) (return) (.....))
3419          (cbind (instance class_normal_let_binding
3420                           :letbind_loc sloc
3421                           :binder csym
3422                           :letbind_type restype 
3423                           ;; :letbind_expr is filled later
3424                           ))
3425          (clocc (instance class_nrep_locsymocc
3426                           :nrep_loc sloc
3427                           :nocc_ctyp restype
3428                           :nocc_symb csym
3429                           :nocc_bind cbind)) 
3430          )
3431     (debug "normexp_return srets=" srets " curproc=" curproc)
3432     ;; special case for empty return
3433     (if (<=i nbrets 0)
3434         (let ( 
3435               (nbindemp (make_list discr_list))
3436               (nemptret 
3437                (instance class_nrep_return
3438                          :nrep_loc sloc
3439                          :nret_main ()
3440                          :nret_rest ()
3441                          ))
3442               )
3443           (unsafe_put_fields cbind :letbind_expr nemptret)
3444           (list_append nbindemp cbind)
3445           (debug "normexp_return empty; return clocc=" clocc " nbindemp=" nbindemp)
3446           (return clocc nbindemp))
3447       (multicall
3448        (nrets nbindrets)
3449        (normalize_tuple srets env ncx sloc)
3450        (debug "normexp_return nrets=" nrets " nbindrets=" nbindrets)
3451        (when (and
3452               (>i nbrets 1)
3453               (is_a curproc class_nrep_hookproc))
3454          (error_at sloc
3455                    "multiple RETURN not allowed inside hooks")
3456          (return))
3457        (let ( (nret0 (multiple_nth nrets 0))
3458               (toth (make_multiple discr_multiple (-i nbrets 1))) 
3459               (ctyp0 (get_ctype nret0 env))
3460               )
3461          (when 
3462              (and 
3463               (!= ctyp0 ctype_value)
3464               (is_a curproc class_nrep_routproc))
3465            (error_at sloc 
3466                         "primary RETURN-ed result from procedure is not a value")
3467            (return))
3468          (when (is_a curproc class_nrep_hookproc)
3469            (when (>i nbrets 1)
3470              (error_at sloc "RETURN with secondary results impossible in a hook")
3471              (return))
3472            (when (and nret0 ctyp0 (!= ctyp0 restype))
3473              (error_at sloc "RETURN with incompatible type in hook expected type $1 gotten $2"_ 
3474                        (get_field :named_name restype)
3475                        (get_field :named_name ctyp0))
3476              (return))
3477            )
3478          (if (null nbindrets) 
3479              (setq nbindrets (make_list discr_list)))
3480          ;; add a void binding to check interrupts
3481          (let ( (rintsymb (clone_symbol '_retint_))
3482                 (nchint (instance class_nrep_checksignal
3483                                   :nrep_loc sloc))
3484                 (rintbind (instance class_normal_let_binding
3485                                     :binder rintsymb
3486                                     :letbind_type ctype_void
3487                                     :letbind_expr nchint
3488                                     ))
3489                 )
3490            (list_append nbindrets rintbind)
3491            )
3492          ;;
3493          (foreach_in_multiple
3494           (nrets)
3495           (ncomp :long ix)
3496           (let ( (nctyp (get_ctype ncomp env))
3497                  )
3498             (assert_msg "check nctyp" (is_a nctyp class_ctype) nctyp)
3499             (unless (get_field :ctype_parchar nctyp)
3500               (error_at sloc "impossible secondary result type $1"_
3501                         (get_field :named_name nctyp)))
3502             )
3503           (if (>i ix 0)
3504               (multiple_put_nth toth (-i ix 1) ncomp)))
3506          (let ( (nret
3507                  (instance class_nrep_return
3508                            :nrep_loc sloc
3509                            :nret_main nret0
3510                            :nret_rest (if (>i nbrets 0) toth)))
3511                 )
3512            (unsafe_put_fields cbind :letbind_expr nret)
3513            (list_append nbindrets cbind)
3514            (debug "normexp_return result clocc=" clocc " nbindrets=" nbindrets)
3515            (return clocc nbindrets)
3516            ))))))
3517 (install_method class_source_return normal_exp normexp_return)
3521 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3522 ;;;;; normalize an if
3523 (defun normexp_if (recv env ncx psloc)
3524   (assert_msg "check if recv" (is_a recv class_source_if) recv)
3525   (assert_msg "check env" (is_a env class_environment) env)
3526   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3527   (debug "normexp_if recv" recv)
3528   (let ( (sloc (unsafe_get_field :loca_location recv))
3529          (stest (unsafe_get_field :sif_test recv))
3530          (ctypif ctype_void)
3531          (sthen (unsafe_get_field :sif_then recv))
3532          (cintsymb (clone_symbol '_if_inter_))
3533          (nchint (instance class_nrep_checksignal
3534                            :nrep_loc sloc))
3535          (cintbind (instance class_normal_let_binding
3536                              :binder cintsymb
3537                              :letbind_type ctype_void
3538                              :letbind_expr nchint))
3539          )
3540     (multicall 
3541      (ntest nbindif)         ;nbindif is also the whole result binding
3542      (normal_exp stest env ncx sloc)
3543      (assert_msg "check nbindif test" (is_list_or_null nbindif) nbindif)
3544      (debug "normexp_if ntest=" ntest " cintbind=" cintbind)
3545      ;; prepend the check interrupt binding
3546      (if (null nbindif) 
3547          (setq nbindif (list cintbind))
3548        (list_prepend nbindif cintbind))
3549      ;;
3550      ;; in practice we don't need to make a common super-
3551      ;; environment with nbindif since all relevant bindings there are
3552      ;; generated, with unique cloned symbols, and these bindings 
3553      ;; are local to the test part
3554      (multicall 
3555       (nthen nbindthen)
3556       (normal_exp sthen env ncx sloc)
3557       (debug "normexp_if nthen" nthen)
3558       (assert_msg "check nbindthen" (is_list_or_null nbindthen) nbindthen)
3559       (let ( (newthenenv (fresh_env env)) )
3560         (list_every 
3561          nbindthen
3562          (lambda (b) (put_env newthenenv b)))
3563         ;; the ctyp of the whole if is initialized to the ctype of the then part
3564         (setq ctypif (get_ctype nthen newthenenv))
3565         ;;
3566         (let ( (csym (clone_symbol '_if_))
3567                (clocc  (instance  class_nrep_locsymocc
3568                                   :nrep_loc sloc
3569                                   :nocc_ctyp ctypif
3570                                   :nocc_symb csym)) 
3571                (wthen (wrap_normal_let1 nthen nbindthen sloc))
3572                (cbind (instance class_normal_let_binding
3573                                 :letbind_loc sloc
3574                                 :binder csym
3575                                 :letbind_type ctypif 
3576                                 :letbind_expr 
3577                                 (instance class_nrep_if
3578                                           :nrep_loc sloc
3579                                           :nif_test ntest
3580                                           :nif_then wthen
3581                                           :nif_else ()
3582                                           :nexpr_ctyp ctypif
3583                                           ))) 
3584                )
3585           (unsafe_put_fields clocc :nocc_bind cbind)
3586           (if (not (is_list nbindif))
3587               (setq nbindif (make_list discr_list)))
3588           (list_append nbindif cbind)
3589           (debug "normexp_if result clocc=" clocc " nbindif=" nbindif)
3590           (return clocc nbindif)
3591           ))
3592       ))))
3593 (install_method class_source_if normal_exp normexp_if)
3596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3597 ;;;;; normalize an ifelse
3598 (defun normexp_ifelse (recv env ncx psloc)
3599   (debug "normexp_ifelse recv=" recv "\n.. env=" debug_more env 
3600          "\n.. of prec=" debug_less (get_field :env_prev env) "\n")
3601   (assert_msg "check if recv" (is_a recv class_source_ifelse) recv)
3602   (assert_msg "check env" (is_a env class_environment) env)
3603   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3604   (let ( (sloc (unsafe_get_field :loca_location recv))
3605          (stest (unsafe_get_field :sif_test recv))
3606          (ctypif ctype_void)
3607          (sthen (unsafe_get_field :sif_then recv))
3608          (selse (unsafe_get_field :sif_else recv))
3609          )
3610     (debug "normexp_ifelse sloc=" debug_less sloc "; stest=" stest)
3611     (multicall 
3612      (ntest nbindif)         ;nbindif is also the whole result binding
3613      (normal_exp stest env ncx sloc)
3614      (debug "normexp_ifelse ntest=" ntest "; nbindif=" nbindif)
3615      (assert_msg "check nbindif test" (is_list_or_null nbindif) nbindif)
3616      ;; prepend interrupt check void binding
3617      (let ( (cintsymb (clone_symbol '_ifelse_inter_))
3618             (nchint (instance class_nrep_checksignal
3619                               :nrep_loc sloc))
3620             (cintbind (instance class_normal_let_binding
3621                                 :binder cintsymb
3622                                 :letbind_type ctype_void
3623                                 :letbind_expr nchint))
3624            )
3625        (if (is_list nbindif)
3626            (list_prepend nbindif cintbind)
3627          (setq nbindif (list cintbind))))
3628      ;; in practice we don't need to make a common super-
3629      ;; environment with nbindif since all relevant bindings there are
3630      ;; generated, with unique cloned symbols, and these bindings 
3631      ;; are local to the test part
3632      (debug "normexp_ifelse sloc=" debug_less sloc "; sthen=" sthen)
3633      (multicall 
3634       (nthen nbindthen)
3635       (normal_exp sthen env ncx sloc)
3636       (debug "normexp_ifelse nthen=" nthen " nbindthen=" nbindthen)
3637       (assert_msg "check nbindthen" (is_list_or_null nbindthen) nbindthen)
3638       (let ( (newthenenv (fresh_env env)) )
3639         (debug "normexp_ifelse sloc=" debug_less sloc "; newthenenv=" newthenenv)
3640         (list_every 
3641          nbindthen
3642          (lambda (b) (put_env newthenenv b)))
3643         ;; the ctyp of the whole if is initialized to the ctype of the then part
3644         (setq ctypif (get_ctype nthen newthenenv))
3645         (debug "normexp_ifelse sloc=" debug_less sloc "; selse=" selse)
3646         (multicall 
3647          (nelse nbindelse)
3648          (normal_exp selse env ncx sloc)
3649          (debug "normexp_ifelse nelse=" nelse " nbindelse=" nbindelse)
3650          (assert_msg "check nbindelse" (is_list_or_null nbindelse) nbindelse)
3651          ;; if we have both then & else branches,
3652          ;; ensure their compatibility of types
3653          (let ( (newelseenv (let ( (nenv (fresh_env env)) )
3654                               (list_every 
3655                                nbindelse
3656                                (lambda (b) (put_env nenv b)))
3657                               nenv
3658                               ))
3659                 (ctypelse (get_ctype nelse newelseenv)) 
3660                 )
3661            (debug "normexp_ifelse sloc=" debug_less sloc " newelseenv=" newelseenv)
3662            (assert_msg "check ctypif" (is_a ctypif class_ctype) ctypif)
3663            (assert_msg "check ctypelse" (is_a ctypelse class_ctype) ctypelse)
3664            (cond
3665             ( (== ctypif ctypelse)
3666               ()
3667               )
3668             ( (and (!= ctypif ctype_void) (== ctypelse ctype_void))
3669               () ;; ctypif is correct
3670               )
3671             ( (and (== ctypif ctype_void) (!= ctypelse ctype_void))
3672               (setq ctypif ctypelse)
3673               )
3674             (:else
3675              (error_at sloc 
3676                             "incompatible types in conditional IF/OR/COND branches: then type is $1 else type is $2"_ 
3677                             (unsafe_get_field :named_name ctypif)
3678                             (unsafe_get_field :named_name ctypelse))
3679              (setq ctypif ctype_void)
3680              )
3681             ))
3682          ;;
3683          ;;
3684          (let ( (csym (clone_symbol '_ifelse_))
3685                 (clocc  (instance  class_nrep_locsymocc
3686                                    :nrep_loc sloc
3687                                    :nocc_ctyp ctypif
3688                                    :nocc_symb csym)) 
3689                 (wthen (wrap_normal_let1 nthen nbindthen sloc))
3690                 (welse (wrap_normal_let1 nelse nbindelse sloc))
3691                 (cbind (instance class_normal_let_binding
3692                                  :letbind_loc sloc
3693                                  :binder csym
3694                                  :letbind_type ctypif 
3695                                  :letbind_expr 
3696                                  (instance class_nrep_if
3697                                            :nrep_loc sloc
3698                                            :nif_test ntest
3699                                            :nif_then wthen
3700                                            :nif_else welse
3701                                            :nexpr_ctyp ctypif
3702                                            ))) )
3703            (unsafe_put_fields clocc :nocc_bind cbind)
3704            (if (not (is_list nbindif))
3705                (setq nbindif (make_list discr_list)))
3706            (list_append nbindif cbind)
3707            (debug "normexp_ifelse result clocc=" clocc " nbindif=" nbindif)
3708            (return clocc nbindif)
3709            )))))))
3710 (install_method class_source_ifelse normal_exp normexp_ifelse)
3714 ;;;;;;;;;;;;;;;; normalize a cppif
3715 (defun normexp_cppif (recv env ncx psloc)
3716   (assert_msg "check cppif recv" (is_a recv class_source_cppif) recv)
3717   (assert_msg "check env" (is_a env class_environment) env)
3718   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3719   (debug "normexp_cppif recv" recv)
3720   (let ( (sloc (unsafe_get_field :loca_location recv))
3721          (scond (unsafe_get_field :sifp_cond recv))
3722          (ctypif ctype_void)
3723          (sthen (unsafe_get_field :sifp_then recv))
3724          (selse (unsafe_get_field :sifp_else recv))
3725          )
3726     ;; normalize the then-part
3727     (multicall 
3728      (nthen nbindthen)
3729      (normal_exp sthen env ncx sloc)
3730      (debug "normexp_cppif nthen" nthen)
3731      (assert_msg "check nbindthen" (is_list_or_null nbindthen) nbindthen)
3732      (let ( (newthenenv (fresh_env env)) )
3733        (list_every 
3734         nbindthen
3735         (lambda (b) (put_env newthenenv b)))
3736        ;; the ctyp of the whole cppif is initialized to the ctype of the then part
3737        (setq ctypif (get_ctype nthen newthenenv))
3738        (assert_msg "check ctypif" (is_a ctypif class_ctype) ctypif)
3739        ;; normalize the else-part
3740        (multicall 
3741         (nelse nbindelse)
3742         (normal_exp selse env ncx sloc)
3743         (debug "normexp_cppif nelse" nelse)
3744         (assert_msg "check nbindelse" (is_list_or_null nbindelse) nbindelse)
3745         (let ( (newelseenv (fresh_env env)) )
3746           (foreach_pair_component_in_list 
3747            (nbindelse)
3748            (curpairelse elsebind) 
3749            (put_env newelseenv elsebind))
3750           (let ( (ctypelse (get_ctype nelse newelseenv)) )
3751             (when (and (!= ctypif ctypelse) (!= ctypif ctype_void) (!= ctypelse ctype_void))
3752               (error_at sloc "CPPIF incompatible then $1 & else $2 types"_
3753                         (unsafe_get_field :named_name ctypif)
3754                         (unsafe_get_field :named_name ctypelse))
3755               ))
3757           (let ( (csym (clone_symbol 'ifcpp_))
3758                  (clocc  (instance  class_nrep_locsymocc
3759                                     :nrep_loc sloc
3760                                     :nocc_ctyp ctypif
3761                                     :nocc_symb csym)) 
3762                  (wthen (wrap_normal_let1 nthen nbindthen sloc))
3763                  (welse (wrap_normal_let1 nelse nbindelse sloc))
3764                  (cbind (instance class_normal_let_binding
3765                                   :letbind_loc sloc
3766                                   :binder csym
3767                                   :letbind_type ctypif 
3768                                   :letbind_expr 
3769                                   (instance class_nrep_cppif
3770                                             :nrep_loc sloc
3771                                             :nifp_cond scond
3772                                             :nifp_then wthen
3773                                             :nifp_else welse
3774                                             :nifp_ctyp ctypif
3775                                             ))) 
3776                  (nbindres (make_list discr_list))
3777                  )
3778             (unsafe_put_fields clocc :nocc_bind cbind)
3779             (list_append nbindres cbind)
3780             (debug "normexp_cppif result clocc=" clocc " nbindres=" nbindres)
3781             (return clocc nbindres)
3782             )))))))
3783 (install_method class_source_cppif normal_exp normexp_cppif)
3785 ;;;;;;;;;;;;;;;; normalize an or
3786 ;; (OR (f1 a1)) is let d1 = (f1 a1) in d1
3787 ;; (OR (f1 a1) (f2 a2)) is let o1 = (let d1 = (f1 a1) in  (if d1 d1 (let d2 = (f2 a2) in d2))) in o1
3788 (defun normexp_or (recv env ncx psloc)
3789   (assert_msg "check or recv" (is_a recv class_source_or) recv)
3790   (assert_msg "check env" (is_a env class_environment))
3791   (assert_msg "check nctxt" (is_a ncx class_normalization_context))
3792   (debug "normexp_or recv" recv)
3793   (let ( 
3794         (boxorcount (make_integerbox discr_integer (melt_callcount)))
3795         (sloc (unsafe_get_field :loca_location recv))
3796         (sdisj (unsafe_get_field :sor_disj recv))
3797         (:long nbdisj (multiple_length sdisj))
3798         (:long ix (-i nbdisj 1))
3799         (norcont (reference ()))
3800         (nbindorcont (reference (make_list discr_list)))
3801         (ctyporcont (reference ctype_void))
3802         (newenv (fresh_env env))
3803         )
3804     (multiple_backward_every 
3805      sdisj
3806      (lambda (scur :long six)
3807        (debug "normexp scur=" scur "call#" (get_int boxorcount))
3808        (multicall
3809         (ncur nbind)
3810         (normal_exp scur env ncx sloc)
3811         (debug "normexp ncur=" ncur " nbind=" nbind " call#" (get_int boxorcount))
3812         (list_every ncur
3813                     (lambda (bnd) (put_env newenv bnd)))
3814         (if (null (deref norcont))
3815             (progn
3816               (set_ref nbindorcont nbind)
3817               (set_ref norcont ncur) 
3818               (set_ref ctyporcont (get_ctype ncur newenv))
3819               ()
3820               )
3821           (let ( (ctypcur (get_ctype ncur newenv))
3822                  )
3823             (assert_msg "check ctypcur" (is_a ctypcur class_ctype))
3824             (if (!= ctypcur (deref ctyporcont))
3825                 (error_at  sloc "disjuncts' type mismatch in OR | COND got $1 expecting $2"_ ctypcur (deref ctyporcont)))
3826             (let (
3827                   ;; ncur is normal, so simple
3828                   (nifor (instance
3829                           class_nrep_if
3830                           :nrep_loc sloc
3831                           :nif_test ncur
3832                           :nif_then ncur
3833                           :nif_else (wrap_normal_let1 (deref norcont) (deref nbindorcont) sloc)
3834                           :nexpr_ctyp ctypcur
3835                           )
3836                          )
3837                   (csymor (clone_symbol 'or_))
3838                   (corbind (instance 
3839                             class_normal_let_binding
3840                             :binder csymor
3841                             :letbind_loc sloc
3842                             :letbind_type ctypcur
3843                             :letbind_expr nifor))
3844                   (corocc (instance
3845                            class_nrep_locsymocc
3846                            :nrep_loc sloc
3847                            :nocc_ctyp ctypcur
3848                            :nocc_symb csymor
3849                            :nocc_bind corbind))
3850                   )
3851               (set_ref nbindorcont (make_list discr_list))
3852               (list_append2list (deref nbindorcont) nbind)
3853               (list_append (deref nbindorcont) corbind)
3854               (set_ref norcont corocc)
3855               ()
3856               )
3857             )
3858           )
3859         )
3860        )
3861      )
3862     (debug "normexp_or result nor=" !norcont " nbindor=" !nbindorcont)
3863     (return !norcont !nbindorcont)
3864     )
3865   )
3866 (install_method class_source_or normal_exp normexp_or)
3868 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3869 ;;;;;; normalize a PROGN
3870 ;;;; (PROGN a1 a2 ... an) is based upon the normalization of (LET () a1 a2 ... an)
3871 (defun normexp_progn (recv env ncx psloc)
3872   (assert_msg "check progn recv" (is_a recv class_source_progn))
3873   (assert_msg "check env" (is_a env class_environment) env)
3874   (assert_msg "check nctxt" (is_a ncx class_normalization_context))
3875   (debug "normexp_progn recv" recv)
3876   (let ( (sloc (unsafe_get_field :loca_location recv))
3877          (sbody (unsafe_get_field :sprogn_body recv))
3878          (:long lnbody (multiple_length sbody)) 
3879          (boxlnbody (make_integerbox discr_integer lnbody))
3880          )
3881     (if (<=i lnbody 0)
3882         (let ( (onull (instance class_nrep_nil :nrep_loc sloc)) )
3883           (error_at sloc "empty PROGN")
3884           (debug "normexp_progn return empty onull" onull)
3885           (return onull)))
3886     (multicall
3887      (nbody nbind)
3888      (normalize_tuple sbody env ncx sloc)
3889      (debug "normexp_progn nbody=" nbody " nbind=" nbind)
3890      (let ( (nlast (multiple_nth nbody -1)) 
3891             (:long lenbody (multiple_length nbody))
3892             (nallbutlast (if (>i lenbody 0) (make_multiple discr_multiple (-i lenbody 1))))
3893             )
3894        ;; fill nallbutlast 
3895        (let ( (:long ix (-i lenbody 1)) )
3896          (forever bodyloop
3897                   (if (<i ix 0) (exit bodyloop))
3898                   (multiple_put_nth nallbutlast ix (multiple_nth nbody ix))
3899                   (setq ix (-i ix 1))))
3900        (debug "normexp_progn nallbutlast" nallbutlast)
3901        (if (null nbind) (setq nbind (make_list discr_list)))
3902        (let (
3903              (csym (clone_symbol 'progn_))
3904              (lastctyp (get_ctype nlast env))
3905              (cbind (instance class_normal_let_binding
3906                               :binder csym
3907                               :letbind_loc sloc
3908                               :letbind_type lastctyp
3909                               :letbind_expr (instance class_nrep_progn
3910                                                       :nrep_loc sloc
3911                                                       :nprogn_seq nallbutlast
3912                                                       :nprogn_last nlast)))
3913              (clocc (instance class_nrep_locsymocc
3914                               :nrep_loc sloc
3915                               :nocc_ctyp lastctyp
3916                               :nocc_symb csym
3917                               :nocc_bind cbind))
3918              )
3919          (list_append nbind cbind)
3920          (debug "normexp_progn return clocc=" clocc " nbind=" nbind)
3921          (return clocc nbind)
3922          )))))
3923 (install_method class_source_progn normal_exp normexp_progn)
3924 (install_method class_nrep_progn get_ctype 
3925                 (lambda (recv env) (get_ctype (unsafe_get_field :nprogn_last recv) env)))
3930 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;         
3931 ;;;;;; normalize a LET
3932 (defun normexp_let (recv env ncx psloc)
3933   (debug "normexp_let" " recv=" recv "\n.. env=" debug_more env
3934          "\n.. ncx=" ncx)
3935   (assert_msg "check let recv" (is_a recv class_source_let))
3936   (assert_msg "check env" (is_a env class_environment) env)
3937   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
3938   (let ( (sloc (unsafe_get_field :loca_location recv))
3939          (sbindings (unsafe_get_field :slet_bindings recv))
3940          (sbody (unsafe_get_field :slet_body recv)) 
3941          (newenv (fresh_env env))
3942          (bindlist (make_list discr_list))
3943          )
3944     ;; loop on source bindings
3945     (foreach_in_multiple
3946      (sbindings)
3947      (sb :long sbix)
3948      (debug "normexp_let" " sloc=" sloc "; sbix#" sbix ";\n sb=" sb
3949             ";\n ncx=" debug_less ncx)
3950      (cond
3951       ;; handle the normal source let binding case
3952       (  (is_a sb class_source_let_binding)
3953          (let ( (sbloc (unsafe_get_field :loca_location sb))
3954                 (sbtyp (unsafe_get_field :sletb_type sb))
3955                 (sbinder (unsafe_get_field :sletb_binder sb))
3956                 (sbexpr (unsafe_get_field :sletb_expr sb)) 
3957                 )
3958            (assert_msg "check sbtyp" (is_a sbtyp class_quasi_ctype) sbtyp)
3959            ;; issue an inform message if the let binding overrides a previous one
3960            (and
3961             (has_extra_warnings)
3962             (find_env env sbinder)
3963             (inform_strv sbloc "this LET binding hides another one in enclosing scope - "
3964                          (get_field :named_name  sbinder))
3965             )
3966            ;; normalize the binding's expression
3967            (multicall
3968             (nbdexpr nbindings)
3969             (normal_exp sbexpr newenv ncx sbloc)
3970             ;;
3971             (debug "normexp_let" " nbdexpr=" nbdexpr " nbindings=" nbindings)
3972             ;; check that the ctype of the normalized expression
3973             ;; is the same as the let binding's ctype
3974             (let ( (nbctype (get_ctype nbdexpr newenv)) 
3975                    )
3976               (assert_msg "check nbctype" (is_a nbctype class_ctype) nbctype)
3977               ;; replace an :auto binding with the appropriate ctype
3978               ;; but reject a void ctype
3979               (when (== sbtyp quasi_ctype_auto)
3980                 (if (== sbtyp ctype_void)
3981                     (error_at sbloc "auto LET binding of $1 should not be void"
3982                               sbinder))
3983                 (setq sbtyp nbctype))
3984               ;; check ctype compatibility
3985               (when (!= nbctype sbtyp)
3986                 (error_at 
3987                  sbloc
3988                  "ctype mismatch in LET binding of local variable $1 got $2 expecting $3"
3989                  (get_field :named_name  sbinder)
3990                  (get_field :named_name nbctype)
3991                  (get_field :named_name sbtyp))
3992                 ))
3993             ;;
3994             (let ( (lastnbinding (pair_head (list_last nbindings))) )
3995               ;; common case of a normalized apply or primitive, hence a
3996               ;; gensymed variable which is the last in the nbindings
3997               (if (and
3998                    (is_a lastnbinding class_normal_let_binding)
3999                    (is_a nbdexpr class_nrep_locsymocc)
4000                    (== (unsafe_get_field :binder lastnbinding) 
4001                        (unsafe_get_field :nocc_symb nbdexpr))
4002                    )
4003                   (let ( (lastnormexp (unsafe_get_field :letbind_expr nbdexpr)) )
4004                     (list_every
4005                      nbindings
4006                      (lambda (b)
4007                        (if (!= b lastnbinding)
4008                            (list_append bindlist b))))
4009                     (let ( (newcbnd
4010                             (instance class_normal_let_binding
4011                                       :binder sbinder
4012                                       :letbind_type (unsafe_get_field :letbind_type lastnbinding)
4013                                       :letbind_expr (unsafe_get_field :letbind_expr lastnbinding)
4014                                       :letbind_loc (unsafe_get_field :letbind_loc lastnbinding)))
4015                            )
4016                       (list_append bindlist newcbnd)
4017                       (put_env newenv newcbnd)
4018                       )
4019                     )
4020                 (progn
4021                   ;; otherwise, eg a plain constant, a complex if...
4022                   (list_append2list bindlist  nbindings)
4023                   (let ( (newpbnd 
4024                           (instance class_normal_let_binding
4025                                     :binder sbinder
4026                                     :letbind_type sbtyp
4027                                     :letbind_expr nbdexpr
4028                                     :letbind_loc sbloc)) )
4029                     (list_append bindlist newpbnd)
4030                     (put_env newenv newpbnd)
4031                     ))
4032                 ))))
4033          )
4034       ;; handle the local :macro binding case, this is happening after macro expansion
4035       ((is_a sb class_source_macro_let_binding)
4036        (debug "normexp_let" " sloc=" sloc ";\n.. macrobinding sb=" sb)
4037        (let ( (macsymb (get_field :sletb_binder sb))
4038               (mloc (or (get_field :loca_location sb) sloc))
4039               (mformals (get_field :sletm_macro_formals sb))
4040               (mbody (get_field :sletm_macro_body sb))
4041               (newmacenv (fresh_env newenv))
4042               (slambda (instance class_source_lambda_for_macro
4043                                  :loca_location mloc
4044                                  :slam_argbind mformals
4045                                  :slam_body mbody
4046                                  :slam_origmacro sb
4047                                  ))
4048               )
4049          (debug "normexp_let:macro" " before normalize_lambda sloc=" sloc "; slambda=" slambda
4050                 "\n.. old ncx=" ncx
4051                 "\n.. env=" debug_more env
4052                 "\n.. newenv=" debug_more newenv
4053                 "\n.. newmacenv=" debug_more newmacenv)
4054          (multicall 
4055           (manproc macsym maclocc maconstrout maclovtup masloc maoldproc mandatarout :long mainsideflag)
4056           (normalize_lambda slambda  newenv newmacenv ncx psloc)
4057           (debug "normexp_let:macro" " after normalize_lambda manproc=" manproc "\n.. macsym=" macsym 
4058                  "\n.. maclocc=" maclocc "\n.. maconstrout=" maconstrout "\n.. maclovtup=" maclovtup
4059                  "\n.. masloc=" masloc "\n.. maoldproc=" maoldproc "\n.. mandatarout=" mandatarout
4060                  "\n.. mainsideflag=" mainsideflag
4061                  "\n.. newenv=" debug_more newenv
4062                  "\n.. newmacenv=" debug_more newmacenv
4063                  "\n.. ncx=" ncx)
4064           (let (
4065                 (maloc (or masloc mloc))
4066                 (maclambda (instance class_nrep_macrolambda
4067                                      :nrep_loc maloc
4068                                      :nlambda_proc manproc
4069                                      :nlambda_constrout maconstrout
4070                                      :nlambda_closedv maclovtup))
4071                 (macbind (instance class_normal_let_binding
4072                                    :letbind_loc maloc
4073                                    :binder macsymb
4074                                    :letbind_type ctype_value
4075                                    :letbind_expr maclambda))
4076                 )
4077             (debug "normexp_let:macro" " maclambda=" maclambda)
4078             (put_fields maclocc :nocc_bind macbind)
4079             (debug "normexp_let:macro" " updated maclocc=" maclocc)
4080             (list_append bindlist macbind)
4081             (debug "normexp_let:macro" " updated bindlist=" bindlist)
4082             (put_env newenv macbind)
4083             (debug "normexp_let:macro" " updated newenv=" debug_more newenv "\n.. mainsideflag=" mainsideflag)
4084             (when mainsideflag
4085               (list_append (get_field :nrclop_constlist maoldproc) mandatarout)
4086               (debug "normexp_let:macro" " updated constlist in maoldproc=" maoldproc)
4087               )
4088             ))))
4089       ;;
4090       ;; impossible binding
4091       (:else
4092        (error_at sloc "impossible LET binding #$1" sbix)
4093        (assert_msg "impossible let binding" () sb sbix)
4094        (return))
4095       )
4096      )
4097     ;; end of loop on source bindings
4098     ;;
4099     (debug "normexp_let" " before normabody sloc=" sloc "; bindlist=" bindlist
4100            "\n.. sbody=" sbody
4101            "\n.. newenv=" debug_more newenv)
4102     (shortbacktrace_dbg "normexp_let before-normalizing-sbody" 15)
4103     (debug "normexp_let" " before normabody sloc=" sloc "\n.. ncx=" debug_less ncx
4104            "\n.. newenv=" debug_more newenv
4105            "\n.. env=" env)
4106     (multicall
4107      (nbody nbodbindings)
4108      (normalize_tuple sbody newenv ncx sloc)
4109      (debug "normexp_let"  " after normabody sloc=" sloc "; nbody=" nbody 
4110             "\n.. nbodbindings=" nbodbindings
4111             "\n.. old bindlist=" bindlist)
4112      (list_append2list bindlist nbodbindings)
4113      (debug "normexp_let"  " after normabody sloc=" sloc 
4114             "; updated bindlist=" bindlist)
4115      (assert_msg "normexp_let check bindlist" (is_list_or_null bindlist) bindlist)
4116      (foreach_pair_component_in_list
4117       (bindlist)
4118       (curpair cbnd) 
4119       (assert_msg "normexp_let check cbnd" (is_a cbnd class_normal_let_binding) cbnd))
4120      ;; remove every locally bound symbol from the symbol cache map
4121      (let ( (sycmap (unsafe_get_field :nctx_symbcachemap ncx)) )
4122        (foreach_pair_component_in_list 
4123         (bindlist)
4124         (curpair bnd)
4125         (mapobject_remove sycmap (unsafe_get_field :binder bnd))
4126         )
4127        (debug "normexp_let shrinked updated sycmap=" sycmap)
4128        )
4129      ;; make the result
4130      (let (
4131            (nlastbody (multiple_nth nbody -1))
4132            ;; the type of a let with empty body is void
4133            (nlastyp (or (get_ctype nlastbody newenv) ctype_void))
4134            (csym (clone_symbol 'let_))
4135            (nlet
4136             (instance class_nrep_let
4137                       :nrep_loc sloc
4138                       :nlet_bindings (list_to_multiple bindlist discr_multiple)
4139                       :nlet_body nbody))
4140            (cbind (instance class_normal_let_binding
4141                             :binder csym
4142                             :letbind_loc sloc
4143                             :letbind_type nlastyp
4144                             :letbind_expr nlet))
4145            (clocc (instance class_nrep_locsymocc
4146                             :nrep_loc sloc
4147                             :nocc_ctyp nlastyp
4148                             :nocc_bind cbind))
4149            (resbinds (make_list discr_list))
4150            )
4151        (list_append resbinds cbind)
4152        (debug "normexp_let result clocc=" clocc " resbinds=" resbinds)
4153        (return clocc resbinds)
4154        )
4155      )))
4156 ;;;;
4157 (install_method class_source_let normal_exp normexp_let)
4158 (install_method class_nrep_let get_ctype 
4159                 (lambda (recv env)
4160                   (let ( (lbod (unsafe_get_field :nlet_body recv))
4161                          (:long lenb (multiple_length lbod)) )
4162                     (if (<=i lenb 0) ctype_void
4163                       (get_ctype (multiple_nth lbod (-i lenb 1)) env)))))
4168 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4169 ;;;; normalize an UNSAFE_GET_FIELD
4170 (defun normexp_unsafe_get_field (recv env ncx psloc)
4171   (debug "normexp unsafeget recv=" recv)
4172   (assert_msg "check unsafegetfield recv" (is_a recv class_source_unsafe_get_field) recv)
4173   (assert_msg "check env" (is_a env class_environment) env)
4174   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4175   (let ( (sloc   (unsafe_get_field :loca_location recv))
4176          (sobj   (unsafe_get_field :suget_obj recv))
4177          (sfld   (unsafe_get_field :suget_field recv)) 
4178          ) 
4179     (assert_msg "check sfld" (is_a sfld class_field) sfld)
4180     (multicall
4181      (nobj nbind)
4182      (normal_exp sobj env ncx sloc)
4183      (if (null nbind) (setq nbind (make_list discr_list)))
4184      (let ( (csym (clone_symbol (unsafe_get_field :named_name sfld)))
4185             (cbind (instance class_normal_let_binding
4186                              :binder csym
4187                              :letbind_loc sloc
4188                              :letbind_type ctype_value
4189                              :letbind_expr 
4190                              (instance class_nrep_unsafe_get_field
4191                                        :nrep_loc sloc
4192                                        :nuget_obj nobj
4193                                        :nuget_field sfld)))
4194             (clocc (instance  class_nrep_locsymocc
4195                               :nrep_loc sloc
4196                               :nocc_ctyp ctype_value
4197                               :nocc_symb csym
4198                               :nocc_bind cbind))
4199             )
4200        (list_append nbind cbind)
4201        (debug "normexp unsafeget result clocc=" clocc " nbind=" nbind)
4202        (return  clocc nbind)))))
4203 (install_method class_source_unsafe_get_field normal_exp normexp_unsafe_get_field)
4205 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4206 ;;;; normalize an GET_FIELD
4207 (defun normexp_get_field (recv env ncx psloc)
4208   (assert_msg "check getfield recv" (is_a recv class_source_get_field) recv)
4209   (assert_msg "check env" (is_a env class_environment) env)
4210   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4211   (debug "normexp_get_field recv" recv)
4212   (let ( (sloc   (unsafe_get_field :loca_location recv))
4213          (sobj   (unsafe_get_field :suget_obj recv))
4214          (sfld   (unsafe_get_field :suget_field recv)) 
4215          ) 
4216     (assert_msg "check sfld" (is_a sfld class_field) sfld)
4217     (multicall
4218      (nobj nbind)
4219      (normal_exp sobj env ncx sloc)
4220      (if (null nbind) (setq nbind (make_list discr_list)))
4221      (debug "normexp_get_field nobj" nobj)
4222      (let ( (csym (clone_symbol (unsafe_get_field :named_name sfld)))
4223             (fcla (unsafe_get_field :fld_ownclass sfld))
4224             (ncla (let ( (nc (normal_exp fcla env ncx psloc)) )
4225                     (debug "normexp_get_field ncla" nc)
4226                     nc))
4227             (nuget (instance class_nrep_unsafe_get_field
4228                              :nrep_loc sloc
4229                              :nuget_obj nobj
4230                              :nuget_field sfld))
4231             (cbind (instance class_normal_let_binding
4232                              :binder csym
4233                              :letbind_loc sloc
4234                              :letbind_type ctype_value
4235                              :letbind_expr 
4236                              (instance class_nrep_ifisa
4237                                        :nrep_loc sloc
4238                                        :nif_testval nobj
4239                                        :nifa_class ncla
4240                                        :nif_then nuget
4241                                        :nexpr_ctyp ctype_value
4242                                        )))
4243             (clocc (instance  class_nrep_locsymocc
4244                               :nrep_loc sloc
4245                               :nocc_ctyp ctype_value
4246                               :nocc_symb csym
4247                               :nocc_bind cbind))
4248             )
4249        (list_append nbind cbind)
4250        (debug "normexp_get_field clocc=" clocc " nbind=" nbind)
4251        (return  clocc nbind)))))
4252 (install_method class_source_get_field normal_exp normexp_get_field)
4255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4256 ;;;; normalize an UNSAFE_PUT_FIELDS
4257 (defun normexp_unsafe_put_fields (recv env ncx psloc)
4258   (assert_msg "check unsafeputfields recv" (is_a recv class_source_unsafe_put_fields) recv)
4259   (assert_msg "check env" (is_a env class_environment) env)
4260   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4261   (debug "normexp_unsafe_put_fields recv" recv)
4262   (let ( (sloc   (unsafe_get_field :loca_location recv))
4263          (sobj   (unsafe_get_field :suput_obj recv))
4264          (sfields (unsafe_get_field :suput_fields recv))
4265          (:long nbfields (multiple_length sfields))
4266          (nfields (make_multiple discr_multiple nbfields))
4267          (csym (clone_symbol 'unsafput_)) 
4268          (cintsymb (clone_symbol 'unsafput_inter_))
4269          (nchint (instance class_nrep_checksignal
4270                               :nrep_loc sloc))
4271          (cintbind (instance class_normal_let_binding
4272                              :binder cintsymb
4273                              :letbind_type ctype_void
4274                              :letbind_expr nchint))
4275          (nbindlist (list cintbind)) 
4276          (cbind (instance class_normal_let_binding
4277                           :binder csym
4278                           :letbind_loc sloc
4279                           :letbind_type ctype_void
4280                           ;; letbind_expr filled later
4281                           :letbind_expr ()))
4282          (clocc (instance  class_nrep_locsymocc
4283                            :nrep_loc sloc
4284                            :nocc_ctyp ctype_void
4285                            :nocc_symb csym
4286                            :nocc_bind cbind))
4287          )
4288     (multicall
4289      (nobj nobjbind)
4290      (normal_exp sobj env ncx sloc)
4291      (list_append2list nbindlist nobjbind)
4292      (multiple_every 
4293       sfields
4294       (lambda (fla :long ix) 
4295         (assert_msg "check fla" (is_a fla class_source_fieldassign) fla)
4296         (let ( (fld (unsafe_get_field :sfla_field fla))
4297                (exp (unsafe_get_field :sfla_expr fla)) 
4298                (fsloc (or (unsafe_get_field :loca_location fla) sloc))
4299                )
4300           (assert_msg "check fld" (is_a fld class_field) fld)
4301           (multicall
4302            (nexp nexpbind)
4303            (normal_exp exp env ncx sloc)
4304            (list_append2list nbindlist  nexpbind)
4305            (let ( (nfla (instance class_nrep_fieldassign
4306                                   :nrep_loc sloc
4307                                   :nfla_field fld
4308                                   :nfla_val nexp)) )
4309              (multiple_put_nth nfields ix nfla)
4310              (let ( (fctyp (get_ctype nexp env)) )
4311                (debug "normexp_unsafe_put_fields fctyp" fctyp)
4312                (if (!= fctyp ctype_value)
4313                    (error_at 
4314                     fsloc 
4315                     "invalid field type $1 in (UNSAFE_PUT_FIELDS ..); expecting a :value"_
4316                     (get_field :named_name fld))))
4317              )))))
4318      (let ( (npuf (instance class_nrep_unsafe_put_fields
4319                             :nrep_loc sloc
4320                             :nuput_obj nobj
4321                             :nuput_fields nfields)) )
4322        (unsafe_put_fields cbind :letbind_expr npuf)
4323        (list_append nbindlist cbind)
4324        (debug "normexp_unsafe_put_fields result clocc=" clocc
4325               " nbindlist=" nbindlist)
4326        (return clocc nbindlist)
4327        ))))
4328 (install_method class_source_unsafe_put_fields normal_exp normexp_unsafe_put_fields)
4329 (install_method class_nrep_unsafe_put_fields get_ctype (lambda (recv env) ctype_void))
4330 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4332 ;;;; normalize an PUT_FIELDS
4333 (defun normexp_put_fields (recv env ncx psloc)
4334   (assert_msg "check putfields recv" (is_a recv class_source_put_fields) recv)
4335   (assert_msg "check env" (is_a env class_environment) env)
4336   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4337   (debug "normexp_put_fields recv" recv)
4338   (let ( (sloc   (unsafe_get_field :loca_location recv))
4339          (sobj   (unsafe_get_field :suput_obj recv))
4340          (sfields (unsafe_get_field :suput_fields recv))
4341          (:long nbfields (multiple_length sfields))
4342          (nfields (make_multiple discr_multiple nbfields))
4343          (csym (clone_symbol 'putfld_))
4344          (cintsymb (clone_symbol 'putfld_inter_))
4345          (nchint (instance class_nrep_checksignal
4346                               :nrep_loc sloc))
4347          (cintbind (instance class_normal_let_binding
4348                              :binder cintsymb
4349                              :letbind_type ctype_void
4350                              :letbind_expr nchint))
4351          (nbindlist (list cintbind)) 
4352          (cbind (instance class_normal_let_binding
4353                           :binder csym
4354                           :letbind_loc sloc
4355                           :letbind_type ctype_void
4356                           ;; letbind_expr filled later
4357                           :letbind_expr ()))
4358          (clocc (instance  class_nrep_locsymocc
4359                            :nrep_loc sloc
4360                            :nocc_ctyp ctype_void
4361                            :nocc_symb csym
4362                            :nocc_bind cbind))
4363          (clacont (reference ()))
4364          )
4365     (multicall
4366      (nobj nobjbind)
4367      (normal_exp sobj env ncx sloc)
4368      (list_append2list nbindlist  nobjbind)
4369      (foreach_in_multiple 
4370       (sfields)
4371       (fla :long ix) 
4372       (debug "normexp_put_fields fla=" fla " clacont=" clacont)
4373       (assert_msg "check fla" (is_a fla class_source_fieldassign) fla)
4374       (let ( (fld (unsafe_get_field :sfla_field fla))
4375              (exp (unsafe_get_field :sfla_expr fla)) 
4376              (fsloc (or (unsafe_get_field :loca_location fla) sloc))
4377              )
4378         (assert_msg "check fld" (is_a fld class_field) fld)
4379         (let ( (fcla (unsafe_get_field :fld_ownclass fld)) 
4380                (precla (deref clacont))
4381                )
4382           (cond ( (null precla)
4383                   (set_ref clacont fcla)
4384                   )
4385                 ( (== precla fcla)
4386                   ()
4387                   )
4388                 ( (subclass_of precla fcla)
4389                   ()
4390                   )
4391                 ( (subclass_of fcla precla)
4392                   (set_ref clacont fcla)
4393                   )
4394                 (:else
4395                  (debug "normexp_put_fields bad fld=" fld " fcla=" fcla
4396                         " precla=" precla)
4397                  (error_at sloc 
4398                            "bad field name $1 in PUT_FIELD should be a field from class $1 but got field from $3"_ 
4399                            (get_field :named_name fld)
4400                            (get_field :named_name precla)
4401                            (get_field :named_name fcla))
4402                  )
4403                 )
4404           )
4405         (multicall
4406          (nexp nexpbind)
4407          (normal_exp exp env ncx sloc)
4408          (list_append2list nbindlist  nexpbind)
4409          (let ( (nfla (instance class_nrep_fieldassign
4410                                 :nrep_loc sloc
4411                                 :nfla_field fld
4412                                 :nfla_val nexp)) )
4413            (let ( (fctyp (get_ctype nexp env)) 
4414                   )
4415              (if (!= fctyp ctype_value)
4416                    (error_at 
4417                     fsloc 
4418                     "invalid field $1 actual type $2 in (PUT_FIELDS ..); expecting a :value"_
4419                     (get_field :named_name fld)
4420                     (get_field :named_name fctyp))
4421                  )
4422              )
4423            (multiple_put_nth nfields ix nfla)
4424            ))))
4425      (let (
4426            (ncla (normal_exp (deref clacont) env ncx sloc))
4427            (npuf (instance class_nrep_unsafe_put_fields
4428                            :nrep_loc sloc
4429                            :nuput_obj nobj
4430                            :nuput_fields nfields)) 
4431            (nif (instance class_nrep_ifisa
4432                           :nrep_loc sloc
4433                           :nif_testval nobj
4434                           :nifa_class ncla
4435                           :nif_then npuf
4436                           :nexpr_ctyp ctype_void
4437                           )
4438                 ))
4439        (unsafe_put_fields cbind :letbind_expr nif)
4440        (list_append nbindlist cbind)
4441        (debug "normexp_put_fields result clocc=" clocc " nbindlist=" nbindlist)
4442        (return clocc nbindlist)
4443        ))))
4444 (install_method class_source_put_fields normal_exp normexp_put_fields)
4446 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4447 ;;;; normalize a setq
4448 (defun normexp_setq (recv env ncx psloc)
4449   (debug "normexp setq recv=" recv)
4450   (assert_msg "check setq recv" (is_a recv class_source_setq) recv)
4451   (assert_msg "check env" (is_a env class_environment) env)
4452   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4453   (let ( (sloc   (unsafe_get_field :loca_location recv))
4454          (svar   (unsafe_get_field :sstq_var recv))
4455          (sexp   (unsafe_get_field :sstq_expr recv)) ) 
4456     (assert_msg "check svar" (is_a svar class_symbol) svar)
4457     (let ( (nvar (normexp_symbol svar env ncx sloc)) 
4458            (varctyp (get_ctype nvar env))
4459            )
4460       (debug "normexp_setq varctyp" varctyp)
4461       (assert_msg "check varctyp" (is_a varctyp class_ctype) varctyp)
4462       (multicall
4463        (nexp nbind)
4464        (normal_exp sexp env ncx sloc)
4465        (if (null nbind) (setq nbind (make_list discr_list)))
4466        (let ( (expctyp (get_ctype nexp env))
4467               )
4468          (debug "normexp_setq expctyp=" expctyp)
4469          (assert_msg "check expctyp" (is_a expctyp class_ctype) expctyp)
4470          (when (!= varctyp expctyp)
4471                (error_at sloc "incompatible type for SETQ of $1 left ctype is $2 right is $3"_
4472                          (unsafe_get_field :named_name svar)
4473                          (unsafe_get_field :named_name varctyp)
4474                          (unsafe_get_field :named_name expctyp))
4475                ))
4476        (when (is_a nvar class_nrep_modulevarocc)
4477          (debug "normexp_setq modulevarocc nexp=" nexp " nvar=" nvar)
4478          (let ( (csym (clone_symbol 'putstatic_))
4479                 (csbind (instance class_normal_let_binding
4480                                  :binder csym
4481                                  :letbind_loc sloc
4482                                  :letbind_type ctype_void
4483                                  :letbind_expr
4484                                  (instance class_nrep_putmodulevar
4485                                            :nrep_loc sloc
4486                                            :nputmod_destvar nvar
4487                                            :nputmod_value nexp)))
4488                 (cslocc (instance class_nrep_locsymocc
4489                                  :nrep_loc sloc
4490                                  :nocc_ctyp ctype_void
4491                                  :nocc_symb csym
4492                                  :nocc_bind csbind)
4493                         )
4494                 )
4495            (debug "normexp_set static csbind=" csbind "\n cslocc=" cslocc)
4496            (list_append nbind csbind)
4497            (return cslocc nbind)
4498          ))
4499        ;;
4500        (let ( (csym (clone_symbol 'setq_)) 
4501               (cbind  (instance class_normal_let_binding
4502                                 :binder csym
4503                                 :letbind_loc sloc
4504                                 :letbind_type varctyp
4505                                 :letbind_expr
4506                                 (instance class_nrep_setq
4507                                           :nrep_loc sloc
4508                                           :nstq_var nvar
4509                                           :nstq_exp nexp)))
4510               (clocc (instance class_nrep_locsymocc
4511                                :nrep_loc sloc
4512                                :nocc_ctyp varctyp
4513                                :nocc_symb csym
4514                                :nocc_bind cbind))
4515               )
4516          (list_append nbind cbind)
4517          (return clocc nbind)
4518          )))))
4519 (install_method class_source_setq normal_exp normexp_setq)
4520 (install_method class_nrep_setq get_ctype 
4521                 (lambda (recv env)
4522                   (get_ctype (unsafe_get_field :nstq_var recv) env)))
4526 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4527 ;;;;;; normalize a instance
4528 (defun normexp_instance (recv env ncx psloc)
4529   (assert_msg "check instance recv" (is_a recv class_source_instance) recv)
4530   (assert_msg "check env" (is_a env class_environment) env)
4531   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4532   (debug "normexp_instance recv=" recv)
4533   (let ( (sloc (unsafe_get_field :loca_location recv))
4534          (sclass (unsafe_get_field :smins_class recv))
4535          (sclabind (unsafe_get_field :smins_clabind recv))
4536          (sfields (unsafe_get_field :smins_fields recv))
4537          (sclasym (if (is_a sclabind class_any_binding) (unsafe_get_field :binder sclabind)))
4538          (cladata (if (is_a sclasym class_symbol) 
4539                       (normal_exp sclasym env ncx sloc)))
4540          (cintsymb (clone_symbol 'instance_inter_))
4541          (nchint (instance class_nrep_checksignal
4542                            :nrep_loc sloc))
4543          (cintbind (instance class_normal_let_binding
4544                              :binder cintsymb
4545                              :letbind_type ctype_void
4546                              :letbind_expr nchint))
4547          (bindlist (list cintbind))
4548          )
4549     ;; initial checks about class
4550     (cond 
4551      ( (is_not_a sclass class_class)
4552        (debug "normexp_instance bad sclass" sclass)
4553        (error_at sloc "bad class in (INSTANCE <class> [:field1 <expr1> ...]) expression")
4554        (return ())
4555        )
4556      ( (is_not_a cladata class_nrep)
4557        (debug "normexp_instance bad cladata" cladata)
4558        (error_at sloc "invalid class $1 in (INSTANCE <class> [:field1 <expr1> ...]) expression" 
4559                    (get_field :named_name sclass))
4560        (return ()))
4561      )
4562     ;; normalize the field assigments
4563     (let ( (nfields 
4564             (multiple_map 
4565              sfields 
4566              (lambda (curflda :long curk)
4567                (debug "normexp_instance.lambda curflda" curflda)
4568                (assert_msg "check curflda" (is_a curflda class_source_fieldassign) curflda)
4569                (let ( (curfloc (unsafe_get_field :loca_location curflda))
4570                       (curfield (unsafe_get_field :sfla_field curflda))
4571                       (curexp (unsafe_get_field :sfla_expr curflda)) )
4572                  (if (null curfloc) (setq curfloc sloc))
4573                  ;; check the curfield
4574                  (cond
4575                   ( (is_not_a curfield class_field)
4576                     (debug "normexp_instance corrupted curflda=" curflda
4577                            " curfield=" curfield)
4578                     (error_at sloc 
4579                               "invalid field #$1 in (INSTANCE $2 [:field1 <expr1> ...]) expression"
4580                               curk
4581                               (get_field :named_name sclass))
4582                     (return))
4583                   ( (not (subclass_or_eq sclass (unsafe_get_field :fld_ownclass curfield)))
4584                     (debug "normexp_instance corrupted curflda=" curflda
4585                            " curfield=" curfield)
4586                     (error_at sloc
4587                               "unexpected field $1 from class $2 in (INSTANCE $3 [:field1 <expr1> ...]) expression"_
4588                               (get_field :named_name curfield)
4589                               (get_field :named_name (get_field :fld_ownclass curfield))
4590                               (get_field :named_name sclass)
4591                               )
4592                     (return))
4593                   )
4594                  ;;
4595                  (multicall
4596                   (nexp nbind)
4597                   (normal_exp curexp env ncx curfloc)
4598                   (assert_msg "check nbind" (is_list_or_null nbind) nbind)
4599                   (let ( (fctyp (get_ctype nexp env)) )
4600                     (debug "normexp_instance fctyp" fctyp)
4601                     (if (!= fctyp ctype_value)
4602                         (error_at 
4603                          curfloc 
4604                          "invalid field $1 type $2 in (INSTANCE ..); expecting a :value"
4605                          (get_field :named_name curfield)
4606                          (get_field :named_name fctyp))))
4607                   (list_append2list bindlist  nbind)
4608                   (instance class_nrep_fieldassign
4609                             :nrep_loc curfloc
4610                             :nfla_field curfield
4611                             :nfla_val nexp)
4612                   )))))
4613            (nmkins 
4614             (instance class_nrep_instance
4615                       :nrep_loc sloc
4616                       :nmins_class sclass
4617                       :nmins_cladata cladata
4618                       :nmins_fields nfields))
4619            (csym (clone_symbol 'inst_))
4620            (cbind (instance class_normal_let_binding
4621                             :binder csym
4622                             :letbind_loc sloc
4623                             :letbind_type ctype_value
4624                             :letbind_expr nmkins))
4625            (clocc (instance class_nrep_locsymocc
4626                             :nrep_loc sloc
4627                             :nocc_ctyp ctype_value
4628                             :nocc_symb csym
4629                             :nocc_bind cbind))
4630            )
4631       (list_append bindlist cbind)
4632       (debug "normexp_instance result clocc=" clocc " bindlist=" bindlist)
4633       (return clocc bindlist)
4634       )
4635     )
4636   )
4637 (install_method class_source_instance normal_exp normexp_instance)
4638 (install_method class_source_instance get_ctype 
4639                 (lambda (recv env) ctype_value))
4641 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4642 ;;;;;; normalize a forever
4644 (defun normexp_forever (recv env ncx psloc)
4645   (assert_msg "check forever recv" (is_a recv class_source_forever) recv)
4646   (assert_msg "check env" (is_a env class_environment) env)
4647   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4648   (debug "normexp_forever recv=" recv)
4649   (let ( (sloc   (unsafe_get_field :loca_location recv))
4650          (slbind (unsafe_get_field :slabel_bind recv))
4651          (sbody (unsafe_get_field :sfrv_body recv))
4652          (newenv (fresh_env env))
4653          )
4654     (assert_msg "check slbind" (is_a slbind class_label_binding) slbind)
4655     (put_env newenv slbind)
4656     (let ( (resy (clone_symbol (unsafe_get_field :binder slbind))) )
4657       (debug "normexp_forever putting resy=" resy " in slbind=" slbind)
4658       (unsafe_put_fields slbind :labind_clonsy resy)
4659       (debug "normexp_forever updated slbind" slbind)
4660       (assert_msg "check resy" (is_a resy class_cloned_symbol) resy)
4661       (debug "normexp_forever got1 clonsy "(unsafe_get_field :labind_clonsy slbind) )
4662       (assert_msg "check did1 put resy" (== (unsafe_get_field :labind_clonsy slbind) resy) resy slbind)
4663       (multicall
4664        (nbody nbodbindings)
4665        (normalize_tuple sbody newenv ncx sloc)
4666        (debug "normexp_forever again slbind=" slbind " nbody=" nbody " nbodbindings=" nbodbindings)
4667        ;; prepend an interrupt check binding
4668        (let ( (cintsymb (clone_symbol 'forever_inter_))
4669               (nchint (instance class_nrep_checksignal
4670                                 :nrep_loc sloc))
4671               (cintbind (instance class_normal_let_binding
4672                                   :binder cintsymb
4673                                   :letbind_type ctype_void
4674                                   :letbind_expr nchint))
4675              )
4676          (if (null nbodbindings) 
4677              (setq nbodbindings (list cintbind))
4678            (list_prepend nbodbindings cintbind))
4679          )
4680        (assert_msg "check size slbind" (<i (get_int labind_clonsy) (object_length slbind)) labind_clonsy slbind)
4681        (let (
4682              (resbody (tuple 
4683                        (wrap_normal_letseq nbody nbodbindings sloc)))
4684              (csym (clone_symbol 'forever_))
4685              (nforever (instance class_nrep_forever
4686                                  :nrep_loc sloc
4687                                  :nforever_bind slbind
4688                                  :nforever_body resbody
4689                                  :nforever_result resy)) 
4690              (cbind (instance class_normal_let_binding
4691                               :binder csym
4692                               :letbind_loc sloc
4693                               :letbind_type ctype_value
4694                               :letbind_expr nforever))
4695              (clocc (instance class_nrep_locsymocc
4696                               :nrep_loc sloc
4697                               :nocc_ctyp ctype_value
4698                               :nocc_symb csym
4699                               :nocc_bind cbind))
4700              (nforbindings (make_list discr_list))
4701              )
4702          (list_append nforbindings cbind)
4703          (debug "normexp_forever return clocc=" clocc 
4704                 " nforbindings=" nforbindings)
4705          (return clocc nforbindings)
4706          )
4707        ))))
4708 (install_method class_source_forever normal_exp normexp_forever)
4711 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4712 ;;;; normalize an exit
4713 ;;; the normalization of an exit is a local variable of ctype_void
4714 ;;; this enables detection of applications like (foo (exit looplab))
4715 (defun normexp_exit (recv env ncx psloc)
4716   (assert_msg "check exit recv" (is_a recv class_source_exit) recv)
4717   (assert_msg "check env" (is_a env class_environment) env)
4718   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4719   (debug "normexp_exit recv" recv)
4720   (let ( (sloc   (unsafe_get_field :loca_location recv))
4721          (slbind (unsafe_get_field :slabel_bind recv))
4722          (sbody (unsafe_get_field :sexi_body recv))
4723          (newenv (fresh_env env))
4724          )
4725     (assert_msg "check slbind" (is_a slbind class_label_binding) slbind)
4726     (put_env newenv slbind)
4727     (multicall
4728      (nbody nbodbindings)
4729      (normalize_tuple sbody newenv ncx sloc)
4730      (if (null nbodbindings)
4731          (setq nbodbindings (make_list discr_list)))
4732      ;; the only interesting value of nbody is the last one
4733      (let ( (nexit (instance class_nrep_exit
4734                              :nrep_loc sloc
4735                              :nexit_bind slbind
4736                              :nexit_val (multiple_nth nbody (-i (multiple_length nbody) 1)))) 
4737             (csym (clone_symbol 'exit_))
4738             (cbind (instance class_normal_let_binding
4739                              :binder csym
4740                              :letbind_loc sloc
4741                              :letbind_type ctype_void
4742                              :letbind_expr nexit))
4743             (clocc (instance class_nrep_locsymocc
4744                              :nrep_loc sloc
4745                              :nocc_ctyp ctype_void
4746                              :nocc_symb csym
4747                              :nocc_bind cbind))
4748             )
4749        (list_append nbodbindings cbind)
4750        (debug "normexp_exit clocc=" clocc " nbodbindings=" nbodbindings)
4751        (return clocc nbodbindings)
4752        ))))
4753 (install_method class_source_exit normal_exp normexp_exit)
4755 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4756 ;;;;;; normalize again
4757 (defun normexp_again (recv env ncx psloc)
4758   (debug "normexp_again recv=" recv)
4759   (assert_msg "check again recv" (is_a recv class_source_again) recv)
4760   (assert_msg "check env" (is_a env class_environment) env)
4761   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4762   (let ( (sloc   (unsafe_get_field :loca_location recv))
4763          (slbind (unsafe_get_field :slabel_bind recv))
4764          (csym (clone_symbol 'again_))
4765          (nagain (instance class_nrep_again
4766                            :nrep_loc sloc
4767                            :nagain_bind slbind))
4768          (cbind (instance class_normal_let_binding
4769                           :binder csym
4770                           :letbind_loc sloc
4771                           :letbind_type ctype_void
4772                           :letbind_expr nagain))
4773          (clocc (instance class_nrep_locsymocc
4774                           :nrep_loc sloc
4775                           :nocc_ctyp ctype_void
4776                           :nocc_symb csym
4777                           :nocc_bind cbind))     
4778          (nbindings (list cbind))
4779          )
4780     (assert_msg "check slbind" (is_a slbind class_label_binding) slbind)
4781     (debug "normexp_again clocc=" clocc " nbindings=" nbindings)
4782     (return clocc nbindings)    
4783     ))
4784 (install_method class_source_again normal_exp normexp_again)
4787 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4788 ;;;;;; normalize ifvariadic
4789 (defun normexp_ifvariadic (recv env ncx psloc)
4790   (debug "normexp_ifvariadic recv=" recv)
4791   (assert_msg "check ifvariadic recv" (is_a recv class_source_ifvariadic) recv)
4792   (assert_msg "check env" (is_a env class_environment) env)
4793   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4794   (let ( (loc (or (unsafe_get_field :loca_location recv) psloc))
4795          (sargs (unsafe_get_field :sifvariadic_argbind recv))
4796          (:long nbargs (multiple_length sargs))
4797          (sthen (unsafe_get_field :sifvariadic_then recv))
4798          (selse (unsafe_get_field :sifvariadic_else recv))
4799          (curpro (unsafe_get_field :nctx_curproc ncx))
4800          (sycmap (unsafe_get_field :nctx_symbcachemap ncx))
4801          (curprocargs (get_field :nrclop_argbindtuple curpro))
4802          (nprovariadic (get_field :nrpro_variadic curpro))
4803          (newenv (fresh_env env))
4804          )
4805     (debug "normexp_ifvariadic curpro=" curpro "\n.. sycmap=" sycmap "\n.. loc=" loc)
4806     (assert_msg "normexp_ifvariadic check sthen" (is_multiple_or_null sthen) sthen)
4807     (assert_msg "normexp_ifvariadic check selse" (is_multiple_or_null selse) selse)
4808     (when (is_not_a curprocargs discr_variadic_formal_sequence)
4809       (debug "normexp_ifvariadic bad curprocargs=" curprocargs " loc=" loc)
4810       (error_at loc "(VARIADIC ...) used in non-variadic function")
4811       (return))
4812     (debug "normexp_ifvariadic nprovariadic=" nprovariadic "; loc=" loc)
4813     (assert_msg "normexp_ifvariadic has nprovariadic" nprovariadic nprovariadic)
4814     ;; we transform the sequence of formal bindings into a sequence of
4815     ;; normal let bindings...
4816     (let ( (letbindtup (make_multiple discr_multiple nbargs))
4817            (letbindthenlist (make_list discr_list))
4818            (locsymtup (make_multiple discr_multiple nbargs))
4819            (ctyptup (make_multiple discr_multiple nbargs))
4820            )
4821       (foreach_in_multiple
4822        (sargs)
4823        (fbi :long fbix)
4824        (debug "normexp_ifvariadic fbi=" fbi)
4825        (assert_msg "check fbi" (is_a fbi class_formal_binding) fbi)
4826        (let ( (curbinder (unsafe_get_field :binder fbi))
4827               (curctype (unsafe_get_field :fbind_type fbi))
4828               (curvararg (instance class_nrep_variadic_argument
4829                                    :nrep_loc loc
4830                                    :nvarg_ctyp curctype
4831                                    :nvarg_variadic nprovariadic
4832                                    :nvarg_offset (make_integerbox discr_constant_integer fbix) 
4833                                    ))
4834               (curletbind (instance class_normal_let_binding
4835                                     :binder curbinder
4836                                     :letbind_loc loc
4837                                     :letbind_type curctype
4838                                     :letbind_expr curvararg))
4839               (curlocc (instance class_nrep_locsymocc
4840                                  :nrep_loc loc
4841                                  :nocc_ctyp curctype
4842                                  :nocc_symb curbinder
4843                                  :nocc_bind curletbind))
4844               )
4845          (multiple_put_nth letbindtup fbix curletbind)
4846          (list_append letbindthenlist curletbind)
4847          (debug "normexp_ifvariadic curletbind=" curletbind
4848                 "\n.. curlocc=" curlocc "\n.. curctype=" curctype)
4849          (multiple_put_nth locsymtup fbix curlocc)
4850          (multiple_put_nth ctyptup fbix curctype)
4851          (assert_msg "check curctype" (is_a curctype class_ctype) curctype)
4852          (put_env newenv curletbind)             
4853          ))
4854       (debug "normexp_ifvariadic letbindthenlist=" letbindthenlist "\n.. letbindtup=" letbindtup 
4855              "\n.. sycmap=" sycmap
4856              "\n.. loc=" loc)
4857       (let ( (cvarsym (clone_symbol 'consumvariadic_))
4858              (nconsume (instance class_nrep_consume_variadic
4859                                  :nrep_loc loc
4860                                  :nconsva_variadic nprovariadic
4861                                  :nconsva_ctypes ctyptup
4862                                  ))
4863              (cvarbind (instance class_normal_let_binding
4864                                  :binder cvarsym
4865                                  :letbind_loc loc
4866                                  :letbind_type ctype_void
4867                                  :letbind_expr nconsume))
4868              )
4869         (list_append letbindthenlist cvarbind)
4870         )
4871       (debug "normexp_ifvariadic letbindthenlist=" letbindthenlist
4872              "\n.. letbindtup=" letbindtup
4873              "\n.. locsymtup=" locsymtup
4874              "\n.. ctyptup=" ctyptup
4875              " sthen=" sthen "\n.. loc=" loc)
4876       (multicall
4877        (nthen nthenbindings)
4878        (normalize_tuple sthen newenv ncx loc)
4879        (debug "normexp_ifvariadic nthen=" nthen " nthenbindings=" nthenbindings
4880               "\n.. loc=" loc)
4881        (list_append2list letbindthenlist nthenbindings)
4882        (debug "normexp_ifvariadic updated letbindthenlist=" letbindthenlist
4883               " selse=" selse "\n.. sycmap=" sycmap "\n.. loc=" loc)
4884        ;; forget every symbol in letbindtup from the sycmap, to fix MELT-SFT-8
4885        (foreach_in_multiple 
4886         (letbindtup)
4887         (curbind :long bix)
4888         (debug "normexp_ifvariadic curbind=" curbind "\n.. bix=" bix "\n.. loc=" loc)
4889         (let ( (cursym (get_field :binder curbind))
4890                (cachlocc (mapobject_get sycmap cursym))
4891                )
4892           (when cachlocc
4893             (assert_msg "check cachlocc" (is_a cachlocc class_nrep_locsymocc) cachlocc)
4894             (debug "normexp_ifvariadic forgetting cachlocc=" cachlocc "\n.. cursym=" cursym)
4895             (mapobject_remove sycmap cursym)))
4896         )
4897        (debug "normexp_ifvariadic cleaned sycmap=" sycmap "\n.. loc=" loc)
4898        ;;
4899        (multicall
4900         (nelse nelsebindings)
4901 ;;;; we had::: (normalize_tuple selse newenv ncx loc)
4902 ;;; but very probably the else don't need the supplementary binding...
4903         (normalize_tuple selse env ncx loc)
4904         (debug "normexp_ifvariadic nelse=" nelse " nelsebindings=" nelsebindings "\n.. loc=" loc)
4905         (let ( 
4906               (csym (clone_symbol 'ifvariadic_))
4907               (cbind (instance class_normal_let_binding
4908                                :binder csym
4909                                :letbind_loc loc
4910                                :letbind_type ctype_void
4911                                :letbind_expr () ;filled later
4912                                ))
4913               (clocc (instance class_nrep_locsymocc
4914                                :nrep_loc loc
4915                                :nocc_ctyp ctype_void
4916                                :nocc_symb csym
4917                                :nocc_bind cbind))
4918               (nthenlet 
4919                (progn
4920                  (debug "normexp_ifvariadic wrapping nthen=" nthen
4921                         "\n.. letbindthenlist=" letbindthenlist
4922                         "\n.. loc=" loc)
4923                  (wrap_normal_letseq nthen letbindthenlist loc)))
4924               (nelselet 
4925                (progn 
4926                  (debug "normexp_ifvariadic wrapping nelse=" nelse
4927                         "\n.. nelsebindings=" nelsebindings
4928                         "\n.. loc=" loc)
4929                  (wrap_normal_letseq nelse nelsebindings loc)))
4930               (nbindlist (list cbind))
4931               (nifv (instance class_nrep_ifvariadic
4932                               :nrep_loc loc
4933                               :nif_then nthenlet
4934                               :nif_else nelselet
4935                               :nifv_variadic nprovariadic
4936                               :nifv_ctypes ctyptup))
4937               )
4938           (debug "normexp_ifvariadic nifv=" nifv)
4939           (put_fields cbind :letbind_expr nifv)
4940           (debug "normexp_ifvariadic result clocc=" clocc " nbindlist=" nbindlist)
4941           (return clocc nbindlist)
4942           ))))))
4943 (install_method class_source_ifvariadic normal_exp normexp_ifvariadic)
4946 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4947 ;;;;;; normalize the compile_warning
4948 (defun normexp_compile_warning  (recv env ncx psloc)
4949   (debug "normexp_compile_warning recv=" recv)
4950   (assert_msg "check compilewarn recv" (is_a recv class_source_compile_warning) recv)
4951   (assert_msg "check env" (is_a env class_environment) env)
4952   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4953   (let ((sloc  (unsafe_get_field :loca_location recv)) 
4954         (swmsg (unsafe_get_field :scdiag_msg recv))
4955         (swexp (unsafe_get_field :scdiag_expr recv))
4956         )
4957     (warning_at sloc "COMPILE_WARNING: $1" swmsg)
4958     (multicall 
4959      (nexp nbind)
4960      (normal_exp swexp env ncx sloc)
4961      (debug "normexp_compile_warning nesult nexp=" nexp " nbind=" nbind)
4962      (return nexp nbind)
4963      )))
4965 (install_method class_source_compile_warning normal_exp normexp_compile_warning)
4966 (install_method class_source_compile_warning get_ctype 
4967                 (lambda (recv env) (get_ctype (get_field :scdiag_expr recv) env)))
4969 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4970 ;;;;;; normalize the compile_error
4971 (defun normexp_compile_error  (recv env ncx psloc)
4972   (debug "normexp_compile_error recv=" recv)
4973   (assert_msg "check compileerror recv" (is_a recv class_source_compile_error) recv)
4974   (assert_msg "check env" (is_a env class_environment) env)
4975   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
4976   (let ((sloc  (unsafe_get_field :loca_location recv)) 
4977         (swmsg (unsafe_get_field :scdiag_msg recv))
4978         (swexp (unsafe_get_field :scdiag_expr recv))
4979         )
4980     (error_at sloc "COMPILE_ERROR: $1" swmsg)
4981     (multicall 
4982      (nexp nbind)
4983      (normal_exp swexp env ncx sloc)
4984      (debug "normexp_compile_error nesult nexp=" nexp " nbind=" nbind)
4985      (return nexp nbind)
4986      )))
4988 (install_method class_source_compile_error normal_exp normexp_compile_error)
4989 (install_method class_source_compile_error get_ctype 
4990                 (lambda (recv env) (get_ctype (get_field :scdiag_expr recv) env)))
4992 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4993 ;;;;;; replace in a tupe of normalized stuff the last with a return 
4994 ;;;;;; for normalization of defun-s or lambda-s
4995 (defun replace_last_by_return (tup env sloc)
4996   (assert_msg "check tup" (is_multiple tup) tup)
4997   (assert_msg "check env" (is_a env class_environment) env)
4998   (let ( (:long tuplen (multiple_length tup)) 
4999          (lastcomp (if (>i tuplen 0) (multiple_nth tup (-i tuplen 1)))) )
5000     (cond 
5001 ;;; last expression is already a return - do nothing
5002      ( (is_a lastcomp class_nrep_return)
5003        (return tup)
5004        )
5005 ;;; last expression is a symbol occurrence (closed or local) - return it if it is a value 
5006      ( (is_a lastcomp class_nrep_symocc)
5007        (if (== (unsafe_get_field :nocc_ctyp lastcomp) ctype_value)
5008            (multiple_put_nth 
5009             tup  (-i tuplen 1)
5010             (instance class_nrep_return
5011                       :nrep_loc sloc
5012                       :nret_main lastcomp)))
5013        (return tup)
5014        )
5015 ;;; last expression is a normal data, return it
5016      ( (is_a lastcomp class_nrep_bound_data)
5017        (multiple_put_nth 
5018         tup  (-i tuplen 1)
5019         (instance class_nrep_return
5020                   :nrep_loc sloc
5021                   :nret_main lastcomp))
5022        (return tup)
5023        )
5024 ;;; no last expression - don't bother to return
5025      ( (null lastcomp)
5026        (return tup)
5027        )
5028 ;;; last expression is a normalized let, recurse on the body within a new env
5029      ( (is_a lastcomp class_nrep_let)
5030        (let ( (lbody (unsafe_get_field :nlet_body lastcomp)) 
5031               (lbinding (unsafe_get_field :nlet_bindings lastcomp))
5032               (lloc (unsafe_get_field :nrep_loc lastcomp))
5033               (newenv (fresh_env env))
5034               )
5035          (multiple_every
5036           lbinding
5037           (lambda (bnd :long ix)
5038             (put_env newenv bnd)
5039             ))
5040          (if (is_multiple lbody) 
5041              (replace_last_by_return lbody newenv lloc))
5042          (return tup)
5043          ))
5044 ;;; last expression is some more complex normalized stuff
5045 ;;; if it is a value wrap it into a normalized let with return 
5046      ( (is_a lastcomp class_nrep)
5047        (let ( (lastyp (get_ctype lastcomp env)) 
5048               (loc (unsafe_get_field :nrep_loc lastcomp))
5049               )
5050          (if (== lastyp ctype_value)
5051              (let ( (rclosym (clone_symbol '_retval_))
5052                     (rclocc (instance class_nrep_locsymocc 
5053                                       :nrep_loc loc
5054                                       :nocc_symb rclosym
5055                                       :nocc_ctyp ctype_value))
5056                     (retn (instance class_nrep_return
5057                                     :nrep_loc loc
5058                                     :nret_main rclocc
5059                                     ))
5060                     (rbind (instance class_normal_let_binding
5061                                      :binder rclosym
5062                                      :letbind_type ctype_value
5063                                      :letbind_expr lastcomp
5064                                      :letbind_loc loc
5065                                      ))
5066                     (rbintup (tuple rbind))
5067                     (rlet (instance class_nrep_let
5068                                     :nrep_loc loc
5069                                     :nlet_bindings rbintup
5070                                     :nlet_body (tuple retn)))
5071                     )
5072                (unsafe_put_fields rclocc :nocc_bind rbind)
5073                (multiple_put_nth 
5074                 tup  (-i tuplen 1)
5075                 rlet)
5076                (return tup)
5077                )))))
5078     (return tup)                        ; returns the original tuple
5079 ;;; general case, do nothing 
5080     )
5081   )
5084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5085 ;;;;;; normalize a DEFUN or a DEFMACRO
5086 (defun normexp_defun_defmacro (recv env ncx psloc)
5087   (debug "normexp_defun_defmacro recv=" recv
5088          "\n.. env=" debug_more env
5089          "\n.. psloc=" psloc)
5090   (shortbacktrace_dbg "normexp_defun_defmacro" 8)
5091   (assert_msg "check defun recv" (is_a recv class_source_defun) recv)
5092   (assert_msg "check env" (is_a env class_environment) env)
5093   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5094   (let ( (sloc (or (unsafe_get_field :loca_location recv) psloc))
5095          (snam (get_field :sdef_name recv))
5096          (sformals (unsafe_get_field :sformal_args recv))
5097          (sbody (unsafe_get_field :sfun_body recv))
5098          (:long ismacro (is_a recv class_source_defmacro))
5099          (:long isletmacro (is_a recv class_source_defmacro_in_let))
5100          (modctx (get_field :nctx_modulcontext ncx))
5101          (modinienv (get_field :mocx_initialenv modctx))
5102          (macroenv (get_field :mocx_macroenv modctx))
5103          (basenv (progn
5104                    (debug "normexp_defun_defmacro" " sloc=" sloc
5105                           " ismacro=" ismacro " isletmacro=" isletmacro
5106                           "\n.. env=" env
5107                           "\n.. macroenv=" macroenv)
5108                    (let
5109                        ( 
5110                         (be (cond
5111                              (isletmacro
5112                               (debug "normexp_defun_defmacro" " isletmacro basenv=env=" debug_less env)
5113                               env)
5114                              (ismacro
5115                               (debug "normexp_defun_defmacro" " ismacro basenv=macroenv=" debug_less macroenv)
5116                               macroenv)
5117                              (:else
5118                               (debug "normexp_defun_defmacro" " nonmacro basenv=env=" debug_less env)
5119                               env)))
5120                         )
5121                      (debug "normexp_defun_defmacro sloc=" debug_less sloc
5122                             "; basenv=" be)
5123                      (debug "normexp_defun_defmacro snam=" snam
5124                             "\n in env got:" (find_env env snam)
5125                             "\n in macroenv got:" (find_env macroenv snam))
5126                      (assert_msg "check basenv" (is_a be class_environment))
5127                      be)))
5128          (sfubind (find_env basenv snam))
5129          (newenv (fresh_env basenv))
5130          (oldproc (unsafe_get_field :nctx_curproc ncx))
5131          (oldsymbcache (unsafe_get_field :nctx_symbcachemap ncx))
5132          (closblis (make_list discr_list))
5133          (cnstlist (make_list discr_list))
5134          (nproc (instance class_nrep_defunroutproc
5135 ;;; dont forget to put the nil fields at end
5136                           :nrep_loc sloc
5137                           :nproc_body () ;filled later
5138                           :nrclop_name snam
5139                           :nrclop_argbindtuple sformals
5140                           :nrclop_clobindlist closblis
5141                           :nrclop_constlist cnstlist
5142                           :nrclop_objconstcachemap (make_mapobject discr_map_objects 31)
5143                           :nrpro_thunklist (make_list discr_list)
5144                           :nrpro_datarout () ; filled below
5145                           :nrpro_dataclos () ; filled below
5146                           :nrpro_variadic () ; filled below
5147                           ))
5148          (ndatarout (instance class_nrep_dataroutine
5149                               :ndata_name snam
5150                               :ndata_discrx (normal_predef discr_routine ncx sloc "discr_routine")
5151                               :ndrou_proc nproc
5152                               ))
5153          (ndataclos (instance class_nrep_dataclosure
5154                               :ndata_name snam
5155                               :ndata_discrx 
5156                               (if ismacro
5157                                   (normal_predef discr_macro_closure ncx sloc "discr_macro_closure")
5158                                 (normal_predef discr_closure ncx sloc "discr_closure"))
5159                               :ndclo_proc nproc
5160                               :ndclo_closv () ;filled below
5161                               ))
5162          )
5163     (debug "normexp_defun_defmacro ismacro=" ismacro "; sloc=" debug_less sloc 
5164            "\n.. basenv=" (if ismacro debug_more debug_less) basenv 
5165            "\n.. newenv=" newenv)
5166     (unsafe_put_fields ncx 
5167                        :nctx_curproc nproc
5168                        :nctx_symbcachemap (make_mapobject discr_map_objects 40))
5169     (debug "normexp_defun_defmacro nproc=" nproc 
5170            "\n.. ndatarout=" ndatarout 
5171            "\n.. ndataclos=" ndataclos
5172            "\n.. newenv=" newenv)
5173     (add_nctx_data ncx ndatarout)
5174     (add_nctx_data ncx ndataclos)
5175     (debug "normexp_defun_defmacro updated ncx=" debug_less ncx "\n.. sloc=" debug_less sloc
5176            "\n.. sfubind=" sfubind)
5177     (when (null sfubind)
5178       (debug "normexp_defun_defmacro null sfubind ismacro=" ismacro 
5179              " from basenv=" debug_more basenv 
5180              "\n... snam=" snam "\n.. recv=" recv "\n")
5181       (if ismacro
5182           (error_at sloc
5183                     "bad defmacro-ed function $1 without binding" (get_field :named_name snam))
5184         (error_at sloc "bad defun-ed function $1 without binding" (get_field :named_name snam)))
5185       (shortbacktrace_dbg "normexp_defun_defmacro bad DEFUNed unbound function" 14)
5186       (return))
5187     (when (and 
5188            (is_not_a sfubind class_function_binding)
5189            (is_not_a sfubind class_macro_binding)
5190            (is_not_a sfubind class_defined_macro_binding))
5191       (debug "normexp_defun_defmacro strange sfubind=" sfubind)
5192       (if ismacro
5193           (error_at sloc
5194                     "bad defmacro-ed function $1 with binding of $2 [nested definitions are prohibited]"
5195                     (get_field :named_name snam) (get_field :named_name (discrim sfubind)))
5196           
5197         (error_at sloc
5198                   "bad defun-ed function $1 with binding of $2 [nested definitions are prohibited]"
5199                   (get_field :named_name snam) (get_field :named_name (discrim sfubind))))
5200       (shortbacktrace_dbg "normexp_defun_defmacro bad DEFUNed function" 14)
5201       (return))
5202     (unsafe_put_fields nproc :nrpro_datarout ndatarout :nrpro_dataclos ndataclos)
5203     (debug "normexp_defun_defmacro updated nproc=" nproc)
5204     (foreach_in_multiple 
5205      (sformals)
5206      (fbi :long ix)
5207      (assert_msg "check fbi" (is_a fbi class_formal_binding) fbi)
5208      (put_env newenv fbi))
5209     (if (is_a sformals discr_variadic_formal_sequence)
5210         (put_fields nproc :nrpro_variadic snam))
5211     (unsafe_put_fields newenv :env_proc nproc)
5212     (debug "normexp_defun_defmacro updated :env_proc of of newenv" debug_more newenv)
5213     (shortbacktrace_dbg "normexp_defun_defmacro update-envproc" 10)
5214     ;; add nproc into ncx
5215     (let ( (ncplis (get_field :nctx_proclist ncx)) 
5216            )
5217       (list_append ncplis nproc)
5218       (debug "normexp_defun_defmacro appended to nctxproclist ncplis=" ncplis
5219              "\n.. ncx=" ncx)
5220       (shortbacktrace_dbg "normexp_defun_defmacro" 15)
5221       )
5222     ;;
5223     (multicall
5224      (nbody nbindings)
5225      (normalize_tuple sbody newenv ncx sloc)
5226      (debug "normexp_defun_defmacro nbody before replace_last_by_return" nbody)
5227      (multiple_every
5228       nbindings
5229       (lambda (nbi :long ix)
5230         (put_env newenv nbi)))
5231      (let ( (nrbody (replace_last_by_return nbody newenv sloc)) 
5232             (npbody (wrap_normal_letseq nrbody nbindings sloc))
5233             )
5234        (unsafe_put_fields nproc  :nproc_body npbody)
5235        (debug "normexp_defun_defmacro after replace_last_by_return npbody=" npbody "\n.. nproc=" nproc)
5236        )
5237      (unsafe_put_fields ncx :nctx_curproc oldproc :nctx_symbcachemap oldsymbcache)
5238      (debug "normexp_defun_defmacro restored ncx=" ncx)
5239      (let ( (clovtup 
5240              (list_to_multiple 
5241               closblis
5242               discr_multiple
5243               (lambda (bnd)
5244                 (assert_msg "normexp_defun_defmacro check bnd" (is_a bnd class_any_binding) bnd)
5245                 (let ( (sy (unsafe_get_field :binder bnd)) 
5246                        ;; since sy is a symbol, its normalized form does not add any binding
5247                        ;; we normalize it in the *old* base environment, not the new one
5248                        (nsy (normal_exp sy basenv ncx sloc))
5249                        )
5250                   nsy
5251                   )))) )
5252        (unsafe_put_fields ndataclos :ndclo_closv clovtup)
5253        )
5254      ;; link the binding and the data
5255      (cond ( (is_a sfubind class_function_binding)
5256              (unsafe_put_fields sfubind :fixbind_data ndataclos))
5257            ( (is_a sfubind class_defined_macro_binding)
5258              (unsafe_put_fields sfubind :mbind_data ndataclos))
5259            ( (is_a sfubind class_macro_binding)
5260              (cond ( (and (melt_is_bootstrapping)
5261                           (== (get_field :binder sfubind) (get_field :ndata_name ndataclos)))
5262                      (debug "normexp_defun_defmacro good bootstrapping macro sfubind=" sfubind "\n ndataclos=" ndataclos)
5263                      (void))
5264                    (:else
5265                     (error_at  sloc "messy definition of $1 with existing macro binding"
5266                                snam)
5267                     (assert_msg "strange macro sfubind & ndataclos" () sfubind ndataclos)
5268                     (return))))
5269            (:else
5270             (debug "normexp_defun_defmacro strange sfubind=" sfubind "\n.. for ndataclos=" ndataclos)
5271             (assert_msg "bad sfubind" () sfubind ndataclos)))
5272      (debug "normexp_defun_defmacro return ndataclos=" ndataclos)
5273      (return ndataclos ())
5274      )
5275     ))
5276 (install_method class_source_defun normal_exp normexp_defun_defmacro)
5279 ;;; normalize the installation of a macro
5280 (defun normexp_macro_installation (recv env ncx psloc)
5281   (debug "normexp_macro_installation recv=" recv "\n... env=" env)
5282   (assert_msg "check recv" (is_a recv class_source_macro_installation) recv)
5283   (assert_msg "check env" (is_a env class_environment) env)
5284   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5285   (shortbacktrace_dbg "normexp_macro_installation" 16)
5286   (let ( (loc (or (unsafe_get_field :loca_location recv) psloc))
5287          (sdefmacro (unsafe_get_field :smacinst_defmacro recv))
5288          (modctx (get_field :nctx_modulcontext ncx))
5289          (macroenv (get_field :mocx_macroenv modctx))
5290          (modname (get_field :mocx_modulename modctx))
5291          (srcenv (get_field :smacinst_env recv))
5292          )
5293     (debug "normexp_macro_installation" " loc=" debug_less loc "; sdefmacro=" sdefmacro
5294            "\n.. macroenv=" debug_more macroenv
5295            "\n.. srcenv=" debug_more srcenv)
5296     (assert_msg "check modctx" (is_a modctx class_any_module_context) modctx)
5297     (assert_msg "check macroenv" (is_a macroenv class_environment) macroenv)
5298     (assert_msg "check srcenv" (is_a srcenv class_environment) srcenv)
5299     (assert_msg "check sdefmacro" (is_a sdefmacro class_source_defmacro) sdefmacro)
5300     (debug "normexp_macro_installation" " before normalizing loc=" loc "; sdefmacro=" sdefmacro)
5301     (let (
5302           (nclos (normexp_defun_defmacro sdefmacro srcenv ncx loc))
5303           (mbind (get_field :smacro_binding sdefmacro))
5304           (msymb (get_field :binder mbind))
5305           )
5306       (debug "normexp_macro_installation" " loc=" debug_less loc "; nclos=" nclos
5307              "\n.. mbind=" mbind "\n.. macroenv=" macroenv
5308              "\n")
5309       (assert_msg "check modctx" (is_a modctx class_running_extension_module_context) modctx recv)
5310       (assert_msg "check nclos" (is_a nclos class_nrep_dataclosure) nclos env recv)
5311       (assert_msg "check mbind" (is_a mbind class_defined_macro_binding) mbind env recv)
5312       (let ( 
5313             (nlitsym (clone_symbol msymb))
5314             (nclosym (clone_symbol msymb))
5315             (nlitbind (let ( (nli (register_literal_value mbind modctx)) )
5316                         (debug "normexp_macro_installation" " nlitbind=" nli)
5317                         nli))
5318             (clobind (instance class_normal_let_binding
5319                                :letbind_loc loc
5320                                :binder nclosym
5321                                :letbind_type ctype_value
5322                                :letbind_expr nclos))
5323             (closocc (instance class_nrep_locsymocc
5324                                :nrep_loc loc
5325                                :nocc_ctyp ctype_value
5326                                :nocc_symb nclosym
5327                                :nocc_bind clobind))
5328             (nlitval (let ( (nlv (instance class_nrep_literalnamedvalue
5329                                            :nlitval_regval nlitbind
5330                                            :nlitval_symbol nlitsym))
5331                             )
5332                        (debug "normexp_macro_installation" " nlitval=" nlv)
5333                        nlv))
5334             (nhcall  (let ( (nhc (instance class_nrep_hook_call
5335                                            :nrep_loc loc
5336                                            :nexpr_ctyp ctype_void
5337                                            :nhook_name '"HOOK_MACRO_INSTALLER"
5338                                            :nexpr_args (tuple nlitval closocc)
5339                                            :nhook_called (normal_predef hook_macro_installer ncx
5340                                                                         loc "hook_macro_installer")
5341                                            :nhook_outs (tuple)
5342                                            :nhook_descr (hook_data hook_macro_installer)
5343                                            )) )
5344                        (debug "normexp_macro_installation" " nhcall=" nhc "\n.. loc=" loc)
5345                        nhc))
5346             (csym (clone_symbol (get_field :binder mbind)))
5347             (cbind (instance class_normal_let_binding
5348                              :letbind_loc loc
5349                              :binder csym
5350                              :letbind_type ctype_void
5351                              :letbind_expr nhcall))
5352             (symocc (instance class_nrep_locsymocc
5353                               :nrep_loc loc
5354                               :nocc_ctyp ctype_void
5355                               :nocc_symb csym
5356                               :nocc_bind cbind))
5357             )
5358         (debug "normexp_macro_installation" " nlitval=" nlitval "\n.. loc=" loc)
5359         (debug "normexp_macro_installation" " csym=" csym " nhcall=" nhcall)
5360         (debug "normexp_macro_installation" " final closocc=" closocc "\n.. symocc=" symocc 
5361                "\n.. cbind=" cbind "\n.. clobind=" clobind)
5362         (return (tuple closocc symocc) (list clobind cbind))
5363         ))))
5364 (install_method class_source_macro_installation normal_exp normexp_macro_installation)
5368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5369 ;;;;;; normalize a DEFHOOK
5370 (defun normexp_defhook (recv  env ncx psloc)
5371   (debug "normexp_defhook recv=" recv "\n.. ncx=" ncx "\n.. env=" env)
5372   (assert_msg "check defhook recv" (is_a recv class_source_defhook) recv)
5373   (assert_msg "check env" (is_a env class_environment) env)
5374   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5375   (let ( (sloc (unsafe_get_field :loca_location recv))
5376          (symb (get_field :sdef_name recv))
5377          (symbname (progn 
5378                      (debug "normexp_defhook symb=" symb)
5379                      (let ( (sn (get_field :named_name symb))
5380                             )
5381                        (debug "normexp_defhook symbname=" sn)
5382                        sn)))
5383          (sinformals (unsafe_get_field :sformal_args recv))
5384          (soutformals (unsafe_get_field :shook_out_formals recv))
5385          (sctype (unsafe_get_field :shook_ctype recv))
5386          (spredef (unsafe_get_field :shook_predef recv))
5387          (smodvar (unsafe_get_field :shook_variable recv))
5388          (sbody (unsafe_get_field :shook_body recv))
5389          (shobind (find_env env symb))
5390          (newenv (fresh_env env))
5391          (oldproc (unsafe_get_field :nctx_curproc ncx))
5392          (oldsymbcache (unsafe_get_field :nctx_symbcachemap ncx))
5393          (closbindlist (make_list discr_list))
5394          (constlist (make_list discr_list))
5395          (nproc (instance class_nrep_hookproc
5396                           :nrep_loc sloc
5397                           :nproc_body ()
5398                           :nrclop_name symbname
5399                           :nrclop_argbindtuple ()
5400                           :nrhook_outb ()
5401                           :nrhook_ctype sctype
5402                           :nrhook_datahook ()
5403                           :nrclop_clobindlist closbindlist
5404                           :nrclop_constlist constlist
5405                           :nrclop_objconstcachemap (make_mapobject discr_map_objects 31)
5406                           ))
5407          (descrhook (instance class_hook_descriptor
5408                               :named_name symbname
5409                               :hookdesc_in_formals sinformals
5410                               :hookdesc_out_formals soutformals
5411                               :hookdesc_ctype sctype
5412                               :hookdesc_hook ()))
5413          (ndatahook (instance class_nrep_datahook
5414                               :ndata_name symbname
5415                               :ndata_discrx (normal_predef discr_hook ncx sloc "discr_hook")
5416                               :ndhook_proc nproc
5417                               :ndhook_data ()
5418                               :ndhook_closv ()
5419                               :ndhook_predef spredef
5420                               :ndhook_modvarbind ()
5421                               ))
5422          ;; map of formal symbol -> data of formal_binding
5423          (formsymbmap (make_mapobject discr_map_objects
5424                                       (+i 9 (*i (+i (multiple_length sinformals) (multiple_length soutformals)) 2))))
5425          (formintuple (make_multiple discr_multiple (multiple_length sinformals)))
5426          (formoutuple (make_multiple discr_multiple (multiple_length soutformals)))                  
5427          (namstrdata (instance class_nrep_datastring
5428                                :nrep_loc sloc
5429                                :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
5430                                :nstr_string  symbname))
5431          (slotup (make_multiple discr_multiple
5432                                 (multiple_length (unsafe_get_field :class_fields class_hook_descriptor))))
5433          (insdata (instance class_nrep_datainstance
5434                             :nrep_loc sloc
5435                             :ndata_name symbname
5436                             :ndata_discrx (normal_predef class_hook_descriptor ncx sloc "class_hook_descriptor") 
5437                             :ninst_hash (make_integerbox discr_integer (obj_hash descrhook))
5438                             :ninst_slots slotup
5439                             )) 
5440          )
5441     (put_fields ndatahook :ndhook_data insdata)
5442     (put_fields nproc :nrhook_datahook ndatahook)
5443     (debug "normexp_defhook newenv=" newenv
5444            "\n.. oldproc=" oldproc "\n.. nproc=" nproc)
5445     (debug "normexp_defhook ndatahook=" ndatahook "\n.. sctype=" sctype)
5446     (debug "normexp_defhook descrhook=" descrhook "\n.. smodvar=" smodvar) 
5447     (if smodvar
5448         (let ( (modvarbind (find_env env smodvar))
5449                )
5450           (debug "normexp_defhook symbname=" symbname " smodvar=" smodvar " modvarbind=" modvarbind)
5451           (when (is_not_a modvarbind class_normal_module_variable_binding)
5452             (error_at sloc "DEFHOOK $1 has bad :VAR annotation, should be a module variable"_
5453                         symbname)
5454             (return)
5455             )
5456           (put_fields ndatahook :ndhook_modvarbind modvarbind)
5457           (debug "normexp_defhook updated ndatahook=" ndatahook)
5458           ))
5459     (assert_msg "check sctype" (is_a sctype class_ctype) sctype)
5460     (assert_msg "check symbname" (is_string symbname) symbname)
5461     (assert_msg "check sinformals" (and (is_multiple_or_null sinformals)
5462                                         (is_not_a sinformals discr_variadic_formal_sequence))
5463                 sinformals)
5464     (assert_msg "check soutformals" (and (is_multiple_or_null soutformals)
5465                                          (is_not_a soutformals discr_variadic_formal_sequence))
5466                 soutformals)
5467     (debug "normexp_defhook shobind=" shobind "\n oldproc=" oldproc " \n nproc=" nproc
5468            "\n ndatahook=" ndatahook)
5469     (put_fields ncx 
5470                 :nctx_curproc nproc
5471                 :nctx_symbcachemap (make_mapobject discr_map_objects 40))
5472     (add_nctx_data ncx ndatahook)
5473     (add_nctx_data ncx insdata)
5474     (when (is_not_a shobind class_hook_binding)
5475       (error_at sloc
5476                 "bad hook definition $1, not bound to a hook but $2 [nested hooks are prohibited]"
5477                 symbname (get_field :named_name (discrim shobind)))
5478       (return))
5479 ;;; fill the named_name of insdata
5480     (debug "normexp_defhook namstrdata=" namstrdata)
5481     (add_nctx_data ncx namstrdata)
5482     (multiple_put_nth slotup (get_int named_name) namstrdata)
5483     ;; fill the hookdesc_in_formals of insdata
5484     (fill_normal_formals sinformals formintuple formsymbmap env ncx sloc)
5485     (let ( (nintupdata (instance class_nrep_datatuple
5486                                  :nrep_loc sloc
5487                                  :ndata_name symbname
5488                                  :ndata_discrx  (normal_predef discr_multiple ncx sloc "discr_multiple")
5489                                  :ntup_comp formintuple))
5490            )
5491       (add_nctx_data ncx nintupdata)
5492       (multiple_put_nth slotup (get_int hookdesc_in_formals) nintupdata)
5493       (debug "normexp_defhook nintupdata=" nintupdata))
5494     ;; fill the hookdesc_out_formals of insdata
5495     (fill_normal_formals soutformals formoutuple formsymbmap env ncx sloc)
5496     (let ( (noutupdata (instance class_nrep_datatuple
5497                                  :nrep_loc sloc
5498                                  :ndata_name symbname
5499                                  :ndata_discrx  (normal_predef discr_multiple ncx sloc "discr_multiple")
5500                                  :ntup_comp formoutuple))
5501            )
5502       (add_nctx_data ncx noutupdata)
5503       (multiple_put_nth slotup (get_int hookdesc_out_formals) noutupdata)
5504       (debug "normexp_defhook noutupdata=" noutupdata))
5505     ;; fill the hookdesc_ctype of insdata
5506     (multiple_put_nth slotup (get_int hookdesc_ctype) (normal_predef sctype ncx sloc "hook ctype"))
5507     ;;
5508     (debug "normexp_defhook slotup=" slotup)
5509     ;;
5510     (debug "normexp_defhook updated ncx=" ncx "\n .. nproc=" nproc)
5511     (foreach_in_multiple
5512      (sinformals)
5513      (fbi :long ix)
5514      (assert_msg "check fbi" (is_a fbi class_formal_binding) fbi)
5515      (put_env newenv fbi))
5516     (foreach_in_multiple
5517      (soutformals)
5518      (fbo :long ix)
5519      (assert_msg "check fbo" (is_a fbo class_formal_binding) fbo)
5520      (put_env newenv fbo))
5521     (put_fields nproc 
5522                 :nrclop_argbindtuple sinformals
5523                 :nrhook_outb soutformals)
5524     (put_fields newenv :env_proc nproc)
5525     (debug "normexp_defhook updated newenv=" newenv)
5526     ;;
5527     (multicall
5528      (nbody nbindings)
5529      (normalize_tuple sbody newenv ncx sloc)
5530      (debug "normexp_defhook nbody=" nbody "\n.. nbindings=" nbindings)
5531      ;; add nproc into ncx
5532      (let ( (ncplis (get_field :nctx_proclist ncx)) 
5533             )
5534        (list_append ncplis nproc)
5535        (debug "normexp_defhook sbody=" sbody "\n.. updated ncx=" ncx "\n.. ncplis=" ncplis)
5536        )
5537      (shortbacktrace_dbg "normexp_defhook" 12)
5538      ;; make the bindings in the newenv
5539      (foreach_in_multiple
5540       (nbindings)
5541       (nbi :long bix)
5542       (put_env newenv nbi))
5543      (debug "normexp_defhook updated newenv=" newenv)
5544      ;; restore the previous symbol cache map & the old proc 
5545      (put_fields ncx 
5546                  :nctx_symbcachemap oldsymbcache
5547                  :nctx_curproc oldproc
5548                  )
5549      (debug "normexp_defhook restored ncx=" ncx)
5550      (debug "normexp_defhook closbindlist=" closbindlist "\n.. constlist=" constlist)
5551      (assert_msg "check closbindlist" (is_list closbindlist) closbindlist)
5552      (assert_msg "check constlist" (is_list constlist) constlist)
5553      ;; normalize the closed and the const values
5554      (let ( (nseq (wrap_normal_letseq nbody nbindings sloc))
5555             (:long nbclosbind (list_length closbindlist))
5556             (:long nbconst (list_length constlist))
5557             (:long ix 0)
5558             (closvtup (make_multiple discr_multiple (+i nbclosbind nbconst)))
5559             )
5560        (debug "normexp_defhook nbclosbind#" nbclosbind " nbconst#" nbconst)
5561        ;;
5562        (foreach_pair_component_in_list 
5563         (closbindlist)
5564         (curpair curclobnd)
5565         (debug "normexp_defhook curclobnd=" curclobnd " ix#" ix)
5566         (assert_msg "check curclobnd" (is_a curclobnd class_any_binding) curclobnd)
5567         (let ( (sy (unsafe_get_field :binder curclobnd)) 
5568                ;; normalize in the *old* environment
5569                (nsy (normal_exp sy env ncx sloc))
5570                )
5571           (debug "normal_exp nsy=" nsy)
5572           (multiple_put_nth closvtup ix nsy)
5573           (setq ix (+i ix 1))
5574           ))                            ;end foreach closbindlist
5575        (debug "normexp_defhook after closbindloop ix=" ix " closvtup=" closvtup)
5576        ;;
5577        (debug "normexp_defhook closing constlist=" constlist)
5578        (foreach_pair_component_in_list
5579         (constlist)
5580         (curpair curconst)
5581         (debug "normexp_defhook curconst=" curconst " ix#" ix)
5582         (assert_msg "check curconst" (is_a curconst class_nrep) curconst)
5583         (multiple_put_nth closvtup ix curconst)
5584         (setq ix (+i ix 1))
5585         )                               ;end foreach constlist
5586        (debug "normexp_defhook after constlistloop ix=" ix " closvtup=" closvtup)
5587        (assert_msg "check final ix" (==i ix (+i nbclosbind nbconst)) ix)
5588        ;;
5589        (debug "normexp_defhook nseq=" nseq "\n ..final closvtup=" closvtup)
5590        (put_fields nproc :nproc_body nseq)
5591        (put_fields ndatahook :ndhook_closv closvtup)
5592        (put_fields shobind :fixbind_data ndatahook)
5593        (debug "normexp_defhook final nproc=" nproc)
5594        (debug "normexp_defhook final ndatahook=" ndatahook 
5595               "\n.. shobind=" shobind)
5596        ;;
5597        (debug "normexp_defhook result nproc=" nproc)
5598        (return nproc ())
5599        ))))
5600 (install_method class_source_defhook normal_exp normexp_defhook)
5605 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5606 ;;;;;; normalize a LAMBDA
5608 ;;; an internal routine useful for lambda inside letrec ... to share
5609 ;;; code between normexp_lambda and handling of lambda-s inside letrec
5610 (defun normalize_lambda (recv env newenv ncx psloc)
5611   (debug "normalize_lambda recv=" recv "\n.. env=" env "\n.. newenv=" newenv
5612          "\n ncx=" debug_less ncx)
5613   (shortbacktrace_dbg "normalize_lambda" 15)
5614   (assert_msg "check lambda recv" (is_a recv class_source_lambda) recv)
5615   (assert_msg "check env" (is_a env class_environment) env)
5616   (assert_msg "check newenv" (is_a newenv class_environment))
5617   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5618   (let ( (sloc (unsafe_get_field :loca_location recv))
5619          (sformalargs (unsafe_get_field :slam_argbind recv))
5620          (sbody (unsafe_get_field :slam_body recv))
5621          (:long ismacrosrc (is_a recv class_source_lambda_for_macro))
5622          (csym (if ismacrosrc
5623                    (clone_symbol 'lambdamacro_) 
5624                  (clone_symbol 'lambda_)))
5625          (clocc (instance class_nrep_locsymocc
5626                           :nrep_loc sloc
5627                           :nocc_ctyp ctype_value
5628                           :nocc_symb csym)) 
5629          (oldproc (unsafe_get_field :nctx_curproc ncx))
5630          (savedcachemap (unsafe_get_field :nctx_symbcachemap ncx))
5631          (closedblist (make_list discr_list))
5632          (cnstlist (make_list discr_list))
5633          (nproc (if ismacrosrc
5634                     (instance class_nrep_macrolambdaroutproc
5635                           :nrep_loc sloc
5636                           :nproc_body () ;filled later
5637                           :nrclop_name csym
5638                           :nrclop_argbindtuple sformalargs
5639                           :nrclop_clobindlist closedblist
5640                           :nrclop_constlist cnstlist
5641                           :nrclop_objconstcachemap (make_mapobject discr_map_objects 31)
5642                           :nrpro_datarout () ; filled below
5643                           :nrpro_dataclos () ; not filled
5644                           :nrpro_thunklist (make_list discr_list)
5645                           :nrpro_variadic () ; filled below
5646                               )
5647                     (instance class_nrep_lambdaroutproc
5648                           :nrep_loc sloc
5649                           :nproc_body () ;filled later
5650                           :nrclop_name csym
5651                           :nrclop_argbindtuple sformalargs
5652                           :nrclop_clobindlist closedblist
5653                           :nrclop_constlist cnstlist
5654                           :nrclop_objconstcachemap (make_mapobject discr_map_objects 31)
5655                           :nrpro_datarout () ; filled below
5656                           :nrpro_dataclos () ; not filled
5657                           :nrpro_thunklist (make_list discr_list)
5658                           :nrpro_variadic () ; filled below
5659                           )))
5660          (ndatarout (instance class_nrep_dataroutine
5661                               :nrep_loc sloc
5662                               :ndata_name csym
5663                               :ndata_discrx (normal_predef discr_routine ncx sloc "discr_routine")
5664                               :ndrou_proc nproc
5665                               ))
5666          )
5667     (debug "normalize_lambda" " sloc=" sloc " made nproc=" nproc "\n.. ndatarout=" ndatarout)
5668     (shortbacktrace_dbg "normalize_lambda" 12)
5669     (add_nctx_data ncx ndatarout)
5670     ;; update the context for the new proc & a fresh symbol cache map
5671     (unsafe_put_fields ncx 
5672                        :nctx_curproc nproc
5673                        :nctx_symbcachemap (make_mapobject discr_map_objects 40))
5674     (put_fields nproc :nrpro_datarout ndatarout)
5675     (debug "normalize_lambda" " sloc=" sloc " updated ncx=" ncx "\n.. nproc=" nproc)
5676     (foreach_in_multiple
5677      (sformalargs)
5678      (fbi :long ix)
5679      (assert_msg "check fbi" (is_a fbi class_formal_binding) fbi)
5680      (put_env newenv fbi))
5681     (if (is_a sformalargs discr_variadic_formal_sequence)
5682         (put_fields nproc :nrpro_variadic csym))
5683     (debug "normalize_lambda"  " sloc=" sloc " before updating newenv=" newenv)
5684     (put_fields newenv :env_proc nproc)
5685     (debug "normalize_lambda"  " sloc=" sloc " updated newenv=" debug_more newenv)
5686     (shortbacktrace_dbg "normalize_lambda" 15)
5687     ;; add nproc into ncx
5688     (let ( (ncplis (get_field :nctx_proclist ncx)) 
5689            )
5690       (list_append ncplis nproc)
5691       (debug "normalize_lambda"  " sloc=" sloc " updated ncplis=" ncplis "\n.. ncx=" ncx)
5692     )
5693     ;;
5694     (multicall
5695      (nbody nbindings)
5696      (normalize_tuple sbody newenv ncx sloc)
5697      (debug "normalize_lambda" " sloc=" sloc " nbody=" nbody "\n.. nbindings=" nbindings)
5698      (foreach_in_multiple
5699       (nbindings)
5700       (nbi :long ix)
5701       (put_env newenv nbi))
5702      (put_fields 
5703       nproc
5704       :nproc_body (wrap_normal_letseq (replace_last_by_return nbody newenv sloc) nbindings sloc)
5705       )
5706      (debug "normalize_lambda" " sloc=" sloc " newenv=" newenv "\n.. nproc=" nproc)
5707      ;; restore the previous symbol cache map & the old proc and return the normalized lambda
5708      (put_fields ncx 
5709                  :nctx_symbcachemap savedcachemap
5710                  :nctx_curproc oldproc
5711                  )
5712      (debug "normalize_lambda restored ncx=" ncx "\n.. updated nproc=" nproc
5713             "\n.. oldproc=" oldproc
5714             "\n.. closedblist=" closedblist)
5715      (let ( 
5716            ;; we make an anonymous constant for the routine unless in toplevel
5717            (:long insideflag (let ( (insfl (is_a oldproc class_nrep_closproc))
5718                                     )
5719                                (debug "normalize_lambda insideflag=" insfl)
5720                                insfl))
5721            (krout (if insideflag
5722                       (instance class_nrep_constant
5723                                 :nrep_loc sloc
5724                                 :nconst_sval recv
5725                                 :nconst_data ndatarout
5726                                 :nconst_proc oldproc)))
5727            (clovtup 
5728             (list_to_multiple 
5729              closedblist
5730              discr_multiple
5731              (lambda (bnd)
5732                (debug "normalize_lambda:lambdaclos" " sloc=" sloc "; bnd=" bnd)
5733                (shortbacktrace_dbg "normalize_lambda:lambdaclos" 10)
5734                (assert_msg "normalize_lambda check bnd" (is_a bnd class_any_binding) bnd)
5735                (let ( (sy (unsafe_get_field :binder bnd)) 
5736                       ;; since sy is a symbol, its normalized form does not add any binding
5737                       ;; we normalize it in the *old* environment, not the new one
5738                       (nsy (normal_exp sy env ncx sloc))
5739                       )
5740                  (debug "normalize_lambda:lambdaclos" " sloc=" sloc "; nsy=" nsy)
5741                  nsy))))
5742            (constrout  (if insideflag krout ndatarout))
5743            )
5744        (debug "normalize_lambda" " sloc=" sloc " insideflag=" insideflag
5745               "\n.. constrout=" constrout)
5746        (shortbacktrace_dbg "normalize_lambda returning" 8)
5747        (debug "normalize_lambda" " final ncx=" ncx
5748               "\n final env=" env
5749               "\n final newenv=" newenv)
5750        (debug "normalize_lambda" " return nproc=" nproc
5751               "\n.. csym=" csym 
5752               "\n.. clocc=" clocc 
5753               "\n.. constrout=" constrout
5754               "\n.. clovtup=" clovtup
5755               "\n.. sloc=" sloc
5756               "\n.. oldproc=" oldproc
5757               "\n.. ndatarout=" ndatarout
5758               "\n.. insideflag=" insideflag "\n")
5759        (return nproc csym clocc constrout clovtup sloc oldproc ndatarout insideflag)
5760        ))))
5762 ;;;;
5763 (defun normexp_lambda (recv env ncx psloc)
5764   (debug "normexp_lambda recv=" recv "\n..env=" env "\n.. ncx=" ncx)
5765   (assert_msg "check lambda recv" (is_a recv class_source_lambda) recv)
5766   (assert_msg "check env" (is_a env class_environment) env)
5767   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5768   (let (
5769         (newenv (fresh_env env))
5770         )
5771     (debug "normexp_lambda before normalize_lambda newenv=" newenv)
5772     (multicall 
5773      (nproc csym clocc constrout clovtup sloc oldproc ndatarout :long insideflag)
5774      (normalize_lambda recv env newenv ncx psloc)
5775      (debug "normexp_lambda after normalize_lambda nproc=" nproc "\n.. csym=" csym 
5776             "\n.. clocc=" clocc "\n.. constrout=" constrout "\n.. clovtup=" clovtup
5777             "\n.. sloc=" sloc "\n.. oldproc=" oldproc "\n.. ndatarout=" ndatarout
5778             "\n.. insideflag=" insideflag
5779             "\n.. newenv=" debug_more newenv)
5780      (let (
5781            (nlambda (instance class_nrep_lambda 
5782                               :nrep_loc sloc
5783                               :nlambda_proc nproc
5784                               :nlambda_constrout constrout
5785                               :nlambda_closedv clovtup
5786                               ))
5787            (cbind (instance class_normal_let_binding
5788                             :letbind_loc sloc
5789                             :binder csym
5790                             :letbind_type ctype_value
5791                             :letbind_expr nlambda))
5792            (nbindlist (make_list discr_list))
5793            )
5794        (unsafe_put_fields clocc :nocc_bind cbind)
5795        (list_append nbindlist cbind)
5796        (debug "normexp_lambda insideflag=" insideflag " oldproc=" oldproc)
5797        (when insideflag
5798          (list_append (get_field :nrclop_constlist oldproc) ndatarout)
5799          (debug "normexp_lambda updated constlist in oldproc=" oldproc)
5800          )
5801        (debug "normexp_lambda return clocc=" clocc " nbindlist=" nbindlist)
5802        (return clocc nbindlist)
5803        ))))
5804 (install_method class_source_lambda normal_exp normexp_lambda)
5805 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5807 (defun normexp_multicall (recv env ncx psloc)
5808   (assert_msg "check multicall recv" (is_a recv class_source_multicall) recv)
5809   (assert_msg "check env" (is_a env class_environment) env)
5810   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5811   (debug "normexp_multicall recv" recv)
5812   (let ( (sloc (unsafe_get_field :loca_location recv))
5813          (sresbind (unsafe_get_field :smulc_resbind recv))
5814          (scall (unsafe_get_field :smulc_call recv))
5815          (sbody (unsafe_get_field :smulc_body recv))
5816          (newenv (fresh_env env))
5817          )
5818     (debug "normexp_multicall scall" scall)
5819     (multicall
5820      (ncall ncallbindings)
5821      (normal_exp scall env ncx sloc)
5822      (debug "normexp_multicall ncall=" ncall " ncallbindings=" ncallbindings)
5823 ;;; since ncall is normalized, it is a class_nrep_locsymocc and
5824 ;;; the last binding in ncallbindings is a class_normal_let_binding
5825 ;;; whose binder is the nocc_symb of the ncall
5826      (assert_msg "normexp_multicall check ncall" (is_a ncall class_nrep_locsymocc) ncall)
5827      (let ( (ncallsym (unsafe_get_field :nocc_symb ncall)) 
5828             (ncontcall (reference ())) ;container to contain the real normalized call
5829             (nrealcall ())                     ;the real call
5830             (nincallbindings (make_list discr_list)) ;list of internal bindings to the call
5831             )
5832        (list_iterate_test       ;loop exited when cbnd is for ncallsym
5833         ncallbindings
5834         (lambda (cbnd)
5835           (assert_msg "normexp_multicall check cbnd" (is_a cbnd class_normal_let_binding) cbnd)
5836           (if (== ncallsym (unsafe_get_field :binder cbnd))
5837               (let ( (nrealcallex (unsafe_get_field :letbind_expr cbnd)) )
5838                 (set_ref ncontcall nrealcallex)
5839                 (return () ()))
5840             (progn (list_append nincallbindings cbnd) 
5841                    (return cbnd ())))
5842           ))
5843        (setq nrealcall (deref ncontcall))
5844        (debug "normexp_multicall got nrealcall" nrealcall)
5845        (multiple_every
5846         sresbind
5847         (lambda (bnd :long ix)
5848           (put_env newenv bnd)))
5849        (multicall
5850         (nbody nbodybindings)
5851         (normalize_tuple sbody newenv ncx sloc)
5852         (debug "normexp_multicall nbody=" nbody " nbodybindings=" nbodybindings)
5853         (let ( (wnbodylet (wrap_normal_letseq nbody nbodybindings sloc)) )
5854 ;;; remove every locally bound symbol from the symbol cache map
5855           (let ( (sycmap (unsafe_get_field :nctx_symbcachemap ncx)) )
5856             (multiple_every sresbind
5857                             (lambda (bnd)
5858                               (mapobject_remove sycmap (unsafe_get_field :binder bnd))
5859                               )))
5860           (let ( 
5861                 (lastnbody (multiple_nth nbody -1))
5862                 (lastntype (if lastnbody (get_ctype lastnbody newenv) ctype_void))
5863                 (csym (clone_symbol 'multi_))
5864                 (cbind (instance class_normal_let_binding
5865                                  :binder csym
5866                                  :letbind_loc sloc
5867                                  :letbind_type lastntype
5868                                         ; :letbind_expr  filled below
5869                                  ))
5870                 (clocc (instance class_nrep_locsymocc
5871                                  :nrep_loc sloc
5872                                  :nocc_ctyp lastntype
5873                                  :nocc_symb csym
5874                                  :nocc_bind cbind))
5875                 )
5876 ;;; handle differently apply & sends
5877             (cond
5878              ( (is_a scall class_source_apply)
5879                (assert_msg "normexp_multicall check nrealcall apply" (is_a nrealcall class_nrep_apply) nrealcall)
5880                (let ( (nres (instance class_nrep_multiapply
5881                                       :nrep_loc sloc
5882                                       :napp_fun (unsafe_get_field :napp_fun nrealcall)
5883                                       :nexpr_args (unsafe_get_field :nexpr_args nrealcall)
5884                                       :nexpr_ctyp lastntype
5885                                       :nmulapp_bindings sresbind
5886                                       :nmulapp_body wnbodylet)) )
5887                  (unsafe_put_fields cbind :letbind_expr nres)
5888                  (list_append nincallbindings cbind)
5889                  (debug "normexp_multicall multiapply result clocc=" clocc
5890                         " nincallbindings=" nincallbindings)
5891                  (return clocc nincallbindings)
5892                  )
5893                )
5894              ( (is_a scall class_source_msend)
5895                (debug "normexp_multicall multicall nrealcall" nrealcall)
5896                (compile_warning "in normexp_multicall we should check against the formals of the selector if available")
5897                (assert_msg "normexp_multicall check nrealcall send" (is_a nrealcall class_nrep_msend) nrealcall)
5898                (let ( (nrecv (get_field :nsend_recv nrealcall)) 
5899                       (nres (instance class_nrep_multimsend
5900                                       :nrep_loc sloc                          
5901                                       :nexpr_ctyp lastntype 
5902                                       :nsend_sel (unsafe_get_field :nsend_sel nrealcall)
5903                                       :nsend_recv nrecv
5904                                       :nexpr_args (unsafe_get_field :nexpr_args nrealcall)
5905                                       :nmulsend_bindings sresbind
5906                                       :nmulsend_body wnbodylet)) 
5907                       )
5908                  (debug "normexp_multicall nrecv from multicall=" nrecv)
5909                  (assert_msg "check nrecv" (is_object nrecv) nrecv)
5910                  (unsafe_put_fields cbind :letbind_expr nres)
5911                  (list_append nincallbindings cbind)
5912                  (debug "normexp_multicall multisend result clocc=" clocc
5913                         " nincallbindings=" nincallbindings)
5914                  (return clocc nincallbindings)
5915                  )
5916                )
5917              ( :else
5918                (error_at sloc "MULTICALL-ed expression neither apply nor send")
5919                (return ())
5920                )
5921              ))))))))
5923 (install_method class_source_multicall normal_exp normexp_multicall)
5925 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5928 (defun normexp_tuple (recv env ncx psloc)
5929   (assert_msg "check tuple recv" (is_a recv class_source_tuple) recv)
5930   (assert_msg "check env" (is_a env class_environment) env)
5931   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
5932   (debug "normexp_tuple recv" recv)
5933   (let ( (sloc (unsafe_get_field :loca_location recv))
5934          (sargs (unsafe_get_field :sargop_args recv))
5935          (csymrec (clone_symbol 'tuplrec_))
5936          (csymtup (clone_symbol 'tuple_))
5937          (normdiscrmult (normal_predef discr_multiple ncx sloc "discr_multiple"))
5938          (newenv (fresh_env env))
5939          )
5940     (debug "normexp_tuple csymrec" csymrec)
5941     (multicall
5942      (nargs nbindings)
5943      (normalize_tuple sargs env ncx sloc)
5944      (debug "normexp_tuple nargs=" nargs " nbindings=" nbindings)
5945      ;; insight: normalize (tuple x1 x2) exactly as 
5946      ;; as an anonymous letrec
5947      (letrec (
5948                (constupbind (instance class_normal_constructed_tuple_binding
5949                                       :binder csymrec
5950                                       :nconsb_loc sloc
5951                                       :nconsb_discr normdiscrmult
5952                                       :nconsb_nletrec nletrec
5953                                       :ntupb_comp nargs
5954                                       ))
5955                (clocc (instance class_nrep_locsymocc
5956                                 :nrep_loc sloc
5957                                 :nocc_ctyp ctype_value
5958                                 :nocc_symb csymrec
5959                                 :nocc_bind constupbind))
5960                (tup1bind (tuple constupbind))
5961                (tup1loc (tuple clocc))
5962                (nbdy (tuple clocc))
5963                (nletrec (instance class_nrep_letrec
5964                                   :nrep_loc sloc
5965                                   :nlet_bindings tup1bind
5966                                   :nlet_body nbdy
5967                                   :nletrec_fill_bindings ()
5968                                   :nletrec_body_bindings ()
5969 ;; perhaps we should avoid having tup1loc to share the same location
5970 ;; for the letrec and the tuple result?
5971                                   :nletrec_locsyms tup1loc
5972                                   ))
5973                (ctupbind (instance class_normal_let_binding
5974                                    :binder csymtup
5975                                    :letbind_loc sloc
5976                                    :letbind_type ctype_value
5977                                    :letbind_expr nletrec))
5978                (ctuplocc (instance class_nrep_locsymocc
5979                                    :nrep_loc sloc
5980                                    :nocc_ctyp ctype_value
5981                                    :nocc_symb csymtup
5982                                    :nocc_bind ctupbind))
5983                (ctupbindlist (list ctupbind))
5984                )
5985              (if (null nbindings)
5986                  (setq nbindings ctupbindlist)
5987                (list_append nbindings ctupbind)
5988                )
5989              (debug "normexp_tuple ctupbind" ctupbind)
5990              (foreach_pair_component_in_list
5991               (nbindings)
5992               (curpair curbind)
5993               (put_env newenv curbind)
5994               )
5995              (foreach_in_multiple
5996               (nargs)
5997               (curnarg :long nix)
5998               (let ( (curctype (get_ctype curnarg newenv))
5999                      )
6000                 (assert_msg "check curctype" (is_a curctype class_ctype))
6001               (when (!= curctype ctype_value)
6002                     (debug "normexp_tuple bad curnarg=" curnarg " of curctype=" curctype)
6003                     (error_at sloc "(TUPLE ...) argument #$1 should be value got $2" nix (get_field :named_name curctype))
6004                     (return)))
6005               )
6006              (debug "normexp_tuple return ctuplocc=" ctuplocc " nbindings=" nbindings)
6007              (return ctuplocc nbindings)
6008              )
6009      ;;
6010      )))
6011 (install_method class_source_tuple normal_exp normexp_tuple)
6013 ;;;;;;;;;;;;;;;;
6016 (defun normexp_list (recv env ncx psloc)
6017   (assert_msg "check list recv" (is_a recv class_source_list) recv)
6018   (assert_msg "check env" (is_a env class_environment) env)
6019   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6020   (debug "normexp_list recv" recv)
6021   (let ( (sloc (or (unsafe_get_field :loca_location recv) psloc))
6022          (sargs (unsafe_get_field :sargop_args recv))
6023          (csymrec (clone_symbol 'listrec_))
6024          (csymlist (clone_symbol 'list_))
6025          (normdiscrpair (normal_predef discr_pair ncx sloc "discr_pair"))
6026          (normdiscrlist (normal_predef discr_pair ncx sloc "discr_list"))
6027          (newenv (fresh_env env))
6028          (:long nbargs (multiple_length sargs))
6029          (consbindtup (list_to_multiple (prepare_constructor_binding recv csymlist ncx sloc)))
6030          (resbindings (make_list discr_list))
6031          (conslistbind (multiple_nth consbindtup -1))
6032          (tuprecloc (multiple_map
6033                      consbindtup
6034                      (lambda (curbind :long bindix)
6035                        (debug "normexp_list curbind" curbind)
6036                        (assert_msg "check curbind" (is_a curbind class_normal_constructor_binding) curbind)
6037                        (instance class_nrep_locsymocc
6038                                  :nrep_loc (or  (get_field :nconsb_loc curbind) sloc)
6039                                  :nocc_ctyp ctype_value
6040                                  :nocc_symb (get_field :binder curbind)
6041                                  :nocc_bind curbind)
6042                        )
6043                      ))
6044          )
6045     (debug "normexp_list csymrec=" csymrec
6046            " consbindtup=" consbindtup " conslistbind=" conslistbind
6047            " tuprecloc=" tuprecloc)
6048     (assert_msg "check conslistbind" (is_a conslistbind class_normal_constructed_list_binding) conslistbind)
6049     (multicall
6050      (nargs nbindings)
6051      (normalize_tuple sargs env ncx sloc)
6052      (debug "normexp_list nargs=" nargs " nbindings=" nbindings)
6053      (assert_msg "check nbindings" (is_list_or_null nbindings) nbindings)
6054      (list_append2list resbindings nbindings)
6055      (foreach_pair_component_in_list
6056       (resbindings)
6057       (curpairbind curbind)
6058       (put_env newenv curbind)
6059       )
6060      (foreach_in_multiple
6061       (nargs)
6062       (curnarg :long nix)
6063       (if (!= (get_ctype curnarg newenv) ctype_value)
6064           (progn
6065             (debug "normexp_list bad curnarg" curnarg)
6066             (error_at sloc "(LIST ...) argument #$1 should be value" nix)
6067             (return))))
6068      (letrec (
6069               (creclocc (instance class_nrep_locsymocc
6070                                   :nrep_loc sloc
6071                                   :nocc_ctyp ctype_value
6072                                   :nocc_symb csymrec
6073                                   :nocc_bind conslistbind))
6074               (nbdy (tuple creclocc))
6075               (nletrec (instance class_nrep_letrec
6076                                  :nrep_loc sloc
6077                                  :nlet_bindings consbindtup
6078                                  :nlet_body nbdy
6079                                  :nletrec_fill_bindings ()
6080                                  :nletrec_body_bindings ()
6081                                  :nletrec_locsyms tuprecloc
6082                                  ))
6083               (clistbind (instance class_normal_let_binding
6084                                    :binder csymlist
6085                                    :letbind_loc sloc
6086                                    :letbind_type ctype_value
6087                                    :letbind_expr nletrec))
6088               (clistlocc (instance class_nrep_locsymocc
6089                                    :nrep_loc sloc
6090                                    :nocc_ctyp ctype_value
6091                                    :nocc_symb csymlist
6092                                    :nocc_bind clistbind))
6093               (clistbindlist (list clistbind))
6094               )
6095              (foreach_in_multiple
6096               (nargs)
6097               (curnarg :long nix)
6098               (let ( (curpairb (multiple_nth consbindtup nix)) 
6099                      (nextb (multiple_nth consbindtup (+i nix 1)))
6100                      )
6101                 (put_int curpairb nix)
6102                 (debug "normexp_list curpairb" curpairb)
6103                 (assert_msg "check curpairb" (is_a curpairb class_normal_constructed_pair_binding) curpairb)
6104                 (assert_msg "check curpairb objnum" (==i (get_int curpairb) nix) curpairb nix)
6105                 (debug "normexp_list curnarg=" curnarg " nextb=" nextb)
6106                 (assert_msg "check nextb" (is_a nextb class_normal_constructor_binding) nextb)
6107                 (let ( (nextsym (get_field :binder nextb))
6108                        (nextloc (if (is_a nextb class_normal_constructed_pair_binding)
6109                                     (nreclist_find_locsym nextsym nletrec)))
6110                        )
6111                   (put_fields curpairb 
6112                               :npairb_head curnarg :npairb_tail nextloc
6113                               :nconsb_nletrec nletrec)
6114                   (debug "normexp_list updated curpairb" curpairb)
6115                   )
6116                 ))
6117              ;;
6118              ;; update the list binding
6119              (let ( (firstpairb (multiple_nth consbindtup 0))
6120                     (lastpairb (multiple_nth consbindtup -2))
6121                     (firstpairsymb
6122                      (if 
6123                          (is_a firstpairb class_normal_constructed_pair_binding)
6124                          (unsafe_get_field :binder firstpairb)))
6125                     (lastpairsymb
6126                      (if 
6127                          (is_a lastpairb class_normal_constructed_pair_binding)
6128                          (unsafe_get_field :binder lastpairb)))
6129                     (firstpairloc 
6130                      (if firstpairsymb  
6131                          (nreclist_find_locsym firstpairsymb  nletrec)))
6132                     (lastpairloc 
6133                      (if lastpairsymb  
6134                          (nreclist_find_locsym lastpairsymb  nletrec)))
6135                    )
6136                (put_fields
6137                 conslistbind
6138                 :nlistb_first firstpairloc :nlistb_last lastpairloc
6139                 :nconsb_nletrec nletrec)
6140                (put_int conslistbind nbargs)
6141                (debug "normexp_list updated conslistbind" conslistbind)
6142                )
6143              ;;
6144              (if (null nbindings)
6145                  (setq nbindings clistbindlist)
6146                (list_append nbindings clistbind)
6147                )
6148              (debug "normexp_list final nletrec=" nletrec
6149                     " clistlocc=" clistlocc " nbindings=" nbindings)
6150              (return clistlocc nbindings)
6151              ))))
6152 (install_method class_source_list normal_exp normexp_list)
6153 ;;;;;;;;;;;;;;;;
6156 (defun normexp_arithmetic_variadic_operation (recv env ncx psloc)
6157   (debug "normexp_arithmetic_variadic_operation recv" recv)
6158   (assert_msg "check recv" (is_a recv class_source_arithmetic_variadic_operation) recv)
6159   (assert_msg "check env" (is_a env class_environment) env)
6160   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6161   (let ( (sloc (or (unsafe_get_field :loca_location recv) psloc))
6162          (sargs (unsafe_get_field :sargop_args recv))
6163          (sneutral (unsafe_get_field :sarithvar_neutral recv))
6164          (sprimitive (unsafe_get_field :sarithvar_primitive recv))
6165          )
6166     (debug "normexp_arithmetic_variadic_operation sprimitive=" sprimitive " sneutral=" sneutral)
6167     (assert_msg "check sprimitive" (is_a sprimitive class_primitive) sprimitive)
6168     (assert_msg "check sneutral" (is_integerbox sneutral) sneutral)
6169     ;; actually, we normalize only to check the type here. We produce
6170     ;; a source primitive which is normalized again.
6171     (multicall
6172      (nargs nbindings)
6173      (normalize_tuple sargs env ncx sloc)
6174      (debug "normexp_arithmetic_variadic_operation nargs=" nargs " nbindings=" nbindings)
6175      (assert_msg "check nbindings" (is_list_or_null nbindings) nbindings)
6176      ;; check that all arguments are :long
6177      (foreach_in_multiple
6178       (nargs)
6179       (curnarg :long argix)
6180       (let ( (argctyp (get_ctype curnarg env))
6181              )
6182         (when (!= argctyp ctype_long)
6183           (error_at sloc "variadic arithmetic operation requires only :long arguments got $1 at #$2"_ (get_field :named_name argctyp) argix)
6184           (return))             
6185         ))
6186      (match
6187       sargs
6188       (?(tuple ?s0)
6189         (let ( (sprim (instance class_source_primitive
6190                                 :loca_location sloc
6191                                 :sprim_oper sprimitive
6192                                 :sargop_args (tuple sneutral s0)))
6193                )
6194           (debug "normexp_arithmetic_variadic_operation unary sprim=" sprim)
6195           (multicall
6196            (nrealargs nrealbindings)
6197            (normexp_primitive sprim env ncx psloc)
6198            (debug "normexp_arithmetic_variadic_operation unary result nrealargs=" nrealargs 
6199                   " nrealbindings=" nrealbindings)
6200            (return nrealargs nrealbindings)
6201            (void)
6202            )))
6203       (?(tuple ?s0 ?s1)
6204         (let ( (sprim (instance class_source_primitive
6205                                 :loca_location sloc
6206                                 :sprim_oper sprimitive
6207                                 :sargop_args (tuple s0 s1)))
6208                )
6209           (debug "normexp_arithmetic_variadic_operation binary sprim=" sprim)
6210           (multicall
6211            (nrealargs nrealbindings)
6212            (normexp_primitive sprim env ncx psloc)
6213            (debug "normexp_arithmetic_variadic_operation binary result nrealargs=" nrealargs 
6214                   " nrealbindings=" nrealbindings)
6215            (return nrealargs nrealbindings)
6216            (void)
6217            )))
6218       (?_
6219        (assert_msg "check #args>2" (>i (multiple_length sargs) 2) sargs)
6220        (let ( (sprim (instance class_source_primitive
6221                                :loca_location sloc
6222                                :sprim_oper sprimitive
6223                                :sargop_args (tuple (multiple_nth sargs 0) (multiple_nth sargs 1))))
6224               )
6225          (foreach_in_multiple
6226           (sargs)
6227           (cursarg :long six)
6228           (if (>i six 1)
6229               (let ( (newsprim (instance class_source_primitive
6230                                          :loca_location sloc
6231                                          :sprim_oper sprimitive
6232                                          :sargop_args (tuple sprim cursarg)))
6233                      )
6234                 (setq sprim newsprim)))
6235           )
6236          (debug "normexp_arithmetic_variadic_operation nary sprim=" sprim)
6237          (multicall
6238           (nrealargs nrealbindings)
6239           (normexp_primitive sprim env ncx psloc)
6240           (debug "normexp_arithmetic_variadic_operation nary result nrealargs=" nrealargs 
6241                  " nrealbindings=" nrealbindings)
6242           (return nrealargs nrealbindings)
6243           (void)         
6244           )))
6245       ))))
6246 (install_method class_source_arithmetic_variadic_operation normal_exp normexp_arithmetic_variadic_operation)
6248 ;;;;;;;;;;;;;;;;
6249 (defselector prepare_constructor_binding class_selector
6250   :doc #{The $PREPARE_CONSTRUCTOR_BINDING selector applied to: an
6251   constructible expression $RECV, a symbol $SYMB, a normalization
6252   context $NCX, a source location $SLOC gives a half-filled instance
6253   of a sub-class of $CLASS_NORMAL_CONSTRUCTOR_BINDING.}#
6254   :formals (recv symb ncx sloc)
6257 (defun badmeth_prepare_constructor_binding (recv symb ncx sloc)
6258   (debug "bad_prepare_constructor_binding recv=" recv " symb=" symb)
6259   (error_at sloc "invalid constructor binding $1 of receiver dicriminant $2"_
6260             (get_field :named_name symb)
6261             (get_field :named_name (discrim recv)))
6262   (assert_msg "@$@badmeth_prepare_constructor_binding" () recv symb)
6264 (install_method discr_any_receiver prepare_constructor_binding badmeth_prepare_constructor_binding)
6267 ;;;;;;;;;;;;;;;;
6268 (defselector normal_letrec_constructive class_selector
6269   :doc #{The $NORMAL_LETREC selector applied to: a constructive
6270   expression $CEXPR for receiver, a symbol $SYMB, a normal
6271   constructive binding $CBIND, an environment $ENV, a normal context
6272   $NCX, a location $SLOC}#
6273   :formals (cexpr symb cbind env ncx sloc))
6275 (defun badmeth_normal_letrec_constructive (cexpr symb cbind env ncx sloc)
6276   (debug "badmeth_normal_letrec_constructive cexpr=" cexpr " symb=" symb
6277          " cbind=" cbind)
6278   (error_at sloc "invalid letrec constructive symbol $1 for reciever $2" 
6279             (get_field :named_name symb)
6280             (get_field :named_name (discrim cexpr)))
6281   (assert_msg "@$@badmeth_normal_letrec_constructive" () cexpr symb)
6283 (install_method discr_any_receiver normal_letrec_constructive badmeth_normal_letrec_constructive)
6285 ;;;;;;;;;;;;;;;;
6286 (defun prepcons_lambda (recv symb ncx sloc)
6287   (debug "prepcons_lambda recv=" recv " symb=" symb)
6288   (assert_msg "check recv" (is_a recv class_source_lambda) recv)
6289   (let  ( (conslam (instance class_normal_constructed_lambda_binding
6290                              :binder symb
6291                              :nconsb_loc sloc
6292                              :nconsb_discr (normal_predef discr_closure ncx sloc "discr_closure")
6293                              ))
6294           )
6295     (debug "prepcons_lambda gives conslam" conslam)
6296     (return conslam)
6298 (install_method class_source_lambda prepare_constructor_binding prepcons_lambda)
6300 ;;;;
6303 (defun normletrec_lambda  (cexpr symb cbind env ncx psloc)
6304   (debug "normletrec_lambda cexpr=" cexpr " symb=" symb
6305          " cbind=" cbind " env=" env)
6306   (assert_msg "check cbind" (is_a cbind class_normal_constructed_lambda_binding) cbind)
6307   (let ( (newenv (fresh_env env))
6308          )
6309     (debug "normletrec_lambda newenv" newenv)
6310     (assert_msg "check newenv" (is_a newenv class_environment) newenv)
6311     (multicall
6312      (nproc csym clocc constrout clovtup sloc oldproc ndatarout :long insideflag)
6313      ;;bad (normalize_lambda cexpr newenv newenv ncx psloc)
6314      (normalize_lambda cexpr env newenv ncx psloc)
6315      (debug "normletrec_lambda after normalize_lambda csym=" csym
6316             "\n.. clocc=" clocc
6317             "\n.. constrout=" constrout
6318             "\n.. clovtup=" clovtup
6319             "\n.. oldproc=" oldproc
6320             "\n.. ndatarout=" ndatarout
6321             "\n.. newenv=" newenv)
6322      (if insideflag
6323          (list_append (get_field :nrclop_constlist oldproc) ndatarout))
6324      (put_fields cbind 
6325                  :nlambdab_nclosed clovtup
6326                  :nlambdab_constrout constrout
6327                  :nlambdab_datarout ndatarout)
6328      (debug "normletrec_lambda updated cbind" cbind)
6329      (compile_warning "unimplemented normletrec_lambda, maybe store the newenv in the cbind")
6330      (shortbacktrace_dbg "normletrec_lambda ended" 15)
6331      )))
6332 (install_method class_source_lambda normal_letrec_constructive normletrec_lambda)
6334 ;;;;;;;;;;;;;;;;
6336 (defun prepcons_tuple (recv symb ncx sloc)
6337   (debug "prepcons_tuple recv=" recv " symb=" symb)
6338   (assert_msg "check recv" (is_a recv class_source_tuple) recv)
6339   (let  ( 
6340          (loc (get_field :loca_location recv))
6341          (tuparg (get_field :sargop_args recv))
6342          (:long nbtuparg (multiple_length tuparg))
6343          (ntup (make_multiple discr_multiple nbtuparg))
6344          (constup (instance class_normal_constructed_tuple_binding
6345                              :binder symb
6346                              :nconsb_loc (or loc sloc)
6347                              :nconsb_discr (normal_predef discr_multiple ncx sloc "discr_multiple")
6348                              :ntupb_comp ntup
6349                              ))
6350           )
6351     (debug "prepcons_tuple gives constup" constup)
6352     (return constup)
6354 (install_method class_source_tuple prepare_constructor_binding prepcons_tuple)
6355 ;;;;
6357 (defun normletrec_tuple  (cexpr symb cbind env ncx sloc)
6358   (debug "normletrec_tuple cexpr=" cexpr " symb=" symb " cbind=" cbind)
6359   (assert_msg "check cexpr" (is_a cexpr class_source_tuple) cexpr)
6360   (assert_msg "check env" (is_a env class_environment) env)
6361   (assert_msg "check cbind" (is_a cbind class_normal_constructed_tuple_binding) cbind)
6362   (let ( 
6363         (loc (or (get_field :loca_location cexpr) sloc))
6364         (sargs (unsafe_get_field :sargop_args cexpr))
6365         (bcomp (get_field :ntupb_comp cbind))
6366         (nletrec (get_field :nconsb_nletrec cbind))
6367         (nrecbinds (get_field :nletrec_fill_bindings nletrec))
6368         )
6369     (debug "normletrec_tuple sargs=" sargs " bcomp=" bcomp
6370            " nletrec=" nletrec " nrecbinds=" nrecbinds)
6371     (assert_msg "check nletrec" (is_a nletrec class_nrep_letrec) nletrec)
6372     (assert_msg "check nrecbinds" (is_list nrecbinds) nrecbinds)
6373     (multicall
6374      (nargs nbinds)
6375      (normalize_tuple sargs env ncx loc)
6376      (debug "normletrec_tuple nargs=" nargs " nbinds=" nbinds)
6377      (assert_msg "check nargs & bcomp samelength" (==i (multiple_length bcomp) (multiple_length nargs)) nargs bcomp)
6378      (assert_msg "check nbinds" (is_list_or_null nbinds) nbinds)
6379      (foreach_in_multiple 
6380       (nargs)
6381       (curnarg :long nix)
6382       (multiple_put_nth bcomp nix curnarg))
6383      (debug "normletrec_tuple updated bcomp" bcomp)
6384      (list_append2list nrecbinds nbinds)
6385      (debug "normletrec_tuple updated nrecbinds" nrecbinds)
6386      (shortbacktrace_dbg "normletrec_tuple ended" 15)
6387      )))
6388 (install_method class_source_tuple normal_letrec_constructive normletrec_tuple)
6390 ;;;;;;;;;;;;;;;;
6392 (defun prepcons_list (recv symb ncx sloc)
6393   (debug "prepcons_list recv=" recv " symb=" symb)
6394   (assert_msg "check recv" (is_a recv class_source_list) recv)
6395   (let  ( 
6396          (reslist (make_list discr_list))
6397          (loc (get_field :loca_location recv))
6398          (listarg (get_field :sargop_args recv))
6399          (:long nblistarg (multiple_length listarg))
6400          (pairsb (make_multiple discr_multiple nblistarg))
6401          (conslist (instance class_normal_constructed_list_binding
6402                              :binder symb
6403                              :nconsb_loc (or loc sloc)
6404                              :nconsb_discr (normal_predef discr_list ncx sloc "discr_list")
6405                              :nlistb_first () 
6406                              :nlistb_last ()
6407                              :nlistb_pairsb pairsb
6408                              ))
6409           )
6410     (foreach_in_multiple 
6411      (listarg)
6412      (curarg :long curix)
6413      (debug "prepcons_list curarg" curarg)
6414      (let ( (pairsymb (clone_symbol (if (is_a curarg class_named) curarg '_pairoflist)))
6415             (conspair (instance class_normal_constructed_pair_binding
6416                                 :binder pairsymb
6417                                 :nconsb_loc (or (get_field :loca_location curarg) loc sloc)
6418                                 :nconsb_discr (normal_predef discr_pair ncx sloc "discr_pair")
6419                                 :npairb_head ()
6420                                 :npairb_tail ()
6421                                 ))
6422             )
6423        (multiple_put_nth pairsb curix conspair)
6424        (list_append reslist conspair)
6425      ))
6426     (list_append reslist conslist)
6427     (debug "prepcons_list gives reslist" reslist)
6428     (return reslist)
6430 (install_method class_source_list prepare_constructor_binding prepcons_list)
6431 ;;;;
6434 ;; auxiliary function to find a symbol in the locsym of a nletrec
6435 (defun nreclist_find_locsym (symb nletrec)
6436   (debug "nreclist_find_locsym symb=" symb)
6437   (assert_msg "check symb" (is_a symb class_symbol) symb)
6438   (assert_msg "check nletrec" (is_a nletrec class_nrep_letrec) nletrec)
6439   (let ( (nlocsyms (get_field :nletrec_locsyms nletrec)) 
6440          )
6441     (foreach_in_multiple
6442      (nlocsyms)
6443      (curlocsym :long locsymix)
6444      (if (== (get_field :nocc_symb curlocsym) symb)
6445          (progn
6446            (debug "nreclist_find_locsym found curlocsym" curlocsym)
6447            (return curlocsym))))
6448     (debug "nreclist_find_locsym not found")
6449     (return)
6450     ))
6453 (defun normletrec_list (cexpr symb cbind env ncx sloc)
6454   (debug "normletrec_list cexpr=" cexpr " symb=" symb " cbind=" cbind)
6455   (assert_msg "check cexpr" (is_a cexpr class_source_list) cexpr)
6456   ;; here cbind is a tuple of constructor bindings -for all the pairs
6457   ;; & the list
6458   (assert_msg "check cbind is tuple" (is_multiple cbind) cbind)
6459   (let ( (loc (or (get_field :loca_location cexpr) sloc))
6460          (sargs (get_field :sargop_args cexpr))
6461          (conslibind (multiple_nth cbind -1))
6462          (nletrec (get_field :nconsb_nletrec conslibind))
6463          (nrecbinds (get_field :nletrec_fill_bindings nletrec))
6464          (nlocsyms (get_field :nletrec_locsyms nletrec))
6465          (firstpairbind (multiple_nth cbind 0))
6466          (lastpairbind (multiple_nth cbind -2))
6467          )
6468     (debug "normletrec_list conslibind" conslibind)
6469     (assert_msg "check conslibind"
6470                 (is_a conslibind class_normal_constructed_list_binding)
6471                 conslibind)
6472     (debug "normletrec_list sargs=" sargs
6473            " nletrec=" nletrec " nrecbinds=" nrecbinds)
6474     (assert_msg "check nletrec" (is_a nletrec class_nrep_letrec) nletrec)
6475     (assert_msg "check nrecbinds" (is_list nrecbinds) nrecbinds)
6476     (multicall
6477      (nargs nbinds)
6478      (normalize_tuple sargs env ncx loc)
6479      (debug "normletrec_list nargs=" nargs " nbinds=" nbinds)
6480      (assert_msg "check nbinds" (is_list_or_null nbinds) nbinds)
6481      (assert_msg "check nargs's length vs cbind's length"
6482                  (==i (multiple_length nargs) (-i (multiple_length cbind) 1))
6483                  nargs cbind)
6484      (foreach_in_multiple
6485       (nargs)
6486       (curnarg :long nix)
6487       (debug "normletrec_list curnarg" curnarg)
6488       (let ( (curcbind  (multiple_nth cbind nix)) 
6489              (nextcbind  (multiple_nth cbind (+i 1 nix)))
6490              (nextpairsymb (if (is_a nextcbind class_normal_constructed_pair_binding)
6491                                (get_field :binder nextcbind)))
6492              )
6493         (debug "normletrec_list curcbind=" curcbind " nextcbind=" nextcbind
6494                " nextpairsymb=" nextpairsymb)
6495         (assert_msg "check curcbind" (is_a curcbind class_normal_constructed_pair_binding) curcbind)
6496         (let ( (nextpairloc     (if nextpairsymb (nreclist_find_locsym nextpairsymb nletrec))) )
6497           (debug "normletrec_list got nextpairloc" nextpairloc)
6498           (put_fields curcbind
6499                       :npairb_head curnarg
6500                       :npairb_tail nextpairloc)
6501           (debug "normletrec_list updated curcbind" curcbind)
6502           (assert_msg "check curcbind" (is_a curcbind class_normal_constructed_pair_binding) curcbind)
6503           )))
6504      (debug "normletrec_list firstpairbind=" firstpairbind
6505             " lastpairbind=" lastpairbind
6506             " conslibind=" conslibind)
6507      (and (is_a firstpairbind class_normal_constructed_pair_binding)
6508           (is_a lastpairbind class_normal_constructed_pair_binding)
6509           (let ( (firstpairsymb (get_field :binder firstpairbind))
6510                  (lastpairsymb (get_field :binder lastpairbind))
6511                  (firstpairlocsy (nreclist_find_locsym firstpairsymb nletrec))
6512                  (lastpairlocsy (nreclist_find_locsym lastpairsymb nletrec))
6513                  )
6514             (debug "normletrec_list firstpairlocsy=" firstpairlocsy " lastpairlocsy=" lastpairlocsy)
6515             (put_fields conslibind
6516                         :nlistb_first firstpairlocsy
6517                         :nlistb_last lastpairlocsy)
6518             (debug "normletrec_list updated conslibind" conslibind)
6519             (void)
6520             ))
6521      (debug "normletrec_list appending nbinds" nbinds)
6522      (list_append2list nrecbinds nbinds)
6523      (debug "normletrec_list ended updated nrecbinds" nrecbinds)
6524      )))
6525 (install_method class_source_list normal_letrec_constructive normletrec_list)
6528 ;;;;;;;;;;;;;;;;
6529 (defun prepcons_instance (recv symb ncx sloc)
6530   (debug "prepcons_instance recv=" recv " symb=" symb)
6531   (assert_msg "check recv" (is_a recv class_source_instance) recv)
6532   (let  ( 
6533          (loc (get_field :loca_location recv))
6534          (cla (get_field :smins_class recv))
6535          (clabind (get_field :smins_clabind recv))
6536          (sclasym (if (is_a clabind class_any_binding) (unsafe_get_field :binder clabind)))
6537          (:long nbclafld (multiple_length (get_field :class_fields cla)))
6538          (tupslot (make_multiple discr_multiple nbclafld))
6539          (consinst (instance class_normal_constructed_instance_binding
6540                                 :binder symb
6541                                 :nconsb_loc (or loc sloc)
6542                                 :nconsb_discr (compile_warning "don't forget to set the discr later...")
6543                                 :ninstb_slots tupslot
6544                                 :ninstb_clabind clabind
6545                                 ))
6546          )
6547     (assert_msg "prepcons_instance check class" (is_a cla class_class) cla)
6548     (debug "prepcons_instance gives consinst" consinst)
6549     (return consinst)
6550     )
6551   )
6552 (install_method class_source_instance prepare_constructor_binding prepcons_instance)
6554 ;;;;
6556 (defun normletrec_instance  (cexpr symb cbind env ncx sloc)
6557   (debug "normletrec_instance cexpr=" cexpr " symb=" symb " cbind=" cbind)
6558   (let ( (loc (or (unsafe_get_field :loca_location cexpr) sloc))
6559          (bslots (get_field :ninstb_slots cbind))
6560          (nletrec (get_field :nconsb_nletrec cbind))
6561          (nrecbinds (get_field :nletrec_fill_bindings nletrec))
6562          (sclass (unsafe_get_field :smins_class cexpr))
6563          (sclabind (unsafe_get_field :smins_clabind cexpr))
6564          (sfields (unsafe_get_field :smins_fields cexpr))
6565          (sclasym (if (is_a sclabind class_any_binding) (unsafe_get_field :binder sclabind)))
6566          (cladata (if (is_a sclasym class_symbol) 
6567                       (normal_exp sclasym env ncx sloc)))
6568          (bindlist (make_list discr_list))
6569          )
6570     (debug "normletrec_instance nletrec" nletrec)
6571     (when (not (is_a cladata class_nrep))
6572       (error_at sloc "invalid class in (INSTANCE $1 ...)" (unsafe_get_field :named_name sclass))
6573       (return ()))
6574     (let ( (nfields 
6575             (multiple_map 
6576              sfields 
6577              (lambda (curflda :long curk)
6578                (assert_msg "check curflda" (is_a curflda class_source_fieldassign) curflda)
6579                (let ( (curfloc (unsafe_get_field :loca_location curflda))
6580                       (curfield (unsafe_get_field :sfla_field curflda))
6581                       (curexp (unsafe_get_field :sfla_expr curflda)) )
6582                  (if (null curfloc) (setq curfloc sloc))
6583                  (multicall
6584                   (nexp nbind)
6585                   (normal_exp curexp env ncx curfloc)
6586                   (debug "normletrec_instance nexp" nexp)
6587                   (assert_msg "check nbind" (is_list_or_null nbind) nbind)
6588                   (list_append2list bindlist  nbind)
6589                   (instance class_nrep_fieldassign
6590                             :nrep_loc curfloc
6591                             :nfla_field curfield
6592                             :nfla_val nexp)
6593                   )))))
6594            )
6595       (debug "normletrec_instance nfields" nfields)
6596       (foreach_in_multiple
6597        (nfields)
6598        (curnfieldass :long fldix)
6599        (debug "normletrec_instance curnfieldass" curnfieldass)
6600        (let ( (curfield (get_field :nfla_field curnfieldass)) 
6601               (curfval (get_field :nfla_val curnfieldass))
6602               (curfloc (get_field :nrep_loc curnfieldass))
6603               (:long curfoff (get_int curfield))
6604               )
6605          (assert_msg "check curfield " (is_a curfield class_field) curfield)
6606          (let ( (fctyp (get_ctype curfval env))
6607                 )
6608            (if (!= fctyp ctype_value)
6609                (error_at
6610                 curfloc 
6611                 "invalid field $1 type in (LETREC .. (INSTANCE ..); expecting a :value gotten a $2"_
6612                 (get_field :named_name curfield)
6613                 (get_field :named_name fctyp))))
6614          (multiple_put_nth bslots curfoff curfval)
6615        ))
6616       (list_append2list nrecbinds bindlist)
6617       (debug "normletrec_instance ended updated nrecbinds" nrecbinds)
6618       )
6619     ))
6620 (install_method class_source_instance normal_letrec_constructive normletrec_instance)
6624 ;;;;;;;;;;;;;;;;
6625 (defun normexp_letrec (recv env ncx psloc)
6626   (assert_msg "check letrec recv" (is_a recv class_source_letrec) recv)
6627   (assert_msg "check env" (is_a env class_environment) env)
6628   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6629   (debug "normexp_letrec recv" recv)
6630   (let ( (sloc (unsafe_get_field :loca_location recv))
6631          (sbinds (unsafe_get_field :slet_bindings recv))
6632          (sbody (unsafe_get_field :slet_body recv))
6633          (:long nbbind (multiple_length sbinds))
6634          (bindlist (make_list discr_list))
6635          (consbindlist (make_list discr_list))
6636          (newenv (fresh_env env))
6637          (:long maplen (+i 5 (*i nbbind 2)))
6638          (symbexprmap (make_mapobject discr_map_objects maplen))
6639          (symbindmap (make_mapobject discr_map_objects maplen))
6640          )
6641 ;;; first preparation loop
6642     (foreach_in_multiple
6643      (sbinds)
6644      (cursbind :long sbix)
6645      (debug "normexp_letrec cursbind" cursbind)
6646      (assert_msg "check cursbind" (is_a cursbind class_source_letrec_binding) cursbind)
6647      (let ( (locb (or (unsafe_get_field :loca_location cursbind) sloc psloc))
6648             (cursymb (unsafe_get_field :sletb_binder cursbind))
6649             (curexpr (unsafe_get_field :sletb_expr cursbind))
6650             )
6651        (debug "normexp_letrec curexpr=" curexpr " cursymb=" cursymb)
6652        (assert_msg "check curexpr" (is_a curexpr class_source) curexpr)
6653        (assert_msg "check cursymb" (is_a cursymb class_symbol) cursymb)
6654        (mapobject_put symbexprmap cursymb curexpr)
6655        (let ( (curconsbind (prepare_constructor_binding curexpr cursymb ncx locb))
6656               )
6657          (debug "normexp_letrec curconsbind" curconsbind)
6658          (cond ( (is_a curconsbind class_normal_constructor_binding)
6659                  (debug "normexp_letrec curconsbind plain consbind" curconsbind)
6660                  (list_append consbindlist curconsbind)
6661                  (mapobject_put symbindmap cursymb curconsbind)
6662                  )
6663                ( (is_multiple curconsbind)
6664                  (debug "normexp_letrec curconsbind multiple" curconsbind)
6665                  (foreach_in_multiple 
6666                   (curconsbind)
6667                   (subconsbind :long subix)
6668                   (assert_msg "normexp_letrec check subconsbind" 
6669                               (is_a subconsbind class_normal_constructor_binding)
6670                               subconsbind)
6671                   (list_append consbindlist subconsbind))
6672                  (mapobject_put symbindmap cursymb curconsbind)
6673                  )
6674                ( (is_list curconsbind)
6675                  (debug "normexp_letrec curconsbind list" curconsbind)
6676                  (foreach_pair_component_in_list
6677                   (curconsbind)
6678                   (subconspair subconsbind)
6679                   (assert_msg "normexp_letrec check subconsbind" 
6680                               (is_a subconsbind class_normal_constructor_binding)
6681                               subconsbind)
6682                   (list_append consbindlist subconsbind))
6683                  (mapobject_put symbindmap cursymb (list_to_multiple curconsbind discr_multiple))
6684                  )
6685                (:else
6686                 (assert_msg "normexp_letrec bad curconsbind" () curconsbind)
6687                 ))
6688          )
6689        )
6690      )
6691     (debug "normexp_letrec consbindlist" consbindlist)
6692     (let (
6693           (:long nbconsbind (list_length consbindlist))
6694           (:long curcix 0)
6695           (nlocsyms (make_multiple discr_multiple nbconsbind))
6696           (ncbindtup (make_multiple discr_multiple nbconsbind))
6697           (recfillbindings (make_list discr_list))
6698           (nletrec (instance class_nrep_letrec
6699                              :nrep_loc sloc
6700                              :nlet_bindings ncbindtup
6701                              :nletrec_fill_bindings recfillbindings 
6702                              :nletrec_locsyms nlocsyms 
6703                              ;; nlet_body & nletrec_body_bindings is set after
6704                              :nlet_body ()
6705                              :nletrec_body_bindings ()
6706                              )) 
6707           )
6708       (debug "normexp_letrec unfilled nletrec" nletrec)
6709       ;;
6710       ;; second loop to make an environment where each constructive
6711       ;; binding is set, and to create the local symbol occurrences
6712       (foreach_pair_component_in_list
6713        (consbindlist)
6714        (curpair curcbind)
6715        (debug "normexp_letrec curcbind" curcbind)
6716        (assert_msg "check curcbind" (is_a curcbind class_normal_constructor_binding) curcbind)
6717        (multiple_put_nth ncbindtup curcix curcbind)
6718        (put_int curcbind curcix)
6719        (put_fields curcbind :nconsb_nletrec nletrec)
6720        (let ( (curbdiscr (unsafe_get_field :nconsb_discr curcbind)) 
6721               (curbinder (unsafe_get_field :binder curcbind))
6722               (nlocsym (instance class_nrep_locsymocc
6723                                  :nrep_loc (or (get_field :nconsb_loc curcbind) 
6724                                                sloc psloc)
6725                                  :nocc_ctyp ctype_value
6726                                  :nocc_symb curbinder
6727                                  :nocc_bind curcbind
6728                         ))
6729               )
6730          (multiple_put_nth nlocsyms curcix nlocsym)
6731          (if (null curbdiscr)
6732              (let ( (clabind (get_field :ninstb_clabind curcbind))
6733                     (clasym (get_field :binder clabind))
6734                     )
6735                (debug "normexp_letrec clabind=" clabind " clasym=" clasym)
6736                ;; the only case when this happens is for instance constructors...
6737                (assert_msg "check curcbind for instance" (is_a curcbind class_normal_constructed_instance_binding) curcbind)
6738                (let ( ;; we normalize the class symbol in the parent environment, not the new one! 
6739                      (cladata (normal_exp clasym env ncx sloc)) 
6740                      )
6741                  (debug "normexp_letrec cladata" cladata)
6742                  (assert_msg "check cladata" (is_a cladata class_nrep) cladata)
6743                  (put_fields curcbind :nconsb_discr cladata)
6744                  )))
6745          )
6746        (setq curcix (+i curcix 1))
6747        (put_env newenv curcbind)
6748        (compile_warning "normexp_letrec should normalize the expression using symbexprmap & curbinder...")
6749        )
6750 ;;; third loop to normalize the bindings content
6751       (foreach_in_multiple
6752        (sbinds)
6753        (cursbind :long sbix)
6754        (debug "normexp_letrec thirdloop cursbind=" cursbind " sbix=" sbix)
6755        (assert_msg "check cursbind" (is_a cursbind class_source_letrec_binding) cursbind)
6756        (let ( (locb (or (unsafe_get_field :loca_location cursbind) sloc psloc))
6757               (cursymb (unsafe_get_field :sletb_binder cursbind))
6758               (curexpr (unsafe_get_field :sletb_expr cursbind))
6759               (curbind (mapobject_get symbindmap cursymb))
6760               (cursexpr (mapobject_get symbexprmap cursymb))
6761               )
6762          (debug "normexp_letrec thirdloop curexpr=" curexpr
6763                 " cursymb=" cursymb
6764                 " curbind=" curbind
6765                 " cursexpr=" cursexpr)
6766          (assert_msg "check curxpr same cursexpr" (== curexpr cursexpr) cursexpr cursexpr)
6767          (normal_letrec_constructive curexpr cursymb curbind newenv ncx sloc)
6768          (debug "normexp_letrec thirdloop done curexpr" curexpr)
6769          )
6770        )
6771       (debug "normexp_letrec recfillbindings before normalizing the body" recfillbindings)
6773 ;;; normalize the body
6774       (debug "normexp_letrec normalizing sbody" sbody)
6775       (multicall
6776        (nbody nbodbindings)
6777        (normalize_tuple sbody newenv ncx sloc)
6778        (debug "normexp_letrec nbody=" nbody " nbodbindings=" nbodbindings)
6779        (assert_msg "normexp_letrec check nbodbindings" (is_list_or_null nbodbindings) nbodbindings)
6780        (put_fields nletrec 
6781                    :nlet_body nbody
6782                    :nletrec_body_bindings nbodbindings)
6783        (debug "normexp_letrec updated nletrec" nletrec)
6784        (assert_msg "normexp_letrec check bindlist" (is_list_or_null bindlist) bindlist)
6785 ;;; remove every locally bound symbol from the symbol cache map
6786        (let ( (sycmap (unsafe_get_field :nctx_symbcachemap ncx)) )
6787          (foreach_pair_component_in_list
6788           (bindlist)
6789           (curpair bnd)
6790           (debug "normexp_letrec removing from sycmap bnd" bnd)
6791           (assert_msg "normexp_letrec check bnd" (is_a bnd class_normal_let_binding) bnd)
6792           (mapobject_remove sycmap (unsafe_get_field :binder bnd))
6793           ))
6794 ;;;; make the result
6795        (let (
6796              (nlastbody (multiple_nth nbody -1))
6797              ;; the type of a let with empty body is void
6798              (nlastyp (or (get_ctype nlastbody newenv) ctype_void))
6799              (csym (clone_symbol 'letrec_))
6800              (cbind (instance class_normal_let_binding
6801                               :binder csym
6802                               :letbind_loc sloc
6803                               :letbind_type nlastyp
6804                               :letbind_expr nletrec))
6805              (clocc (instance class_nrep_locsymocc
6806                               :nrep_loc sloc
6807                               :nocc_ctyp nlastyp
6808                               :nocc_bind cbind))
6809              (resbinds (make_list discr_list))
6810              )
6811          (list_append resbinds cbind)
6812          (debug "normexp_letrec result clocc=" clocc 
6813                 " nletrec=" nletrec " resbinds=" resbinds)
6814          (shortbacktrace_dbg "normexp_letrec ending" 15)
6815          (return clocc resbinds)
6816          )))))
6817 (install_method class_source_letrec normal_exp normexp_letrec)
6821 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6823 ;;; create the normal predef (or fail with a msg) 
6824 (defun normal_predef (pred ncx sloc :cstring predname)
6825   (debug "normal_predef pred=" pred)
6826   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6827   (let ( (predefmap (unsafe_get_field :nctx_predefmap ncx)) 
6828          (brk (or (mapobject_get predefmap pred)
6829                   (get_raw_symbol predname)))
6830          )
6831     (debug "normal_predef brk=" brk)
6832     (if (or (is_integerbox brk) (is_a brk class_symbol))
6833         (let ( (res (instance class_nrep_predef
6834                             :nrep_loc sloc
6835                             :nrpredef brk))
6836                )
6837           (debug "normal_predef res=" res)
6838           (return res))
6839       (progn
6840         (debug "normalpredef fail predefmap=" predefmap " pred=" pred)
6841         (error_at sloc "not a predef: $1" (make_stringconst discr_verbatim_string predname))
6842         (return ())
6843         ))))
6846 ;; retrieve or create the normalized datasym for a symbol
6847 (defun normal_symbol_data (sym ncx sloc)
6848   ;; sym should be strictly a symbol (not be in a subclass of class_symbol!)
6849   (debug "normal_symbol_data start sym=" sym)
6850   (shortbacktrace_dbg "normal_symbol_data" 12)
6851   (assert_msg "check sym" (== (discrim sym) class_symbol) sym)
6852   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6853   (let ( (valmap  (unsafe_get_field :nctx_valmap ncx))
6854          (osydata (mapobject_get valmap sym)) )
6855     (debug "normal_symbol_data osydata=" osydata)
6856     (when osydata
6857       (debug "normal_symbol_data found osydata" osydata)
6858       (return osydata))
6859     (let ( (:long syhash (obj_hash sym))
6860            (synamstr (unsafe_get_field :named_name sym))
6861            ;; make the datastring from synamstr
6862            (synamstrdata 
6863             (instance class_nrep_datastring 
6864                       :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
6865                       :nstr_string synamstr
6866                       ))
6867            (syslots (make_multiple discr_multiple
6868                                    (multiple_length (unsafe_get_field :class_fields class_symbol))))
6869            (sydata (instance class_nrep_datasymbol
6870                              :ndata_name sym
6871                              :ndata_discrx (normal_predef class_symbol ncx sloc "class_symbol")
6872                              :ninst_hash (make_integerbox discr_integer syhash)
6873                              :ninst_slots syslots
6874                              :ndsy_namestr synamstr))
6875            )
6876       (debug "normal_symbol_data sydata=" sydata "\n.. synamstrdata=" synamstrdata)
6877       (multiple_put_nth syslots (obj_num named_name) synamstrdata)
6878       (add_nctx_data ncx sydata)
6879       (add_nctx_data ncx synamstrdata)
6880       (mapobject_put valmap sym sydata)
6881       (mapstring_putstr (unsafe_get_field :nctx_symbmap ncx) synamstr sydata)
6882       (debug "normal_symbol_data return sydata" sydata)
6883       (return sydata)
6884       )))
6888 ;; retrieve or create the normalized datakeyword for a keyword
6889 (defun normal_keyword_data (keyw ncx sloc)
6890   ;; keyw should be strictly a keyword (not be in a subclass of class_keyword!)
6891   (debug "normal_keyword_data keyw=" keyw)
6892   (assert_msg "check keywb" (== (discrim keyw) class_keyword) keyw)
6893   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6894   (let ( (valmap  (unsafe_get_field :nctx_valmap ncx))
6895          (osydata (mapobject_get valmap keyw)) )
6896     (if osydata osydata
6897       (let ( (:long syhash (obj_hash keyw))
6898              (synamstr (unsafe_get_field :named_name keyw))
6899              ;; make the datastring from synamstr
6900              (synamstrdata 
6901               (instance class_nrep_datastring 
6902                         :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
6903                         :nstr_string synamstr
6904                         ))
6905              (syslots (make_multiple discr_multiple
6906                                      (multiple_length (unsafe_get_field :class_fields class_keyword))))
6907              (sydata (instance class_nrep_datakeyword
6908                                :ndata_name keyw
6909                                :ndata_discrx (normal_predef class_keyword ncx sloc "class_keyword")
6910                                :ninst_hash (make_integerbox discr_integer syhash)
6911                                :ninst_slots syslots
6912                                :ndsy_namestr synamstr))
6913              )
6914         (shortbacktrace_dbg "normal_keyword_data" 15)
6915         (debug "normal_keyword_data sydata=" sydata "\n ..keyw=" keyw)
6916         (multiple_put_nth syslots (obj_num named_name) synamstrdata)
6917         (add_nctx_data ncx sydata)
6918         (add_nctx_data ncx synamstrdata)
6919         (mapobject_put valmap keyw sydata)
6920         (mapstring_putstr (unsafe_get_field :nctx_keywmap ncx) synamstr sydata)
6921         (debug "normal_keyword_data return sydata=" sydata)
6922         (return sydata)
6923         ))))
6926 ;; create the tuples of slots of a datainstance for a particular class
6927 (defun create_data_slots (cla)
6928   (assert_msg "check cla" (is_a cla class_class) cla) 
6929   (debug "create_data_slots cla" cla)
6930   (let ( (tupslo 
6931           (make_multiple discr_multiple  (multiple_length (unsafe_get_field :class_fields cla)))) 
6932          )
6933     (debug "create_data_slots tupslo" tupslo)
6934     tupslo
6935     ))
6937 ;; fill a slot of a datainstance
6938 (defun fill_data_slot (di field val)
6939   (assert_msg "check di" (is_a di class_nrep_datainstance) di)
6940   (assert_msg "check field" (is_a field class_field))
6941   (let ( (:long fix (obj_num field))
6942          (slots (unsafe_get_field :ninst_slots di)) )
6943     (multiple_put_nth slots fix val)
6944     ))
6949 ;;;;;; normalize a QUOTE-d symbol, string or integer
6951 (defun normexp_quote (recv env ncx psloc)
6952   (debug "normexp_quote recv=" recv)
6953   (assert_msg "check quote recv" (is_a recv class_source_quote) recv)
6954   (assert_msg "check env" (is_a env class_environment) env)
6955   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
6956   (shortbacktrace_dbg "normexp_quote" 16)
6957   (let ( (sloc   (unsafe_get_field :loca_location recv))
6958          (quoted (unsafe_get_field :squoted recv)) 
6959          (curproc (unsafe_get_field :nctx_curproc ncx))
6960          (ndata 
6961           (cond
6962            ( (== (discrim quoted) class_symbol)
6963              (debug "normexp_quote symbol quoted=" quoted)
6964              (normal_symbol_data quoted ncx psloc))
6965            ( (is_integerbox quoted)
6966              (debug "normexp_quote integer quoted=" quoted)
6967              (let (
6968                    (nintdata (instance class_nrep_databoxedinteger
6969                                        :ndata_discrx (normal_predef discr_constant_integer ncx sloc "discr_constant_integer") 
6970                                        :nboxint_num quoted))
6971                    )
6972                (debug "normexp_quote nintdata=" nintdata)
6973                (add_nctx_data ncx nintdata)
6974                nintdata
6975                ))
6976            ( (is_string quoted)
6977              (debug "normexp_quote string quoted=" quoted)
6978              (let ( (nstrdata 
6979                      (instance class_nrep_datastring
6980                                :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
6981                                :nstr_string quoted))
6982                     )
6983                (debug "normexp_quote nstrdata=" nstrdata)
6984                (add_nctx_data ncx nstrdata)
6985                nstrdata))
6986            (:else
6987             ;; this should not happen, because it is checked at
6988             ;; macroexpansion time.
6989             (assert_msg "unexpected quoted stuff" () quoted))
6991            ))
6992          )
6993     (debug "normexp_quote ndata=" ndata "\n.. curproc=" curproc)
6994     (if (is_a curproc class_nrep_closproc)
6995         (let ( 
6996               (nconst (instance class_nrep_constant
6997                                 :nrep_loc sloc
6998                                 :nconst_sval quoted
6999                                 :nconst_data ndata
7000                                 :nconst_proc curproc
7001                                 )) )
7002           (list_append (get_field :nrclop_constlist curproc) ndata)
7003           (debug "normexp_quote in routine nconst=" nconst)
7004           (return nconst ()))
7005       (progn
7006         (debug "normexp_quote in init ndata=" ndata)
7007         (return ndata ())
7008         ))))
7009 (install_method class_source_quote normal_exp normexp_quote)
7012 ;;;;;; normalize a COMMENT
7013 (defun normexp_comment (recv env ncx psloc)
7014   (debug "normexp_comment start recv" recv)
7015   (assert_msg "check comment recv" (is_a recv class_source_comment) recv)
7016   (assert_msg "check env" (is_a env class_environment) env)
7017   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7018   (let ( (sloc (unsafe_get_field :loca_location recv))
7019          (scomm (unsafe_get_field :scomm_str recv))
7020          (ncomm (instance class_nrep_comment
7021                           :nrep_loc sloc
7022                           :ncomm_string scomm
7023                           ))  
7024          (csym (clone_symbol 'comment_)) 
7025          (cbind (instance class_normal_let_binding
7026                           :letbind_loc sloc
7027                           :binder csym
7028                           :letbind_type ctype_void
7029                           :letbind_expr ncomm))
7030          (clocc (instance class_nrep_locsymocc
7031                           :nrep_loc sloc
7032                           :nocc_ctyp ctype_void
7033                           :nocc_symb csym
7034                           :nocc_bind cbind))
7035          (bindlist (make_list discr_list))
7036          )
7037     (if scomm (assert_msg "check scomm" (is_string scomm) scomm))
7038     (list_append bindlist cbind)
7039     (debug "normexp_comment end ncomm=" ncomm
7040            " return clocc=" clocc " bindlist=" bindlist)
7041     (return clocc bindlist)
7042     ))
7043 (install_method class_source_comment normal_exp normexp_comment)
7046 ;;;;;; normalize a keyword
7047 (defun normexp_keyword (recv env ncx psloc)
7048   (debug "normexp_keyword recv=" recv)
7049   (shortbacktrace_dbg "normexp_keyword" 10)
7050   (assert_msg "check keyword recv" (is_a recv class_keyword) recv)
7051   (assert_msg "check env" (is_a env class_environment) env)
7052   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7053   (let ( (curproc (unsafe_get_field :nctx_curproc ncx)) 
7054          (constlist (get_field :nrclop_constlist curproc))
7055          (objconstmap (get_field :nrclop_objconstcachemap curproc))
7056          (cacheres (mapobject_get objconstmap recv))
7057          )
7058     (when cacheres
7059       (debug "normexp_keyword return cacheres=" cacheres)
7060       (return cacheres ()))
7061     (let (
7062           (kdata (normal_keyword_data recv ncx psloc)) 
7063           )
7064       (debug "normexp_keyword kdata=" kdata "\n.. curproc=" curproc)
7065       (assert_msg "check curproc" (is_a curproc class_nrep_anyproc) curproc)
7066       (if (is_a curproc class_nrep_closproc)
7067           (let (
7068                 (nconst (instance class_nrep_constant
7069                                   :nrep_loc psloc
7070                                   :nconst_sval recv
7071                                   :nconst_data kdata
7072                                   :nconst_proc curproc))
7073                 )
7074             (debug "normexp_keyword closproc curproc=" curproc
7075                    "\n.. adding const kdata=" kdata)
7076             (list_append constlist kdata)
7077             (mapobject_put objconstmap recv nconst)
7078             (debug "normexp_keyword updated constlist=" constlist 
7079                    "\n.. objconstmap=" objconstmap)
7080             (debug "normexp_keyword result nconst=" nconst)
7081             (return nconst ())
7082             )
7083         (progn
7084           (debug "normexp_keyword routineinit result kdata=" kdata)
7085           (return kdata ())
7086           )))))
7087 (install_method class_keyword normal_exp normexp_keyword)
7089 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7090 ;;; utilities for normalization of DEFPRIMITIVE & DEFCITERATOR
7091 ;;;; fill the normal single formal bind
7092 (defun fill_normal_formalbind (fargb formsymbmap env ncx sloc)
7093   (assert_msg "check fargb" (is_a fargb class_formal_binding) fargb)
7094   (let ( (ftyp (unsafe_get_field :fbind_type fargb)) 
7095          (fsymb (unsafe_get_field :binder fargb))
7096          (fdataslot (create_data_slots class_formal_binding))
7097          (fargdata 
7098           (instance 
7099            class_nrep_datainstance
7100            :nrep_loc sloc
7101            :ndata_discrx (normal_predef class_formal_binding ncx sloc "class_formal_binding") 
7102            :ninst_hash (make_integerbox discr_integer (nonzero_hash))
7103            :ninst_slots fdataslot
7104            ))
7105          (fsymbdata (normal_symbol_data fsymb ncx sloc))
7106          (ftypdata (normal_predef ftyp ncx sloc "primitive arg type"))
7107          )
7108     (assert_msg "check ftyp" (is_a ftyp class_ctype) ftyp)
7109     (add_nctx_data ncx fargdata)
7110     (fill_data_slot fargdata binder fsymbdata)
7111     (fill_data_slot fargdata fbind_type ftypdata)
7112     (mapobject_put formsymbmap fsymb fargdata)
7113     (return fargdata)
7114     ))
7116 ;;;; fill the normal formal args
7117 (defun fill_normal_formals (sargs nargtuple formsymbmap env ncx sloc)
7118   (foreach_in_multiple
7119    (sargs)
7120    (fargb :long ix)
7121    (let ( (fargdata (fill_normal_formalbind fargb formsymbmap env ncx sloc))
7122           )
7123      (assert_msg "check fargdata" (is_a fargdata class_nrep_datainstance) fargdata)
7124      (unsafe_put_fields fargdata
7125                         :ninst_objnum (make_integerbox discr_integer ix))
7126      (multiple_put_nth nargtuple ix fargdata)
7127      )))
7129 ;;;; fill the normal expansion for primitive etc...
7130 (defun fill_normal_expansion (sexp nexptuple ncx sloc)
7131   (multiple_every
7132    sexp
7133    (lambda (expcomp :long ix)
7134      (let ( (discrcomp (discrim expcomp)) 
7135             (compdata 
7136              (cond ( (== discrcomp discr_verbatim_string)
7137                      (add_nctx_data ncx
7138                                     (instance 
7139                                      class_nrep_datastring
7140                                      :ndata_discrx (normal_predef discr_verbatim_string ncx sloc "discr_verbatim_string") 
7141                                      :nstr_string expcomp
7142                                      )))
7143                    ( (== discrcomp class_symbol)
7144                      (normal_symbol_data expcomp ncx sloc)
7145                      )
7146                    ( :else 
7147                      (debug "bad component in C code expansion expcomp" expcomp)
7148                      (error_at sloc "unexpected component #$1 of dicriminant $2 in C code expansion" ix (get_field :named_name discrcomp)))))
7149             )
7150        (multiple_put_nth nexptuple ix compdata)
7151        )))
7152   )
7154 ;;;;;; normalize a DEFPRIMITIVE
7155 (defun normexp_defprimitive (recv env ncx psloc)
7156   (debug "normexp_defprimitive recv=" recv)
7157   (assert_msg "check defprimitive recv" (is_a recv class_source_defprimitive) recv)
7158   (assert_msg "check env" (is_a env class_environment) env)
7159   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7160   (let ( (sloc   (unsafe_get_field :loca_location recv))
7161          (sname  (unsafe_get_field :sdef_name recv))
7162          (sargs  (unsafe_get_field :sformal_args recv))
7163          (stype  (unsafe_get_field :sprim_type recv))
7164          (sexp   (unsafe_get_field :sprim_expansion recv))
7165          (sprimbind (find_env env sname))
7166          ;; we compile to the making of an instance of class_primitive
7167          (nslotuple (create_data_slots class_primitive))
7168          (nexptuple (make_multiple discr_multiple
7169                                    (multiple_length sexp)))
7170          (nargtuple (make_multiple discr_multiple
7171                                    (multiple_length sargs)))
7172          (nexpdata (instance class_nrep_datatuple
7173                              :nrep_loc sloc
7174                              :ndata_name sname
7175                              :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7176                              :ntup_comp nexptuple))
7177          (nargdata (instance class_nrep_datatuple
7178                              :nrep_loc sloc
7179                              :ndata_name sname
7180                              :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7181                              :ntup_comp nargtuple))
7182          (nprimdata (instance class_nrep_datainstance
7183                               :nrep_loc sloc
7184                               :ndata_name sname
7185                               :ndata_discrx (normal_predef class_primitive ncx sloc "class_primitive")
7186                               :ninst_hash (make_integerbox discr_integer (nonzero_hash))
7187                               :ninst_slots nslotuple)) 
7188          (nsymdata (normal_symbol_data sname ncx sloc))
7189          ;; map of formal symbol -> data of formal_binding
7190          (formsymbmap (make_mapobject discr_map_objects (+i 3 (*i (multiple_length sargs) 2))))
7191          )
7192     (add_nctx_data ncx nprimdata)
7193     (add_nctx_data ncx nexpdata)
7194     (add_nctx_data ncx nargdata)
7195     ;; dont add nsymdata, it has already been added
7196     ;; fill the formal arguments of the data
7197     (fill_normal_formals sargs nargtuple formsymbmap env ncx sloc)
7198     ;; fill the expansion of the data
7199     (fill_normal_expansion sexp nexptuple ncx sloc)
7200 ;;; fill the primitive data    
7201     (fill_data_slot nprimdata named_name 
7202                     (add_nctx_data 
7203                      ncx
7204                      (instance 
7205                       class_nrep_datastring
7206                       :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
7207                       :nstr_string (unsafe_get_field :named_name sname))))
7208     (fill_data_slot nprimdata prim_formals nargdata)
7209     (fill_data_slot nprimdata prim_expansion nexpdata)
7210     (fill_data_slot nprimdata prim_type
7211                     (normal_predef stype ncx sloc "primitive res type"))
7212 ;;; put the data into the primitive binding
7213     (if (is_a sprimbind class_primitive_binding)
7214         (put_fields sprimbind  :fixbind_data nprimdata))
7215     (return () ())                   ;normalized defprimitive is empty
7216     ))
7217 (install_method class_source_defprimitive normal_exp normexp_defprimitive)
7220 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7221 ;;;;;; normalize a DEFCITERATOR
7222 (defun normexp_defciterator (recv env ncx psloc)
7223   (debug "normexp_defciterator recv=" recv)
7224   (assert_msg "check defciterator recv" (is_a recv class_source_defciterator) recv)
7225   (assert_msg "check env" (is_a env class_environment) env)
7226   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7227   (let ( 
7228         (sloc (unsafe_get_field :loca_location recv))
7229         (sname (unsafe_get_field :sdef_name recv))
7230         (sciter (let ( (sc (unsafe_get_field :sciterdef_citerator recv)) )
7231                   (assert_msg "check sciter" (is_a sc class_citerator) sc)
7232                   sc))
7233         (citbind (find_env env sname))
7234         (citstafor (unsafe_get_field :citer_start_formals sciter))
7235         (slotup (make_multiple discr_multiple
7236                                (multiple_length (unsafe_get_field :class_fields class_citerator))))
7237         (formstatup (make_multiple discr_multiple
7238                                    (multiple_length citstafor)))
7239         (citbodfor (unsafe_get_field :citer_body_formals sciter))
7240         (formbodtup (make_multiple discr_multiple 
7241                                    (multiple_length citbodfor)))
7242         (citstatsy (unsafe_get_field :citer_state sciter))
7243         (citexpbef (unsafe_get_field :citer_expbefore sciter))
7244         (expbeftup (make_multiple discr_multiple (multiple_length citexpbef)))
7245         (citexpaft (unsafe_get_field :citer_expafter sciter))
7246         (expafttup (make_multiple discr_multiple (multiple_length citexpaft)))
7247         ;; map of formal symbol -> data of formal_binding
7248         (formsymbmap (make_mapobject discr_map_objects
7249                                      (+i 5 (*i (+i (multiple_length citstafor) (multiple_length citbodfor)) 2))))
7250         (namstrdata (instance class_nrep_datastring
7251                               :nrep_loc sloc
7252                               :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
7253                               :nstr_string (unsafe_get_field :named_name sname)))
7254         (insdata (instance class_nrep_datainstance
7255                            :nrep_loc sloc
7256                            :ndata_name sname
7257                            :ndata_discrx (normal_predef class_citerator ncx sloc "class_citerator") 
7258                            :ninst_hash (make_integerbox discr_integer (nonzero_hash))
7259                            :ninst_slots slotup
7260                            )) 
7261         )
7262     (add_nctx_data ncx insdata)
7263     (add_nctx_data ncx namstrdata)
7264 ;;; fill the named_name of insdata
7265     (multiple_put_nth slotup (get_int named_name) namstrdata)
7266 ;;; fill the citer_start_formals of insdata
7267     (fill_normal_formals citstafor formstatup formsymbmap env ncx sloc)
7268     (let ( (nstatupdata (instance class_nrep_datatuple
7269                                   :nrep_loc sloc
7270                                   :ndata_name sname
7271                                   :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7272                                   :ntup_comp formstatup))
7273            )
7274       (add_nctx_data ncx nstatupdata)
7275       (multiple_put_nth slotup (get_int citer_start_formals) 
7276                         nstatupdata)
7277       )
7278 ;;; fill the citer_state
7279     (assert_msg "check citstatsy" (is_a citstatsy class_symbol) citstatsy)
7280     (let ( (nstatsydata (normal_symbol_data citstatsy ncx sloc)) )
7281       (multiple_put_nth slotup (get_int citer_state) 
7282                         nstatsydata)
7283       )
7284 ;;; fill the citer_body_formals of insdata
7285     (fill_normal_formals citbodfor formbodtup formsymbmap env ncx sloc)
7286     (let ( (nbodtupdata (instance class_nrep_datatuple
7287                                   :nrep_loc sloc
7288                                   :ndata_name sname
7289                                   :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7290                                   :ntup_comp formbodtup))
7291            )
7292       (add_nctx_data ncx nbodtupdata)
7293       (multiple_put_nth slotup (get_int citer_body_formals) nbodtupdata)
7294       )
7295 ;;; fill the citer_expbefore of insdata
7296     (fill_normal_expansion citexpbef expbeftup ncx sloc)
7297     (let ( (nbeftupdata  (instance class_nrep_datatuple
7298                                    :nrep_loc sloc
7299                                    :ndata_name sname
7300                                    :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7301                                    :ntup_comp expbeftup))
7302            )
7303       (add_nctx_data ncx nbeftupdata)
7304       (multiple_put_nth slotup (get_int citer_expbefore) nbeftupdata)
7305       )
7306 ;;; fill the citer_expafter of insdata
7307     (fill_normal_expansion citexpaft expafttup ncx sloc)
7308     (let ( (nafttupdata  (instance class_nrep_datatuple
7309                                    :nrep_loc sloc
7310                                    :ndata_name sname
7311                                    :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7312                                    :ntup_comp expafttup))
7313            )
7314       (add_nctx_data ncx nafttupdata)
7315       (multiple_put_nth slotup (get_int citer_expafter) nafttupdata)
7316       )
7317     (assert_msg "check citbind" (is_a citbind class_citerator_binding) citbind)
7318     (put_fields citbind :fixbind_data insdata)
7319 ;;;;;;;
7320     ;; return the data
7321     (debug "normexp_defciterator return insdata" insdata)
7322     (return insdata ())
7323     ))
7324 (install_method class_source_defciterator normal_exp normexp_defciterator)
7327 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7328 ;;;;;; normalize a citeration
7329 (defun normexp_citeration (recv env ncx psloc)
7330   (debug "normexp_citeration recv" recv)
7331   (assert_msg "check citeration recv" (is_a recv class_source_citeration) recv)
7332   (assert_msg "check env" (is_a env class_environment) env)
7333   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7334   (let ( (sloc (unsafe_get_field :loca_location recv))
7335          (soper (unsafe_get_field :sciter_oper recv))
7336          (sargs (unsafe_get_field :sargop_args recv))
7337          (svbind (unsafe_get_field :sciter_varbind recv))
7338          (sbody (unsafe_get_field :sciter_body recv))
7339          (nbndtup (make_multiple discr_multiple (multiple_length svbind)))
7340          (bodyenv (fresh_env env))
7341          ;; we need to remove or add stuff from the symbol cache map, as normexp_let does
7342          (sycmap (unsafe_get_field :nctx_symbcachemap ncx))
7343          ;; the list of symbol to remove at end from the above map
7344          (uncachelist (make_list discr_list))
7345          )
7346     (assert_msg "check soper" (is_a soper class_citerator) soper)
7347     ;; normalize the iterator input arguments
7348     (multicall
7349      (nargs nbindings)
7350      (normalize_tuple sargs env ncx sloc)
7351      (if (null nbindings) (setq nbindings (make_list discr_list)))
7352      (debug "normexp_citeration nargs=" nargs " nbindings=" nbindings)
7353      (let ( (starformals (unsafe_get_field :citer_start_formals soper)) )
7354        (debug "normexp_citeration starformals" starformals)
7355        (let ( (:long nbformals (multiple_length starformals))
7356               (:long nbargs (multiple_length nargs))
7357               )
7358        (when (!=i nbformals nbargs)
7359              (error_at sloc "start formals $1 and actuals $2 lengths mismatch in citerator $3" nbformals nbargs (unsafe_get_field :named_name soper))
7360              (return)))
7361        (multiple_every_both 
7362         nargs starformals
7363         (lambda (curnarg curforb :long ix)
7364           (debug "normexp_citeration curnarg=" curnarg " curforb=" curforb " ix=" ix)
7365           (assert_msg "check curforb" (is_a curforb class_formal_binding) curforb)
7366           (let ( (curctyp (get_ctype curnarg env)) 
7367                  (formctyp (unsafe_get_field :fbind_type curforb))
7368                  (formarg (unsafe_get_field :binder curforb))
7369                  )
7370             (if (== curctyp formctyp)
7371                 (let ( (nlbind (instance class_normal_let_binding
7372                                          :letbind_loc sloc
7373                                          :binder formarg
7374                                          :letbind_type curctyp
7375                                          :letbind_expr curnarg
7376                                          )) )
7377                   (multiple_put_nth nbndtup ix nlbind)
7378                   )
7379               (progn
7380                 (error_at sloc "start formal $1 and actual arg #$2 type mismatch, got $3 expecting $4, in citerator $5"_ 
7381                           (get_field :named_name formarg)
7382                           ix
7383                           (get_field :named_name curctyp)
7384                           (get_field :named_name formctyp)
7385                           (unsafe_get_field :named_name soper))
7386                 ))
7387             ))
7388         )
7389        (debug "normexp_citeration nbndtup" nbndtup)
7390        ;; bind the local vars
7391        (debug "normexp_citeration svbind" svbind)
7392        (let ( (citbform (unsafe_get_field :citer_body_formals soper))
7393               (:long nbcitbform (multiple_length citbform))
7394               (nlocbindtup (make_multiple discr_multiple nbcitbform))
7395               (nsymocctup (make_multiple discr_multiple nbcitbform))
7396               )
7397          (debug "normexp_citeration citbform" citbform)
7398          (let ( (:long nbsvbind (multiple_length svbind))
7399                 )
7400            (when (!=i nbcitbform nbsvbind)
7401                (error_at sloc 
7402                          "body formals #$1 and actuals #$2 length mismatch in citerator $3"_ 
7403                          nbcitbform nbsvbind (unsafe_get_field :named_name soper))
7404                (return)))
7405          (multiple_every_both 
7406           svbind citbform
7407           (lambda (curvbind curbform :long ix)
7408             (debug "normexp_citeration curvbind=" curvbind 
7409                    " curbform=" curbform " ix=" ix)
7410             (assert_msg "check curvbind" (is_a curvbind class_formal_binding) curvbind)
7411             (assert_msg "check curbform" (is_a curbform class_formal_binding) curbform)
7412             (let ( (curvsym (unsafe_get_field :binder curvbind))
7413                    (curctyp (unsafe_get_field :fbind_type curvbind))
7414                    (curvfor (unsafe_get_field :binder curbform))
7415                    (forctyp (unsafe_get_field :fbind_type curbform))
7416                    )
7417               (if (== curctyp forctyp)
7418                   (let ( (nlvbind (instance class_normal_let_binding
7419                                             :letbind_loc sloc
7420                                             :binder curvsym
7421                                             :letbind_type curctyp
7422                                             :letbind_expr ()
7423                                             ))
7424                          (clocc (instance class_nrep_locsymocc
7425                                           :nrep_loc sloc
7426                                           :nocc_ctyp curctyp
7427                                           :nocc_symb curvsym
7428                                           :nocc_bind nlvbind))
7429                          )
7430                     (multiple_put_nth nlocbindtup ix nlvbind)
7431                     (multiple_put_nth nsymocctup ix clocc)
7432                     (debug "normexp_citeration nlvbind" nlvbind)
7433                     ;;(put_env bodyenv nlvbind)
7434                     ;; update the curvsym in the symbol cache map to
7435                     ;; ensure that it will be normalized as the same
7436                     ;; local symbol occurence
7437                     (mapobject_put sycmap curvsym clocc)
7438                     (debug "normexp_citeration updated sycmap=" sycmap " clocc=" clocc)
7439                     (list_append uncachelist curvsym)
7440                     )
7441                 (progn
7442                   (error_at sloc "local formal type $1 and actual type $2 for formal $3 #$4 mismatch in citerator $5"_ 
7443                             (get_field :named_name forctyp)
7444                             (get_field :named_name curctyp)
7445                             (get_field :named_name curvsym)
7446                             ix (unsafe_get_field :named_name soper))
7447                   ))
7448               )
7449             (put_env bodyenv curvbind)
7450             ))
7451          (debug "normexp_citeration nlocbindtup=" nlocbindtup
7452                 " nsymocctup=" nsymocctup)
7453          (multicall
7454           (nbody nbodbindings)
7455           (normalize_tuple sbody bodyenv ncx sloc)
7456           (debug "normexp_citeration nbody=" nbody " nbodbindings=" nbodbindings)
7457           (let ( (citstate (unsafe_get_field :citer_state soper))
7458                  (citstsym (clone_symbol citstate))
7459                  (nchint (instance class_nrep_checksignal
7460                                    :nrep_loc sloc))
7461                  (citstbind (instance class_normal_let_binding
7462                                       :letbind_loc sloc
7463                                       :binder citstsym
7464                                       :letbind_type ctype_void
7465                                       :letbind_expr nchint))
7466                  (citstocc (instance class_nrep_locsymocc
7467                                      :nrep_loc sloc
7468                                      :nocc_ctyp ctype_void
7469                                      :nocc_symb citstsym
7470                                      :nocc_bind citstbind))
7471                  (citexpbefore (unsafe_get_field :citer_expbefore soper))
7472                  (citexpafter (unsafe_get_field :citer_expafter soper))
7473                  (citlocmap (make_mapobject discr_map_objects (+i 10 nbcitbform)))
7474                  (citexpander 
7475                   (lambda (xtup)
7476                     (debug "normexp_citeration expanding xtup=" xtup)
7477                     (multiple_map 
7478                      xtup 
7479                      (lambda (curelem :long ix)
7480                        (if (is_a curelem class_symbol)
7481                            (let ( (exelem (mapobject_get citlocmap curelem)) )
7482                              (if (null exelem)
7483                                  (debug "normexp_citeration bad curelem" curelem))
7484                              (assert_msg "check exelem in citeration" exelem)
7485                              exelem)
7486                          curelem)
7487                        ))
7488                     ))
7489                  )
7490             (mapobject_put citlocmap citstate citstocc)
7491             (debug "normexp_citeration  again starformals=" starformals
7492                    " nsymocctup=" nsymocctup)
7493             (multiple_every_both 
7494              starformals nargs
7495              (lambda (curvloc curnarg :long ix)
7496                (debug "normexp_citeration curvloc=" curvloc " curnarg=" curnarg)
7497                (mapobject_put citlocmap (unsafe_get_field :binder curvloc) curnarg)
7498                ))
7499             (debug "normexp_citeration  middle citlocmap=" citlocmap
7500                    " citbform=" citbform)
7501             (multiple_every
7502              citbform
7503              (lambda (curformb :long ix)
7504                (assert_msg "check curform" (is_a curformb class_formal_binding) curformb)
7505                (mapobject_put citlocmap
7506                               (unsafe_get_field :binder curformb)
7507                               (multiple_nth  nsymocctup ix))
7508                
7509                ))
7510             (debug "normexp_citeration citlocmap done" citlocmap)
7511             (let ( (chkbefore (citexpander citexpbefore))
7512                    (chkafter (citexpander citexpafter))
7513                    )
7514               (debug "normexp_citeration chkbefore=" chkbefore
7515                      " chkafter=" chkafter)
7516               (let ( (nciter
7517                       (instance  class_nrep_citeration
7518                                  :nrep_loc sloc
7519                                  :nciter_citerator soper
7520                                  :nciter_locbindings nlocbindtup
7521                                  :nciter_chunkbefore chkbefore
7522                                  :nciter_body nbody
7523                                  :nciter_statocc citstocc
7524                                  :nciter_bodbindings nbodbindings
7525                                  :nciter_chunkafter chkafter
7526                                  ))
7527                      (csym (clone_symbol (unsafe_get_field :named_name soper)))
7528                      (cbind (instance class_normal_let_binding
7529                                       :letbind_loc sloc
7530                                       :binder csym
7531                                       :letbind_type ctype_void
7532                                       :letbind_expr nciter))
7533                      (clocc (instance class_nrep_locsymocc
7534                                       :nrep_loc sloc
7535                                       :nocc_ctyp ctype_void
7536                                       :nocc_symb csym
7537                                       :nocc_bind cbind))
7538                      )
7539                 (list_append nbindings cbind)
7540                 ;; remove all required stuff from the symbol cache
7541                 (list_every 
7542                  uncachelist
7543                  (lambda (csy) (mapobject_remove sycmap csy)))
7544                 (debug "normexp_citeration nciter=" nciter
7545                        " result clocc=" clocc " nbindings=" nbindings)
7546                 (return clocc nbindings)
7547                 ))))))))
7548   )
7549 (install_method class_source_citeration normal_exp normexp_citeration)
7557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7558 ;;;;;;;;;;;;;;;; normalize a DEFCMATCHER
7559 (defun normexp_defcmatcher (recv env ncx psloc)
7560   (debug "normexp_defcmatcher recv=" recv "\n.. env=" debug_more env)
7561   (assert_msg "check defcmatcher recv" (is_a recv class_source_defcmatcher) recv)
7562   (assert_msg "check env" (is_a env class_environment) env)
7563   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7564   (let ( (sloc   (unsafe_get_field :loca_location recv))
7565          (sname  (unsafe_get_field :sdef_name recv))
7566          (sformals (unsafe_get_field :sformal_args recv))
7567          (cmatcher (let ( (cm (unsafe_get_field :scmatdef_cmatcher recv)) )
7568                      (debug "normexp_defcmatcher cmatcher" cm)
7569                      (assert_msg "check cmatcher" (is_a cm class_cmatcher) cm)
7570                      cm))
7571          (cmbind (let ( (b (find_env env sname)) )
7572                    (debug "normexp_defcmatcher cmbind=" b "; sname=" sname)
7573                    (assert_msg "check cmbind" (is_a b class_cmatcher_binding) b)
7574                    b))
7575          (slotup (make_multiple discr_multiple (object_length cmatcher)))
7576          (inscma (unsafe_get_field :amatch_in cmatcher))
7577          (mbicma (unsafe_get_field :amatch_matchbind cmatcher))
7578          (outscma (unsafe_get_field :amatch_out cmatcher))
7579          (statcma (unsafe_get_field :cmatch_state cmatcher))
7580          (testcma (unsafe_get_field :cmatch_exptest cmatcher))
7581          (fillcma (unsafe_get_field :cmatch_expfill cmatcher))
7582          (opercma (unsafe_get_field :cmatch_expoper cmatcher))
7583          (instup (make_multiple discr_multiple (multiple_length inscma)))
7584          (outstup (make_multiple discr_multiple (multiple_length outscma)))
7585          (testtup (if testcma (make_multiple discr_multiple (multiple_length testcma))))
7586          (filltup (if fillcma (make_multiple discr_multiple (multiple_length fillcma))))
7587          (opertup (if opercma (make_multiple discr_multiple (multiple_length opercma))))
7588          ;; map of formal symbol -> data of formal_binding
7589          (formsymbmap (make_mapobject discr_map_objects
7590                                       (+i 5 (*i (+i (multiple_length inscma) (multiple_length outscma)) 2))))
7591          (namstrdata (instance class_nrep_datastring
7592                                :nrep_loc sloc
7593                                :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
7594                                :nstr_string (unsafe_get_field :named_name sname)))
7595          (insdata (instance class_nrep_datainstance
7596                             :nrep_loc sloc
7597                             :ndata_name sname
7598                             :ndata_discrx (normal_predef class_cmatcher ncx sloc "class_cmatcher") 
7599                             :ninst_hash (make_integerbox discr_integer (obj_hash cmatcher))
7600                             :ninst_slots slotup
7601                             )) 
7602          )
7603     (add_nctx_data ncx insdata)
7604     (add_nctx_data ncx namstrdata)
7605 ;;; fill the named_name of insdata
7606     (multiple_put_nth slotup (get_int named_name) namstrdata)
7607 ;;; fill the amatch_in of insdata
7608     (fill_normal_formals inscma instup formsymbmap env ncx sloc)
7609     (let ( (instupdata (instance class_nrep_datatuple
7610                                  :nrep_loc sloc
7611                                  :ndata_name sname
7612                                  :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7613                                  :ntup_comp instup))
7614            )
7615       (add_nctx_data ncx instupdata)
7616       (multiple_put_nth slotup (get_int amatch_in) 
7617                         instupdata)
7618       )
7619 ;;; fill the amatch_matchbind of insdata
7620     (let ( (mbdata (fill_normal_formalbind mbicma formsymbmap env ncx sloc)) )
7621       (multiple_put_nth slotup (get_int amatch_matchbind)
7622                         mbdata)
7623       )
7624 ;;; fill the amatch_out of insdata
7625     (fill_normal_formals outscma outstup formsymbmap env ncx sloc)
7626     (let ( (outstupdata (instance class_nrep_datatuple
7627                                   :nrep_loc sloc
7628                                   :ndata_name sname
7629                                   :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7630                                   :ntup_comp outstup))
7631            )
7632       (add_nctx_data ncx outstupdata)
7633       (multiple_put_nth slotup (get_int amatch_out) 
7634                         outstupdata)
7635       )
7636 ;;; fill the cmatch_state of insdata
7637     (assert_msg "check statcma" (is_a statcma class_symbol) statcma)
7638     (let ( (nstatcmadata (normal_symbol_data statcma ncx sloc)) )
7639       (multiple_put_nth slotup (get_int cmatch_state) 
7640                         nstatcmadata)
7641       )
7642 ;;; fill the cmatch_exptest of insdata
7643     (when (is_multiple testcma)
7644       (fill_normal_expansion testcma testtup ncx sloc)
7645       (let ( (ntesttupdata  (instance class_nrep_datatuple
7646                                       :nrep_loc sloc
7647                                       :ndata_name sname
7648                                       :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7649                                       :ntup_comp testtup))
7650              )
7651         (add_nctx_data ncx ntesttupdata)
7652         (multiple_put_nth slotup (get_int cmatch_exptest) ntesttupdata)
7653         )
7654       )
7655 ;;; fill the cmatch_expfill of insdata
7656     (when (is_multiple fillcma)
7657       (fill_normal_expansion fillcma filltup ncx sloc)
7658       (let ( (nfilltupdata  (instance class_nrep_datatuple
7659                                       :nrep_loc sloc
7660                                       :ndata_name sname
7661                                       :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7662                                       :ntup_comp filltup))
7663              )
7664         (add_nctx_data ncx nfilltupdata)
7665         (multiple_put_nth slotup (get_int cmatch_expfill) nfilltupdata)
7666         )
7667       )
7668 ;;; fill the cmatch_expoper of insdata
7669     (when (is_multiple opercma)
7670       (fill_normal_expansion opercma opertup ncx sloc)
7671       (let ( (nopertupdata  (instance class_nrep_datatuple
7672                                       :nrep_loc sloc
7673                                       :ndata_name sname
7674                                       :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7675                                       :ntup_comp opertup))
7676              )
7677         (add_nctx_data ncx nopertupdata)
7678         (multiple_put_nth slotup (get_int cmatch_expoper) nopertupdata)
7679         )
7680       )
7681 ;;; put the data in the binding
7682     (put_fields cmbind :fixbind_data insdata)
7683     ;; return the data
7684     (debug "normexp_defcmatcher return insdata=" insdata)
7685     (return insdata ())
7686     )
7687   )
7688 (install_method class_source_defcmatcher normal_exp normexp_defcmatcher)
7692 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7693 ;;;;;; normalize a DEFUNMATCHER
7694 (defun normexp_defunmatcher (recv env ncx psloc)
7695   (debug "normexp_defunmatcher start recv=" recv)
7696   (assert_msg "normexp_defunmatcher check recv" (is_a recv class_source_defunmatcher) recv)
7697   (assert_msg "normexp_defunmatcher check env" (is_a env class_environment))
7698   (assert_msg "normexp_defunmatcher check ncx" (is_a ncx class_normalization_context))
7699   (let ( (sloc (unsafe_get_field :loca_location recv))
7700          (sname (unsafe_get_field :sdef_name recv))
7701          (smatched (multiple_nth (get_field :sformal_args recv) 0))
7702          (sins (unsafe_get_field :sfumatdef_ins recv))
7703          (souts (unsafe_get_field :sfumatdef_outs recv))
7704          (smatchf (unsafe_get_field :sfumatdef_matchf recv))
7705          (sapplyf (unsafe_get_field :sfumatdef_applyf recv))
7706          (sdata (unsafe_get_field :sfumatdef_data recv))
7707          (resbinds (make_list discr_list))
7708          (insfma (subseq_multiple sins 1 -1))
7709          (mbifma (multiple_nth sins 0))
7710          (fmbind (let ( (b (find_env env sname)) )
7711                    (debug "normexp_defunmatcher fmbind" b)
7712                    (assert_msg "check fmbind" (is_a b class_funmatcher_binding) b)
7713                    b))
7714          (funmatcher (get_field :fmbind_funmatcher fmbind))
7715          )
7716     (debug "normexp_defunmatcher made funmatcher" funmatcher)
7717     (assert_msg "check smatched" (is_a smatched class_formal_binding) smatched)
7718     (assert_msg "check sins" (is_multiple sins) sins)
7719     (assert_msg "check souts" (is_multiple souts) souts)
7720     (assert_msg "check mbifma" (is_a mbifma class_formal_binding) mbifma)
7721     (multicall
7722      (nmatchf nmabinds)
7723      (normal_exp smatchf env ncx sloc)
7724      (debug "normexp_defunmatcher nmatchf" nmatchf)
7725      (list_append2list resbinds nmabinds)
7726      (multicall
7727       (napplf napbinds)
7728       (normal_exp sapplyf env ncx sloc)
7729       (debug "normexp_defunmatcher napplf" napplf)
7730       (list_append2list resbinds napbinds)
7731       (multicall
7732        (ndata ndabinds)
7733        (normal_exp sdata env ncx sloc)
7734        (debug "normexp_defunmatcher ndata=" ndata " resbinds=" resbinds)
7735        (let (
7736              (namstrdata (instance class_nrep_datastring
7737                                    :nrep_loc sloc
7738                                    :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
7739                                    :nstr_string (unsafe_get_field :named_name sname)))
7740              (slotup (make_multiple discr_multiple (object_length funmatcher)))
7741              (insdata (instance class_nrep_datainstance
7742                                 :nrep_loc sloc
7743                                 :ndata_name sname
7744                                 :ndata_discrx (normal_predef class_cmatcher ncx sloc "class_funmatcher") 
7745                                 :ninst_hash (make_integerbox discr_integer (nonzero_hash))
7746                                 :ninst_slots slotup
7747                                 )) 
7748              (instup (make_multiple discr_multiple (multiple_length insfma)))
7749              (outstup (make_multiple discr_multiple (multiple_length souts)))
7750              ;; map of formal symbol -> data of formal_binding
7751              (formsymbmap (make_mapobject discr_map_objects
7752                                           (+i 5 (*i (+i (multiple_length insfma) 
7753                                                         (multiple_length souts)) 2))))
7754              )
7755          (add_nctx_data ncx namstrdata)
7756          (add_nctx_data ncx insdata)
7757 ;;; fill the named_name of insdata
7758          (multiple_put_nth slotup (get_int named_name) namstrdata)
7759 ;;; fill the amatch_in of insdata
7760          (fill_normal_formals insfma instup formsymbmap env ncx sloc)
7761          (let ( (instupdata (instance class_nrep_datatuple
7762                                       :nrep_loc sloc
7763                                       :ndata_name sname
7764                                       :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7765                                       :ntup_comp instup))
7766                 )
7767            (add_nctx_data ncx instupdata)
7768            (multiple_put_nth slotup (get_int amatch_in) 
7769                              instupdata)
7770            )
7771 ;;; fill the amatch_matchbind of insdata
7772          (let ( (mbdata (fill_normal_formalbind mbifma formsymbmap env ncx sloc)) )
7773            (multiple_put_nth slotup (get_int amatch_matchbind)
7774                              mbdata)
7775            )
7776 ;;; fill the amatch_out of insdata
7777          (fill_normal_formals souts outstup formsymbmap env ncx sloc)
7778          (let ( (outstupdata (instance class_nrep_datatuple
7779                                        :nrep_loc sloc
7780                                        :ndata_name sname
7781                                        :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
7782                                        :ntup_comp outstup))
7783                 )
7784            (add_nctx_data ncx outstupdata)
7785            (multiple_put_nth slotup (get_int amatch_out) 
7786                              outstupdata)
7787            )
7788 ;;; fill the fmatch_matchf of insdata
7789          (multiple_put_nth slotup (get_int fmatch_matchf)
7790                            nmatchf)
7791 ;;; fill the fmatch_applyf of insdata
7792          (multiple_put_nth slotup (get_int fmatch_applyf)
7793                            napplf)
7794 ;;; fill the fmatch_data of insdata
7795          (multiple_put_nth slotup (get_int fmatch_data)
7796                            ndata)
7797 ;;; put the data in the binding
7798          (put_fields fmbind :fixbind_data insdata)
7799 ;;; make a funmatcher binding
7800          (debug "normexp_defunmatcher final fmbind" fmbind)
7801          (compile_warning "$@$incomplete normexp_defunmatcher" ())
7802 ;;; return insdata and resbinds
7803          (debug "normexp_defunmatcher return insdata=" insdata
7804                 " resbinds=" resbinds)
7805          (return insdata resbinds)
7806          )
7807        )))
7808     ))
7809 (install_method class_source_defunmatcher normal_exp normexp_defunmatcher)
7814 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7815 ;;;;;; normalize a DEFCLASS
7816 (defun normexp_defclass (recv env ncx psloc)
7817   (debug "normexp_defclass recv=" recv)
7818   (assert_msg "check defclass recv" (is_a recv class_source_defclass) recv)
7819   (assert_msg "check env" (is_a env class_environment) env)
7820   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7821   (let ( (sloc   (unsafe_get_field :loca_location recv))
7822          (sname  (unsafe_get_field :sdef_name recv))
7823          (spredef (unsafe_get_field :sobj_predef recv))
7824          (sclabind (unsafe_get_field :sclass_clabind recv))
7825          (superbind (unsafe_get_field :sclass_superbind recv))
7826          (sfldbinds (unsafe_get_field :sclass_fldbinds recv))
7827          )
7828     (assert_msg "check sclabind" (is_a sclabind class_class_binding) sclabind)
7829     (let ( (claobj (unsafe_get_field :cbind_class sclabind)) 
7830            (namsymdata (normal_symbol_data sname ncx sloc))
7831            (namstr (unsafe_get_field :named_name sname))
7832            (namstrdata
7833             (instance class_nrep_datastring
7834                       :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
7835                       :nstr_string namstr
7836                       ))
7837            (claslots (make_multiple discr_multiple (obj_len claobj)))
7838            (cladata 
7839             (instance class_nrep_datainstance
7840                       :nrep_loc sloc
7841                       :ndata_name sname
7842                       :ndata_discrx (normal_predef class_class ncx sloc "class_class")
7843                       :ninst_hash  (make_integerbox discr_integer (obj_hash claobj))
7844                       :ninst_predef spredef
7845                       :ninst_slots claslots
7846                       :ninst_objnum 'MELTOBMAG_OBJECT
7847                       )) 
7848            (ancseq (unsafe_get_field :class_ancestors claobj))
7849            (:long nbanc (multiple_length ancseq))
7850            (anctup (make_multiple discr_multiple nbanc))
7851            (ancdata (instance 
7852                      class_nrep_datatuple
7853                      :nrep_loc sloc
7854                      :ndata_name sname
7855                      :ndata_discrx (normal_predef discr_class_sequence ncx sloc "discr_class_sequence")
7856                      :ntup_comp anctup
7857                      ))
7858            (fldseq (unsafe_get_field :class_fields claobj))
7859            (:long nbfld (multiple_length fldseq)) ;total number of fields
7860            (:long nbownfld (multiple_length sfldbinds)) ;number of own fields
7861            (:long nbsupfld (-i nbfld nbownfld)) ;number of super(ie inherited) fields
7862            (:long ix 0)                         ;temporary index
7863            (fldtup (make_multiple discr_multiple nbfld))
7864            (flddata (instance 
7865                      class_nrep_datatuple
7866                      :nrep_loc sloc
7867                      :ndata_name sname
7868                      :ndata_discrx (normal_predef discr_field_sequence ncx sloc "discr_field_sequence")
7869                      :ntup_comp fldtup
7870                      ))
7871            ;; the data representing the superclass
7872            (superdata (if (is_a superbind class_any_binding) 
7873                           (normal_exp (unsafe_get_field :binder superbind) env ncx sloc)))
7874            )
7875       (assert_msg "chechk namstr" (is_string namstr) namstr)
7876       ;; Issue a warning if we have no super class and if the class is
7877       ;; not predefined.
7878       (if (and (null superbind)
7879                (null spredef))
7880           (warning_strv sloc "DEFCLASS of class without :SUPER -class" 
7881                         namstr))
7882       ;; Issue a warning if namstr does not start with "CLASS_" to
7883       ;; enforce a coding convention.
7884       (let ( (:long dontstartwith_class 0)
7885              )
7886         (code_chunk 
7887          startwithclass
7888          #{ $DONTSTARTWITH_CLASS 
7889               = strncmp (melt_string_str ((melt_ptr_t) $NAMSTR), 
7890                          "CLASS_", strlen("CLASS_"));
7891          }#)
7892         (if dontstartwith_class
7893             (warning_strv sloc "DEFCLASS-ed name should start with CLASS_ !" 
7894                           namstr)))
7895       ;;
7896       (assert_msg "check claobj" (is_a claobj class_class) claobj)
7897       (add_nctx_data ncx cladata)
7898       (add_nctx_data ncx namstrdata)
7899       (add_nctx_data ncx ancdata)
7900       (add_nctx_data ncx flddata)
7901       (fill_data_slot cladata named_name namstrdata)
7902       (fill_data_slot cladata class_ancestors ancdata)
7903       (fill_data_slot cladata class_fields flddata)
7904       (assert_msg "check sclabind" (is_a sclabind class_class_binding) sclabind)
7905       (put_fields sclabind :fixbind_data cladata)
7906       ;; for each field which is not own, make a data to copy it from the superclass
7907       (setq ix 0)
7908       (forever loopsuperfield
7909                (if (>=i ix nbsupfld) (exit loopsuperfield))
7910                (let ( (supfldata 
7911                        (instance class_nrep_multacc
7912                                  :nrep_loc sloc
7913                                  :naccm_mul
7914                                  (instance class_nrep_fieldacc
7915                                            :nrep_loc sloc
7916                                            :naccf_obj superdata
7917                                            :naccf_fld class_fields
7918                                            )
7919                                  :naccm_ix (make_integerbox discr_integer ix)         
7920                                  )) 
7921                       )
7922                  (multiple_put_nth fldtup ix supfldata)
7923                  )
7924                (setq ix (+i ix 1))
7925                )
7926       (setq ix 0)
7927       ;; for each own field, make an instance of it
7928       (forever loopownfield
7929                (if (>=i ix nbownfld) (exit loopownfield))
7930                (let ( (ownfldbind (multiple_nth sfldbinds ix)) )
7931                  (assert_msg "check ownfldbind" (is_a ownfldbind class_field_binding) ownfldbind)
7932                  (let ( (ownfldsym (unsafe_get_field :binder ownfldbind))
7933                         (ownfld (unsafe_get_field :flbind_field ownfldbind))
7934                         )
7935                    (assert_msg "check ownfldsym" (is_a ownfldsym class_symbol) ownfldsym)
7936                    (assert_msg "check ownfld" (is_a ownfld class_field) ownfld)
7937                    (let ( (ownfldsymdata (normal_symbol_data ownfldsym ncx sloc)) 
7938                           (ownfldslots (make_multiple discr_multiple (obj_len ownfld)))
7939                           (ownflstrdata 
7940                            (instance class_nrep_datastring
7941                                      :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
7942                                      :nstr_string  (unsafe_get_field :named_name ownfld)
7943                                      ))
7944                           (ownfldata (instance class_nrep_datainstance
7945                                                :nrep_loc sloc
7946                                                :ndata_name ownfldsym
7947                                                :ndata_discrx (normal_predef class_field ncx sloc "class_field")
7948                                                :ninst_hash (make_integerbox discr_integer (obj_hash ownfld))
7949                                                :ninst_objnum (make_integerbox discr_integer (obj_num ownfld))
7950                                                :ninst_slots ownfldslots))
7951                           )
7952                      (add_nctx_data ncx ownfldata)
7953                      (add_nctx_data ncx ownflstrdata)
7954                      (fill_data_slot ownfldata named_name ownflstrdata)
7955                      (fill_data_slot ownfldata fld_ownclass cladata)
7956                      (multiple_put_nth fldtup (+i ix nbsupfld) ownfldata)
7957                      ;; fill the field binding with its compiled data
7958                      (put_fields ownfldbind :fixbind_data ownfldata)
7959                      )))
7960                (setq ix (+i ix 1))
7961                )
7962       ;; set the disc_super field to the superclass
7963       (if superdata (fill_data_slot cladata disc_super superdata))
7964       ;; compute the class_ancestors into anctup
7965       (setq ix 0)
7966       ;; loop on the ancestors of the superclass
7967       (forever loopancestorsuper
7968                (if (>=i ix (-i nbanc 1)) (exit loopancestorsuper))
7969                (let ( (supancdata
7970                        (instance class_nrep_multacc
7971                                  :nrep_loc sloc
7972                                  :naccm_mul
7973                                  (instance class_nrep_fieldacc
7974                                            :nrep_loc sloc
7975                                            :naccf_obj superdata
7976                                            :naccf_fld class_ancestors)
7977                                  :naccm_ix (make_integerbox discr_integer ix))) )
7978                  (multiple_put_nth anctup ix supancdata)
7979                  )
7980                (setq ix (+i ix 1))
7981                )
7982       ;; add the superdata as the last component of anctup
7983       (if superdata (multiple_put_nth anctup (-i nbanc 1) superdata))
7984       ;; the normalized form of the defclass is the classdata
7985       (return cladata ())
7986       )))
7987 (install_method class_source_defclass normal_exp normexp_defclass)
7992 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
7993 ;;;;;; normalize a DEFINSTANCE
7994 (defun normexp_definstance (recv env ncx psloc)
7995   (debug "normexp_definstance recv=" recv)
7996   (assert_msg "check definstance recv" (is_a recv class_source_definstance) recv)
7997   (assert_msg "check env" (is_a env class_environment) env)
7998   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
7999   (let ( (sloc   (unsafe_get_field :loca_location recv))
8000          (sname  (unsafe_get_field :sdef_name recv))
8001          (spredef (unsafe_get_field :sobj_predef recv))
8002          (sdocstr (unsafe_get_field :sdef_doc recv))
8003          (sinstclass (unsafe_get_field :sinst_class recv))
8004          (sinstclabnd (unsafe_get_field :sinst_clabind recv))
8005          (sinstclasym (if (is_a sinstclabnd class_any_binding) (unsafe_get_field :binder sinstclabnd)))
8006          (sinstobjnum (unsafe_get_field :sinst_objnum recv))
8007          (sinstfields (unsafe_get_field :sinst_fields recv))
8008          (nbindlist (make_list discr_list))
8009          (nbindcont (reference nbindlist))
8010          (bindins (find_env env sname))
8011          (namdata (normal_symbol_data sname ncx sloc))
8012          ;; data representing the class
8013          (icladata (if (is_a sinstclasym class_symbol) 
8014                        (normal_exp sinstclasym env ncx sloc)))
8015          )
8016     (debug "normexp_definstance bindins" bindins)
8017     (assert_msg "check bindins" (is_a  bindins class_instance_binding) bindins)
8018     (when (is_not_a icladata class_nrep)
8019       (error_at sloc "invalid class $1 in definstance" (unsafe_get_field :named_name sname))
8020       (return ()))
8021     (cond
8022      ( (null spredef) () )
8023      ( (is_integerbox spredef) () )
8024      ( (is_a spredef class_symbol) () )
8025      (:else
8026       (error_at sloc "bad predef $1 in DEFINSTANCE"  (unsafe_get_field :named_name sname))
8027       (return ())))
8028     (assert_msg "check sinstclass" (is_a sinstclass class_class) sinstclass)
8029     (assert_msg "check sinstclasym" (is_a sinstclasym class_symbol) sinstclasym)
8030     (let (
8031           (slotup (make_multiple discr_multiple
8032                                  (multiple_length (unsafe_get_field :class_fields sinstclass))))
8033           (insdata (instance class_nrep_datainstance
8034                              :nrep_loc sloc
8035                              :ndata_name sname
8036                              :ndata_discrx icladata
8037                              :ninst_hash (make_integerbox discr_integer (nonzero_hash))
8038                              :ninst_predef spredef
8039                              :ninst_slots slotup
8040                              :ninst_objnum sinstobjnum
8041                              )) 
8042           )
8043       (add_nctx_data ncx insdata)
8044       (put_env env bindins)
8045       (put_fields bindins :fixbind_data insdata)
8046       ;; scan the fields initialization
8047       (foreach_in_multiple
8048        (sinstfields)
8049        (flda :long ix)
8050        (debug "normexp_definstance flda" flda)
8051        (assert_msg "check flda" (is_a flda class_source_fieldassign) flda)
8052        (let ( (curfld (unsafe_get_field :sfla_field flda))
8053               (curexp (unsafe_get_field :sfla_expr flda))
8054               (:long curoff (obj_num curfld))
8055               )
8056          (assert_msg "check curfld" (is_a curfld class_field) curfld)
8057          (when (!= (multiple_nth (unsafe_get_field :class_fields sinstclass) curoff) 
8058                    curfld)
8059            (error_at sloc
8060                      "inappropriate field $1 in DEFINSTANCE"
8061                      (get_field :named_name curfld)
8062                      )
8063            (return))
8064          (debug "normexp_definstance field curexp" curexp)
8065          (multicall
8066           (ncur nbindcur)
8067           (normal_exp curexp env ncx sloc)
8068           (debug "normexp_definstance field ncur=" ncur " nbindcur=" nbindcur)
8069           (let ( (curctype (get_ctype ncur env))
8070                  )
8071             (if (!= curctype ctype_value)
8072                 (error_at sloc
8073                           "field $1 in DEFINSTANCE don't get a value but a $2"
8074                           (get_field :named_name curfld) (get_field :named_name curctype)))
8075             )
8076           (multiple_put_nth slotup curoff ncur)
8077           (if (is_list nbindcur)
8078               (let ( (thebindlist (deref nbindcont)))
8079                 (setq thebindlist (list_append2list thebindlist nbindcur))
8080                 (set_ref nbindcont thebindlist))))))
8081 ;;; put the binding into the data
8082       (let ( (thebindlist (deref nbindcont)) 
8083              (nbindtup (list_to_multiple thebindlist discr_multiple))
8084              )
8085         (if (>i (multiple_length nbindtup) 0) 
8086             (unsafe_put_fields insdata :ndata_locbind nbindtup))
8087         ;; return the data
8088         (debug "normexp_definstance return insdata" insdata)
8089         (return insdata ())
8090         ))))
8091 (install_method class_source_definstance normal_exp normexp_definstance)
8094 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
8095 ;;;;;; normalize a DEFVAR for a static variable
8096 (defun normexp_defvar (recv env ncx psloc)
8097   (debug "normexp_defvar recv=" recv)
8098   (assert_msg "check defvar recv" (is_a recv class_source_defvar) recv)
8099   (assert_msg "check env" (is_a env class_environment) env)
8100   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8101   (let ( (sloc (unsafe_get_field :loca_location recv))
8102          (sname (unsafe_get_field :sdef_name recv))
8103          (modctx (unsafe_get_field :nctx_modulcontext ncx))
8104          (curproc (unsafe_get_field :nctx_curproc ncx)) 
8105          (bnbvar (unsafe_get_field :mocx_varcount modctx))
8106          (varlist (unsafe_get_field :mocx_varlist modctx))
8107          (:long numvar (+i (get_int bnbvar) 1))
8108          )
8109     (debug "normexp_defvar modctx=" modctx)
8110     (when (is_not_a curproc class_nrep_initproc)
8111       (error_at sloc "(DEFVAR $1) can appear only at top-level"_ sname)
8112       (return))
8113     (multicall
8114      (vbind procs gotenv)
8115      (find_enclosing_env env sname)
8116      (debug "normexp_defvar vbind=" vbind "\n procs=" procs "\n gotenv=" gotenv)
8117      (when 
8118          (or (!= gotenv env) 
8119              (is_not_a vbind class_variable_binding))
8120        (error_at sloc "cannot redefine variable $1 with DEFVAR"_ 
8121                  (get_field :named_name sname))
8122        (return))
8123      (debug "normexp_defvar class_normal_module_variable_binding=" class_normal_module_variable_binding)
8124      (let (
8125            (bnumvar (constant_box numvar))
8126            (varbnd (instance class_normal_module_variable_binding
8127                              :binder sname
8128                              :nvarb_num bnumvar))
8129            )
8130        (debug "normexp_defvar varbnd=" varbnd)
8131        (put_int bnbvar numvar)
8132        (put_env env varbnd)
8133        (list_append varlist varbnd)
8134        (debug "normexp_defvar updated varlist=" varlist)
8135        (return)
8136        ))))
8137 (install_method class_source_defvar normal_exp normexp_defvar)
8138     
8139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
8140 ;;;;;; normalize a DEFINE for a constant
8141 (defun normexp_define (recv env ncx psloc)
8142   (assert_msg "check define recv" (is_a recv class_source_define) recv)
8143   (assert_msg "check env" (is_a env class_environment) env)
8144   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8145   (debug "normexp define recv" recv)
8146   (shortbacktrace_dbg "normexp_define" 7)
8147   (let ( 
8148         (sloc (unsafe_get_field :loca_location recv))
8149         (sname (unsafe_get_field :sdef_name recv))
8150         (sbody (unsafe_get_field :sdefine_body recv))
8151         (binddef (let ( (bdf (find_env env sname))
8152                         ) 
8153                    (debug "normexp_define binddef bdf=" bdf)
8154                    bdf
8155                    ))
8156         (namdata (normal_symbol_data sname ncx sloc))
8157         (curproc (unsafe_get_field :nctx_curproc ncx)) 
8158         (newenv (fresh_env env))
8159         (locbind (instance class_normal_let_binding
8160                            :letbind_loc sloc
8161                            :binder sname
8162                            :letbind_type ctype_value
8163                            :letbind_expr ()
8164                            ))
8165         (sycmap (unsafe_get_field :nctx_symbcachemap ncx))
8166         )
8167     (debug "normexp_define namdata=" namdata " binddef=" binddef " sycmap=" sycmap)
8168     (assert_msg "check body tuple" (is_multiple sbody) sbody)
8169     (assert_msg "check binddef" (is_a binddef class_defined_value_binding) binddef)
8170     (debug "normexp_define curproc=" curproc " newenv=" newenv)
8171     ;; TODO:: maybe we could have internal defines for constants...
8172     (when (is_not_a curproc class_nrep_initproc)
8173       (error_at sloc "(DEFINE $1 ...) can appear only at top-level"_ sname)
8174       (return))
8175     (put_env newenv locbind)
8176     (debug "normexp_define sbody=" sbody "\n newenv=" newenv)
8177     (multicall
8178      (nbody nbindings)
8179      (normalize_tuple sbody newenv ncx sloc)
8180      (debug "normexp_define nbody=" nbody " nbindings=" nbindings
8181             " sname=" sname)
8182      (if (null nbindings)
8183          (setq nbindings (make_list discr_list)))
8184      (let (
8185            (procdefbinds (get_field :ninit_defbinds curproc))
8186            (ndefname (normexp_symbol sname env ncx sloc))
8187            (:long nbodylen (multiple_length nbody))
8188            (nlastbody (multiple_nth nbody -1))
8189            (newbody (make_multiple discr_multiple (+i nbodylen 2)))
8190            (snamestr (get_field :named_name sname))
8191            (nlastassign (instance class_nrep_setq
8192                                   :nrep_loc sloc
8193                                   :nstq_var ndefname
8194                                   :nstq_exp nlastbody))
8195            )
8196        (debug "normexp_define nlastassign=" nlastassign " ndefname=" ndefname)
8197        (list_every nbindings (lambda (nb) (put_env newenv nb)))
8198        (foreach_in_multiple
8199         (nbody)
8200         (curnbody :long bodix)
8201         (multiple_put_nth newbody bodix curnbody))
8202        (multiple_put_nth newbody nbodylen nlastassign)
8203        (multiple_put_nth newbody (+i nbodylen 1) ndefname)
8204        (list_append procdefbinds binddef)
8205        (debug "normexp_define updated procdefbinds=" procdefbinds
8206               " ndefname=" ndefname " newbody=" newbody)
8207        (let ( (curctype (get_ctype ndefname env))
8208               (lastctype (get_ctype nlastbody newenv))
8209               )
8210          (if (!= curctype ctype_value)
8211              (error_at sloc "DEFINE-d name $1 is not a value but a $2"_ 
8212                        snamestr (get_field :named_name curctype)))
8213          (if (!= lastctype ctype_value)
8214              (error_at sloc "(DEFINE $1 ...) body don't end with a value but with a $2"_ snamestr
8215                        (get_field :named_name lastctype)))
8216          )
8217        (debug "normexp_define newbody=" newbody " sname=" sname " sycmap=" sycmap)
8218        (let ( (nwrlet (wrap_normal_letseq newbody nbindings sloc))
8219               (nlocbindings (list locbind))
8220               (syca (mapobject_get sycmap sname))
8221               )
8222          (debug "normexp_define nwrlet=" nwrlet)
8223          (debug "normexp_define syca=" syca " locbind=" locbind)
8224          (assert_msg "check syca" (is_a syca class_nrep_defined_constant) syca)
8225          (mapobject_remove sycmap sname)
8226          (debug "normexp_define shrinked updated sycmap=" sycmap)
8227          (debug "normexp_define return nwrlet=" nwrlet  " nlocbindings=" nlocbindings)
8228          (return nwrlet nlocbindings)
8229          )))))
8230 (install_method class_source_define normal_exp normexp_define)
8234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
8235 ;;;;;; normalize a DEFSELECTOR
8236 (defun normexp_defselector (recv env ncx psloc)
8237   (debug "normexp defselector recv=" recv)
8238   (assert_msg "check defselector recv" (is_a recv class_source_defselector) recv)
8239   (assert_msg "check env" (is_a env class_environment) env)
8240   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8241   (let ( 
8242         (sloc (unsafe_get_field :loca_location recv))
8243         (sname (unsafe_get_field :sdef_name recv))
8244         (spredef (unsafe_get_field :sobj_predef recv))
8245         (sdocstr (unsafe_get_field :sdef_doc recv))
8246         (sinstclass (unsafe_get_field :sinst_class recv))
8247         (sinstclabnd (unsafe_get_field :sinst_clabind recv))
8248         (sinstclasym (if (is_a sinstclabnd class_any_binding) (unsafe_get_field :binder sinstclabnd)))
8249         (sinstobjnum (unsafe_get_field :sinst_objnum recv))
8250         (sinstfields (unsafe_get_field :sinst_fields recv))
8251         (sformals (unsafe_get_field :sdefsel_formals recv))
8252         (nbindlist (make_list discr_list))
8253         (nbindcont (reference nbindlist))
8254         (bindsel (find_env env sname))
8255         (namdata (normal_symbol_data sname ncx sloc))
8256         ;; data representing the class
8257         (icladata (if (is_a sinstclasym class_symbol) 
8258                       (normal_exp sinstclasym env ncx sloc)))
8259         )
8260     (assert_msg "check bindsel" (is_a bindsel class_selector_binding) bindsel)
8261     (when  (is_not_a icladata class_nrep)
8262           (error_at sloc "invalid class in DEFSELECTOR $1"_ (unsafe_get_field :named_name sname))
8263           (return ()))
8264     (if spredef
8265         (when (not (or (is_integerbox spredef) (is_a spredef class_symbol)))
8266           (error_at sloc "bad predef in DEFSELECTOR $1"  (unsafe_get_field :named_name sname))
8267           (return ())))
8268     (assert_msg "check sinstclass" (is_a sinstclass class_class) sinstclass)
8269     (assert_msg "check sinstclasym" (is_a sinstclasym class_symbol) sinstclasym)
8270     (assert_msg "check sname" (is_a sname class_symbol) sname)
8271     (let (
8272           (slotup (make_multiple discr_multiple
8273                                  (multiple_length (unsafe_get_field :class_fields sinstclass))))
8274           (namstrdata (instance class_nrep_datastring
8275                                 :nrep_loc sloc
8276                                 :ndata_discrx (normal_predef discr_string ncx sloc "discr_string") 
8277                                 :nstr_string (unsafe_get_field :named_name sname)))
8278           (insdata (instance class_nrep_datainstance
8279                              :nrep_loc sloc
8280                              :ndata_name sname
8281                              :ndata_discrx icladata
8282                              :ninst_hash (make_integerbox discr_integer (nonzero_hash))
8283                              :ninst_predef spredef
8284                              :ninst_slots slotup
8285                              :ninst_objnum sinstobjnum
8286                              )) 
8287           (formsymbmap (make_mapobject discr_map_objects (+i 3 (*i (multiple_length sformals) 2))))
8288           (nformtup (if sformals
8289                         (let ( (:long nbformals (multiple_length sformals))
8290                                (nformaltuple (make_multiple discr_multiple nbformals))
8291                                (nformdata (instance 
8292                                            class_nrep_datatuple
8293                                            :nrep_loc sloc
8294                                            :ndata_name sname
8295                                            :ndata_discrx (normal_predef discr_multiple ncx sloc "discr_multiple")
8296                                            :ntup_comp nformaltuple))
8297                                )
8298                           (fill_normal_formals sformals nformaltuple formsymbmap env ncx sloc)
8299                           (add_nctx_data ncx nformdata)   
8300                           (fill_data_slot insdata  sdefsel_formals nformdata)
8301                           nformaltuple
8302                           )))
8303           )
8304       (add_nctx_data ncx insdata)
8305       (add_nctx_data ncx namstrdata)
8306       (put_fields bindsel :fixbind_data insdata)
8307       ;; scan the fields initialization
8308       (foreach_in_multiple
8309        (sinstfields)
8310        (flda :long ix)
8311        (assert_msg "check flda" (is_a flda class_source_fieldassign) flda)
8312        (let ( (curfld (unsafe_get_field :sfla_field flda))
8313               (curexp (unsafe_get_field :sfla_expr flda))
8314               (:long curoff (obj_num curfld))
8315               )
8316          (assert_msg "check curfld" (is_a curfld class_field) curfld)
8317          (assert_msg "good curfld"
8318                      (== (multiple_nth (unsafe_get_field :class_fields sinstclass) curoff) 
8319                          curfld) curoff curfld)  
8320          (multicall
8321           (ncur nbindcur)
8322           (normal_exp curexp env ncx sloc)
8323           (multiple_put_nth slotup curoff ncur)
8324           (if (is_list nbindcur)
8325               (let ( (thebindlist (deref nbindcont)))
8326                 (setq thebindlist (list_append2list thebindlist nbindcur))
8327                 (set_ref nbindcont thebindlist))))))
8328 ;;; put the binding into the data
8329       (let ( (thebindlist (deref nbindcont)) 
8330              (nbindtup (list_to_multiple thebindlist discr_multiple))
8331              )
8332         (if (>i (multiple_length nbindtup) 0) 
8333             (unsafe_put_fields insdata :ndata_locbind nbindtup))
8334         ;; force the name of the selectordata
8335         (multiple_put_nth slotup (get_int named_name) namstrdata)
8336         (if (is_a bindsel class_selector_binding)
8337             (put_fields bindsel :fixbind_data insdata))
8338         ;; return the data
8339         (debug "normexp_defselector return insdata" insdata)
8340         (return insdata ())
8341         ))))
8342 (install_method class_source_defselector normal_exp normexp_defselector)
8346 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8347 ;; internal function for value export
8349 ;;; sym is the exported symbol
8351 ;;; nexp is the normalized expression of its value
8353 (defun normal_exported_value (sym nexp env ncx psloc bindslist)
8354   (debug "normal_exported_value start sym=" sym " nexp=" nexp)
8355   (assert_msg "check sym" (is_a sym class_symbol) sym)
8356   (assert_msg "check nexp" (is_a nexp class_nrep) nexp)
8357   (assert_msg "check env" (is_a env class_environment) env)
8358   (assert_msg "check ncx" (is_a ncx class_normalization_context))
8359   (assert_msg "check bindslist" (is_list bindslist) bindslist)
8360   (let ( (csymexpo (clone_symbol '_exported_))
8361          (symdata (normal_symbol_data sym ncx psloc))
8362          (iniproc (unsafe_get_field :nctx_initproc ncx))
8363          (curproc (unsafe_get_field :nctx_curproc ncx))
8364          (csbuf (let ( (sb (make_strbuf discr_strbuf)) )
8365                   (add2sbuf_strconst sb "norm.exp.val : ")
8366                   (add2sbuf_string sb (unsafe_get_field :named_name sym))
8367                   sb))
8368          (scurenvbox (instance class_source_current_module_environment_reference
8369                                :loca_location psloc
8370                                :cmec_comment (strbuf2string discr_string csbuf)))
8371          )
8372     (debug "normal_exported_value scurenvbox=" scurenvbox)
8373     (multicall 
8374      (ncurenvbox curenvbinds)
8375      (normal_exp scurenvbox env ncx psloc)
8376      (debug "normal_exported_value ncurenvbox=" ncurenvbox " curenvbinds=" curenvbinds)
8377      ;;; if we are not at toplevel it has no sense to call the cont_fresh_env!
8378      (list_append2list bindslist curenvbinds)
8379      (let (
8380            (argtup  (tuple symdata nexp ncurenvbox))
8381            (cbind (instance class_normal_let_binding
8382                             :letbind_loc psloc
8383                             :binder csymexpo
8384                             :letbind_type ctype_void
8385                             :letbind_expr 
8386                             (instance class_nrep_hook_call
8387                                       :nrep_loc psloc
8388                                       :nexpr_ctyp ctype_value
8389                                       :nhook_name '"HOOK_VALUE_EXPORTER"
8390                                       :nexpr_args argtup
8391                                       :nhook_called (normal_predef hook_value_exporter ncx
8392                                                                    psloc "hook_value_exporter")
8393                                       :nhook_outs (tuple)
8394                                       :nhook_descr (hook_data hook_value_exporter)
8395                                       )
8396                             ))
8397            (syocc (instance class_nrep_locsymocc
8398                             :nrep_loc psloc
8399                             :nocc_ctyp ctype_void 
8400                             :nocc_symb csymexpo
8401                             :nocc_bind cbind) )
8402            )
8403        (debug "normal_exported_value cbind=" cbind " syocc=" syocc)
8404        (list_append bindslist cbind)
8405        syocc
8406        ;;
8407        ))))
8410 ;;;; normalize an export_values
8411 (defun normexp_export_values (recv env ncx psloc)
8412   ;; actually, export of values & classes could be simple.  the
8413   ;; export of a symbol should be expanded as the invocation of the
8414   ;; value exporter on the current module environment. we don't need
8415   ;; anything special in the initproc for the export.
8416 ;;;; this implies that a locally let-bound symbol could be passed to
8417 ;;;; export_values, some kind of strange practice.
8418   (debug "normexp_export_values recv=" recv)
8419   (assert_msg "check exportval recv" (is_a recv class_source_export_values) recv)
8420   (assert_msg "check env" (is_a env class_environment) env)
8421   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8422   (let ( 
8423         (sloc (unsafe_get_field :loca_location recv))
8424         (sxnames (unsafe_get_field :sexport_names recv))
8425         (bindslist (make_list discr_list))
8426         (nilnrep (instance class_nrep_nil
8427                            :nrep_loc sloc))
8428         )
8429     (foreach_in_multiple
8430      (sxnames)
8431      (xnam :long ix)
8432        (assert_msg "check xnam" (is_a xnam class_symbol) xnam)
8433        (debug "normexp_export_values xnam" xnam)
8434        (multicall
8435         (nsym nsymbinds)
8436         (normal_exp xnam env ncx sloc)
8437         (debug "normexp_export_values nsym=" nsym " nsymbinds=" nsymbinds)
8438         (list_append2list bindslist nsymbinds)
8439         (debug "normexp_export_values again xnam=" xnam " bindslist=" bindslist)
8440         (let ( (nexpv (normal_exported_value xnam nsym env ncx sloc bindslist))
8441                )
8442           (debug "normexp_export_values normal_exported_value gave nexpv" nexpv)
8443           )))
8444     (debug "normexp_export_values final nilnrep=" nilnrep " bindslist=" bindslist)
8445     (return nilnrep bindslist)
8446     ))
8449 (install_method class_source_export_values normal_exp normexp_export_values)
8451 ;;;; normalize an export_synonym
8452 (defun normexp_export_synonym (recv env ncx psloc)
8453   ;; it should be a bit like export_values, since it create a value binding..
8454   (debug "normexp_export_synonym recv=" recv)
8455   (assert_msg "check exportsyn recv" (is_a recv class_source_export_synonym) recv)
8456   (assert_msg "check env" (is_a env class_environment) env)
8457   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8458   (let ( 
8459         (sloc (unsafe_get_field :loca_location recv))
8460         (newname (unsafe_get_field :sexpsyn_newname recv))
8461         (oldname (unsafe_get_field :sexpsyn_oldname recv))
8462         (bindslist (make_list discr_list))
8463         (nilnrep (instance class_nrep_nil
8464                            :nrep_loc sloc))
8465         )
8466     (debug "normexp_export_synonym newname=" newname     " oldname=" oldname)
8467     (assert_msg "check newname" (is_a newname class_symbol) newname)
8468     (assert_msg "check oldname" (is_a oldname class_symbol) oldname)
8469     ;; when a class has a synonym, we should generate in the C code 
8470     ;;; const int meltclasslen__<SYNONYMNAME>
8471     ;; when a field has a synonym, we should generate in the C code
8472     ;;; const int meltfieldoff__<SYNONYMNAME> 
8473     (compile_warning "export_synonym should also generate a class length or field offset when needed")
8474     (multicall
8475      (noldsym noldsymbinds)
8476      (normal_exp oldname env ncx sloc)
8477      (debug "normexp_export_synonym noldsym=" noldsym " noldsymbinds=" noldsymbinds)
8478      (list_append2list bindslist noldsymbinds)
8479      (let ( (nexpv (normal_exported_value newname noldsym env ncx sloc bindslist))
8480             )
8481        (debug "normexp_export_synonym normal_exported_value gave nexpv=" nexpv
8482               " final nilnrep=" nilnrep
8483               " bindslist=" bindslist)
8484        (return nilnrep bindslist)
8485        ))))
8486       
8487 (install_method class_source_export_synonym normal_exp normexp_export_synonym)
8489 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8490 ;;;; normalize an export_class
8491 (defun normexp_export_class (recv env ncx psloc)
8492   (debug "normexp export_class recv=" recv)
8493   (assert_msg "check export_class recv" (is_a recv class_source_export_class) recv)
8494   (assert_msg "check env" (is_a env class_environment) env)
8495   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8496   (let ( 
8497         (sloc (unsafe_get_field :loca_location recv))
8498         (sxnames (unsafe_get_field :sexport_names recv))
8499         (bindslist (make_list discr_list))
8500         (nilnrep (instance class_nrep_nil
8501                            :nrep_loc sloc))
8502         (mocx (unsafe_get_field :nctx_modulcontext ncx))
8503         )
8504     (assert_msg "check mocx" (is_a mocx class_any_module_context) mocx)
8505     (foreach_in_multiple
8506      (sxnames)
8507      (xnam :long ix)
8508      (assert_msg "check xnam" (is_a xnam class_symbol) xnam)
8509      (let ( (xbind (find_env env xnam)) 
8510             (xsymdata (normal_symbol_data xnam ncx sloc))
8511             )
8512        (debug "normexp_export_class xbind" xbind)
8513        (assert_msg "check xsymdata" (is_a xsymdata class_nrep_datasymbol) xsymdata)
8514        (when (is_not_a xbind class_class_binding)
8515          (error_at sloc "EXPORT_CLASS with non-class-bound symbol $1"_
8516                    (unsafe_get_field :named_name xnam))
8517              (return))
8518        (let ( (xdata (unsafe_get_field :fixbind_data xbind)) 
8519               (xclass (unsafe_get_field :cbind_class xbind))
8520               )
8521          (debug "normexp_export_class xdata" xdata)
8522          (if (is_not_a xdata class_nrep_bound_data)
8523              (error_at sloc "forward defined class symbol $1 to EXPORT_CLASS"
8524                        (unsafe_get_field :named_name xnam)))
8525          (let ( (nclav (normal_exported_value xnam xdata env ncx sloc bindslist))
8526                 )
8527            (debug "normexp_export_class nclav" nclav)
8528            (assert_msg "check xclass" (is_a xclass class_class) xclass)
8529            (let ( (xclfields (unsafe_get_field :class_fields xclass))
8530                   (expcladic (get_field :mocx_expclassdict mocx))
8531                   (expfldic (get_field :mocx_expfieldict mocx))
8532                   )
8533              (assert_msg "check expcladic" (is_mapstring expcladic) expcladic)
8534              (assert_msg "check expfldic" (is_mapstring expfldic) expfldic)
8535              (mapstring_putstr expcladic (unsafe_get_field :named_name xclass) xclass)
8536              (foreach_in_multiple
8537               (xclfields)
8538               (curfld :long ix)
8539               (assert_msg "check curfld" (is_a curfld class_field) curfld)
8540               (let ( (fldnam (unsafe_get_field :named_name curfld))
8541                      (fldclass (unsafe_get_field :fld_ownclass curfld)) )
8542                 ;; export as value each field belonging to this class
8543                 (if (== fldclass xclass)
8544                     (let ( (fldsym (get_symbolstr fldnam))
8545                            (fldbind (find_env env fldsym))
8546                            )
8547                       (assert_msg "check fldbind" (is_a fldbind class_field_binding) fldbind)
8548                       (let ( (fldata (unsafe_get_field :fixbind_data fldbind))
8549                              (field (unsafe_get_field :flbind_field fldbind))
8550                              (nfld (normal_exported_value fldsym fldata env ncx sloc bindslist))
8551                              )
8552                         (assert_msg "check field" (is_a field class_field) field)
8553                         (assert_msg "check expfldic" (is_mapstring expfldic) expfldic)
8554                         (mapstring_putstr expfldic (unsafe_get_field :named_name field) field)
8555                         (debug "normexp_export_class nfld=" nfld)
8556                         )))))
8557              ))))
8558      )
8559     (debug "normexp_export_class final nilnrep=" nilnrep " bindslist=" bindslist)
8560     (return nilnrep bindslist)
8561     ))
8562 (install_method class_source_export_class normal_exp normexp_export_class)
8564 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8566 ;;;;;;;;;;;;;;;;
8569 ;; return the normalized application to do the macro expport
8570 (defun normal_exported_macro (sym nexp env ncx psloc bindslist)
8571   (debug "normal_exported_macro start sym=" sym "; psloc=" psloc
8572          "\n.. nexp=" nexp "\n.. env=" env)
8573   (assert_msg "check sym" (is_a sym class_symbol) sym)
8574   (assert_msg "check nexp" (is_a nexp class_nrep) nexp)
8575   (assert_msg "check env" (is_a env class_environment) env)
8576   (assert_msg "check ncx" (is_a ncx class_normalization_context))
8577   (assert_msg "check bindslist" (is_list bindslist) bindslist)
8578   (let ( (csymexpo (clone_symbol '_exportedm_))
8579          (symdata (normal_symbol_data sym ncx psloc))
8580          (csbuf (let ( (sb (make_strbuf discr_strbuf)) )
8581                   (add2sbuf_strconst sb "norm.exp.val : ")
8582                   (add2sbuf_string sb (unsafe_get_field :named_name sym))
8583                   sb))
8584          (scurenvbox (instance class_source_current_module_environment_reference
8585                                :loca_location psloc
8586                                :cmec_comment (strbuf2string discr_string csbuf)))
8587          )
8588     (debug "normal_exported_macro sgetcurenvbox" scurenvbox)
8589     (multicall 
8590      (ncurenvbox curenvbinds)
8591      (normal_exp scurenvbox env ncx psloc)
8592      (debug "normal_exported_macro ncurenvbox=" ncurenvbox " curenvbinds=" curenvbinds)
8593      (if (is_list curenvbinds) (list_append2list bindslist curenvbinds))
8594      (let (
8595            (argtup (tuple symdata nexp ncurenvbox))
8596            (cbind (instance class_normal_let_binding
8597                             :letbind_loc psloc
8598                             :binder csymexpo
8599                             :letbind_type ctype_void
8600                             :letbind_expr
8601                             (instance class_nrep_hook_call
8602                                       :nexpr_ctyp ctype_void
8603                                       :nhook_name '"HOOK_MACRO_EXPORTER"
8604                                       :nexpr_args argtup
8605                                       :nhook_called  (normal_predef hook_macro_exporter ncx
8606                                                                     psloc "hook_macro_exporter")
8607                                       :nhook_outs (tuple)
8608                                       :nhook_descr (hook_data hook_macro_exporter))                   
8609                             ))
8610            (syocc (instance class_nrep_locsymocc
8611                             :nrep_loc psloc
8612                             :nocc_ctyp ctype_void 
8613                             :nocc_symb csymexpo
8614                             :nocc_bind cbind) )
8615            )
8616        (debug "normal_exported_macro cbind=" cbind " syocc=" syocc)
8617        (list_append bindslist cbind)
8618        syocc
8619        ;;
8620        ))))
8622 ;;;; normalize an export_macro with an explicit expander
8623 (defun normexp_export_macro (recv env ncx psloc)
8624   (debug "normexp export_macro recv=" recv " env=" debug_less env)
8625   (assert_msg "check export_macro recv" (is_a recv class_source_export_macro) recv)
8626   (assert_msg "check env" (is_a env class_environment) env)
8627   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8628   (let ( 
8629         (sloc (unsafe_get_field :loca_location recv))
8630         (mname (unsafe_get_field :sexpmac_mname recv))
8631         (mvalexp (unsafe_get_field :sexpmac_mval recv))
8632         (bindslist (make_list discr_list))
8633         (nrepnil (instance class_nrep_nil :nrep_loc sloc))
8634         )
8635     (assert_msg "check mname" (is_a mname class_symbol) mname)
8636     (multicall 
8637      (nexp nbinds)
8638      (normal_exp mvalexp env ncx sloc)
8639      (list_append2list bindslist nbinds)
8640      (let ( 
8641            (nexpm (normal_exported_macro mname nexp env ncx sloc bindslist))
8642            )
8643        (debug "normexp_export_macro nexpm" nexpm)
8644        )
8645      (debug "normexp_export_macro final nrepnil=" nrepnil
8646             " bindslist=" bindslist)
8647      (return nrepnil bindslist)
8648      )))
8649 (install_method class_source_export_macro normal_exp normexp_export_macro)
8651 ;;;; normalize an export_macro for a defmacro
8652 (defun normexp_export_defmacro (recv env ncx psloc)
8653   (debug "normexp_export_defmacro recv=" recv " env=" debug_more env)
8654   (assert_msg "check export_defmacro recv" (is_a recv class_source_export_defmacro) recv)
8655   (assert_msg "check env" (is_a env class_environment) env)
8656   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8657   (let ( 
8658         (modctx (get_field :nctx_modulcontext ncx))
8659         (macroenv (get_field :mocx_macroenv modctx))
8660         (sloc (unsafe_get_field :loca_location recv))
8661         (mname (unsafe_get_field :sexpmac_mname recv))
8662         (bindslist (make_list discr_list))
8663         (nrepnil (instance class_nrep_nil :nrep_loc sloc))
8664         )
8665     (assert_msg "check mname" (is_a mname class_symbol) mname)
8666     (debug "normexp_export_defmacro sloc=" debug_less sloc "; macroenv=" debug_more macroenv)
8667     (multicall 
8668      (nexp nbinds)
8669      (normal_exp mname macroenv ncx sloc)
8670      (list_append2list bindslist nbinds)
8671      (debug "normexp_export_defmacro sloc=" debug_less sloc "; nexp=" nexp " nbinds=" nbinds)
8672      (let ( 
8673            (nexpm (normal_exported_macro mname nexp macroenv ncx sloc bindslist))
8674            )
8675        (debug "normexp_export_defmacro  sloc=" debug_less sloc "; nexpm=" nexpm)
8676        )
8677      (debug "normexp_export_macro final nrepnil=" nrepnil
8678             " bindslist=" bindslist)
8679      (return nrepnil bindslist)
8680      )))
8681 (install_method class_source_export_defmacro normal_exp normexp_export_defmacro)
8683 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8686 ;; return the normalized application to do the patmacro expport
8687 ;; sym is the symbol which is export_patmacro-ed
8688 ;; nmacroxp is the nrep of the macro expander
8689 ;; npattxp is the nrep of the pattern expander
8690 (defun normal_exported_patmacro (sym nmacroxp npattxp env ncx psloc bindslist)
8691   (debug "normal_exported_patmacro start sym=" sym
8692          " nmacroxp=" nmacroxp " npattxp=" npattxp)
8693   (assert_msg "check sym" (is_a sym class_symbol) sym)
8694   (assert_msg "check nmacroxp" (is_a nmacroxp class_nrep) nmacroxp)
8695   (assert_msg "check env" (is_a env class_environment) env)
8696   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8697   (assert_msg "check bindslist" (is_list bindslist) bindslist)
8698   (let ( (csymexpo (clone_symbol '_exportedpat_))
8699          (symdata (normal_symbol_data sym ncx psloc))
8700          (csbuf (let ( (sb (make_strbuf discr_strbuf)) )
8701                   (add2sbuf_strconst sb "norm.exp.pat : ")
8702                   (add2sbuf_string sb (unsafe_get_field :named_name sym))
8703                   sb))
8704          (scurenvbox (instance class_source_current_module_environment_reference
8705                                :loca_location psloc
8706                                :cmec_comment (strbuf2string discr_string csbuf)))
8707          )
8708     (debug "normal_exported_patmacro sgetcurenvbox" scurenvbox)
8709     (multicall 
8710      (ncurenvbox curenvbinds)
8711      (normal_exp scurenvbox env ncx psloc)
8712      (debug "normal_exported_patmacro ncurenvbox=" ncurenvbox
8713             " curenvbinds=" curenvbinds)
8714      (if (is_list curenvbinds) (list_append2list bindslist curenvbinds))
8715      (let (
8716            (argtup  (tuple symdata nmacroxp npattxp ncurenvbox))
8717            (cbind (instance class_normal_let_binding
8718                             :letbind_loc psloc
8719                             :binder csymexpo
8720                             :letbind_type ctype_void
8721                             :letbind_expr 
8722                             (instance class_nrep_hook_call
8723                                       :nexpr_ctyp ctype_void
8724                                       :nhook_name '"HOOK_PATMACRO_EXPORTER"
8725                                       :nexpr_args argtup
8726                                       :nhook_called  (normal_predef hook_patmacro_exporter ncx
8727                                                                     psloc "hook_patmacro_exporter")
8728                                       :nhook_outs (tuple)
8729                                       :nhook_descr (hook_data hook_patmacro_exporter))
8730                             ))
8731            (syocc (instance class_nrep_locsymocc
8732                             :nrep_loc psloc
8733                             :nocc_ctyp ctype_void 
8734                             :nocc_symb csymexpo
8735                             :nocc_bind cbind) )
8736            )
8737        (debug "normal_exported_patmacro cbind=" cbind " return syocc=" syocc)
8738        (list_append bindslist cbind)
8739        syocc
8740        ;;
8741        ))))
8743 ;;;;;;;;;;;;;;;;
8744 ;;;; normalize an export_patmacro
8745 (defun normexp_export_patmacro (recv env ncx psloc)
8746   (debug "normexp export_patmacro recv=" recv)
8747   (assert_msg "check export_patmacro recv" (is_a recv class_source_export_patmacro) recv)
8748   (assert_msg "check env" (is_a env class_environment) env)
8749   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8750   (let (
8751         (sloc (unsafe_get_field :loca_location recv))
8752         (mname (unsafe_get_field :sexpmac_mname recv))
8753         (mvalexp (unsafe_get_field :sexpmac_mval recv))
8754         (mpatexp (unsafe_get_field :sexppat_pval recv))
8755         (bindslist (make_list discr_list))
8756         (nrepnil (instance class_nrep_nil :nrep_loc sloc))
8757         )
8758     (debug "normexp export_patmacro mname=" mname)
8759     (assert_msg "check mname" (is_a mname class_symbol) mname)
8760     (multicall 
8761      (nexpmac nbindms)
8762      (normal_exp mvalexp env ncx sloc)
8763      (list_append2list bindslist nbindms)
8764      (debug "normexp_export_patmacro nexpmac" nexpmac)
8765      (multicall 
8766       (nexppat nbindps)
8767       (normal_exp mpatexp env ncx sloc)
8768       (list_append2list bindslist nbindps)
8769       (debug "normexp_export_patmacro nexppat" nexpmac)
8770       (let ( (nexpm (normal_exported_patmacro mname nexpmac nexppat env ncx sloc bindslist)) )
8771         (debug "normexp_export_patmacro nexpm=" nexpm)
8772         (debug "normexp_export_patmacro final nrepnil=" nrepnil " bindslist=" bindslist)
8773         (return nrepnil bindslist)
8774         )
8775       ))
8776     ))
8777 (install_method class_source_export_patmacro normal_exp normexp_export_patmacro)
8779 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8780 ;;;; normalize current_module_environment_reference
8781 (defun normexp_current_module_environment_reference (recv env ncx psloc)
8782   (debug "normexp_current_module_environment_reference recv=" recv)
8783   (assert_msg "check current_module_environment_reference recv" 
8784               (is_a recv class_source_current_module_environment_reference) recv)
8785   (assert_msg "check env" (is_a env class_environment) env)
8786   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8787   (let ( 
8788         (sloc (unsafe_get_field :loca_location recv))
8789         (scomm (unsafe_get_field :cmec_comment recv))
8790         (ncurmodenvlist (unsafe_get_field :nctx_procurmodenvlist ncx))
8791         (curproc (unsafe_get_field :nctx_curproc ncx))
8792         (qdatcur (unsafe_get_field :nctx_qdatcurmodenvbox ncx))
8793         (nquasi (instance class_nrep_quasiconst_current_module_environment_reference
8794                           :nrep_loc sloc
8795                           :nconst_sval recv
8796                           :nconst_proc curproc
8797                           :nconst_data qdatcur
8798                           :nqcmec_comment scomm
8799                           ))
8800         )
8801     (assert_msg "check qdatcur" (is_a qdatcur class_nrep_quasidata_current_module_environment_reference) qdatcur)
8802     (when (is_a curproc class_nrep_hookproc)
8803       (error_at sloc "(CURRENT_MODULE_ENVIRONMENT_REFERENCE) cannot be used within hooks"_)
8804       (return))
8805     (when (is_a curproc class_nrep_routproc)
8806           (list_append (get_field :nrclop_constlist curproc) qdatcur)
8807           (list_append ncurmodenvlist curproc)
8808           )
8809     (debug "normexp_current_module_environment_reference nquasi" nquasi)
8810     (return nquasi ())
8811     ))
8812 (install_method class_source_current_module_environment_reference normal_exp normexp_current_module_environment_reference)
8813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8815 ;;;; normalize parent_module_environment
8816 (defun normexp_parent_module_environment (recv env ncx psloc)
8817   (debug "normexp_parent_module_environment recv=" recv)
8818   (assert_msg "check parent_module_environment recv" (is_a recv class_source_parent_module_environment) recv)
8819   (assert_msg "check env" (is_a env class_environment) env)
8820   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8821   (let ( 
8822         (sloc (unsafe_get_field :loca_location recv))
8823         (curproc (unsafe_get_field :nctx_curproc ncx))
8824         (qdatpar (unsafe_get_field :nctx_qdatparmodenv ncx))
8825         (nquasi (instance class_nrep_quasiconst_parent_module_environment
8826                           :nrep_loc sloc
8827                           :nconst_sval recv
8828                           :nconst_proc curproc
8829                           :nconst_data qdatpar
8830                           ))
8831         )
8832     (when (is_a curproc class_nrep_hookproc)
8833       (error_at sloc "(PARENT_MODULE_ENVIRONMENT) cannot be used within hooks"_)
8834       (return))
8835     (assert_msg "check qdatpar" (is_a qdatpar class_nrep_quasidata_parent_module_environment) qdatpar)
8836     (if (is_a curproc class_nrep_routproc)
8837         (list_append (get_field :nrclop_constlist curproc) qdatpar))
8838     (debug "normexp_parent_module_environment nquasi" nquasi)
8839     (return nquasi ())
8840     ))
8841 (install_method class_source_parent_module_environment normal_exp normexp_parent_module_environment)
8842 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8844 ;;; normalize update_current_module_environment_reference
8845 (defun normexp_update_current_module_environment_reference (recv env ncx psloc)
8846   (debug "normexp_update_current_module_environment_reference recv=" recv
8847          "\n env=" env
8848          "\n ncx=" debug_less ncx)
8849   (assert_msg "check update_current_module_environment_reference recv"
8850               (is_a recv class_source_update_current_module_environment_reference) recv)
8851   (assert_msg "check env" (is_a env class_environment) env)
8852   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8853   (shortbacktrace_dbg "normexp_update_current_module_environment_reference" 20)
8854   (let ( 
8855         (sloc (unsafe_get_field :loca_location recv))
8856         (scomm (unsafe_get_field :sucme_comment recv))
8857         (curproc (unsafe_get_field :nctx_curproc ncx))
8858         (iniproc (unsafe_get_field :nctx_initproc ncx))
8859         (modctx (unsafe_get_field :nctx_modulcontext ncx))
8860         (modnam  (get_field :mocx_modulename modctx))
8861         )
8862     (when (!= curproc iniproc)
8863           (error_at sloc "(UPDATE_CURRENT_MODULE_ENVIRONMENT_REFERENCE) not at toplevel"_)
8864           (return))
8865     (debug "normexp_update_current_module_environment_reference modctx=" 
8866            debug_less modctx)
8867     (cond ((is_a modctx class_running_extension_module_context)
8868            (let ( (nchk (instance class_nrep_check_running_module_environment_container
8869                                   :nrep_loc sloc
8870                                   :nchrumod_comment scomm
8871                                   ))
8872                   (csym (clone_symbol 'checkrunmodenvbox_))
8873                   (cbind (instance 
8874                           class_normal_let_binding
8875                           :letbind_loc sloc
8876                           :binder csym
8877                           :letbind_type ctype_void
8878                           ;; ctype_void because the sideffect is in nchk
8879                           :letbind_expr nchk))
8880                   (clocc (instance 
8881                           class_nrep_locsymocc
8882                           :nrep_loc sloc
8883                           :nocc_ctyp ctype_void
8884                           :nocc_symb csym
8885                           :nocc_bind cbind))
8886                   (bindlist (list cbind))
8887                   )
8888              (debug "normexp_update_current_module_environment_reference gives nchk=" nchk
8889                     " clocc=" clocc " bindlist=" bindlist)
8890              (return clocc bindlist)
8891              ))
8892           ((is_a modctx class_any_module_context)
8893            (assert_msg "check modctx not running" (is_not_a modctx class_running_extension_module_context) modctx)
8894            (let ( (nup (instance class_nrep_update_current_module_environment_reference
8895                                  ;; :ncumeb_expr filled later
8896                                  :nrep_loc sloc
8897                                  :ncumeb_comment scomm
8898                                  )) 
8899                   (csym (clone_symbol 'updatcurmodenvbox_))
8900                   (cbind (instance 
8901                           class_normal_let_binding
8902                           :letbind_loc sloc
8903                           :binder csym
8904                           :letbind_type ctype_void
8905                           ;; ctype_void because the sideffect is in nup
8906                           :letbind_expr nup))
8907                   (clocc (instance 
8908                           class_nrep_locsymocc
8909                           :nrep_loc sloc
8910                           :nocc_ctyp ctype_void
8911                           :nocc_symb csym
8912                           :nocc_bind cbind))
8913                   (csbuf (let ( (sb (make_strbuf discr_strbuf)) )
8914                            (add2sbuf_strconst sb "cur.mod.env.cont : ")
8915                            (add2sbuf_string sb scomm)
8916                            sb))
8917                   (scurenvbox (instance class_source_current_module_environment_reference
8918                                         :loca_location sloc
8919                                         :cmec_comment (strbuf2string discr_string csbuf)))
8920                   (sgetcurenvbox
8921                    (instance 
8922                     class_source_or
8923                     :loca_location psloc
8924                     :sor_disj 
8925                     (tuple
8926                      scurenvbox
8927                      (instance 
8928                       class_source_hook_call
8929                       :loca_location psloc
8930                       :shook_called hook_fresh_environment_reference_maker
8931                       :sargop_args (tuple
8932                                     (instance class_source_parent_module_environment
8933                                               :loca_location psloc)
8934                                     modnam
8935                                     ))
8936                      )))
8937                   )
8938              (multicall
8939               (ncurenvbox bindlist)
8940               (normal_exp sgetcurenvbox env ncx sloc)
8941               (list_append bindlist cbind)
8942               (unsafe_put_fields nup :nucmeb_expr ncurenvbox)
8943               (debug "normexp_update_current_module_environment_reference result bindlist=" bindlist" clocc=" clocc)
8944               (return clocc bindlist)
8945               )
8946              ))
8947           (:else
8948            (assert_msg "normexp_update_current_module_environment_reference unexpected module context" () modctx))
8949           )))
8950 (install_method class_source_update_current_module_environment_reference normal_exp normexp_update_current_module_environment_reference)
8952 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8954 ;;;; normalize a fetch_predefined
8955 (defun normexp_fetch_predefined (recv env ncx psloc)
8956   (debug "normexp_fetch_predefined recv=" recv)
8957   (assert_msg "check fetch_predefined recv" (is_a recv class_source_fetch_predefined) recv)
8958   (assert_msg "check env" (is_a env class_environment) env)
8959   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
8960   (let ( 
8961         (sloc (unsafe_get_field :loca_location recv))
8962         (spred (unsafe_get_field :sfepd_predef recv))
8963         (predefmap (unsafe_get_field :nctx_predefmap ncx))
8964         )
8965     (cond ( (is_a spred class_symbol)
8966             ;; if the spred is a symbol, check that it is a value in the predefmap
8967             (let ( (contk (reference ())) 
8968                    )
8969               (mapobject_every predefmap
8970                                (lambda (key val)
8971                                  (if (== val spred) (set_ref contk key))))
8972               (if (null (deref contk))
8973                   (warning_strv sloc "FETCH_PREDEFINED unknown predef name"
8974                                 (unsafe_get_field :named_name spred)))
8975               )
8976             )
8977           ( (is_integerbox spred)
8978             ;; if spred is an integer, check it
8979             (let ( (:long predrk (get_int spred)) )
8980               (if (or (<=i predrk 0) (>=i predrk (last_globpredef_index)))
8981                   (warning_plain sloc "FETCH_PREDEFINED invalid predef rank"))
8982               )
8983             )
8984           (:else
8985            (assert_msg "FETCH_PREDEFINED bad predef" () spred))
8986           )
8987     (let ( (npre (instance class_nrep_predef
8988                            :nrep_loc sloc
8989                            :nrpredef spred
8990                            ))
8991            )
8992       (debug "normexp_fetch_predefined result npre" npre)
8993       (return npre ())
8994       )))
8995 (install_method class_source_fetch_predefined normal_exp normexp_fetch_predefined)
8998 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9000 ;;;; normalize a store_predefined
9001 (defun normexp_store_predefined (recv env ncx psloc)
9002   (debug "normexp_store_predefined recv=" recv)
9003   (assert_msg "check store_predefined recv" (is_a recv class_source_store_predefined) recv)
9004   (assert_msg "check env" (is_a env class_environment) env)
9005   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
9006   (let ( 
9007         (sloc (unsafe_get_field :loca_location recv))
9008         (spred (unsafe_get_field :sstpd_predef recv))
9009         (sval (unsafe_get_field :sstpd_value recv))
9010         (predefmap (unsafe_get_field :nctx_predefmap ncx))
9011         )
9012     (cond ( (is_a spred class_symbol)
9013             ;; if the spred is a symbol, check that it is a value in the predefmap
9014             (let ( (contk (reference ())) 
9015                    )
9016               (mapobject_every predefmap
9017                                (lambda (key val)
9018                                  (if (== val spred) (set_ref contk key))))
9019               (if (null (deref contk))
9020                   (warning_strv sloc "STORE_PREDEFINED unknown predef name"
9021                                 (unsafe_get_field :named_name spred)))
9022               )
9023             )
9024           ( (is_integerbox spred)
9025             ;; if spred is an integer, check it
9026             (let ( (:long predrk (get_int spred)) )
9027               (if (or (<=i predrk 0) (>=i predrk (last_globpredef_index)))
9028                   (warning_plain sloc "STORE_PREDEFINED invalid predef rank"))
9029               )
9030             )
9031           (:else
9032            (assert_msg "STORE_PREDEFINED bad predef" () spred))
9033           )
9034     (multicall 
9035      (nval nbinds)
9036      (normal_exp sval env ncx sloc)
9037      (if (null nbinds) 
9038          (setq nbinds (make_list discr_list)))
9039      (let ( (csym (clone_symbol '_storepredef_))
9040             (nfpre (instance class_nrep_store_predefined
9041                              :nrep_loc sloc
9042                              :nstpd_predef spred
9043                              :nstpd_value nval))
9044             (cbind (instance class_normal_let_binding
9045                              :binder csym
9046                              :letbind_type ctype_value
9047                              :letbind_expr nfpre))
9048             (syocc (instance class_nrep_locsymocc
9049                              :nrep_loc sloc
9050                              :nocc_ctyp ctype_value
9051                              :nocc_symb csym
9052                              :nocc_bind cbind))
9053             )
9054        (list_append nbinds cbind)
9055        (debug "normexp_store_predefined result nbinds=" nbinds " syocc=" syocc)
9056        (return syocc nbinds)
9057        ))))
9058 (install_method class_source_store_predefined normal_exp normexp_store_predefined)
9060 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9062 ;;;; normalize a cheader
9063 (defun normexp_cheader (recv env ncx psloc)
9064   (debug "normexp_cheader recv=" recv "\n* ncx=" ncx)
9065   (assert_msg "check cheader recv" (is_a recv class_source_cheader) recv)
9066   (assert_msg "check env" (is_a env class_environment) env)
9067   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
9068   (let ( 
9069         (sloc (unsafe_get_field :loca_location recv))
9070         (modctx (get_field :nctx_modulcontext ncx))
9071         (mcheadlist (get_field :mocx_cheaderlist modctx))
9072         )
9073     (debug "normexp_cheader modctx=" modctx "\n.. mcheadlist=" mcheadlist
9074            "\n.. recv=" recv)
9075     (shortbacktrace_dbg "normexp_cheader" 12)
9076     (assert_msg "check modctx" (is_a modctx class_any_module_context) modctx)
9077     (assert_msg "check mcheadlist" (is_list mcheadlist) mcheadlist)
9078     (cppif MELT_HAVE_DEBUG
9079            (foreach_pair_component_in_list
9080             (mcheadlist)
9081             (curpair curhead)
9082             (assert_msg "check curhead != recv" (!= curhead recv) curhead
9083                         mcheadlist modctx))
9084            )
9085     (list_append mcheadlist recv)
9086     (debug "normexp_cheader updated mcheadlist=" mcheadlist "\n modctx=" modctx "\n")
9087     (return () ())
9089 (install_method class_source_cheader normal_exp normexp_cheader)
9092 ;;;; normalize a cimplement
9093 (defun normexp_cimplement (recv env ncx psloc)
9094   (debug "normexp_cimplement recv=" recv "\n* ncx=" ncx)
9095   (assert_msg "check cimplement recv" (is_a recv class_source_cimplement) recv)
9096   (assert_msg "check env" (is_a env class_environment) env)
9097   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
9098   (let ( 
9099         (sloc (unsafe_get_field :loca_location recv))
9100         (modctx (get_field :nctx_modulcontext ncx))
9101         (mcimplemlist (get_field :mocx_cimplementlist modctx))
9102         )
9103     (debug "normexp_cimplement modctx=" modctx "\n mcimplemlist=" mcimplemlist)
9104     (assert_msg "check modctx" (is_a modctx class_any_module_context) modctx)
9105     (assert_msg "check mcimplemlist" (is_list mcimplemlist) mcimplemlist)
9106     (list_append mcimplemlist recv)
9107     (debug "normexp_cimplement updated mcimplemlist=" mcimplemlist "\n modctx=" modctx "\n")
9108     (return () ())
9110 (install_method class_source_cimplement normal_exp normexp_cimplement)
9113 ;;;; normalize a module_is_gpl_compatible
9114 (defun normexp_module_is_gpl_compatible (recv env ncx psloc)
9115   (debug "normexp_module_is_gpl_compatible recv=" recv "\n* ncx=" ncx)
9116   (assert_msg "check module_is_gpl_compatible recv" (is_a recv class_source_module_is_gpl_compatible) recv)
9117   (assert_msg "check env" (is_a env class_environment) env)
9118   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
9119   (let ( 
9120         (sloc (unsafe_get_field :loca_location recv))
9121         (modctx (get_field :nctx_modulcontext ncx))
9122         (modgplcomp (get_field :mocx_isgplcompatible modctx))
9123         (gplcomp (get_field :sc_codestring recv))
9124         )
9125     (debug "normexp_module_is_gpl_compatible modctx=" modctx " modgplcomp=" modgplcomp " gplcomp=" gplcomp)
9126     (assert_msg "check modctx" (is_a modctx class_any_module_context) modctx)
9127     (assert_msg "check gplcomp" (is_string gplcomp) gplcomp)
9128     (when modgplcomp
9129       (assert_msg "check modgplcomp" (is_string modgplcomp))
9130       (warning_at sloc "duplicate MODULE_IS_GPL_COMPATIBLE, previous was $1, current is $2"
9131                   modgplcomp gplcomp)
9132       )
9133     (put_fields modctx :mocx_isgplcompatible gplcomp)
9134     (return () ())
9136 (install_method class_source_module_is_gpl_compatible normal_exp normexp_module_is_gpl_compatible)
9139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9141 ;;;; normalize a use_package_from_pkg_config
9142 (defun normexp_use_package_from_pkg_config (recv env ncx psloc)
9143   (debug "normexp_use_package_from_pkg_config recv=" recv "\n* ncx=" ncx)
9144   (assert_msg "check cheader recv" (is_a recv class_source_use_package_from_pkg_config) recv)
9145   (assert_msg "check env" (is_a env class_environment) env)
9146   (assert_msg "check ncx" (is_a ncx class_normalization_context) ncx)
9147   (let ( 
9148         (sloc (unsafe_get_field :loca_location recv))
9149         (pkgtup (get_field :susepackage_pkgtuple recv))
9150         (modctx (get_field :nctx_modulcontext ncx))
9151         (mcpackagelist (get_field :mocx_packagepclist modctx))
9152         )
9153     (debug "normexp_use_package_from_pkg_config initial mcpackagelist=" mcpackagelist)
9154     (assert_msg "check modctx" (is_a modctx class_any_module_context) modctx)
9155     (assert_msg "check mcpackagelist" (is_list mcpackagelist) mcpackagelist)
9156     ;; append each package name only if it is not already in the list
9157     (foreach_in_multiple
9158      (pkgtup)
9159      (curpkgname :long pkgix)
9160      (debug "normexp_use_package_from_pkg_config curpkgname=" curpkgname)
9161      (assert_msg "check curpkgname" (is_string curpkgname) curpkgname)
9162      (let ( (:long found 0)
9163             )
9164        (foreach_pair_component_in_list
9165         (mcpackagelist)
9166         (curpair oldpkgname)
9167         (when (==s oldpkgname curpkgname)
9168           (setq found 1)
9169           (setq curpair ())))
9170        (unless found
9171          (list_append mcpackagelist curpkgname))
9172        )
9173      )
9174     ;;
9175     (debug "normexp_use_package_from_pkg_config final mcpackagelist=" mcpackagelist)
9176     ))
9177 (install_method class_source_use_package_from_pkg_config normal_exp normexp_use_package_from_pkg_config)
9181 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9183 (export_values
9184  check_ctype_nargs
9185  compile_obj
9186  create_normcontext
9187  create_normal_extending_context
9188  discr_normalizing_closure
9189  get_ctype
9190  normal_exp
9191  normal_letrec_constructive
9192  normal_predef
9193  normal_import
9194  normalize_binding
9195  normalize_tuple
9196  prepare_constructor_binding
9197  register_literal_value
9198  wrap_normal_let1
9199  wrap_normal_letseq
9202 ;; compatibility with old code
9203 (export_synonym class_nrep_data class_nrep_bound_data)
9204 (export_synonym class_nrep_checkinterrupt class_nrep_checksignal)
9205 (export_synonym class_nrep_quasiconst_current_module_environment_container class_nrep_quasiconst_current_module_environment_reference)
9206 (export_synonym class_nrep_quasidata_current_module_environment_container class_nrep_quasidata_current_module_environment_reference)
9207 (export_synonym class_nrep_update_current_module_environment_container class_nrep_update_current_module_environment_reference)
9209 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9210 ;;; eof warmelt-normal.melt