1 /*
2     This file is part of GNU APL, a free implementation of the
3     ISO/IEC Standard 13751, "Programming Language APL, Extended"
4 
5     Copyright (C) 2008-2019  Dr. Jürgen Sauermann
6 
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef __PRIMITIVE_FUNCTION_HH_DEFINED__
22 #define __PRIMITIVE_FUNCTION_HH_DEFINED__
23 
24 #include <vector>
25 
26 #include "Common.hh"
27 #include "Function.hh"
28 #include "Performance.hh"
29 #include "Value.hh"
30 #include "Id.hh"
31 
32 class ArrayIterator;
33 class CharCell;
34 class IntCell;
35 class CollatingCache;
36 
37 //-----------------------------------------------------------------------------
38 /**
39     Base class for the APL system functions (Quad functions and primitives
40     like +, -, ...) and operators
41 
42     The individual system functions are derived from this class
43  */
44 /// Base class for all internal functions of the interpreter
45 class PrimitiveFunction : public Function
46 {
47 public:
48    /// Construct a PrimitiveFunction with \b TokenTag \b tag
PrimitiveFunction(TokenTag tag,CellFunctionStatistics * stat_AB=0,CellFunctionStatistics * stat_B=0)49    PrimitiveFunction(TokenTag tag,
50                      CellFunctionStatistics * stat_AB = 0,
51                      CellFunctionStatistics * stat_B = 0)
52    : Function(tag),
53        statistics_AB(stat_AB),
54        statistics_B(stat_B)
55    {}
56 
57    /// overloaded Function::has_result()
has_result() const58    virtual bool has_result() const   { return true; }
59 
60    /// return the dyadic cell statistics of \b this (scalar) function
61    CellFunctionStatistics *
get_statistics_AB() const62    get_statistics_AB() const   { return statistics_AB; }
63 
64    /// return the monadic cell statistics of \b this (scalar) function
65    CellFunctionStatistics *
get_statistics_B() const66    get_statistics_B() const   { return statistics_B; }
67 
68    /// overloaded Function::eval_fill_AB()
69    virtual Token eval_fill_AB(Value_P A, Value_P B);
70 
71 protected:
72    /// overloaded Function::print_properties()
73    virtual void print_properties(ostream & out, int indent) const;
74 
75    /// overloaded Function::eval_fill_B()
76    virtual Token eval_fill_B(Value_P B);
77 
78    /// Print the name of \b this PrimitiveFunction to \b out
79    virtual ostream & print(ostream & out) const;
80 
81    /// performance statistics for eval_B()
82    CellFunctionStatistics * statistics_AB;
83 
84    /// performance statistics for dyadic calls
85    CellFunctionStatistics * statistics_B;
86 
87    /// a cell containing ' '
88    static const CharCell c_filler;
89 
90    /// a cell containing 0
91    static const IntCell n_filler;
92 };
93 //-----------------------------------------------------------------------------
94 /// Base class for all internal non-scalar functions of the interpreter
95 class NonscalarFunction : public PrimitiveFunction
96 {
97 public:
98    /// Constructor
NonscalarFunction(TokenTag tag)99    NonscalarFunction(TokenTag tag)
100    : PrimitiveFunction(tag)
101    {}
102 };
103 //-----------------------------------------------------------------------------
104 /** System function zilde (⍬) */
105 /// The class implementing ⍬ (the empty numeric vector)
106 class Bif_F0_ZILDE : public NonscalarFunction
107 {
108 public:
109    /// Constructor
Bif_F0_ZILDE()110    Bif_F0_ZILDE()
111    : NonscalarFunction(TOK_F0_ZILDE)
112    {}
113 
114    static Bif_F0_ZILDE * fun;   ///< Built-in function
115    static Bif_F0_ZILDE  _fun;   ///< Built-in function
116 
117    /// overladed Function::eval_()
118    virtual Token eval_();
119 
120 protected:
121    /// overladed Function::may_push_SI()
may_push_SI() const122    virtual bool may_push_SI() const   { return false; }
123 };
124 //-----------------------------------------------------------------------------
125 /** System function execute */
126 /// The class implementing ⍎
127 class Bif_F1_EXECUTE : public NonscalarFunction
128 {
129 public:
130    /// Constructor
Bif_F1_EXECUTE()131    Bif_F1_EXECUTE()
132    : NonscalarFunction(TOK_F1_EXECUTE)
133    {}
134 
135    static Bif_F1_EXECUTE * fun;   ///< Built-in function
136    static Bif_F1_EXECUTE  _fun;   ///< Built-in function
137 
138    /// execute string containing an APL expression or an APL command
139    static Token execute_statement(UCS_string & statement);
140 
141    /// execute string containing an APL command
142    static Token execute_command(UCS_string & command);
143 
144    /// overladed Function::eval_B()
145    virtual Token eval_B(Value_P B);
146 
147    /// the number of outstanding )COPYs with APL scipts
148    static int copy_pending;
149 
150 protected:
151    /// overladed Function::may_push_SI()
may_push_SI() const152    virtual bool may_push_SI() const   { return true; }
153 };
154 //-----------------------------------------------------------------------------
155 /** System function index (⌷) */
156 /// The class implementing ⌷
157 class Bif_F2_INDEX : public NonscalarFunction
158 {
159 public:
160    /// Constructor
Bif_F2_INDEX()161    Bif_F2_INDEX()
162    : NonscalarFunction(TOK_F2_INDEX)
163    {}
164 
165    /// overloaded Function::eval_AB()
166    virtual Token eval_AB(Value_P A, Value_P B);
167 
168    /// overloaded Function::eval_AXB()
169    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
170 
171    static Bif_F2_INDEX * fun;   ///< Built-in function
172    static Bif_F2_INDEX  _fun;   ///< Built-in function
173 protected:
174 };
175 //-----------------------------------------------------------------------------
176 /** primitive functions partition and enclose */
177 /// The class implementing ⊂
178 class Bif_F12_PARTITION : public NonscalarFunction
179 {
180 public:
181    /// Constructor
Bif_F12_PARTITION()182    Bif_F12_PARTITION()
183    : NonscalarFunction(TOK_F12_PARTITION)
184    {}
185 
186    /// overloaded Function::eval_B()
eval_B(Value_P B)187    virtual Token eval_B(Value_P B)
188       { return Token(TOK_APL_VALUE1, do_eval_B(B)); }
189 
190    /// implementation of eval_B()
191    Value_P do_eval_B(Value_P B);
192 
193    /// overloaded Function::eval_AB()
eval_AB(Value_P A,Value_P B)194    virtual Token eval_AB(Value_P A, Value_P B)
195       { return partition(A, B, B->get_rank() - 1); }
196 
197    /// overloaded Function::eval_XB()
eval_XB(Value_P X,Value_P B)198    virtual Token eval_XB(Value_P X, Value_P B)
199       { return Token(TOK_APL_VALUE1, do_eval_XB(X, B)); }
200 
201    /// implementation of eval_XB()
202    Value_P do_eval_XB(Value_P X, Value_P B);
203 
204    /// overloaded Function::eval_AXB()
205    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
206 
207    static Bif_F12_PARTITION * fun;   ///< Built-in function
208    static Bif_F12_PARTITION  _fun;   ///< Built-in function
209 
210    /// enclose_with_axes
211    static Value_P enclose_with_axes(const Shape & shape_X, Value_P B);
212 
213 protected:
214    /// enclose B
215    Token enclose(Value_P B);
216 
217    /// enclose B
218    Token enclose_with_axis(Value_P B, Value_P X);
219 
220    /// Partition B according to A
221    Token partition(Value_P A, Value_P B, Axis axis);
222 
223    /// Copy one partition to dest
224    static void copy_segment(Cell * dest, Value & dest_owner, ShapeItem h,
225                             ShapeItem from, ShapeItem to,
226                             ShapeItem m_len, ShapeItem l, ShapeItem len_l,
227                             Value_P B);
228 };
229 //-----------------------------------------------------------------------------
230 /** primitive functions pick and disclose */
231 /// The class implementing ⊃
232 class Bif_F12_PICK : public NonscalarFunction
233 {
234 public:
235    /// Constructor
Bif_F12_PICK()236    Bif_F12_PICK()
237    : NonscalarFunction(TOK_F12_PICK)
238    {}
239 
240    /// overloaded Function::eval_AB()
241    virtual Token eval_AB(Value_P A, Value_P B);
242 
243    /// overloaded Function::eval_B()
eval_B(Value_P B)244    virtual Token eval_B(Value_P B)
245       { return disclose(B, false); }
246 
247    /// ⊃B
248    static Token disclose(Value_P B, bool rank_tolerant);
249 
250    /// overloaded Function::eval_XB()
eval_XB(Value_P X,Value_P B)251    virtual Token eval_XB(Value_P X, Value_P B)
252       { const Shape axes_X = Value::to_shape(X.get());
253         return disclose_with_axis(axes_X, B, false); }
254 
255    /// ⊃[X]B
256    static Token disclose_with_axis(const Shape & axes_X, Value_P B,
257                                    bool rank_tolerant);
258 
259    static Bif_F12_PICK * fun;   ///< Built-in function
260    static Bif_F12_PICK  _fun;   ///< Built-in function
261 
262 protected:
263    /// the shape of the items being disclosed
264    static Shape compute_item_shape(Value_P B, bool rank_tolerant);
265 
266    /// Pick from B according to cA and len_A. \b cell_owner is non-zero
267    /// if a left-vlues is picked, (e.g (2 1⊃B)←'TR')
268    static Value_P pick(const Cell * cA, ShapeItem len_A, Value_P B,
269                        APL_Integer qio, Value * cell_owner);
270 };
271 //-----------------------------------------------------------------------------
272 /** Comma related functions (catenate, laminate, and ravel.) */
273 /// Base class for , and ⍪
274 class Bif_COMMA : public NonscalarFunction
275 {
276 public:
277    /// Constructor
Bif_COMMA(TokenTag tag)278    Bif_COMMA(TokenTag tag)
279    : NonscalarFunction(tag)
280    {}
281 
282    /// ravel along axis, with axis being the first (⍪( or last (,) axis of B
283    Token ravel_axis(Value_P X, Value_P B, uAxis axis);
284 
285    /// Return the ravel of B as APL value
286    static Token ravel(const Shape & new_shape, Value_P B);
287 
288    /// Catenate A and B
289    static Token catenate(Value_P A, Axis axis, Value_P B);
290 
291    /// Laminate A and B
292    static Token laminate(Value_P A, Axis axis, Value_P B);
293 
294    /// Prepend scalar cell_A to B along axis
295    static Value_P prepend_scalar(const Cell & cell_A, uAxis axis, Value_P B);
296 
297    /// Prepend scalar cell_B to A along axis
298    static Value_P append_scalar(Value_P A, uAxis axis, const Cell & cell_B);
299 };
300 //-----------------------------------------------------------------------------
301 /** primitive functions catenate, laminate, and ravel along last axis */
302 /// The class implementing ,
303 class Bif_F12_COMMA : public Bif_COMMA
304 {
305 public:
306    /// Constructor
Bif_F12_COMMA()307    Bif_F12_COMMA()
308    : Bif_COMMA(TOK_F12_COMMA)
309    {}
310 
311    /// overloaded Function::eval_B()
312    virtual Token eval_B(Value_P B);
313 
314    /// overloaded Function::eval_AB()
315    virtual Token eval_AB(Value_P A, Value_P B);
316 
317    /// overloaded Function::eval_XB()
eval_XB(Value_P X,Value_P B)318    virtual Token eval_XB(Value_P X, Value_P B)
319       { return ravel_axis(X, B, B->get_rank()); }
320 
321    /// overloaded Function::eval_AXB()
322    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
323 
324    static Bif_F12_COMMA * fun;   ///< Built-in function
325    static Bif_F12_COMMA  _fun;   ///< Built-in function
326 
327 protected:
328 };
329 //-----------------------------------------------------------------------------
330 /** primitive functions catenate and laminate along first axis, table */
331 /// The class implementing ⍪
332 class Bif_F12_COMMA1 : public Bif_COMMA
333 {
334 public:
335    /// Constructor
Bif_F12_COMMA1()336    Bif_F12_COMMA1()
337    : Bif_COMMA(TOK_F12_COMMA1)
338    {}
339 
340    /// overloaded Function::eval_B()
341    virtual Token eval_B(Value_P B);
342 
343    /// overloaded Function::eval_AB()
344    virtual Token eval_AB(Value_P A, Value_P B);
345 
346    /// overloaded Function::eval_XB()
eval_XB(Value_P X,Value_P B)347    virtual Token eval_XB(Value_P X, Value_P B)
348       { return ravel_axis(X, B, 0); }
349 
350    /// overloaded Function::eval_AXB()
351    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
352 
353    static Bif_F12_COMMA1 * fun;   ///< Built-in function
354    static Bif_F12_COMMA1  _fun;   ///< Built-in function
355 protected:
356 };
357 //-----------------------------------------------------------------------------
358 /** primitive functions member and enlist */
359 /// The class implementing ∈
360 class Bif_F12_ELEMENT : public NonscalarFunction
361 {
362 public:
363    /// Constructor
Bif_F12_ELEMENT()364    Bif_F12_ELEMENT()
365    : NonscalarFunction(TOK_F12_ELEMENT)
366    {}
367 
368    /// overloaded Function::eval_B()
369    virtual Token eval_B(Value_P B);
370 
371    /// overloaded Function::eval_AB()
372    virtual Token eval_AB(Value_P A, Value_P B);
373 
374    static Bif_F12_ELEMENT * fun;   ///< Built-in function
375    static Bif_F12_ELEMENT  _fun;   ///< Built-in function
376 protected:
377 };
378 //-----------------------------------------------------------------------------
379 /** primitive functions match and depth */
380 /// The class implementing ≡
381 class Bif_F12_EQUIV : public NonscalarFunction
382 {
383 public:
384    /// Constructor
Bif_F12_EQUIV()385    Bif_F12_EQUIV()
386    : NonscalarFunction(TOK_F12_EQUIV)
387    {}
388 
389    /// overloaded Function::eval_B()
390    virtual Token eval_B(Value_P B);
391 
392    /// overloaded Function::eval_AB()
393    virtual Token eval_AB(Value_P A, Value_P B);
394 
395    static Bif_F12_EQUIV * fun;   ///< Built-in function
396    static Bif_F12_EQUIV  _fun;   ///< Built-in function
397 
398 protected:
399    /// return the depth of B
400    Token depth(Value_P B);
401 };
402 //-----------------------------------------------------------------------------
403 /** primitive function natch (≢) */
404 /// The class implementing ≡
405 class Bif_F12_NEQUIV : public NonscalarFunction
406 {
407 public:
408    /// Constructor
Bif_F12_NEQUIV()409    Bif_F12_NEQUIV()
410    : NonscalarFunction(TOK_F12_NEQUIV)
411    {}
412 
413    /// overloaded Function::eval_B()
414    virtual Token eval_B(Value_P B);
415 
416    /// overloaded Function::eval_AB()
417    virtual Token eval_AB(Value_P A, Value_P B);
418 
419    static Bif_F12_NEQUIV * fun;   ///< Built-in function
420    static Bif_F12_NEQUIV  _fun;   ///< Built-in function
421 };
422 //-----------------------------------------------------------------------------
423 /** System function encode */
424 /// The class implementing ⊤
425 class Bif_F12_ENCODE : public NonscalarFunction
426 {
427 public:
428    /// Constructor
Bif_F12_ENCODE()429    Bif_F12_ENCODE()
430    : NonscalarFunction(TOK_F12_ENCODE)
431    {}
432 
433    /// overloaded Function::eval_AB()
434    virtual Token eval_AB(Value_P A, Value_P B);
435 
436    static Bif_F12_ENCODE * fun;   ///< Built-in function
437    static Bif_F12_ENCODE  _fun;   ///< Built-in function
438 protected:
439    /// encode b according to A (integer A and b)
440    void encode(ShapeItem dZ, Cell * cZ, ShapeItem ah, ShapeItem al,
441                const Cell * cA, APL_Integer b);
442 
443    /// encode b according to A
444    void encode(ShapeItem dZ, Cell * cZ, ShapeItem ah, ShapeItem al,
445                const Cell * cA, APL_Float b, double qct);
446 
447    /// encode B according to A
448    void encode(ShapeItem dZ, Cell * cZ, ShapeItem ah, ShapeItem al,
449                const Cell * cA, APL_Complex b, double qct);
450 };
451 //-----------------------------------------------------------------------------
452 /** System function decode */
453 /// The class implementing ⊥
454 class Bif_F12_DECODE : public NonscalarFunction
455 {
456 public:
457    /// Constructor
Bif_F12_DECODE()458    Bif_F12_DECODE()
459    : NonscalarFunction(TOK_F12_DECODE)
460    {}
461 
462    /// overloaded Function::eval_AB()
463    virtual Token eval_AB(Value_P A, Value_P B);
464 
465    static Bif_F12_DECODE * fun;   ///< Built-in function
466    static Bif_F12_DECODE  _fun;   ///< Built-in function
467 protected:
468    /// decode B according to len_A and cA (integer A, B and Z)
469    bool decode_int(Cell * cZ, ShapeItem len_A, const Cell * cA,
470                    ShapeItem len_B, const Cell * cB, ShapeItem dB);
471 
472    /// decode B according to len_A and cA (real A and B)
473    void decode_real(Cell * cZ, ShapeItem len_A, const Cell * cA,
474                     ShapeItem len_B, const Cell * cB, ShapeItem dB,
475                     double qct);
476 
477    /// decode B according to len_A and cA (complex A or B)
478    void decode_complex(Cell * cZ, ShapeItem len_A, const Cell * cA,
479                        ShapeItem len_B, const Cell * cB, ShapeItem dB,
480                        double qct);
481 };
482 //-----------------------------------------------------------------------------
483 /** primitive functions matrix divide and matrix invert */
484 /// The class implementing ⌹
485 class Bif_F12_DOMINO : public NonscalarFunction
486 {
487 public:
488    /// Constructor
Bif_F12_DOMINO()489    Bif_F12_DOMINO()
490    : NonscalarFunction(TOK_F12_DOMINO)
491    {}
492 
493    /// overloaded Function::eval_B()
494    virtual Token eval_B(Value_P B);
495 
496    /// overloaded Function::eval_AB()
497    virtual Token eval_AB(Value_P A, Value_P B);
498 
499    static Bif_F12_DOMINO * fun;   ///< Built-in function
500    static Bif_F12_DOMINO  _fun;   ///< Built-in function
501 
502    /// overloaded Function::eval_fill_B()
503    virtual Token eval_fill_B(Value_P B);
504 
505    /// overloaded Function::eval_fill_AB()
506    virtual Token eval_fill_AB(Value_P A, Value_P B);
507 
508 protected:
509    /// Invert matrix B
510    Token matrix_inverse(Value_P B);
511 
512    /// Divide matrix A by matrix B
513    Token matrix_divide(Value_P A, Value_P B);
514 };
515 //-----------------------------------------------------------------------------
516 /** primitive functions rotate and reverse */
517 /// Base class for implementing ⌽ and ⊖
518 class Bif_ROTATE : public NonscalarFunction
519 {
520 public:
521    /// Constructor.
Bif_ROTATE(TokenTag tag)522    Bif_ROTATE(TokenTag tag)
523    : NonscalarFunction(tag)
524    {}
525 
526 protected:
527    /// Rotate B according to A along axis
528    static Token rotate(Value_P A, Value_P B, Axis axis);
529 
530    /// Reverse B along axis
531    static Token reverse(Value_P B, Axis axis);
532 };
533 //-----------------------------------------------------------------------------
534 /** primitive functions rotate and reverse along last axis */
535 /// The class implementing ⌽
536 class Bif_F12_ROTATE : public Bif_ROTATE
537 {
538 public:
539    /// Constructor
Bif_F12_ROTATE()540    Bif_F12_ROTATE()
541    : Bif_ROTATE(TOK_F12_ROTATE)
542    {}
543 
544    /// overloaded Function::eval_B()
eval_B(Value_P B)545    virtual Token eval_B(Value_P B)
546       { return reverse(B, B->get_rank() - 1); }
547 
548    /// overloaded Function::eval_AB()
eval_AB(Value_P A,Value_P B)549    virtual Token eval_AB(Value_P A, Value_P B)
550       { return rotate(A, B, B->get_rank() - 1); }
551 
552    /// overloaded Function::eval_XB()
553    virtual Token eval_XB(Value_P X, Value_P B);
554 
555    /// overloaded Function::eval_AXB()
556    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
557 
558    static Bif_F12_ROTATE * fun;   ///< Built-in function
559    static Bif_F12_ROTATE  _fun;   ///< Built-in function
560 protected:
561 };
562 //-----------------------------------------------------------------------------
563 /** primitive functions rotate and reverse along first axis */
564 /// The class implementing ⊖
565 class Bif_F12_ROTATE1 : public Bif_ROTATE
566 {
567 public:
568    /// Constructor
Bif_F12_ROTATE1()569    Bif_F12_ROTATE1()
570    : Bif_ROTATE(TOK_F12_ROTATE1)
571    {}
572 
573    /// overloaded Function::eval_B()
eval_B(Value_P B)574    virtual Token eval_B(Value_P B)
575       { return reverse(B, 0); }
576 
577    /// overloaded Function::eval_AB()
eval_AB(Value_P A,Value_P B)578    virtual Token eval_AB(Value_P A, Value_P B)
579       { return rotate(A, B, 0); }
580 
581    /// overloaded Function::eval_XB()
582    virtual Token eval_XB(Value_P X, Value_P B);
583 
584    /// overloaded Function::eval_AXB()
585    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
586 
587    static Bif_F12_ROTATE1 * fun;   ///< Built-in function
588    static Bif_F12_ROTATE1  _fun;   ///< Built-in function
589 protected:
590 };
591 //-----------------------------------------------------------------------------
592 /** System function transpose */
593 /// The class implementing ⍉
594 class Bif_F12_TRANSPOSE : public NonscalarFunction
595 {
596 public:
597    /// Constructor
Bif_F12_TRANSPOSE()598    Bif_F12_TRANSPOSE()
599    : NonscalarFunction(TOK_F12_TRANSPOSE)
600    {}
601 
602    /// overloaded Function::eval_B()
603    virtual Token eval_B(Value_P B);
604 
605    /// overloaded Function::eval_AB()
606    virtual Token eval_AB(Value_P A, Value_P B);
607 
608    static Bif_F12_TRANSPOSE * fun;   ///< Built-in function
609    static Bif_F12_TRANSPOSE  _fun;   ///< Built-in function
610 
611 protected:
612    /// Transpose B according to A (without diagonals)
613    Value_P transpose(const Shape & A, Value_P B);
614 
615    /// Transpose B according to A (with diagonals)
616    Value_P transpose_diag(const Shape & A, Value_P B);
617 
618    /// for \b sh being a permutation of 0, 1, ... rank - 1,
619    /// return the inverse permutation sh⁻¹
620    static Shape inverse_permutation(const Shape & sh);
621 
622    /// return sh permuted according to permutation perm
623    static Shape permute(const Shape & sh, const Shape & perm);
624 
625    /// return true iff sh is a permutation
626    static bool is_permutation(const Shape & sh);
627 };
628 //-----------------------------------------------------------------------------
629 /** System function index of (⍳) */
630 /// The class implementing ⍳
631 class Bif_F12_INDEX_OF : public NonscalarFunction
632 {
633 public:
634    /// Constructor
Bif_F12_INDEX_OF()635    Bif_F12_INDEX_OF()
636    : NonscalarFunction(TOK_F12_INDEX_OF)
637    {}
638 
639    /// overloaded Function::eval_B()
640    virtual Token eval_B(Value_P B);
641 
642    /// overloaded Function::eval_AB()
643    virtual Token eval_AB(Value_P A, Value_P B);
644 
645    static Bif_F12_INDEX_OF * fun;   ///< Built-in function
646    static Bif_F12_INDEX_OF  _fun;   ///< Built-in function
647 
648 protected:
649 };
650 //-----------------------------------------------------------------------------
651 /** primitive functions reshape and shape */
652 /// The class implementing ⍴
653 class Bif_F12_RHO : public NonscalarFunction
654 {
655 public:
656    /// Constructor
Bif_F12_RHO()657    Bif_F12_RHO()
658    : NonscalarFunction(TOK_F12_RHO)
659    {}
660 
661    /// overloaded Function::eval_B()
662    virtual Token eval_B(Value_P B);
663 
664    /// overloaded Function::eval_AB()
665    virtual Token eval_AB(Value_P A, Value_P B);
666 
667    /// Reshape B according to rank and shape
668    static Token do_reshape(const Shape & shape, const Value & B);
669 
670    static Bif_F12_RHO * fun;   ///< Built-in function
671    static Bif_F12_RHO  _fun;   ///< Built-in function
672 protected:
673 };
674 //-----------------------------------------------------------------------------
675 /** System function ∪ (unique/union) */
676 /// The class implementing ∪
677 class Bif_F12_UNION : public NonscalarFunction
678 {
679 public:
680    /// Constructor
Bif_F12_UNION()681    Bif_F12_UNION()
682    : NonscalarFunction(TOK_F12_UNION)
683    {}
684 
685    /// overloaded Function::eval_AB()
686    virtual Token eval_AB(Value_P A, Value_P B);
687 
688    /// overloaded Function::eval_B()
689    virtual Token eval_B(Value_P B);
690 
691    /// pointer to _fun
692    static Bif_F12_UNION * fun;
693 
694    /// Built-in function
695    static Bif_F12_UNION  _fun;
696 
697 protected:
698    /// return \b true iff \b cell is different from all \b others within \b qct
is_unique(const Cell & cell,std::vector<const Cell * > & others,double qct)699    static bool is_unique(const Cell & cell,
700                          std::vector<const Cell *> & others, double qct)
701       { loop(z, others.size())
702             { if (others[z]->equal(cell, qct))  return false; }
703         return true;
704       }
705 };
706 //-----------------------------------------------------------------------------
707 /** System function ∩ (intersection) */
708 /// The class implementing ∩
709 class Bif_F2_INTER : public NonscalarFunction
710 {
711 public:
712    /// Constructor
Bif_F2_INTER()713    Bif_F2_INTER()
714    : NonscalarFunction(TOK_F2_INTER)
715    {}
716 
717    /// overloaded Function::eval_AB()
718    virtual Token eval_AB(Value_P A, Value_P B);
719 
720    static Bif_F2_INTER  _fun;   ///< Built-in function
721    static Bif_F2_INTER * fun;   ///< pointer to _fun
722 
723 protected:
724 };
725 //-----------------------------------------------------------------------------
726 /** System function left (⊣) */
727 /// The class implementing ⊣
728 class Bif_F2_LEFT : public NonscalarFunction
729 {
730 public:
731    /// Constructor
Bif_F2_LEFT()732    Bif_F2_LEFT()
733    : NonscalarFunction(TOK_F2_LEFT)
734    {}
735 
736    /// overloaded Function::eval_B()
eval_B(Value_P B)737    virtual Token eval_B(Value_P B)
738       { return Token(TOK_APL_VALUE2, IntScalar(0, LOC)); }
739 
740    /// overloaded Function::eval_AB()
eval_AB(Value_P A,Value_P B)741    virtual Token eval_AB(Value_P A, Value_P B)
742       { return Token(TOK_APL_VALUE1, A->clone(LOC)); }
743 
744    static Bif_F2_LEFT * fun;   ///< Built-in function
745    static Bif_F2_LEFT  _fun;   ///< Built-in function
746 protected:
747 };
748 //-----------------------------------------------------------------------------
749 /** System function right (⊢) */
750 /// The class implementing ⊢
751 class Bif_F2_RIGHT : public NonscalarFunction
752 {
753 public:
754    /// Constructor
Bif_F2_RIGHT()755    Bif_F2_RIGHT()
756    : NonscalarFunction(TOK_F2_RIGHT)
757    {}
758 
759    /// overloaded Function::eval_B()
eval_B(Value_P B)760    virtual Token eval_B(Value_P B)
761       { return Token(TOK_APL_VALUE1, B->clone(LOC)); }
762 
763    /// overloaded Function::eval_AB()
eval_AB(Value_P A,Value_P B)764    virtual Token eval_AB(Value_P A, Value_P B)
765       { return Token(TOK_APL_VALUE1, B->clone(LOC)); }
766 
767    /// overloaded Function::eval_AXB()
768    virtual Token eval_AXB(Value_P A, Value_P X, Value_P B);
769 
770    static Bif_F2_RIGHT * fun;   ///< Built-in function
771    static Bif_F2_RIGHT  _fun;   ///< Built-in function
772 protected:
773 };
774 //-----------------------------------------------------------------------------
775 
776 #endif // __PRIMITIVE_FUNCTION_HH_DEFINED__
777