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