changeset 142:697bc543368c

Implement distinction between . and * for OS9 modules
author lost@l-w.ca
date Fri, 19 Aug 2011 23:55:40 -0600
parents 11ebce0183a5
children 42a7a16a058f
files lwasm/debug.c lwasm/instab.c lwasm/instab.h lwasm/list.c lwasm/lwasm.c lwasm/lwasm.h lwasm/os9.c lwasm/pass1.c lwasm/pass2.c lwasm/pass3.c lwasm/pass4.c lwasm/pass5.c lwasm/pseudo.c
diffstat 13 files changed, 210 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/debug.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/debug.c	Fri Aug 19 23:55:40 2011 -0600
@@ -44,8 +44,9 @@
 	
 	for (cl = as -> line_head; cl; cl = cl -> next)
 	{
-		debug_message(as, 100, "%p INSN %d (%s) LEN %d PRAGMA %x", cl, cl -> insn, (cl -> insn >= 0) ? instab[cl -> insn].opcode : "<none>", cl -> len, cl -> pragmas);
+		debug_message(as, 100, "%p INSN %d (%s) LEN %d DLEN %d PRAGMA %x", cl, cl -> insn, (cl -> insn >= 0) ? instab[cl -> insn].opcode : "<none>", cl -> len, cl -> dlen, cl -> pragmas);
 		debug_message(as, 100, "    ADDR: %s", lw_expr_print(cl -> addr));
+		debug_message(as, 100, "    DADDR: %s", lw_expr_print(cl -> daddr));
 		debug_message(as, 100, "    PB: %02X; LINT: %X; LINT2: %X", cl -> pb, cl -> lint, cl -> lint2);
 		for (le = cl -> exprs; le; le = le -> next)
 		{
--- a/lwasm/instab.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/instab.c	Fri Aug 19 23:55:40 2011 -0600
@@ -590,10 +590,10 @@
 	{ "export",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_export,	pseudo_resolve_export,			pseudo_emit_export,			lwasm_insn_setsym},
 	{ "extdep",		{	-1,		-1,		-1,		-1 },	pseudo_parse_extdep,	pseudo_resolve_extdep,			pseudo_emit_extdep,			lwasm_insn_setsym},
 
-	{ "rmb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct},
-	{ "rmd", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmd,		pseudo_resolve_rmd,				pseudo_emit_rmd,			lwasm_insn_struct},
-	{ "rmw", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmd,		pseudo_resolve_rmd,				pseudo_emit_rmd,			lwasm_insn_struct},
-	{ "rmq", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmq,		pseudo_resolve_rmq,				pseudo_emit_rmq,			lwasm_insn_struct},
+	{ "rmb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct | lwasm_insn_setdata},
+	{ "rmd", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmd,		pseudo_resolve_rmd,				pseudo_emit_rmd,			lwasm_insn_struct | lwasm_insn_setdata},
+	{ "rmw", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmd,		pseudo_resolve_rmd,				pseudo_emit_rmd,			lwasm_insn_struct | lwasm_insn_setdata},
+	{ "rmq", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmq,		pseudo_resolve_rmq,				pseudo_emit_rmq,			lwasm_insn_struct | lwasm_insn_setdata},
 
 	{ "zmb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmb,		pseudo_resolve_zmb,				pseudo_emit_zmb,			lwasm_insn_normal},
 	{ "zmd", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmd,		pseudo_resolve_zmd,				pseudo_emit_zmd,			lwasm_insn_normal},
@@ -689,9 +689,9 @@
 	{ ".asciz",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcn,		pseudo_resolve_fcn,				pseudo_emit_fcn,			lwasm_insn_normal},
 	{ ".strz",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcn,		pseudo_resolve_fcn,				pseudo_emit_fcn,			lwasm_insn_normal},
 
-	{ ".blkb",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct},
-	{ ".ds",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct},
-	{ ".rs",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct},
+	{ ".blkb",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct | lwasm_insn_setdata},
+	{ ".ds",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct | lwasm_insn_setdata},
+	{ ".rs",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				pseudo_emit_rmb,			lwasm_insn_struct | lwasm_insn_setdata},
 
 	// for compatibility
 	{ ".end", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_end,		pseudo_resolve_end,				pseudo_emit_end,			lwasm_insn_normal},
--- a/lwasm/instab.h	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/instab.h	Fri Aug 19 23:55:40 2011 -0600
@@ -43,6 +43,7 @@
 	lwasm_insn_setsym = 4,		/* insn sets symbol address */
 	lwasm_insn_is6309 = 8,		/* insn is 6309 only */
 	lwasm_insn_struct = 16,		/* insn allowed in a struct */
+	lwasm_insn_setdata = 32,	/* insn uses the data address for symbols */
 	lwasm_insn_normal = 0
 };
 
--- a/lwasm/list.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/list.c	Fri Aug 19 23:55:40 2011 -0600
@@ -110,11 +110,11 @@
 				memmove(obytes, cl -> output, cl -> outputl);
 			}
 		}
-		if (cl -> len < 1 && obytelen < 1)
+		if ((cl -> len < 1 && cl -> dlen < 1) && obytelen < 1)
 		{
 			if (cl -> soff >= 0)
 			{
-				fprintf(of, "%04X                  ", cl -> soff & 0xffff);
+				fprintf(of, "%04Xs                 ", cl -> soff & 0xffff);
 			}
 			else if (cl -> dshow >= 0)
 			{
@@ -153,13 +153,16 @@
 		else
 		{
 			lw_expr_t te;
-			te = lw_expr_copy(cl -> addr);
+			if (instab[cl -> insn].flags & lwasm_insn_setdata)
+				te = lw_expr_copy(cl -> daddr);
+			else
+				te = lw_expr_copy(cl -> addr);
 			as -> exportcheck = 1;
 			as -> csect = cl -> csect;
 			lwasm_reduce_expr(as, te);
 			as -> exportcheck = 0;
 //			fprintf(of, "%s\n", lw_expr_print(te));
-			fprintf(of, "%04X ", lw_expr_intval(te) & 0xffff);
+			fprintf(of, "%04X%c", lw_expr_intval(te) & 0xffff, ((cl -> inmod || (cl -> dlen != cl -> len)) && instab[cl -> insn].flags & lwasm_insn_setdata) ? '.' : ' ');
 			lw_expr_destroy(te);
 			for (i = 0; i < obytelen && i < 8; i++)
 			{
--- a/lwasm/lwasm.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/lwasm.c	Fri Aug 19 23:55:40 2011 -0600
@@ -104,7 +104,16 @@
 				return lw_expr_build(lw_expr_type_int, 0);
 			return NULL;
 		}
-			
+
+	case lwasm_expr_linedlen:
+		{
+			line_t *cl = ptr;
+			if (cl -> dlen == -1)
+				return NULL;
+			return lw_expr_build(lw_expr_type_int, cl -> dlen);
+		}
+		break;
+					
 	case lwasm_expr_linelen:
 		{
 			line_t *cl = ptr;
@@ -114,6 +123,12 @@
 		}
 		break;
 		
+	case lwasm_expr_linedaddr:
+		{
+			line_t *cl = ptr;
+			return lw_expr_copy(cl -> daddr);
+		}
+	
 	case lwasm_expr_lineaddr:
 		{
 			line_t *cl = ptr;
@@ -284,14 +299,19 @@
 	if (!**p)
 		return NULL;
 	
-	if (**p == '*' || (
-			**p == '.'
+	if (**p == '.'
 			&& !((*p)[1] >= 'A' && (*p)[1] <= 'Z')
 			&& !((*p)[1] >= 'a' && (*p)[1] <= 'z')
 			&& !((*p)[1] >= '0' && (*p)[1] <= '9')
-		))
+		)
 	{
-		// special "symbol" for current line addr (*, .)
+		(*p)++;
+		return lw_expr_build(lw_expr_type_special, lwasm_expr_linedaddr, as -> cl);
+	}
+	
+	if (**p == '*')
+	{
+		// special "symbol" for current line addr (*)
 		(*p)++;
 		return lw_expr_build(lw_expr_type_special, lwasm_expr_lineaddr, as -> cl);
 	}
--- a/lwasm/lwasm.h	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/lwasm.h	Fri Aug 19 23:55:40 2011 -0600
@@ -42,7 +42,9 @@
 	lwasm_expr_prevbp = 4,			// previous branch point
 	lwasm_expr_syment = 5,			// symbol table entry
 	lwasm_expr_import = 6,			// symbol import entry
-	lwasm_expr_secbase = 7			// section base address
+	lwasm_expr_secbase = 7,			// section base address
+	lwasm_expr_linedaddr = 8,		// data address of the line
+	lwasm_expr_linedlen = 9			// data length of the line
 };
 
 enum lwasm_output_e
@@ -147,7 +149,9 @@
 struct line_s
 {
 	lw_expr_t addr;						// assembly address of the line
+	lw_expr_t daddr;					// data address of the line (os9 only)
 	int len;							// the "size" this line occupies (address space wise) (-1 if unknown)
+	int dlen;							// the data "size" this line occupies (-1 if unknown)
 	int insn;							// number of insn in insn table
 	int symset;							// set if the line symbol was consumed by the instruction
 	char *sym;							// symbol, if any, on the line
--- a/lwasm/os9.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/os9.c	Fri Aug 19 23:55:40 2011 -0600
@@ -114,6 +114,10 @@
 	lw_expr_destroy(l -> addr);
 	l -> addr = lw_expr_build(lw_expr_type_int, 0);
 
+	// likewise for data pointer
+	lw_expr_destroy(l -> daddr);
+	l -> daddr = lw_expr_build(lw_expr_type_int, 0);
+
 	// init crc
 	as -> inmod = 1;
 	
--- a/lwasm/pass1.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/pass1.c	Fri Aug 19 23:55:40 2011 -0600
@@ -118,11 +118,13 @@
 		cl -> dsize = 0;
 		cl -> dptr = NULL;
 		cl -> isbrpt = 0;
+		cl -> dlen = 0;
 		as -> cl = cl;
 		if (!as -> line_tail)
 		{
 			as -> line_head = cl;
 			cl -> addr = lw_expr_build(lw_expr_type_int, 0);
+			cl -> daddr = lw_expr_build(lw_expr_type_int, 0);
 		}
 		else
 		{
@@ -138,6 +140,12 @@
 			lwasm_reduce_expr(as, cl -> addr);
 //			lw_expr_simplify(cl -> addr, as);
 
+			// set the data address if relevant
+			te = lw_expr_build(lw_expr_type_special, lwasm_expr_linedlen, cl -> prev);
+			cl -> daddr = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, cl -> prev -> daddr, te);
+			lw_expr_destroy(te);
+			lwasm_reduce_expr(as, cl -> daddr);
+
 			// carry DP value forward
 			cl -> dpval = cl -> prev -> dpval;
 			
@@ -321,7 +329,15 @@
 
 						cl -> len = -1;
 						// call parse function
+					debug_message(as, 100, "len = %d, dlen = %d", cl -> len, cl -> dlen);
 						(instab[opnum].parse)(as, cl, &p1);
+						if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
+						{
+							if (cl -> len == 0)
+								cl -> len = cl -> dlen;
+							else
+								cl -> dlen = cl -> len;
+						}
 					
 						if (*p1 && !isspace(*p1))
 						{
@@ -343,6 +359,13 @@
 						if (cl -> insn >= 0 && instab[cl -> insn].resolve)
 						{
 							(instab[cl -> insn].resolve)(as, cl, 0);
+							if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
+							{
+								if (cl -> len == 0)
+									cl -> len = cl -> dlen;
+								else
+									cl -> dlen = cl -> len;
+							}
 						}
 
 					}
@@ -362,10 +385,21 @@
 				debug_message(as, 50, "Register symbol %s: %s", cl -> sym, lw_expr_print(cl -> addr));
 	
 				// register symbol at line address
-				if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none))
+				if (instab[cl -> insn].flags & lwasm_insn_setdata)
 				{
-					// symbol error
-					// lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym);
+					if (!register_symbol(as, cl, cl -> sym, cl -> daddr, symbol_flag_none))
+					{
+						// symbol error
+						// lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym);
+					}
+				}
+				else
+				{
+					if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none))
+					{
+						// symbol error
+						// lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym);
+					}
 				}
 			}
 			debug_message(as, 40, "Line address: %s", lw_expr_print(cl -> addr));
--- a/lwasm/pass2.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/pass2.c	Fri Aug 19 23:55:40 2011 -0600
@@ -86,6 +86,9 @@
 		
 		// simplify address
 		lwasm_reduce_expr(as, cl -> addr);
+
+		// simplify data address
+		lwasm_reduce_expr(as, cl -> daddr);
 		
 		// simplify each expression
 		for (le = cl -> exprs; le; le = le -> next)
--- a/lwasm/pass3.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/pass3.c	Fri Aug 19 23:55:40 2011 -0600
@@ -51,18 +51,29 @@
 			// simplify address
 			lwasm_reduce_expr(as, cl -> addr);
 		
+			// simplify data address
+			lwasm_reduce_expr(as, cl -> daddr);
+
 			// simplify each expression
 			for (le = cl -> exprs; le; le = le -> next)
 				lwasm_reduce_expr(as, le -> expr);
 			
-			if (cl -> len == -1)
+			if (cl -> len == -1 || cl -> dlen == -1)
 			{
 				// try resolving the instruction length
 				// but don't force resolution
 				if (cl -> insn >= 0 && instab[cl -> insn].resolve)
 				{
 					(instab[cl -> insn].resolve)(as, cl, 0);
-					if (cl -> len != -1)
+					debug_message(as, 100, "len = %d, dlen = %d", cl -> len, cl -> dlen);
+					if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
+					{
+						if (cl -> len == 0)
+							cl -> len = cl -> dlen;
+						else
+							cl -> dlen = cl -> len;
+					}
+					if (cl -> len != -1 && cl -> dlen != -1)
 						rc++;
 				}
 			}
--- a/lwasm/pass4.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/pass4.c	Fri Aug 19 23:55:40 2011 -0600
@@ -56,7 +56,8 @@
 		{
 			as -> cl = sl;
 			lwasm_reduce_expr(as, sl -> addr);
-		
+			lwasm_reduce_expr(as, sl -> daddr);
+	
 			// simplify each expression
 			for (le = sl -> exprs; le; le = le -> next)
 				lwasm_reduce_expr(as, le -> expr);
@@ -65,7 +66,8 @@
 		// simplify address
 		as -> cl = sl;
 		lwasm_reduce_expr(as, sl -> addr);
-		
+		lwasm_reduce_expr(as, sl -> daddr);
+			
 		// simplify each expression
 		for (le = sl -> exprs; le; le = le -> next)
 			lwasm_reduce_expr(as, le -> expr);
@@ -93,7 +95,7 @@
 			
 				// simplify address
 				lwasm_reduce_expr(as, cl -> addr);
-		
+				lwasm_reduce_expr(as, cl -> daddr);
 				// simplify each expression
 				for (le = cl -> exprs; le; le = le -> next)
 					lwasm_reduce_expr(as, le -> expr);
@@ -105,7 +107,14 @@
 					if (cl -> insn >= 0 && instab[cl -> insn].resolve)
 					{
 						(instab[cl -> insn].resolve)(as, cl, 0);
-						if (cl -> len != -1)
+						if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
+						{
+							if (cl -> len == 0)
+								cl -> len = cl -> dlen;
+							else
+								cl -> dlen = cl -> len;
+						}
+						if (cl -> len != -1 && cl -> dlen != -1)
 						{
 							rc++;
 							cnt--;
--- a/lwasm/pass5.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/pass5.c	Fri Aug 19 23:55:40 2011 -0600
@@ -77,6 +77,9 @@
 		lwasm_reduce_expr(as, cl -> addr);
 		if (!exprok(as, cl -> addr))
 			cnt++;
+		lwasm_reduce_expr(as, cl -> daddr);
+		if (!exprok(as, cl -> daddr))
+			cnt++;
 	}
 
 	sl = as -> line_head;
@@ -85,7 +88,7 @@
 		ocnt = cnt;
 		
 		// find an unresolved address
-		for ( ; sl && exprok(as, sl -> addr); sl = sl -> next)
+		for ( ; sl && exprok(as, sl -> addr) && exprok(as, sl -> daddr); sl = sl -> next)
 			/* do nothing */ ;
 
 		// simplify address
@@ -96,7 +99,13 @@
 		
 			if (exprok(as, cl -> addr))
 			{
-				if (0 == --cnt);
+				if (0 == --cnt)
+					return;
+			}
+			lwasm_reduce_expr(as, sl -> daddr);
+			if (exprok(as, cl -> addr))
+			{
+				if (0 == --cnt)
 					return;
 			}
 		}
@@ -114,6 +123,10 @@
 			{
 				lwasm_register_error(as, cl, "Cannot resolve line address");
 			}
+			if (!exprok(as, cl -> daddr))
+			{
+				lwasm_register_error(as, cl, "Cannot resolve line data address");
+			}
 		}
 	}
 }
