!* 001 AA
! Muokattu: oct 9 933516 "peruna... ei koskettu kirjastoon"
! sis. >> parsi.h arvelu.h luonnos.h ttyypit.h tulosta.h hakkyra.h
!==> parsi.h <==

!!! parsi.h !!!

! jos sanoo että tämä on systeemifilu, ei tule varoituksia
! että käytetään -> kutsuttaessa --> tai tables taulukoita
! jos merkinnät korjaa (?), esim. nakki ja tädit menee rikki 
System_file; ! poista tämä niin saat enemmän varoituksia


! ** Dictinary Lookup
#Ifdef TARGET_ZCODE;

[ DL b l i;
    if (l == 0 || l > Tlimit) return 0; !+lisäys
    for (i=0 : i<l : i++) buffer2->(2+i) = b->i;
    buffer2->1 = l;
    Tokenise__(buffer2,parse2);
    return parse2-->1;
];

#Ifnot; ! TARGET_GLULX

[ DL b l i;
    if (l == 0 || l > Tlimit) return 0; !+lisäys
    for (i=0 : i<l : i++) buffer2->(WORDSIZE+i) = b->i;
    buffer2-->0 = l;
    Tokenise__(buffer2,parse2);
    return parse2-->1;
];

#Endif; ! TARGET_



Attribute oletus_par;

! ** Parser Error (error code)
!
! jos sija ON olemassa (esim. ei "pallorz%s5t"),
! ja esine/asia ON paikalla,
! mutta konteksti väärä (">ota palloLLE"),
! ei sanota "Et näe mitään sellaista" (error_code 4),
! vaan:
!
!   >ota pallosta
!   En ihan käsittänyt.
!
! ...ja myös:
!
!   >ota pallox
!	En ihan käsittänyt.
!
! menee sijamuotona koska "x//" on sanakirjassa
! (samoin "pallosyö" ("syö" on sanak) -> "En ihan käsittänyt"
! mikä on ihan hyvä vastaus jos pallo on huoneessa).
! Se on käytännössä sama kuin etype 1
! (error type 1 == STUCK_PE == "En käsittänyt tuota lausetta.")

[ ParserError error_code;
    
#Ifdef DEBUG;
    if (parser_trace > 1)
    { print "^ ParserError: etype ", etype, "  muu_sija: ", muu_sija,
	" ecode: ", error_code, " ^";
    	if (error_code == 2) print "vähennetään UPTO_PE -> STUCK_PE:ksi^";
    	if (muu_sija == true && error_code == 4) print
	    "~Et näe mitään sellaista.~ (ecode 4) -> ~En ihan
    	    käsittänyt.~ (käytännössä sama kuin ecode 1)^";
    }
#Endif;
    
    ! vähennetään UPTO_PE -> STUCK_PE:ksi
    if (error_code == 2) etype = 1;
    
    if (muu_sija == true && error_code == 4)
	print_ret "En ihan käsittänyt.";
    
    ! (vai annetaanko merkkijono?)
    if (error_code ofclass String) print_ret (string) error_code;
    
    rfalse; ! Print standard parser error message
];

!* 002
! muuten sama kuin wordinproperty mutta palauttaa
! paikan obj.#prop listassa jos löytyy.
! koska 0 on ensimmäinen, tämä antaa väärän falsen
! (käytä WordInPropertyä siihen, se sanoo onko true / false) 

! +suttux alku
! -*- mode: inform  -*-
! ==============================================================================
! esiparsi -- tee taulut esiparsi temp taulut
!

!! temp-taulujen on tarkoitus korvata vastaavat tulostus- ja parsi-taulut
Constant NomGenPar_temp_len = 120;
Array NomGenPar_temp --> NomGenPar_temp_len;

! ? tekeekö taulu suffiksi mitään missään? 
Constant Suffiksi_temp_len = 10;
Array Suffiksi_temp --> Suffiksi_temp_len;


Constant temp_match_arr_len = 90;
Array temp_match_arr-->temp_match_arr_len;


! yks. & monikko
Constant nom_temp_arr_len = 90;
Array nom_temp_arr-->nom_temp_arr_len;
Constant gen_temp_arr_len = 90;
Array gen_temp_arr-->gen_temp_arr_len;
Constant par_temp_arr_len = 90;
! yksikkö (ja monikko koska ill_arr ei käytetä)
Array par_temp_arr-->par_temp_arr_len;


Constant osa_temp_len = 60;
Array osa_temp_arr --> osa_temp_len;


Constant inp_temp_arr_len = 102;
Array inp_temp_arr-->inp_temp_arr_len;

!* 004
[ tyhjenna_taulut_temp; 
    

    ("").print_to_array(temp_match_arr);

    ("").print_to_array(osa_temp_arr);    
    
    ("").print_to_array(nom_temp_arr);
    ("").print_to_array(gen_temp_arr);
    ("").print_to_array(par_temp_arr);
    ("").print_to_array(nomgenpar_temp);
    ("").print_to_array(suffiksi_temp);    

];


[ pilko_ngp_versio taulusta nom_ gen_ par_ at pituus nom_loppu gen_loppu nom_jatke_alku;
    
    
    !if (dp>3) print "# pilko_ngp_versio: pituus ", taulusta-->0, " ";!pituus
    
    pituus = taulusta-->0;
    
    ! "äll|i/n/ä" pit 9
    !print ">>>", pituus, "*";
    
    for (at=WORDSIZE:at<pituus+WORDSIZE:at++)
    {	
	
	!if (taulusta->at ~= '|' or '/')
	!print(char)taulusta->at;

	if (taulusta->at == '|') nom_jatke_alku = at;
	
	    
	if (nom_loppu == 0 && taulusta->at == '|' && taulusta->(at+1) == '/')
	{
	    nom_loppu = at;
	    at = at+2;
	}
	else if (nom_loppu == 0 && taulusta->at == '/')
	{
	    nom_loppu = at;
	    at++;	    
	}
	
	if (nom_loppu && gen_loppu == 0 && taulusta->at == '/')
	{
	    gen_loppu = at;
	    at++;
	}
	
    }
    
    !print "^#### (", pituus, ") ", nom_loppu, " ", gen_loppu, " ";
    
    !for (at=WORDSIZE:at<pituus+WORDSIZE:at++)
    !{
    !	!if (taulusta->at ~= '|' or '/')
    !	print(char)taulusta->at;	
    !}
    
    !print " ####^";
    
    if (nom_jatke_alku == 0) nom_jatke_alku = WORDSIZE;
    

    taulusta_tauluun(taulusta, nom_, nom_jatke_alku, nom_loppu);
    taulusta_tauluun(taulusta, gen_, nom_loppu, gen_loppu);
    taulusta_tauluun(taulusta, par_, gen_loppu, pituus+WORDSIZE);

    ! print ">>>"; print_arr(temp_match_arr); print "*";
    
];


! 
[ taulusta_tauluun taulusta tauluun alku loppu at merkki;
    
     
    @output_stream 3 tauluun;
    
    print_arr(temp_match_arr);
    
    for (at = alku : at < loppu : at++)
	
	!merkki = taulusta->at;
    	
	if (taulusta->at ~= '|' or '/')
	    print(char)taulusta->at;
    
    @output_stream -3;
    
    
];

