Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
 
2
#define __mathuserfunc_h__
3
4
 
5
#include "lispuserfunc.h"
6
#include "grower.h"
7
8
 
9
10
 
11
/// This is the basic class which implements functions in Yacas.
12
/// Evaluation is done by consulting a set of rewriting rules. The
13
/// body of the first rule that matches, is evaluated and this gives
14
/// the result of evaluating the function.
15
16
 
17
{
18
public:
19
  /// Structure containing name of parameter and whether it is put on hold.
20
  class BranchParameter : public YacasBase
21
  {
22
  public:
23
    BranchParameter(LispString * aParameter = NULL, LispInt aHold=LispFalse)
24
        : iParameter(aParameter), iHold(aHold) {}
25
    LispString * iParameter;
26
    LispInt       iHold;
27
  };
28
29
 
30
  class BranchRuleBase : public YacasBase
31
  {
32
  public:
33
    virtual ~BranchRuleBase();
34
    virtual LispBoolean Matches(LispEnvironment& aEnvironment, LispPtr* aArguments) = 0;
35
    virtual LispInt Precedence() const = 0;
36
    virtual LispPtr& Body() = 0;
37
  };
38
39
 
40
  /// This rule matches if the predicate evaluates to #LispTrue.
41
  class BranchRule : public BranchRuleBase
42
  {
43
  public:
44
    virtual ~BranchRule();
45
    BranchRule(LispInt aPrecedence,LispPtr& aPredicate,LispPtr& aBody) : iPrecedence(aPrecedence),iBody(aBody),iPredicate(aPredicate)
46
    {
47
    }
48
49
 
50
    /// #iPredicate is evaluated in \a Environment. If the result
51
    /// IsTrue(), this function returns true.
52
    virtual LispBoolean Matches(LispEnvironment& aEnvironment, LispPtr* aArguments);
53
54
 
55
    virtual LispInt Precedence() const;
56
57
 
58
    virtual LispPtr& Body();
59
  protected:
60
    BranchRule() : iPrecedence(0),iBody(),iPredicate() {};
61
  protected:
62
    LispInt iPrecedence;
63
    LispPtr iBody;
64
    LispPtr iPredicate;
65
  };
66
67
 
68
  class BranchRuleTruePredicate : public BranchRule
69
  {
70
  public:
71
    BranchRuleTruePredicate(LispInt aPrecedence,LispPtr& aBody)
72
    {
73
      iPrecedence = aPrecedence;
74
      iBody = (aBody);
75
    }
76
    /// Return #LispTrue, always.
77
    virtual LispBoolean Matches(LispEnvironment& aEnvironment, LispPtr* aArguments);
78
  };
79
80
 
81
  class BranchPattern : public BranchRuleBase
82
  {
83
  public:
84
    /// Destructor.
85
    /// This function contains no code.
86
    virtual ~BranchPattern();
87
88
 
89
    /// \param aPrecedence precedence of the rule
90
    /// \param aPredicate generic object of type \c Pattern
91
    /// \param aBody body of the rule
92
    BranchPattern(LispInt aPrecedence,LispPtr& aPredicate,LispPtr& aBody) : iPrecedence(aPrecedence),iBody(aBody),iPredicate(aPredicate),iPatternClass(NULL)
93
    {
94
      GenericClass *gen = aPredicate->Generic();
95
      DYNCAST(PatternClass,"\"Pattern\"",pat,gen)
96
      Check(pat,KLispErrInvalidArg);
97
      iPatternClass = pat;
98
    }
99
100
 
101
    virtual LispBoolean Matches(LispEnvironment& aEnvironment, LispPtr* aArguments);
102
103
 
104
    virtual LispInt Precedence() const;
105
106
 
107
    virtual LispPtr& Body();
108
109
 
110
    BranchPattern(const BranchPattern& aOther) : iPrecedence(0),iBody(),iPredicate(),iPatternClass(NULL)
111
    {
112
      // copy constructor not written yet, hence the assert
113
      LISPASSERT(0);
114
    }
115
    BranchPattern& operator=(const BranchPattern& aOther)
116
    {
117
      // copy constructor not written yet, hence the assert
118
      LISPASSERT(0);
119
      return *this;
120
    }
121
122
 
123
    /// The precedence of this rule.
124
    LispInt iPrecedence;
125
126
 
127
    LispPtr iBody;
128
129
 
130
    LispPtr iPredicate;
131
132
 
133
    PatternClass *iPatternClass;
134
  };
135
136
 
137
  /// \param aParameters linked list constaining the names of the arguments
138
  ///
139
  /// #iParamList and #iParameters are set from \a aParameters.
140
  BranchingUserFunction(LispPtr& aParameters);
141
142
 
143
  /// There is no code inside this function.
144
  virtual ~BranchingUserFunction();
145
146
 
147
  /// \param aResult (on output) the result of the evaluation
148
  /// \param aEnvironment the underlying Lisp environment
149
  /// \param aArguments the arguments to the function
150
  ///
151
  /// First, all arguments are evaluated by the evaluator associated
152
  /// to \a aEnvironment, unless the \c iHold flag of the
153
  /// corresponding parameter is true. Then a new LispLocalFrame is
154
  /// constructed, in which the actual arguments are assigned to the
155
  /// names of the formal arguments, as stored in \c iParameter. Then
156
  /// all rules in #iRules are tried one by one. The body of the
157
  /// first rule that matches is evaluated, and the result is put in
158
  /// \a aResult. If no rule matches, \a aResult will recieve a new
159
  /// expression with evaluated arguments.
160
  virtual void Evaluate(LispPtr& aResult,LispEnvironment& aEnvironment, LispPtr& aArguments);
161
162
 
163
  /// \param aVariable name of argument to put un hold
164
  ///
165
  /// The \c iHold flag of the corresponding argument is set. This
166
  /// implies that this argument is not evaluated by Evaluate().
167
  virtual void HoldArgument(LispString * aVariable);
168
169
 
170
  virtual LispInt IsArity(LispInt aArity) const;
171
172
 
173
  LispInt Arity() const;
174
175
 
176
  /// \sa InsertRule()
177
  virtual void DeclareRule(LispInt aPrecedence, LispPtr& aPredicate, LispPtr& aBody);
178
179
 
180
  /// \sa InsertRule()
181
  virtual void DeclareRule(LispInt aPrecedence, LispPtr& aBody);
182
183
 
184
  /// \sa InsertRule()
185
  void DeclarePattern(LispInt aPrecedence, LispPtr& aPredicate, LispPtr& aBody);
186
187
 
188
  /// This function does the real work for DeclareRule() and
189
  /// DeclarePattern(): it inserts the rule in #iRules, while
190
  /// keeping it sorted. The algorithm is \f$O(\log n)\f$, where
191
  /// \f$n\f$ denotes the number of rules.
192
  void InsertRule(LispInt aPrecedence,BranchRuleBase* newRule);
193
194
 
195
  virtual LispPtr& ArgList();
196
197
 
198
  /// List of arguments, with corresponding \c iHold property.
199
  CArrayGrower > iParameters;
200
201
 
202
  CDeletingArrayGrower >     iRules;
203
204
 
205
  LispPtr iParamList;
206
};
207
208
 
209
{
210
public:
211
  ListedBranchingUserFunction(LispPtr& aParameters);
212
  virtual LispInt IsArity(LispInt aArity) const;
213
  virtual void Evaluate(LispPtr& aResult,LispEnvironment& aEnvironment, LispPtr& aArguments);
214
};
215
216
 
217
 
218
{
219
public:
220
  MacroUserFunction(LispPtr& aParameters);
221
  virtual void Evaluate(LispPtr& aResult,LispEnvironment& aEnvironment, LispPtr& aArguments);
222
};
223
224
 
225
 
226
{
227
public:
228
  ListedMacroUserFunction(LispPtr& aParameters);
229
  virtual LispInt IsArity(LispInt aArity) const;
230
  virtual void Evaluate(LispPtr& aResult,LispEnvironment& aEnvironment, LispPtr& aArguments);
231
};
232
233
 
234
 
235
 
236
 
237