--- a/lwasm/pseudo.c	Fri Aug 19 20:36:43 2011 -0600
+++ b/lwasm/pseudo.c	Fri Aug 19 23:55:40 2011 -0600
@@ -494,7 +494,14 @@
 			l -> symset = 1;
 		}
 	}
-	
+	else
+	{
+		if (l -> inmod)
+		{
+			l -> dlen = -1;
+			l -> len = 0;
+		}
+	}
 	lwasm_save_expr(l, 0, expr);
 }
 
@@ -505,14 +512,25 @@
 	if (l -> lint)
 		return;
 	
-	if (l -> len >= 0)
-		return;
-	
+	if (l -> inmod)
+	{
+		if (l -> dlen >= 0)
+			return;
+	}
+	else
+	{
+		if (l -> len >= 0)
+			return;
+	}
+			
 	expr = lwasm_fetch_expr(l, 0);
 	
 	if (lw_expr_istype(expr, lw_expr_type_int))
 	{
-		l -> len = lw_expr_intval(expr);
+		if (l -> inmod)
+			l -> dlen = lw_expr_intval(expr);
+		else
+			l -> len = lw_expr_intval(expr);
 	}
 }
 
@@ -521,7 +539,7 @@
 	if (l -> lint)
 		return;
 
-	if (l -> len < 0)
+	if (l -> len < 0 || l -> dlen < 0)
 		lwasm_register_error(as, l, "Expression not constant");
 }
 
