fan-1.0 /src/sys/dotnet/fan/sys/Func.cs

Language C# Lines 403
MD5 Hash 06aa2d14a37bd9aeaf4e95a5a1e203ed Estimated Cost $8,220 (why?)
Repository https://bitbucket.org/bedlaczech/fan-1.0 View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
//
// Copyright (c) 2006, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
//   23 Jul 07  Andy Frank  Creation
//

namespace Fan.Sys
{
  /// <summary>
  /// Func models an executable subroutine.
  /// </summary>
  public abstract class Func : FanObj
  {

  //////////////////////////////////////////////////////////////////////////
  // Methods
  //////////////////////////////////////////////////////////////////////////

    public override Type @typeof() { return Sys.FuncType; }

    public abstract Type returns();

    public abstract long arity();

    public abstract List @params();

    public override abstract bool isImmutable();

    public abstract Method method();

    public abstract object callList(List args);
    public abstract object callOn(object target, List args);
    public abstract object call();
    public abstract object call(object a);
    public abstract object call(object a, object b);
    public abstract object call(object a, object b, object c);
    public abstract object call(object a, object b, object c, object d);
    public abstract object call(object a, object b, object c, object d, object e);
    public abstract object call(object a, object b, object c, object d, object e, object f);
    public abstract object call(object a, object b, object c, object d, object e, object f, object g);
    public abstract object call(object a, object b, object c, object d, object e, object f, object g, object h);

    public override object toImmutable()
    {
      if (isImmutable()) return this;
      throw NotImmutableErr.make().val;
    }

    // Hooks used by compiler to generate runtime const field checks for it-blocks
    public virtual void enterCtor(object o) {}
    public virtual void exitCtor() {}
    public virtual void checkInCtor(object o) {}

  //////////////////////////////////////////////////////////////////////////
  // Indirect
  //////////////////////////////////////////////////////////////////////////

    public static readonly int MaxIndirectParams = 8;  // max callX()

    /// <summary>
    /// Indirect is the base class for the IndirectX classes, which are
    /// used as the common base classes for closures and general purpose
    /// functions.  An Indirect method takes a funcType for it's type,
    /// and also extends Func for the callList() implementations.
    /// </summary>
    public abstract class Indirect : Func
    {
      protected Indirect(FuncType type) { this.m_type = type; }

      public string name() { return GetType().Name; }
      public override Type @typeof()  { return m_type; }
      public override string  toStr() { return m_type.signature(); }
      public override bool isImmutable() { return false; }
      public override Method method() { return null; }
      public Err.Val tooFewArgs(int given) { return Err.make("Too few arguments: " + given + " < " + m_type.m_params.Length).val; }

      public override Type returns() { return m_type.m_ret; }
      public override long arity() { return m_type.m_params.Length; }
      public override List @params()
      {
        // lazily build params list
        if (m_params == null) m_params = m_type.toMethodParams().ro();
        return m_params;
      }

      public override object callOn(object obj, List args)
      {
        List flat = args.dup();
        flat.insert(0, obj);
        return callList(flat);
      }

      FuncType m_type;
      private List m_params;
    }

    public abstract class Indirect0 : Indirect
    {
      protected Indirect0(FuncType type) : base(type) {}
      protected Indirect0() : base(type0) {}
      public override object callList(List args) { return call(); }
      public override abstract object call();
      public override object call(object a) { return call(); }
      public override object call(object a, object b) { return call(); }
      public override object call(object a, object b, object c) { return call(); }
      public override object call(object a, object b, object c, object d) { return call(); }
      public override object call(object a, object b, object c, object d, object e) { return call(); }
      public override object call(object a, object b, object c, object d, object e, object f) { return call(); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(); }
    }

    public abstract class Indirect1 : Indirect
    {
      protected Indirect1(FuncType type) : base(type) {}
      protected Indirect1() : base(type1) {}
      public override object callList(List args) { return call(args.get(0)); }
      public override object call() { throw tooFewArgs(0); }
      public override abstract object call(object a);
      public override object call(object a, object b) { return call(a); }
      public override object call(object a, object b, object c) { return call(a); }
      public override object call(object a, object b, object c, object d) { return call(a); }
      public override object call(object a, object b, object c, object d, object e) { return call(a); }
      public override object call(object a, object b, object c, object d, object e, object f) { return call(a); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a); }

      public override void enterCtor(object o) { this.m_inCtor = o; }
      public override void exitCtor() { this.m_inCtor = null; }
      public override void checkInCtor(object it)
      {
        if (it == m_inCtor) return;
        string msg = it == null ? "null" : FanObj.@typeof(it).qname();
        throw ConstErr.make(msg).val;
      }

