1 /* ==================================================================== */
5 /* This is a demo of Macsyma's macroexpanding commands and the use of
6 the macroexpansion switch. */
8 (showtime:all,macroexpansion:false)$
10 /* First we need a macro to play with. Let's define a caseq statement
13 caseq(<var>,[<keys1>],<stmt1>,
18 where the first <stmt> that has <var> as a member of the associated
19 <keys> is the one chosen to execute. */
23 then buildq([var,keys:first(pairs),statement:last(pairs)],
24 if member(var,'keys) then statement)
25 else buildq([var,keys:first(pairs),
26 statement:first(rest(pairs)),
27 pairs:rest(rest(pairs))],
30 else caseq(var,splice(pairs)))$
32 /* let's use our caseq macro to define a simple predicate. */
34 variablep(x)::=buildq([x],caseq(x,[a,b,c,d,e],true));
36 /* to make sure it works. */
38 display(variablep(var1),variablep(var2)),var1:'a,var2:'z;
40 /* we can see what variablep is expanding into. */
42 macroexpand(variablep(some_form));
44 /* we can also watch the expansion by stages. */
46 macroexpand1(variablep(some_form));
50 /* we might also create simple typep macro using caseq. */
53 typep(x)::=buildq([x],caseq(x,[1,2,3,4,5,6,7,8,9,0], 'digit,
54 [a,b,c,d,e,f,g,h,i,j], 'variable,
55 ["+","-","*","/","^"], 'operator))$
57 /* let's see what things are expanding into. */
59 macroexpand(typep(test));
61 /* the nested caseq doesn't expand because macroexpand and
62 macroexpand1 only look at the top level function. to expand all
65 scanmap('macroexpand,'(typep(test)));
67 /* let's test it just to make sure it works. */
71 /* compare the time it just took to evaluate the macro when expanded
72 to the time it takes to expand it from scratch and then eval. */
74 ev(typep(test),test="*");
76 /* this is why we can save time by using the macroexpansion switch. */
82 macroexpansion:expand;
86 /* there's no savings on the first call after macroexpansion has been
87 reset, but there is on all subsequent calls. */
91 /* macroexpand also uses the saved expansion. */
95 /* note that form still displays nicely. */
99 /* if we set macroexpansion to displace however, each macro call will
100 be completely replaced by the equivalent code. */
102 (macroexpansion:displace,ev(form));
106 /* note that once the call is displaced, the original call cannot be
107 retrieved by resetting macroexpansion. */
109 (macroexpansion:false,ev(form));