@@ -553,6 +571,14 @@
 			l -> lint = 1;
 		}
 	}
+	else
+	{
+		if (l -> inmod)
+		{
+			l -> dlen = -1;
+			l -> len = 0;
+		}
+	}
 	lwasm_save_expr(l, 0, expr);
 }
 
@@ -563,14 +589,25 @@
 	if (l -> lint)
 		return;
 	
-	if (l -> len >= 0)
-		return;
+	if (l -> inmod)
+	{
+		if (l -> dlen >= 0)
+			return;
+	}
+	else
+	{
+		if (l -> len >= 0)
+			return;
+	}
 	
 	expr = lwasm_fetch_expr(l, 0);
 	
 	if (lw_expr_istype(expr, lw_expr_type_int))
 	{
-		l -> len = lw_expr_intval(expr) * 2;
+		if (l -> inmod)
+			l -> dlen = lw_expr_intval(expr) * 2;
+		else
+			l -> len = lw_expr_intval(expr) * 2;
 	}
 }
 
@@ -579,7 +616,7 @@
 	if (l -> lint)
 		return;
 
-	if (l -> len < 0)
+	if (l -> len < 0 || l -> dlen < 0)
 		lwasm_register_error(as, l, "Expression not constant");
 }
 
@@ -611,7 +648,14 @@
 			l -> lint = 1;
 		}
 	}
