--HG-- branch : dtrg-buildsystem rename : lang/basic/build.mk => lang/pc/build.mk rename : lang/cem/cemcom.ansi/build.mk => lang/pc/comp/build.mk rename : lang/basic/lib/build.mk => lang/pc/libpc/build.mk
		
			
				
	
	
		
			169 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*	L A B E L   H A N D L I N G	*/
 | |
| 
 | |
| #include	<alloc.h>
 | |
| #include	<em.h>
 | |
| 
 | |
| #include    "parameters.h"
 | |
| #include	"LLlex.h"
 | |
| #include	"def.h"
 | |
| #include	"idf.h"
 | |
| #include	"main.h"
 | |
| #include	"node.h"
 | |
| #include	"scope.h"
 | |
| #include	"type.h"
 | |
| 
 | |
| 
 | |
| DeclLabel(nd)
 | |
| 	struct node *nd;
 | |
| {
 | |
| 	struct def *df;
 | |
| 
 | |
| 	if( !(df = define(nd->nd_IDF, CurrentScope, D_LABEL)) ) {
 | |
| 		node_error(nd, "label %s redeclared", nd->nd_IDF->id_text);
 | |
| 	}
 | |
| 	else	{
 | |
| 		df->lab_no = ++text_label;
 | |
| 		nd->nd_def = df;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| chk_labels(Slevel)
 | |
| {
 | |
| 	register struct node *labnd = BlockScope->sc_lablist;
 | |
| 	register struct def *df;
 | |
| 
 | |
| 	while( labnd )	{
 | |
| 		df = labnd->nd_def;
 | |
| 		if( Slevel == 1 )	{
 | |
| 			if( !df->lab_level )
 | |
| 				if( df->lab_next )
 | |
| 				/* jump to undefined label */
 | |
| 					error("jump to undefined label %s",
 | |
| 							df->df_idf->id_text);
 | |
| 				else
 | |
| 					warning(
 | |
| 					  "label %s declared but never defined",
 | |
| 							df->df_idf->id_text);
 | |
| 		}
 | |
| 		else if( df->lab_level == Slevel )
 | |
| 			df->lab_level = -1;
 | |
| 		else if( !df->lab_level )	{
 | |
| 			struct lab *plab = df->lab_next;
 | |
| 
 | |
| 			while( plab )	{
 | |
| 				if( plab->lb_level == Slevel )
 | |
| 					plab->lb_level--;
 | |
| 				plab = plab->lb_next;
 | |
| 			}
 | |
| 		}
 | |
| 		labnd = labnd->nd_next;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| TstLabel(nd, Slevel)
 | |
| 	register struct node *nd;
 | |
| {
 | |
| 	register struct def *df;
 | |
| 
 | |
| 	df = lookfor(nd, CurrVis, 0);
 | |
| 	if( df->df_kind == D_ERROR )	{
 | |
| 		node_error(nd, "label %s not declared", df->df_idf->id_text);
 | |
| 		df->df_kind = D_LABEL;
 | |
| 		nd->nd_def = df;
 | |
| 		nd->nd_next = BlockScope->sc_lablist;
 | |
| 		BlockScope->sc_lablist = nd;
 | |
| 	}
 | |
| 	else
 | |
| 		FreeNode(nd);
 | |
| 
 | |
| 	df->df_flags = D_USED;
 | |
| 	if( !df->lab_level )	{
 | |
| 		/* forward jump */
 | |
| 		register struct lab *labelptr;
 | |
| 
 | |
| 		labelptr = new_lab();
 | |
| 		labelptr->lb_next = df->lab_next;
 | |
| 		df->lab_next = labelptr;
 | |
| 		if( df->df_scope == BlockScope )	{
 | |
| 			/* local jump */
 | |
| 			labelptr->lb_level = Slevel;
 | |
| 			CodeLabel(df, 1);
 | |
| 		}
 | |
| 		else	{
 | |
| 			/* non-local jump, only permitted to
 | |
| 			   outermost level (ISO 6.8.1 Note 2)
 | |
| 			*/
 | |
| 			labelptr->lb_level = 1;
 | |
| 			CodeLabel(df, 0);
 | |
| 		}
 | |
| 	}
 | |
| 	else if( df->lab_level == -1 || df->lab_level > Slevel )
 | |
| 		node_error(nd, "illegal jump to label %s", df->df_idf->id_text);
 | |
| 	else
 | |
| 		CodeLabel(df, 1);
 | |
| }
 | |
| 
 | |
| DefLabel(nd, Slevel)
 | |
| 	register struct node *nd;
 | |
| {
 | |
| 	register struct def *df;
 | |
| 
 | |
| 	if( !(df = lookup(nd->nd_IDF, BlockScope, D_INUSE)) )	{
 | |
| 		node_error(nd, "label %s must be declared in same block"
 | |
| 							, nd->nd_IDF->id_text);
 | |
| 		df = define(nd->nd_IDF, BlockScope, D_LABEL);
 | |
| 		nd->nd_def = df;
 | |
| 		df->lab_no = ++text_label;
 | |
| 		nd->nd_next = BlockScope->sc_lablist;
 | |
| 		BlockScope->sc_lablist = nd;
 | |
| 	}
 | |
| 	else FreeNode(nd);
 | |
| 
 | |
| 	df->df_flags |= D_SET;
 | |
| 	if( df->lab_level)
 | |
| 		node_error(nd, "label %s already defined", nd->nd_IDF->id_text);
 | |
| 	else	{
 | |
| 		register struct lab *labelptr;
 | |
| 
 | |
| 		df->lab_level = Slevel;
 | |
| 		labelptr = df->lab_next;
 | |
| 		while( labelptr )	{
 | |
| 			if( labelptr->lb_level < Slevel )	{
 | |
| 				node_error(nd, "illegal jump to label %s",
 | |
| 							nd->nd_IDF->id_text);
 | |
| 				return;
 | |
| 			}
 | |
| 			labelptr = labelptr->lb_next;
 | |
| 		}
 | |
| 		C_df_ilb(df->lab_no);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| CodeLabel(df, local)
 | |
| 	register struct def *df;
 | |
| {
 | |
| 	if( err_occurred ) return;
 | |
| 
 | |
| 	if( local )
 | |
| 		C_bra(df->lab_no);
 | |
| 	else	{
 | |
| 		/* non-local jump */
 | |
| 		int level = df->df_scope->sc_level;
 | |
| 
 | |
| 		if( !df->lab_descr )	{
 | |
| 			/* generate label for goto descriptor */
 | |
| 			df->lab_descr = ++data_label;
 | |
| 			C_ina_dlb(data_label);
 | |
| 		}
 | |
| 		/* perform the jump */
 | |
| 		C_lae_dlb(df->lab_descr, (arith) 0);
 | |
| 
 | |
| 		/* LB of target procedure */
 | |
| 		if( level > 0 )
 | |
| 			C_lxl((arith) proclevel - level);
 | |
| 		else
 | |
| 			C_zer(pointer_size);
 | |
| 		C_cal("_gto");
 | |
| 		C_asp( 2 * pointer_size);
 | |
| 	}
 | |
| }
 |