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