-	
+	else
+	{
+		if (as -> inmod)
+		{
+			l -> dlen = -1;
+			l -> len = 0;
+		}
+	}
 	lwasm_save_expr(l, 0, expr);
 }
 
@@ -622,14 +666,25 @@
 	if (l -> lint)
 		return;
 	
-	if (l -> len >= 0)
-		return;
+	if (l -> inmod)
+	{
+		if (l -> dlen >= 0)
+			return;
+	}
+	else
+	{
+		if (l -> len >= 0)
+			return;
+	}
 	
 	expr = lwasm_fetch_expr(l, 0);
 	
 	if (lw_expr_istype(expr, lw_expr_type_int))
 	{
-		l -> len = lw_expr_intval(expr) * 4;
+		if (l -> inmod)
+			l -> dlen = lw_expr_intval(expr) * 4;
+		else 
+			l -> len = lw_expr_intval(expr) * 4;
 	}
 }
 
@@ -638,7 +693,7 @@
 	if (l -> lint)
 		return;
 
-	if (l -> len < 0)
+	if (l -> len < 0 || l -> dlen < 0)
 		lwasm_register_error(as, l, "Expression not constant");
 }
 
@@ -783,8 +838,14 @@
 		return;
 	}
 	
-	lw_expr_destroy(l -> addr);
-	l -> addr = e;
+	lw_expr_destroy(l -> daddr);
+	l -> daddr = e;
+	
+	if (l -> inmod == 0)
+	{
+		lw_expr_destroy(l -> addr);
+		l -> addr = e;
+	}
 	l -> len = 0;
 }