!
! jotenkin näin 
! nimen_osat() kutsuu about näin [paitsi tässä "tulostus" on "temp"]: 
!   pilko_nomgenpar_temp(osa_temp_arr, nom_temp_arr, gen_temp_arr,
!                       par_temp_arr, jatke_temp_arr)
! languagerefers() näin: 
!   pilko_nomgenpar(nomgenpar, nom_arr, gen_arr, par_arr, jatke_arr);
!
! ao. tarkoitus korvata pilko_nomgenpar_tulostus() ja ..._parsi()
! ne ei eroa toisistaan mitenkään mielekkäästi !
!*** ept LanguageRefers()
! [ pilko_nomgenpar_temp taulusta nom_ gen_ par_ at pituus n gen_at par_at alku temp;

    
!     if (dp) print "# pilko_nomgenpar_temp: pituus ", taulusta-->(0), " ";!pituus
    
!     pituus = taulusta-->(0);
    
    
!     alku=WORDSIZE; ! alku jos ei jatketta '|'
    
!     for (at=WORDSIZE:at<pituus:at++)
!     { 
!     	if (taulusta->(at)=='|') alku = at;	
	
! 	! temp esim. muusimuusi: 'muusi' "muusi|/n/a"
! 	! jotta jatke-tauluun ei tulisi "muusi|" vaan "muusi"
!         if (taulusta->(at)=='|' && taulusta->(at+1)=='/')
! 	    !! tämä... niin "tarot|/in/ia" toimii
! 	    !{at++; alku = alku+at+1; temp=1;}
! 	    !! tämä... niin "älli|/n/ä" toimii
! 	    !{at++; alku = at; temp=1;}
! 	    !! entä tämä...
! 	    {at++; alku = at+1; temp=1;}
	
! 	! jos nomgenpar merkkijonossa ei ole nom
! 	! esim 'risti' "/n/ä"
    	
!     	if (alku == gen_at) at++; 
	
! 	if (taulusta->(at)=='/' && gen_at == 0) 
!     	    gen_at = at;
	
! 	else
!     	    if (taulusta->(at)=='/' && gen_at >0 && par_at == 0)
!     		par_at = at;
!     }
    
!     if (dp) print_arr(taulusta);    
!     if (dp) print " ", alku, "/", gen_at, "/", par_at, " >>";
    
!     ! jatke_ (ja muut) pitää tyhjentää kun ne on käytetty
!     ! muuten ne jää kummittelemaan
    
!     if (alku >= WORDSIZE) 
!     {
!     	@output_stream 3 nom_;
! 	print_arr(temp_match_arr); !!!!!	
!     	for (n=alku+1:n<gen_at:n++)
!     	    print(char)taulusta->n;
!     	@output_stream -3;
!     }
    
!     ! if (alku == WORDSIZE) 
!     ! {
!     ! 	@output_stream 3 nom_;
!     ! 	print_arr(temp_match_arr); !!!!!
!     ! 	for (n=alku:n<gen_at:n++)
!     ! 	    print(char)taulusta->n;
!     ! 	@output_stream -3;
!     ! }
    
!     if (gen_at) 
!     {
!     	@output_stream 3 gen_;
! 	print_arr(temp_match_arr); !!!!!	
!     	for (n=gen_at+1:n<par_at:n++)
!     	    print(char)taulusta->n;
!     	@output_stream -3;
!     }
    
!     if (par_at) 
!     {
! 	@output_stream 3 par_;
! 	print_arr(temp_match_arr); !!!!!	
!     	for (n=par_at+1:n<=pituus+1:n++)
!     	    print (char)taulusta->n;
!     	@output_stream -3;
!     }   
    
!     ! if (DP) 
!     ! {

!     ! 		print "^** taulut temp    :";
       	
    	
!     ! 	for(n=WORDSIZE:n<WORDSIZE+nom_-->0:n++)
!     !    	    print(char)nom_->n;
    	
!     ! 	print " ";
    	
!     ! 	for(n=WORDSIZE:n<WORDSIZE+gen_-->0:n++)
!     ! 	    print (char)gen_->(n);
!     ! 	print " ";
    	
!     ! 	for(n=WORDSIZE:n<WORDSIZE+par_-->0:n++)
!     ! 	    !print ".";
!     ! 	    print (char)par_->(n);
!     ! 	print " == ";
	
!     ! 	print_arr(gen_); print " "; print_arr(par_);
!     ! 	print " (temp_match_arr: ", print_arr(temp_match_arr);
!     ! 	print ") (osa_temp_arr:"; print_arr(osa_temp_arr);
!     ! 	    print ")^";
	
!     ! }    
    
    
! ];



!* 005
! hae_vart_x
! ----------
! tulostaa / parsii
! - languagerefers() sanoo:
!     suffiksi = hae_vart_x(adr, len, end);
! - nimen_osat() sanoo: 
!     hae_vart_x(osa_temp_arr, osa_temp_arr-->0, 0, print_sija);

[ hae_vart_x adr len end print_sija char_at ttkoodi;
    
    if (DP>1) 
    {	
	print "^^[hae_vart_x: "; 

	if (print_sija)
	{	    
	    if (print_sija == 99) print "tulostetaan vart kuin sn";
	    else print "tulostetaan";
	print " (adr ", adr, " len ", len, " end ", end, ")]^";
	}
	else print "parsitaan";
	
    }

    

    ! ** esiparsi (ttkoodi ei ole taulussa)
    ! huom.: esiparsi() antaa ttyyppi.char_at_temp
    ! kun parsitaan/tulostetaan esiparsimalla suoraan,
    ! voidaan käyttää sitä...
    ! ..jos parsitaan/tulostetaan hakemalla ttkoodi taulusta
    ! (ei esiparsita) char_at tai ttyyppi.char_at_temp
    ! pitää hakea toisin...

    ! esim. jos (ttkoodi == 0) ttkoodi:tä ei haettu taulusta
    ! tai taulua ei ole, esiparsitaan...
    	ttkoodi = erittele(adr);

    ! ...jos ttkoodi löytyy, ei esiparsita...

    !! ...tarkoittaa myös että char_at pitää saada jostain
    !! muualta kuin esiparsista! hae_s1_s2() liikuttelee sitä
    !char_at = ttyyppi.char_at_temp;

    ! char_at tiedetään vasta kun ttkoodi?
    
    if (dp) print " [", ttkoodi, "] "; 
	
    ! parsitaan (suoraan)
    if (print_sija == false) 
    {
	! jos ei tätä, voi tulla ikuinen silmukka
	if (ttyyppi.s1 || ttyyppi.s2)
	{
	if(dp) print "^** ai jaha! **^";    
	    rfalse;
	} 
	else
	hae_s1_s2(adr, len, ttkoodi, char_at);

    	return ttyyppi.parsi(ttkoodi);
    }
    ! jos 99, palauta ttkoodi. ks tulosta_vart_osat_kuin_sn()
    if (print_sija == 99) return ttkoodi;
    
    ! tulostetaan (suoraan)
    ttyyppi.tulosta(ttkoodi, print_sija);

    
    
];

