1 package net.sf.yacas;
2 
3 
4 class MacroUserFunction extends BranchingUserFunction
5 {
MacroUserFunction(LispPtr aParameters)6   public MacroUserFunction(LispPtr  aParameters) throws Exception
7   {
8     super(aParameters);
9     LispIterator iter = new LispIterator(aParameters);
10     int i=0;
11     while (iter.GetObject() != null)
12     {
13         LispError.Check(iter.GetObject().String() != null,LispError.KLispErrCreatingUserFunction);
14         iParameters.get(i).iHold = true;
15         iter.GoNext();
16         i++;
17     }
18     UnFence();
19   }
20   @Override
Evaluate(LispPtr aResult,LispEnvironment aEnvironment, LispPtr aArguments)21   public void Evaluate(LispPtr  aResult,LispEnvironment  aEnvironment,
22                 LispPtr  aArguments) throws Exception
23   {
24     int arity = Arity();
25     int i;
26 
27     //hier
28 /*TODO fixme
29     if (Traced())
30     {
31         LispPtr tr;
32         tr.Set(LispSubList.New(aArguments.Get()));
33         TraceShowEnter(aEnvironment,tr);
34         tr.Set(null);
35     }
36 */
37     LispIterator iter = new LispIterator(aArguments);
38     iter.GoNext();
39 
40     // unrollable arguments
41     LispPtr[] arguments;
42     if (arity==0)
43         arguments = null;
44     else
45     {
46         LispError.LISPASSERT(arity>0);
47         arguments = new LispPtr[arity];
48     }
49 
50     // Walk over all arguments, evaluating them as necessary
51     for (i=0;i<arity;i++)
52     {
53         arguments[i] = new LispPtr();
54         LispError.Check(iter.GetObject() != null, LispError.KLispErrWrongNumberOfArgs);
55         if (iParameters.get(i).iHold)
56         {
57           arguments[i].Set(iter.GetObject().Copy(false));
58         }
59         else
60         {
61             LispError.Check(iter.Ptr() != null, LispError.KLispErrWrongNumberOfArgs);
62             aEnvironment.iEvaluator.Eval(aEnvironment, arguments[i], iter.Ptr());
63         }
64         iter.GoNext();
65     }
66 /*TODO fixme
67     if (Traced())
68     {
69         LispIterator iter = new LispIterator(aArguments);
70         iter.GoNext();
71         for (i=0;i<arity;i++)
72         {
73             TraceShowArg(aEnvironment,*iter.Ptr(),
74                   arguments[i]);
75 
76             iter.GoNext();
77         }
78     }
79 */
80     LispPtr substedBody = new LispPtr();
81     {
82       // declare a new local stack.
83       aEnvironment.PushLocalFrame(false);
84       try
85       {
86         // define the local variables.
87         for (i=0;i<arity;i++)
88         {
89             String variable = iParameters.get(i).iParameter;
90             // set the variable to the new value
91             aEnvironment.NewLocal(variable,arguments[i].Get());
92         }
93 
94         // walk the rules database, returning the evaluated result if the
95         // predicate is true.
96         int nrRules = iRules.size();
97         UserStackInformation st = aEnvironment.iEvaluator.StackInformation();
98         for (i=0;i<nrRules;i++)
99         {
100             BranchRuleBase thisRule = iRules.get(i);
101 //TODO remove            CHECKPTR(thisRule);
102             LispError.LISPASSERT(thisRule != null);
103 
104             st.iRulePrecedence = thisRule.Precedence();
105             boolean matches = thisRule.Matches(aEnvironment, arguments);
106             if (matches)
107             {
108                 st.iSide = 1;
109 
110                 BackQuoteBehaviour behaviour = new BackQuoteBehaviour(aEnvironment);
111                 LispStandard.InternalSubstitute(substedBody, thisRule.Body(), behaviour);
112   //              aEnvironment.iEvaluator.Eval(aEnvironment, aResult, thisRule.Body());
113                 break;
114             }
115 
116             // If rules got inserted, walk back
117             while (thisRule != iRules.get(i) && i>0) i--;
118         }
119       }
120       catch (Exception e)
121       {
122         throw e;
123       }
124       finally
125       {
126         aEnvironment.PopLocalFrame();
127       }
128     }
129 
130 
131     if (substedBody.Get() != null)
132     {
133         aEnvironment.iEvaluator.Eval(aEnvironment, aResult, substedBody);
134     }
135     else
136     // No predicate was true: return a new expression with the evaluated
137     // arguments.
138       {
139         LispPtr full = new LispPtr();
140         full.Set(aArguments.Get().Copy(false));
141         if (arity == 0)
142         {
143             full.Get().Next().Set(null);
144         }
145         else
146         {
147             full.Get().Next().Set(arguments[0].Get());
148             for (i=0;i<arity-1;i++)
149             {
150                 arguments[i].Get().Next().Set(arguments[i+1].Get());
151             }
152         }
153         aResult.Set(LispSubList.New(full.Get()));
154     }
155 //FINISH:
156 /*TODO fixme
157     if (Traced())
158     {
159         LispPtr tr;
160         tr.Set(LispSubList.New(aArguments.Get()));
161         TraceShowLeave(aEnvironment, aResult,tr);
162         tr.Set(null);
163     }
164 */
165   }
166 }
167 
168 
169