// macro-s.txt  macro expansion
//   for som-v24 	2 Jan 2007

// return pointer to n-th ele of e
to pick e n =
	if e == NIL
		NIL
	else if n < 1
		NIL
	else if n == 1
		car e
	else
		pick (cdr e) (n-1)

// map atom with n-arg in e, e is the actual arg list
// sustitute get.local with n-th ele of e
to mapAtom a e =
	if (car a) != LNAME
		a
	else
		pick e cdr a	// n-arg of caller

// e1 is the body of macro def, e2 is the actual arg list
to subst e1 e2 =
	if e1 == NIL
		NIL
	else if isatom e1
		mapAtom e1 e2
	else if isatom car e1
		cons (mapAtom car e1 e2) (subst cdr e1 e2)
	else
		cons (subst car e1 e2) (subst cdr e1 e2)

// macro expansion
// should have special case for arity 1
to domacro idx el | e a i op n first =
	if (getType idx) == tyMAC		// simple macro
		e = subst (getRef idx) el	// subst body
		genex e
	else							// full macro
		genlist el
		// extend current f locals
		first = getLv currentf
		setLv currentf first+(getLv idx)
		// pass param
		a = getArity idx
		for i 1 a
			outa icPut first+(a-i+1)
		// rename body
		i = getRef idx
		op = CS[i] & 255
		n = CS[i] >> 8
		while op != icEnd
			case op
				icGet: n = first + n
				icPut: n = first + n
				icInc: n = first + n
				icDec: n = first + n
			outa op n
			i = i + 1
			op = CS[i] & 255
			n = CS[i] >> 8

// End