!* 006
!** p
[ LanguageRefers obj wnum adr len end w str suffiksi j_pit
    str_at_prop_num ttkoodi obj_paikka ttkoodin_paikka; 
    
    adr = WordAddress(wnum); len = WordLength(wnum);

    ! nollataan
    !ttyyppi.char_at_temp = 0;
    ttyyppi.s1 = 0;
    ttyyppi.s2 = 0;
    

    
    for (end = len: end ~= 0 : --end) 
    {
	w = DL (adr, end);
	

	if (w ~= 0 && WordInProperty(w, obj, vart))
	{
            if (dp>1) print "# _LanguageRefers_ (vart) ";	


	    ! ao. antaa ttkoodin järjestysluvun
	    ! laskee kaikki merkkijonot vart-taulusta ennen paikkaa
	    ! ensimmäinen on 1
 	    ttkoodin_paikka = anna_ttkoodin_jarjestysluku(w, obj, vart);
	    
	    str_at_prop_num = vart_str_at_prop_num(w, obj, vart);	    
	    str = vart_hae_str(str_at_prop_num, obj);

	    
	    
            
            if (str)
            {
                if (DP>1) print "# _LR_ end ", end, " len ", len, "^";
                ! mikä pituus? voi olla pitkä!
		! näppärämpi?
		PrintToBuffer(NomGenPar_temp, 120, str);
		
	       	j_pit = jatke_pituus();	
		
  		! jatke annettu, jatke ja syöte -- erilaiset?
               	if (j_pit && jatke_match(wnum, end, j_pit) == false) rfalse; 

				
		!! mitä tapahtui? eikö tätä tarvita?
		!vart_jatke_match(end, adr, len);
		
		
                !if (DP>1) print "LR match_len ", match_len, "^";
                !if (match_len == 0) rfalse;
		
                ! nyt erittele_yks purkaa, sen voisi tehdä pura_nomgenpar tms tässä
                ! *huom! onko tarkastettu onko nomgenpar string ylipäänsä annettu?*
                ! -- tyhjenna_taulut_temp(); -- ei tyhjennetä täällä!
		! tyhjenna_taulut_temp(); ! näppärämpi? (tässä parsa)
		! onko? ...jos temp tekisi parsan ja tulostuksen?
                ! milloin tyhjennetään?
		
		! jos jatke ok, end on end plus jatkeen pituus -1
		if (j_pit) end = end+j_pit-1; 
		
        !syötetty sana kokonaan tauluun
	        input_tauluun(wnum);

		input_match_tauluun(wnum, end);		
 
		! pärämpi?
		pilko_ngp_versio(nomgenpar_temp, nom_temp_arr, gen_temp_arr, par_temp_arr);

    		! onko_obj_taulussa(obj, vart_taulu, vart_taulu_len);
		! ...ja mitä sitten?

		!print_ret "^j_pit", j_pit;
		!if (j_pit)
		!    suffiksi = onko_suffiksi_nomgenpar(end, wnum);
		!else
		!("").print_to_array(jatke_temp_arr);

		
 		! suffiksi = hae_vart_x(adr, len, end);
		!
		! ** esiparsi (ttkoodi ei ole taulussa)
    		! huom.: esiparsi() antaa ttyyppi.char_at_temp
    		! kun parsitaan/tulostetaan esiparsimalla suoraan,
    		! voidaan käyttää sitä...
    		! ..jos parsitaan/tulostetaan hakemalla ttkoodi taulusta
    		! (ei esiparsita) char_at tai ttyyppi.char_at_temp
    		! pitää hakea toisin...

		obj_paikka = onko_obj_taulussa(obj, vart_taulu,
					       vart_taulu_len);
		if (obj_paikka)
		{
		    ttkoodi = vart_taulu-->(obj_paikka+ttkoodin_paikka);
		    if (dp) print "^** PARSI ttkoodi ", ttkoodi, " haettu taulusta-->",
			obj_paikka+ttkoodin_paikka, " **^"; 
		}
		else
    		! esim. jos (ttkoodi == 0) ttkoodia ei haettu taulusta
    		    ! tai taulua ei ole, esiparsitaan...
    		ttkoodi = erittele(adr);
		
    		! ...jos ttkoodi löytyy, ei esiparsita...
		
    		!! ...tarkoittaa myös että char_at pitää saada jostain
    		!! muualta kuin esiparsista! hae_s1_s2() liikuttelee sitä
    		!char_at = ttyyppi.char_at_temp;
		
    		! char_at tiedetään vasta kun ttkoodi?
    		
    		if (dp) print " [", ttkoodi, "] "; 
		

		    ! jos ei tätä, voi tulla ikuinen silmukka
		    if (ttyyppi.s1 || ttyyppi.s2)
		    {
			if(dp) print "^** ai jaha! **^";    
	    		rfalse;
		    } 
		    else
			hae_s1_s2(adr, len, ttkoodi);
		    
    		    return ttyyppi.parsi(ttkoodi);

		

                if (DP>1) 
                {    
                    debugsijat(adr, wnum, len, end, w, csLR);
                    print "^* adr: ", print_merkkij_taulu(adr), " *^";
                  
                    if (suffiksi == csLR) {print "^# _LR_ suffiksi ", suffiksi, " kelpaa^";}
                    !print "# suffiksi ", suffiksi, " ", csLR
                }
                !! ESIM jos nom gen tai par ks suoraan
                
                if (suffiksi == csLR) rtrue; !nom, gen tai par
                !if (suffiksi > 0 && suffiksi ~= csLR) muu_sija = true; !paitsi että vertaa alla
                else
                    !suffiksi = LR_ks_taivutus(obj, adr, len, end); ! TEMP
                    if (suffiksi == 0) rfalse; ! TEMP
     		
                !! jos joku muu, eritellään
		
             	!if (obj hasnt gen)                
		!return erittele_yks_vart(adr, len, end);
		!else
		!return erittele_mon_vart(adr, len, end);
            }
    	    else rfalse;
	    
	    
    	}   
	else	
	    
    	    !! Mihin & miten: ilmansuunnat, ylös, alas, sisään jne
	    if (parent (obj) == Compass)
	    { ! väliaik.!: (end == len)
	     	if (end == len && w ~= 0 && WordInProperty (w, obj, name)) rtrue;
	 	!	&&
	 	!	hae_suffiksi(adr, len, end, obj)) rtrue;
  	    	! ao. hyväksyy vain partitiivin ">t ptä" ">mene pohjoista"
	    	! muuten esim. ">lu" (luode) vastaa: "Länsi vai luode?"
	    	if (csLR ~= 3) rfalse; 
	    }	
	
	!! taipumaton
	!! esimerkiksi genetiiviattribuutti "pöydän" -> "pöydän antimet"	   
    	if ( end == len && w ~= 0 && WordInProperty (w, obj, taipumaton)) rtrue;
	
	
    }
    
    rfalse; 
];

!* 007
! DM4 §2.4
!*** p LanguageRefers()
[ print_merkkij_taulu the_array i;
    for (i=1: i<=the_array->0: i++) print (char) the_array->i;
];