      internal object m_inCtor;
    }

    public abstract class Indirect2 : Indirect
    {
      protected Indirect2(FuncType type) : base(type) {}
      protected Indirect2() : base(type2) {}
      public override object callList(List args) { return call(args.get(0), args.get(1)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override abstract object call(object a, object b);
      public override object call(object a, object b, object c) { return call(a, b); }
      public override object call(object a, object b, object c, object d) { return call(a, b); }
      public override object call(object a, object b, object c, object d, object e) { return call(a, b); }
      public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b); }
    }

    public abstract class Indirect3 : Indirect
    {
      protected Indirect3(FuncType type) : base(type) {}
      protected Indirect3() : base(type3) {}
      public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override abstract object call(object a, object b, object c);
      public override object call(object a, object b, object c, object d) { return call(a, b, c); }
      public override object call(object a, object b, object c, object d, object e) { return call(a, b, c); }
      public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b, c); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c); }
    }

    public abstract class Indirect4 : Indirect
    {
      protected Indirect4(FuncType type) : base(type) {}
      protected Indirect4() : base(type4) {}
      public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override object call(object a, object b, object c) { throw tooFewArgs(3); }
      public override abstract object call(object a, object b, object c, object d);
      public override object call(object a, object b, object c, object d, object e) { return call(a, b, c, d); }
      public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b, c, d); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c, d); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d); }
    }

    public abstract class Indirect5 : Indirect
    {
      protected Indirect5(FuncType type) : base(type) {}
      public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override object call(object a, object b, object c) { throw tooFewArgs(3); }
      public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
      public override abstract object call(object a, object b, object c, object d, object e);
      public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b, c, d, e); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c, d, e); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d, e); }
    }

    public abstract class Indirect6 : Indirect
    {
      protected Indirect6(FuncType type) : base(type) {}
      public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4), args.get(5)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override object call(object a, object b, object c) { throw tooFewArgs(3); }
      public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
      public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
      public override abstract object call(object a, object b, object c, object d, object e, object f);
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c, d, e, f); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d, e, f); }
    }

    public abstract class Indirect7 : Indirect
    {
      protected Indirect7(FuncType type) : base(type) {}
      public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4), args.get(5), args.get(6)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override object call(object a, object b, object c) { throw tooFewArgs(3); }
      public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
      public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
      public override object call(object a, object b, object c, object d, object e, object f) { throw tooFewArgs(6); }
      public override abstract object call(object a, object b, object c, object d, object e, object f, object g);
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d, e, f, g); }
    }

    public abstract class Indirect8 : Indirect
    {
      protected Indirect8(FuncType type) : base(type) {}
      public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4), args.get(5), args.get(6), args.get(7)); }
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override object call(object a, object b, object c) { throw tooFewArgs(3); }
      public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
      public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
      public override object call(object a, object b, object c, object d, object e, object f) { throw tooFewArgs(6); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { throw tooFewArgs(7); }
      public override abstract object call(object a, object b, object c, object d, object e, object f, object g, object h);
    }

    public abstract class IndirectX : Indirect
    {
      protected IndirectX(FuncType type) : base(type) {}
      public override abstract object callList(List args);
      public override object call() { throw tooFewArgs(0); }
      public override object call(object a) { throw tooFewArgs(1); }
      public override object call(object a, object b)  { throw tooFewArgs(2); }
      public override object call(object a, object b, object c) { throw tooFewArgs(3); }
      public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
      public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
      public override object call(object a, object b, object c, object d, object e, object f) { throw tooFewArgs(6); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { throw tooFewArgs(7); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { throw tooFewArgs(8); }
    }

  //////////////////////////////////////////////////////////////////////////
  // Retype
  //////////////////////////////////////////////////////////////////////////

    public Func retype(Type t)
    {
      try
      {
        return new Wrapper((FuncType)t, this);
      }
      catch (System.InvalidCastException)
      {
        throw ArgErr.make("Not a Func type: " + t).val;
      }
    }

    internal class Wrapper : Indirect
    {
      internal Wrapper(FuncType t, Func orig) : base(t) { m_orig = orig; }
      public override bool isImmutable() { return m_orig.isImmutable(); }
      public override Method method() { return m_orig.method(); }
      public override object callOn(object target, List args) { return m_orig.callOn(target, args); }
      public override object callList(List args) { return m_orig.callList(args); }
      public override object call() { return m_orig.call(); }
      public override object call(object a) { return m_orig.call(a); }
      public override object call(object a, object b)  { return m_orig.call(a, b); }
      public override object call(object a, object b, object c) { return m_orig.call(a, b, c); }
      public override object call(object a, object b, object c, object d) { return m_orig.call(a, b, c, d); }
      public override object call(object a, object b, object c, object d, object e) { return m_orig.call(a, b, c, d, e); }
      public override object call(object a, object b, object c, object d, object e, object f) { return m_orig.call(a, b, c, d, e, f); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return m_orig.call(a, b, c, d, e, f, g); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return m_orig.call(a, b, c, d, e, f, g, h); }
      Func m_orig;
    }

  //////////////////////////////////////////////////////////////////////////
  // Bind
  //////////////////////////////////////////////////////////////////////////

    public Func bind(List args)
    {
      if (args.sz() == 0) return this;
      if (args.sz() > @params().sz()) throw ArgErr.make("args.size > params.size").val;

      Type[] newParams = new Type[@params().sz()-args.sz()];
      for (int i=0; i<newParams.Length; ++i)
        newParams[i] = ((Param)@params().get(args.sz()+i)).m_type;

      FuncType newType = new FuncType(newParams, this.returns());
      return new BindFunc(newType, this, args);
    }

    internal class BindFunc : Indirect
    {
      internal BindFunc (FuncType type, Func orig, List bound)
        : base(type)
      {
        this.m_orig  = orig;
        this.m_bound = bound.ro();
      }

      public override Method method() { return null; }

      public override bool isImmutable()
      {
        if (this.m_isImmutable == null)
        {
          bool isImmutable = false;
          if (m_orig.isImmutable())
          {
            isImmutable = true;
            for (int i=0; i<m_bound.sz(); ++i)
            {
              object obj = m_bound.get(i);
              if (obj != null && !FanObj.isImmutable(obj))
                { isImmutable = false; break; }
            }
          }
          this.m_isImmutable = Boolean.valueOf(isImmutable);
        }
        return this.m_isImmutable.booleanValue();
      }

      // this isn't a very optimized implementation
      public override object call() { return callList(new List(Sys.ObjType, new object[] {})); }
      public override object call(object a) { return callList(new List(Sys.ObjType, new object[] {a})); }
      public override object call(object a, object b) { return callList(new List(Sys.ObjType, new object[] {a,b})); }
      public override object call(object a, object b, object c) { return callList(new List(Sys.ObjType, new object[] {a,b,c})); }
      public override object call(object a, object b, object c, object d) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d})); }
      public override object call(object a, object b, object c, object d, object e) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e})); }
      public override object call(object a, object b, object c, object d, object e, object f) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e,f})); }
      public override object call(object a, object b, object c, object d, object e, object f, object g) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e,f,g})); }
      public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e,f,g,h})); }

      public override object callList(List args)
      {
        int origReq  = m_orig.@params().sz();
        int haveSize = m_bound.sz() + args.sz();
        Method m = m_orig.method();
        if (m != null)
        {
          origReq = m.minParams();
          if (haveSize > origReq) origReq = haveSize;
        }
        if (origReq <= m_bound.sz()) return m_orig.callList(m_bound);

        object[] temp = new object[haveSize];
        m_bound.copyInto(temp, 0, m_bound.sz());
        args.copyInto(temp, m_bound.sz(), temp.Length-m_bound.sz());
        return m_orig.callList(new List(Sys.ObjType, temp));
      }

      public override object callOn(object obj, List args)
      {
        int origSize = m_orig.@params().sz();
        object[] temp = new object[origSize];
        m_bound.copyInto(temp, 0, m_bound.sz());
        temp[m_bound.sz()] = obj;
        args.copyInto(temp, m_bound.sz()+1, temp.Length-m_bound.sz()-1);
        return m_orig.callList(new List(Sys.ObjType, temp));
      }

      private readonly Func m_orig;
      private readonly List m_bound;
      private Boolean m_isImmutable;
    }

  //////////////////////////////////////////////////////////////////////////
  // Fields
  //////////////////////////////////////////////////////////////////////////

    internal static readonly object[] noArgs = new object[0];
    internal static readonly FuncType type0 = new FuncType(new Type[] {}, Sys.ObjType);
    internal static readonly FuncType type1 = new FuncType(new Type[] { Sys.ObjType }, Sys.ObjType);
    internal static readonly FuncType type2 = new FuncType(new Type[] { Sys.ObjType, Sys.ObjType }, Sys.ObjType);
    internal static readonly FuncType type3 = new FuncType(new Type[] { Sys.ObjType, Sys.ObjType, Sys.ObjType }, Sys.ObjType);
    internal static readonly FuncType type4 = new FuncType(new Type[] { Sys.ObjType, Sys.ObjType, Sys.ObjType, Sys.ObjType }, Sys.ObjType);
  }
}
Back to Top