!* 008
!*** p LanguageRefers()
[ debugsijat adr wnum len end w;
    print
	"^** debugsijat: etype == ", etype, " wnum: ", wnum, " / len-end (pääte): ", (len-end)," ",
	"adr: ", adr,
	" end: ", end,
	" len: ", len,
	" adr w: ", (address) w, ", ", (the)w, " csLR:";
    switch (csLR) {
     0: "0";
     1: "1 Nominatiivi";
     2: "2 Genetiivi";
     3: "3 Partitiivi";
     4: "4 Inessiivi";
     5: "5 Elatiivi";
     6: "6 Illatiivi";
     7: "7 Adessiivi";
     8: "8 Ablatiivi";
     9: "9 Allatiivi";
     10: "10 Essiivi";
     11: "11 Translatiivi";
	!default: "0";
    };  print "^";
];
!* 009
!**** p LanguageRefers() ... ks_tati_vrt_nakki() ...
[ hae_v_char pp char_at_input arr len char_at_vart v_vart v_input;
    
    ! nyt antaa vain nom / gen arr pituudet
    ! (hmm? molemmat arr-->0 ja arr->1 tuntuu antavan oikean
    ! pituuden... onko näin?)
   
   if (luku_(pp) == 2)
       arr = nom_temp_arr;	
   else
       arr = gen_temp_arr;
    
    len = arr-->0;

    !!!!!!!!!!!!!!!!!!!!!!!
    char_at_vart = len;
    char_at_input = char_at_input; !!! ks. täti vrt. nakki
    !!!!!!!!!!!!!!!!!!!!!!!
    ! älliä  (syöte)
    !    ^
    ! ällin (taulu)
    !    ^

        !!! ks. täti vrt. nakki
    v_vart = arr->char_at_vart;   
    v_input = inp_temp_arr->char_at_input;

    v_vart = LowerCase(v_vart);
    v_input = LowerCase(v_input);

    if (dp>3)
    print "^*** hae v char^ char_at_vart ", char_at_vart, " ", (char) v_vart,
	" char_at_input ", char_at_input, " ", (char) v_input,
	" inp_temp_arr_len ", inp_temp_arr-->0, " ** ** ^";


    
    if (v_vart == v_input)
    	return v_vart;
       else
    	return 0;

    !!!! ks. täti vrt. nakki
     ! if (v_vart == v_input)
     ! {
     ! 	! *molemmat* (s1 ja s2) nollataan!?
     ! 	if (char_at_input == char_at_vart)
     ! 	{ 
     ! 	    ttyyppi.s1 = 0;	    	
     ! 	    ttyyppi.s2 = 0;
     ! 	}
     ! 	return v_vart;
     ! }
    


    
  	    
];


!*** p LanguageRefers()
[ hae_s1_s2 adr len ttkoodi char_at av av1 av2 av1_pit av2_pit av1_input
    av2_input s1_alku s2_alku s1_pit s2_pit;
    
    ttyyppi.s1 = 0;
    ttyyppi.s2 = 0;
    
    av = av_(ttkoodi);
    
    char_at = temp_match_arr-->0;
    
    if (dp>2) print "^** hae_s1_s2 ^";
    
    !print "=== av: ", av ," === ";
    
    if (dp>3) print "   alkutila: char_at ", char_at, ", av ", av, "^";!!!temp
    
    if (av)
    {
	! av * 4 koska tauluista haetaan...
	av = av*4;
	
    	av1 = avt-->(av+1);
    	av2 = avt-->(av+2);
    	
	!av1_pit = anna_av_pit(av1, adr+char_at);
    	!av2_pit = anna_av_pit(av2, adr+char_at);
	
	av1_pit = avt-->(av+3);
	av2_pit = avt-->(av+4);

	! ...kun on haettu tauluista, av:n arvon voisi palauttaa
	! jos haluaa -- se ei tee enää mitään mutta syy ehkä... debug (alla)?
	av = av/4;
    	!print "av ", av;
	

    }
    
    ! kvantitatiivinen? -- kk k, k kk jne...?
    ! ** ensimmäinen toteuttaa myös käänteisen?
    ! 
    ! (vain) toinen 2 merkkiä pitkä?
    if (av1_pit == 2 || av2_pit == 2 && av1_pit ~= av2_pit) 
    {
	
	char_at = char_at;
	
	if (dp>2)
	{	    
	print " kvantitatiivinen?";
	if (av2_pit == 2) print " (käänteinen?)";
       	
	print " len: ", len, " char_at: ", char_at, " ";!!!temp
	print " av1_pit ", av1_pit, ", av2_pit ", av2_pit, "^"; !!!temp
	}
	
	!  char_at ":" laatik:k siirretään laati:kk? -- vai miten?
	
	av1_input = DL(adr+char_at-1, av1_pit); ! huom. char_at-1
	s1_alku = adr+char_at+av1_pit;
	s1_pit = len-(char_at+av1_pit);
	
	av2_input = DL(adr+char_at-1, av2_pit); ! huom. char_at-1
	s2_alku = adr+char_at+av2_pit;
	s2_pit = len-(char_at+av2_pit);
	
	
	
	
	ttyyppi.v_char1 = hae_v_char(ttkoodi, char_at+av1_pit+1);
	ttyyppi.v_char2 = hae_v_char(ttkoodi, char_at+av2_pit+1);
	
	!print "^!", (char) ttyyppi.v_char1, "/", (char)
	! ttyyppi.v_char2, "!^";
	
	if (ttyyppi.v_char1) ! nakk-I-a
	    ttyyppi.s1 = DL(s1_alku, s1_pit+1); ! nakki-A
	else
	    ttyyppi.s1 = DL(s1_alku, s1_pit); ! (nakk-IA)? 
	
	
	if (ttyyppi.v_char2)
	    ttyyppi.s2 = DL(s2_alku, s2_pit+1);
	else
	    ttyyppi.s2 = DL(s2_alku, s2_pit);
	
	!print (address) ttyyppi.s1;
	
	if (av1 && av1_input ~= av1) ttyyppi.s1 = './/';
	if (av2 && av2_input ~= av2) ttyyppi.s2 = './/';
	
	
	! char at on lopussa? 
	if (char_at+av1_pit == inp_temp_arr-->0 && ttyyppi.s1 ~= './/')
	    ttyyppi.s1 = 0;
	
	if (char_at+av2_pit == inp_temp_arr-->0 && ttyyppi.s2 ~= './/')
	    ttyyppi.s2 = 0;
	
	
    } ! kvantitatiivinen END
    
    ! kvalitatiivinen? -- t d, d t jne...?
    ! entä nk ng, ng nk... ?
    else if (av1_pit == 1 && av2_pit == 1)
    {
	
	char_at = char_at;

	if (dp>2)
	{
	print " kvalitatiivinen? ** len: ", len, " char_at: ", char_at, " ";
	print " av1_pit ", av1_pit, ", av2_pit ", av2_pit, "^"; 
	}
	 
	
    	av1_input = DL(adr+char_at, av1_pit);
	s1_alku = adr+char_at+av1_pit;
	s1_pit = len-(char_at+av1_pit);
	
    	av2_input = DL(adr+char_at, av2_pit);
	s2_alku = adr+char_at+av2_pit;
	s2_pit = len-(char_at+av2_pit);
	
	!ttyyppi.s1 = DL(s1_alku+1, s1_pit);
    	!ttyyppi.s2 = DL(s2_alku+1, s2_pit);

	!!! ks. täti vrt. nakki
	! 0 jos ei kelpaa astevaihtelulle tjsp.
	!if (av1 && av1_input ~= av1) ttyyppi.s1 = './/';
    	!if (av2 && av2_input ~= av2) ttyyppi.s2 = './/';
	
	!!!***********************
	
	ttyyppi.v_char1 = hae_v_char(ttkoodi, char_at+av1_pit+2);
	ttyyppi.v_char2 = hae_v_char(ttkoodi, char_at+av2_pit+2);

	if (dp>2)
	print "^!", (char) ttyyppi.v_char1, "/", (char)
	 ttyyppi.v_char2, "!^";
	
	if (ttyyppi.v_char1) ! tät-I-ä
	    ttyyppi.s1 = DL(s1_alku, s1_pit+1); ! täti-Ä
	else
	    ttyyppi.s1 = DL(s1_alku, s1_pit); ! (tät-IÄ)? 
	
	
	if (ttyyppi.v_char2)
	    ttyyppi.s2 = DL(s2_alku, s2_pit+1);
	else
	    ttyyppi.s2 = DL(s2_alku, s2_pit);
	
	!print (address) ttyyppi.s1;
	
	if (av1 && av1_input ~= av1) ttyyppi.s1 = './/';
	if (av2 && av2_input ~= av2) ttyyppi.s2 = './/';
	
	
	! char at on lopussa? 
	if (char_at+av1_pit+1 == inp_temp_arr-->0 && ttyyppi.s1 ~= './/')
	    ttyyppi.s1 = 0;
	if (char_at+av2_pit+1 == inp_temp_arr-->0 && ttyyppi.s2 ~= './/')
	    ttyyppi.s2 = 0;

	
	
    }
    ! oli tämä sitten mikä tahansa tai ei ole...
    ! ei astevaihtelua? mutta...
    ! ....mielivaltaa?
    ! nainen naisen naista
    ! naiset naisten naisia 38 13800
    ! mekot    
    ! mekon 1 A 10101 s0 = 'o'
    ! ällin 1 10100 s0 = 'i'
    
    else if (av == false)
    {
	
	if (dp>2) print "** ei av ** len: ", len, " char_at: ", char_at, "^";
	
	
	s1_alku = adr+char_at;
	s1_pit = len-char_at;
	!s1_pit = s1_pit+1;
	
	s2_alku = adr+char_at;
	s2_pit = len-char_at;
	!s2_pit = s2_pit+1;
	
	ttyyppi.s1 = DL(s1_alku, s1_pit);
    	ttyyppi.s2 = DL(s2_alku, s2_pit); 

	! merkitään tämä samalla tavalla koska ks. täti vrt. nakki
	! en nyt muista miksi +1
	char_at = char_at+1;
	
    	! ttkoodista katsotaan vain luku
	ttyyppi.v_char1 = hae_v_char(ttkoodi, char_at);
	ttyyppi.v_char2 = hae_v_char(ttkoodi, char_at);
      	! !!!!


    }


    !!! ks. täti vrt. nakki
    ! jos char_at on yhtä pitkä kuin input_temp_arr...
    !if (inp_temp_arr-->0 == char_at)
    !{
	
	!ttyyppi.s1 = 0;
	!ttyyppi.s2 = 0;
    !}
    
    

    !!! DP alku
    if (dp>2)
    {	
    !print "^!!! char_at ", char_at, "^!!! inp len ", inp_temp_arr-->0, "^";
   
     
    if (av)
    {
    	print "^** av: ", av, " ";
     	print "^** av1_input: ";   
    if (av1_input) print (address) av1_input; 
    else
	print "-ei ole-";
    print " **^";
    
    print "** av2_input: ";   
    if (av2_input) print (address) av2_input; 
    else
	print "-ei ole-";
    print " ** ";
    }
    
    if (av1 && av1_input == av1) print "^av1: ", (address) av1_input;
    else print "^av1: -";    
    
    print " s1: "; if (ttyyppi.s1) print (address) ttyyppi.s1;
    else print "- "; 
    print " (alku ", s1_alku," pit ", s1_pit, ")^";
    
    if (av2 && av2_input == av2) print "av2: ", (address) av2_input;	
    else print "av2: -";
    
    print " s2: "; if (ttyyppi.s2) print (address) ttyyppi.s2;
    else print "- ";    
    print " (alku ", s2_alku," pit ", s2_pit, ")^";
     
    print "---^len: ", len, " char_at: ", char_at, " av1_pit: ", av1_pit,
	" av2_pit: ", av2_pit, "^";
    
    print "** ttyyppi.v_char1: ";
    if (ttyyppi.v_char1) print (char) ttyyppi.v_char1, " ^";
        print "** ttyyppi.v_char2: ";
    if (ttyyppi.v_char2) print (char) ttyyppi.v_char2, " ^";

 else print 0, "^";

    } !!!!!! DP loppu
    
    
];



!* 010
!**** p LanguageRefers()
[ WordInPropNum wd obj prop k l m;
    k = obj.&prop; l = (obj.#prop)/WORDSIZE-1;
    for (m=0 : m<=l : m++)
        if (wd == k-->m) return m;
    rfalse;
];


!* 011
!*** p LanguageRefers()
[ jatke_pituus at arr_len; 
    
    arr_len = NomGenPar_temp-->0;
    
    for (at=1:at<arr_len:at++)
    {
        if (NomGenPar_temp->(at)=='|') return at-1;
        else if (NomGenPar_temp->(at)=='/') rfalse;
    }
    rfalse;
    
];

! ks. av_match arr at adr i v_pit;

!*** p LanguageRefers()
[ jatke_match wnum end jatke_pit adr len at;
    adr = WordAddress(wnum); len = WordLength(wnum);
    print "^* jatke match (at ";
    for (at=WORDSIZE:at<len:at++)
    {
     print at, " ";
    	
    	if (NomGenPar_temp->(at) ~= adr->(end+at-WORDSIZE))
	{
    	    print "!) ei täsmää * ^";
	    rfalse;
	}
	
	! pituus (at) tiedetään jo koska jatke_pituus()
	! palauttaa sen, tää vois palata true/false
	! ja ynnätään lopuksi match_len ja end tjsp?
    	if (NomGenPar_temp->(at) == adr->(end+at-WORDSIZE) &&
	    (at==jatke_pit))
	{
	    print ") täsmää * ^";
	    return true;
	    
	}
	
    }
    rfalse;     
];

!* 012
! täällä esim 0+1 hämää (ks. tyhjenna_taulut)
![ tyhjenna_inp_end_arr_taulu i;
!    for (i=WORDSIZE:i<=inp_end_arr-->0+1:i++) 
!    inp_end_arr-->i = 0;    
!    inp_end_arr-->0 = 0;
!];

! koko sana
!*** p LanguageRefers()
[ input_tauluun wnum adr len i x;    
    adr = WordAddress(wnum); len = WordLength(wnum);

    x = WORDSIZE;
    
    for (:i<=len:i++, x++)
    {     
        ! huolettaa tämä. laitetaanko syötteen loppu taulukkoon
        ! vain jos EI nom gen par
        ! inp_end_arr ei ole tarpeen jos == nom gen par?   
      	
        inp_temp_arr->x = adr->i;
        inp_temp_arr-->0 = len;
    }
    
];
!*** p LanguageRefers()
[ input_match_tauluun wnum end adr len i x;    
    adr = WordAddress(wnum); len = WordLength(wnum);
    
    x = WORDSIZE;
    
    for (:i<=end:i++, x++)
    {     
        ! huolettaa tämä. laitetaanko syötteen loppu taulukkoon
        ! vain jos EI nom gen par
        ! inp_end_arr ei ole tarpeen jos == nom gen par?   
      	
	temp_match_arr->x = adr->i; !näppärämpi?
        temp_match_arr-->0 = end; !näppärämpi?

    }
        
 
];


!* 013
! vart_hae_str
! ------------
! LanguageRefers ks onko WordInProperty vart
! > vart_hae_str
!   > WordInPropNum ks missä kohtaa prop on (at_prop)
!   > check_vart hakee stringin str 
!   > check_string_prop hakee kaikenlaista stringistä str
!   > erittele_vart jäsentelee
!*** p LanguageRefers()
[ vart_hae_str at_prop obj str; 
    
    str = obj.&vart-->(at_prop);
    if (dp>3) print " >> vart_hae_str: ~", str, "~^";
    if (str ofclass string)
	return str;
    
];

! laskee kaikki merkkijonot ennen at_prop (vart propertyn)
! ensimmäinen järjestysluku on 1
!*** p LanguageRefers()
[ anna_ttkoodin_jarjestysluku w obj vart at_prop i jarjestysluku;
    
    
    at_prop = WordInPropNum(w, obj, vart);

    jarjestysluku = 1;
    
    for (i=1:i<at_prop:i++)
    {
	! lasketaan kaikki merkkijonot!
     	if (obj.&vart-->i ofclass string)
     	    jarjestysluku++;
	
    }
    return jarjestysluku;
    
    
];


!*** p LanguageRefers()
[ vart_str_at_prop_num w obj vart at_prop; 

    at_prop = WordInPropNum(w, obj, vart);
     	
    !if (dp) print "^# vart_str_at_prop_num() hakusanoja: ", n_of, " ";
	
     ! oliko tässä turha for?
	if (obj.&vart-->(at_prop+1) ofclass string)
        {
	    
            if (dp>3) print " >> vart_str_at_prop_num() ret: ", (at_prop+1), "^";
            return (at_prop+1);
        }
    !! poistettu rutiinit ja kutsut: check_endpoint() ja check_vart() tästä
    !! koska sanakirjasanojen lukeminen yhdyssanoina ei onnistunut
    if (dp>3) print " >> vart_str_at_prop_num: ei string, rfalse^";
    rfalse;    
    
];


!* 014
[ WordInPropNumVart wd obj prop tark k l m;
    
    
    k = obj.&prop; l = (obj.#prop)/WORDSIZE-1;
    for (m=0 : m+2<=l : m++, m=m+2)
        if (m+2 <= l && wd == k-->m)
	    return obj.&prop-->(m+tark);
    rfalse;
];


!* 015
[ onko_taulussa alkio taulu n len;
    
    ! print taulu-->0;
    
    len = taulu-->0;
    
    for(n = 1 : n <= len : n++)
      	if (alkio == taulu-->n)
	    rtrue;
    rfalse;
];

!* 016
! debug ! tark. WORDSIZE & arr-->0+1 (???) 
[ print_arr arr i; 
    for(i=WORDSIZE:i<=arr-->0+1:i++)
	print(char)arr->i; !? mielummin: -->
];

!* 017
! ks myös suttux osa_temp_arr näppärämpi (muka!)

! varoitus! "temp" on sekakäyttäjä
[ tulosta_sn obj print_sija temp;
 
    if (obj provides gen) ! gen ja/tai par ess ill ine?
	CCase(obj, print_sija, temp); ! "legacy" tulostus
    else    
	if (obj provides lname) ! adhoc lname ks. alla
	{	    

	    nimen_osat(obj, print_sija, temp);
	    
	}
    
    !else
	!if (obj provides short_name)
	else
	print (object)obj;
    ];

! oli temp testi2.h: palat_n() tulosta_ngp()



! tulostettaessa (print sija > 0):
!         osa 0   osa arr pituus


! tätä vähän muokataan...
! voiko at_prop voi olla prop järjestysluku (vart ttkooditauluun tulostus)
! tai sitten... laskuri? täällä? (lname pp tauluun tulostus)
[ nimen_osat obj print_sija paikkamerkki at_prop lkm len at merkki at_osa
    alku loppu adhoc_match_len ttkoodi;

    !print "Syy: ", print_sija, " ";
    !tyhjenna_taulut_temp();

    !nollautuu kun tämä rutiini käydään kerran läpi
    !print ">>>"; print NomGenPar_temp-->0; print "<<<";
    
    ! nollataan
    !ttyyppi.char_at_temp = 0;
    ttyyppi.s1 = 0;
    ttyyppi.s2 = 0;

    ! todo: isolla alkukirjaimella?
    ! jos paikkamerkki on tosi, tulostetaan isolla... 
    ! 
    ! if (paikkamerkki) ...tulostetaan isolla...
    !
    ! huom! paikkamerkki kierrätetään (alla) kun
    ! haetaan lname-taulun oikea kohta...

    !print ">>>print sija ", print_sija, "*"; ! ts. SYY_

    
    alku=WORDSIZE;


    ! tee_lname_taulu()sta tulee lkm
    ! ks. myös peruna.inf! onko ao. rivi turha?
    ! tee lname 999 tarvii lkm?
    !if (lkm == 0) lkm = nimen_osat_lkm(); 


    ! mikä tätä käyttää jos käyttää? ei mikään.
    !if (print_sija == SYY_LKM) { print "^%%%%%^ LKM ^%%%%%^"; return lkm; 
    !}
    

   ! print "**> ", lkm, " <**";
 !print "[?! ", print_sija, " ", paikkamerkki, " ", at_prop, " ", lkm, " ", len, " ";   
 !print at, " ", k_at, " ", at_osa, " ", alku, " ", loppu, " ";   
 !print adhoc_match_len, " ", ttkoodi, " ?!]";
    
    

!    at_osa=0;
    

	
!   while(lkm > at_osa)
!   {
!       at_osa++;

       ! tehdään nomgenpar_temp-taulu
       nimen_osat_tee_nomgenpar(obj, print_sija, at_prop);
       !print ">>>"; print_arr(NomGenPar_temp); print "*";
       !print ">>> lkm: ", nimen_osat_lkm(), " at_osa ", at_osa, "<<<";

    lkm = nimen_osat_lkm();
    
       len = WORDSIZE+NomGenPar_temp-->0;
       !print ">>>", len, "*";
       
       !print ">>>", alku, "*";
       !print ">>>lkm ", lkm, " at_osa ", at_osa, "*";
       
       !print_arr(nomgenpar_temp);

       
    for (at=alku:at<=len:at++)
    {
	!if (alku == loppu) break; ! >>> poistuu 1. osan jälkeen
	!if (alku == adhoc_match_len) break; ! >>> ei tee mitään

	
	
    	if (NomGenPar_temp->(at) == '|' && (at<len))
	{	    
	    adhoc_match_len = at;
	    !>>>!print " *adhoc ",at, "* ";
	    
	}
	
	if (NomGenPar_temp->(at) == '/' or '|') merkki = true;

	if ((at == len) || (merkki && NomGenPar_temp->(at+1) == ' ' or
	','))
	{
	    !at_osa++;

	    
	    !if (DP) print "^at ", at, " len ", len, " ";

	    ! toistoa ja suttua mutta...
	    ! at+1, muuten ei kirjoitu oikein
	    if (merkki && NomGenPar_temp->(at+1) == ' ' or ',')
	    { loppu = at+1;
		!print ">>>LOPPU=AT+1*";
		
	    }
	    
	    ! at, muuten tulee ylimääräinen merkki loppuun
	    else
		if (at == len)
		{		    
		    loppu = at;
		    !print ">>>LOPPU=AT*";
		    
	    	}
	    
		
	    !if (DP) print "alku ", alku, " loppu ", loppu, " ";
	    
	    !at_osa++;
	    merkki = 0;	    
	    ! lkm++;


	    
	    !! lkm on osien määrä. paluuarvoa voi tarvita debug
	    !if (print_sija == SYY_LKM) return lkm;

	    	    
	    ! jos '|' adhoc
	    !print " * adhoc ", adhoc_match_len, " * ";
	    nimen_osat_adhoc_osa_arr(adhoc_match_len, alku, loppu);
 
	    
	    ! pärämpi?
	    
	    pilko_ngp_versio(osa_temp_arr, nom_temp_arr, gen_temp_arr, par_temp_arr);
	    !print ">>>"; print_arr(nom_temp_arr); print "*";
	    !! TEMP
	    !sija = csPar;
	    !if (sija == csPar) {
		!print "^##### ";	
		!print_arr(par_arr); 
	    !}
		
	    !! TEMP
		switch(print_sija)
		{
			csNom: print_arr(nom_temp_arr);
			csGen: print_arr(gen_temp_arr);
			csPar: print_arr(par_temp_arr);
		}

	    !! at_osa saadaan... tääältä?
	    at_osa++;


	    ! huom! paikkamerkkiä ja at osaa käyttää myös print_sija
	    ! 999 (ks. alla ja peruna.inf)
	    ! ------------------------------------------------------------------------
	    ! pitäisi kysyä ensin onko taulua ennenkuin haetaan
	    ! sieltä...
	    ! ...esim.: SYY_HAE_LN_TAULUSTA
	    if (print_sija < 100)
	    {		
	     paikkamerkki = onko_obj_taulussa(obj, lname_taulu, lname_taulu_len);

	     if (paikkamerkki)
	      {
	      	ttkoodi = lname_taulu-->(paikkamerkki+at_osa);
	      	if (dp) print "^** ttkoodi ", ttkoodi, " haettu taulusta-->", paikkamerkki+at_osa, " **^";
	      }
	    }
	    
	      else
	      ttkoodi = erittele();

	    !print ">>>", ttkoodi, "[ print sija: ", print_sija, "] ";
	    
	    ! esim. jos (ttkoodi == 0) ttkoodia ei haettu taulusta
    		! tai taulua ei ole, esiparsitaan...


	    !!! * muusit ja nakki *
	    !!! vart tuntuu toimivan, mutta lname tulee viallisena siten
	    !!! että toinen eriteltävä sana ei tule eritellyksi ollenkaan
	    !!! tai ainakaan oikein
	    !!! (jos on vain yksi sana, se tuntuu menevän oikein,
	    !!! mutta kun on "muusit ja nakki", niin "nakki" ei.)
	    

	    ! 999: tehdään lname-taulu
	    if (print_sija == 999)
	    {

						
		!paikkamerkki=paikkamerkki+at_osa;
		
		lname_taulu-->(paikkamerkki+at_osa)=ttkoodi;
    	    
	    if (dp) print "[", obj, ": paikka:", paikkamerkki, " lkm:",
	lkm, " at:", at_osa, "] ";

	    }
	    
	    

	    
	    !!! vart osia (muka) tulostettiin, jotta saadaan ttkoodi
	    !if (print_sija == SYY_VART || SYY_SN_TTKOODI)
	    if (print_sija == SYY_VART || print_sija ==
		SYY_SN_TTKOODI)
	    {

		!print "###   ", lkm, " ", ttkoodi, "   ###"; 
	    	return ttkoodi;
	    }
	    
	    

    	    if (print_sija < 100)
	    ttyyppi.tulosta(ttkoodi, print_sija);

	    !! tällä poistutaan silmukasta ilman turhia häntiä
	    !! ei riko mitään mutta ei myöskään ratkaise ongelmaa
	    !print ">>>[", at_osa+1, " ", lkm, "]*";
	    !if (at_osa+1==lkm) break;
	    

	    
 
	    !! ...tämäkään ei toimi (nysvää)
	    ! print "%%%%%%%%%%% ", nom_tulostus_arr-->0;
	    !	   	    
	    !! ei toimi...
	    ! hae_vart_tulostus(nom_tulostus_arr, nom_tulostus_arr-->0, tulostus_match_arr-->0, print_sija);

	    !if  (dp>4) debug_taulut_print(); !!!
	    
	    tyhjenna_taulut_temp(); !näppärämpi?

	    !! lkm on osien määrä. paluuarvoa tarvitaan (?)
	!if (print_sija == SYY_LKM) return lkm;
	    
	    alku=loppu;
	    
	} ! if
	!! lkm on osien määrä. paluuarvoa tarvitaan (?)
	!if (print_sija == SYY_LKM) return lkm;
	!! tähänkö tämä tulisi jos tulisi...   
       	!if (print_sija == 999) return at_osa; 
   
    } ! for
       !! ...vai tähän?
 if (print_sija == 999) return lkm; 
 !  }  !while
    
    
];


[ nimen_osat_adhoc_osa_arr adhoc_match_len alku loppu k_at; 
    
    	    if (adhoc_match_len)
	    {

		! näppärämpi?
		@output_stream 3 temp_match_arr;
		for (k_at=alku:k_at<adhoc_match_len:k_at++)
         	    print(char)NomGenPar_temp->k_at;
		@output_stream -3;

		! at on oikein
		!
		!print ">>>"; print_arr(temp_match_arr); print "*";
		!print ">>>adhoc ", adhoc_match_len, "*";

		!EI! if (loppu>adhoc_match_len) loppu = adhoc_match_len;

		!print ">>>A ", adhoc_match_len, " ", alku, " ", loppu, " ";
		!print_arr(temp_match_arr); print "*";
		
	    }

    !print ">>>adhoc ", adhoc_match_len;
    !print ", k_at ", k_at, ", alku ", alku, " loppu ", loppu, "*";

            
	    @output_stream 3 osa_temp_arr;
    	    for (k_at=alku:k_at<loppu:k_at++)
    	    	print(char)NomGenPar_temp->k_at;
    	    @output_stream -3;

    !print ">>>B ", loppu, " ", alku, " ", loppu, " ";
    !print_arr(osa_temp_arr); print "*";

	    
	    ! if (DP) print "^osa (", lkm, ") <", alku, " ~";
	    ! if (DP) print_arr(sn_osa_arr);
	    ! if (DP) print "~ ", loppu, ">";

];


! (obj, print_sija, arr, paikkamerkki, at_prop)
! print_sija on "syy"
[ nimen_osat_tee_nomgenpar obj print_sija at_prop;

    tyhjenna_taulut_temp();
    
    ! jos syy on vart tulostetaan vart osat kuin lname
    if (print_sija == SYY_VART)
    {
	
    @output_stream 3 NomGenPar_temp;
	
    print (address) obj.&vart-->(at_prop-1);
    print "|";
    print (string) obj.&vart-->at_prop;						    
    @output_stream -3;
    }
    ! tulostetaan lname (korvaa tässä "sn" eli "short name":n) 
    else
    PrintToBuffer(NomGenPar_temp, 120, obj.lname); ! adhoc lname

];


[ nimen_osat_lkm alku len at adhoc_match_len merkki loppu at_osa lkm;
   
    alku = WORDSIZE;
    len = WORDSIZE+NomGenPar_temp-->0;
    
    
    for (at=alku:at<=len:at++)
    {
    	if (NomGenPar_temp->(at) == '|') adhoc_match_len = at;
	
	if (NomGenPar_temp->(at) == '/' or '|') merkki = true;
	
	if ((at == len) || (merkki && NomGenPar_temp->(at+1) == ' '))
	{
	    
	    !if (DP) print "^at ", at, " len ", len, " ";
	    
	    ! toistoa ja suttua mutta...
	    ! at+1, muuten ei kirjoitu oikein
	    if (merkki && NomGenPar_temp->(at+1) == ' ') loppu = at+1;
	    ! at, muuten tulee ylimääräinen merkki loppuun
	    else if (at == len) loppu = at;
	    
	    
	    !if (DP) print "alku ", alku, " loppu ", loppu, " ";
	    
	    at_osa++;
	    merkki = 0;	    
	    lkm++;

   	    alku=loppu;
	    
	}
    }
    !print " ** lkm ", lkm, " ** ";
    return lkm;
    
];


!* 018
[ debug_taulut_print;

    
    ! ** temp ! pärämpi???      

    print "^** temp^";

    print "inp_temp_arr^----------------------> ";    
    print_arr(inp_temp_arr); print "^";
    print "temp_match_arr^----------------------> ";    
    print_arr(temp_match_arr); print "^";
    print "osa_temp_arr^----------------------> ";    
    print_arr(osa_temp_arr); print "^";    


    print "nom_temp_arr^----------------------> ";    
    print_arr(nom_temp_arr); print "^";
    print "gen_temp_arr^----------------------> ";    
    print_arr(gen_temp_arr); print "^";
    print "par_temp_arr^----------------------> ";    
    print_arr(par_temp_arr); print "^";
    print "nomgenpar_temp^----------------------> ";    
    print_arr(nomgenpar_temp); print "^";
    print "suffiksi_temp^----------------------> ";    
    print_arr(suffiksi_temp); print "^";


    
];

!* 019
! ** c_token ks. finng.h - etsii sijapäätteen
!??? CaseIs = komennon verbin tulostamiseen 
!??? multiflag jottei luule montaa asiaa haettavan
!??? nyt kys. onkin onko edes tämä "ei MULTI_" ehto paikallaan

[ c_token  idtok csID retval;
    
    
    csLR = csID;
    
    retval = ParseToken (ELEMENTARY_TT, idtok);
    
    ! mikä tämä on? reparse code
    if (retval == 10000) sija = 10000; else sija = 0; 
    
    CaseIs = csID;   
    
    ! multiflag jottei luule montaa asiaa haettavan      
    if (idtok ~= MULTI_TOKEN || MULTIHELD_TOKEN)  
  	multiflag = 1;
    
#Ifdef DEBUG;			     
    if (parser_trace >= 2)
    {
	
	print 	"^[! c_token! idtok (", idtok, "): ";  
    	switch (idtok) {
     	 NOUN_TOKEN: print "NOUN_TOKEN^";
     	 HELD_TOKEN: print "HELD_TOKEN^";
     	 CREATURE_TOKEN: print "CREATURE_TOKEN^";
     	 MULTI_TOKEN: print "MULTI_TOKEN^";
     	 MULTIHELD_TOKEN: print "MULTIHELD_TOKEN^";
	    
    	}
	if (idtok ~= MULTI_TOKEN || MULTIHELD_TOKEN)
    	    print "- Asetetaan *multiflag* koska muuten luulee moneksi -^",     
		" CaseIs: ", CaseIs,
		"^ csLR: ", csLR,
		"^ csID: ", csID,
		"^ sija: ", sija,
		"^ retval: ", retval, "]^";
    }
    
#Endif;	
    
    
    csLR = 0;
    
    return retval;
    
];

[ LanguagePrintShortName obj
    sn;
    
    sn = short_name;
    
    if (obj provides gen) ! "legacy"
    {	
    if (sija == 0 or 10000 && obj hasnt oletus_par) CCase (obj, csNom, false);	   
	if (sija == 0 or 10000 && obj has oletus_par) CCase (obj, csPar, false);
    if (sija ~= 0) rfalse;
    }
    else 
    
    {	
    if (sija == 0 or 10000 && obj hasnt oletus_par) tulosta_sn(obj, csNom, false);
	if (sija == 0 or 10000 && obj has oletus_par) tulosta_sn(obj, csPar, false);
    if (sija ~= 0) rfalse;
    }

    rtrue;
];


!* 020
! ** Tulosta verbi isolla alkukirjaimella

Constant verbi_pituus = 39;
Array verbi_array --> verbi_pituus;

#Ifdef TARGET_ZCODE;

! tämä eikö tämä toimi zcode?
! kaatuu: "more than 15 locals are not allowed"
![ VerbiKap;
!    print(Cap)verb_word;     
!];

[ VerbiKap i k iso;
    
    @output_stream 3 verbi_array;
    print (address) verb_word;
    @output_stream -3;
    
    k = verbi_array->2;
    
    ! mielummin PrintCapitalised tms. ???
    
    switch (k)
 { 155, 158: iso = 158; ! ä -> Ä
     156, 159: iso = 159; ! ö -> Ö
     201, 202: iso = 202; ! å -> Å
     default: iso = k-32;
    }
    
    print (char) iso;
    
    for (i=2:i<=verbi_array-->0:i++)
     	print (char) verbi_array->(i+1);
    
    
];

#Ifnot; ! TARGET_GLULX
[ VerbiKap;
    print(Cap)verb_word;
];
#Endif; ! TARGET_



! ** verbin loppuosan tulostus

[ VerbEnd obj csID;
    
    switch (csID) {
     vbInf: print (string) obj.inf_;	
     	! vbInd: print (string) obj.ind_y;
 	!     vbY2: print "t";
	!     vbY3: print (string) obj.ind_y;
	!     vbM3: print (string) obj.ind_m;
     default: print "^[ !verbin tulostusvirhe! ]^";
    }
];


!* 021
!==> hakkyra.h <==
!!! hakkyra.h !!!

! hakkyra ikääänk ttyypit v2

! ...jos parsitaan "suoraan" (?)
!   return ttyyppi.p(vk, tvtyyppi, mon);

! ...jos esim. halutaan purkaa ja kirjoittaa esim taulu
! ttyyppi.tauluun(vk,tvtyyppi);
! 	- objectloop kirjoittaisi kaikista joilla vart jonkinl taulun tn, av? 
! 	jos sitten halutaan lukea siitä taulusta, .parsi voisi ks. onko oliolla
! 	taulu, jos on, parsittaisiin siitä, muuten oletus .parsi tekee sen mitä tekee nyt
! ...jos tulostetaan, jonnekin tänne lähetetään tulostettava sija niin tiedetään ettei prs... silloin tarvitaan ehkä vk myös myöhemmin 

!Property av1;
!Property av2;
!Property char_at;
Property s1;
Property s2;
Property sijamuoto;

!Constant ei_av = 0; !
Constant kk_k = 1; ! 1x4
Constant k_kk = 2; ! 2x4
Constant pp_p = 3; !3x4
Constant p_pp = 4;
Constant tt_t = 5;
Constant t_tt = 6;
Constant k_ = 7;
Constant _k = 8;
Constant p_v = 9;
Constant v_p = 10;
Constant t_d = 11;
Constant d_t = 12;


Array avt table

! haetaan täältä 
! A: av 1 * 4 = 4 (suora av) nakki
!    av 2 * 4 = 8 (käänteinen av) kastike
! B: av 3 * 4 = 16 jne...
!   +1   +2    +3 +4
    0    0      0 0
    'kk' 'k//'  2 1
    'k//' 'kk'  1 2
    'pp' 'p//'  2 1  
    'p//' 'pp'  1 2 !      4
    'tt' 't//'  2 1 ! C    5
    't//' 'tt'  1 2 !      6
    'k//' 0     1 0 ! D    7 (reikä) rei+k+ä rei+än, vuo+k+a vuo+an
    0     'k//' 0 1 !      8 (aie) ra+e ra+k+een, pyyh+e pyyh+k+een
    'p//' 'v//' 1 1 ! E    9 (sopu)
    'v//' 'p//' 1 1 !      10 (taive)
    't//' 'd//' 1 1 ! F    11 (satu) pa+t+a pa+d+an
    'd//' 't//' 1 1;!      12 (keidas) voi+d+e voi+t+een


Array avt_tulostus table
    0 0
    'k' 0
    0 'k'
    'p' 0
    0 'p'
    't' 0
    'k' 0
    0 'k'
    'p' 'v'
    'v' 'p'
    't' 'd'
    'd' 't'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x'
    'x' 'x';


