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-2015 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 __SYSTEM_VARIABLE_HH_DEFINED__ 22 #define __SYSTEM_VARIABLE_HH_DEFINED__ 23 24 #include "Id.hh" 25 #include "Parallel.hh" 26 #include "Symbol.hh" 27 28 #include <sys/time.h> 29 30 //----------------------------------------------------------------------------- 31 /** 32 Base class for all system variables (Quad variables). 33 */ 34 /// Base class for all APL system variables 35 class SystemVariable : public Symbol 36 { 37 public: 38 /// Construct a \b SystemVariable with \b Id \b id SystemVariable(Id id)39 SystemVariable(Id id) 40 : Symbol(id) 41 {} 42 43 /// return the TokenTag for this system variable get_token()44 Token get_token() 45 { return Token(TokenTag(ID::get_token_tag(get_Id())), this); } 46 47 /// overloaded Symbol::print(). 48 virtual ostream & print(ostream & out) const; 49 50 /// overloaded Symbol::assign(). 51 virtual void assign(Value_P value, bool clone, const char * loc); 52 53 /// overloaded Symbol::assign_indexed(). 54 virtual void assign_indexed(Value_P X, Value_P value); 55 56 /// overloaded Symbol::get_attributes(). 57 virtual void get_attributes(int mode, Cell * dest) const; 58 59 /// system vars cannot be expunged. expunge()60 virtual int expunge() { return 0; } 61 62 /// do not allow (...⎕xxx)←... resolve_lv(const char * loc)63 virtual Token resolve_lv(const char * loc) 64 { SYNTAX_ERROR; } 65 }; 66 //----------------------------------------------------------------------------- 67 /** 68 A system variable that cannot be localized (push and pop have no effect). 69 */ 70 /// Base class for all APL system variables that cannot be localized 71 class NL_SystemVariable : public SystemVariable 72 { 73 public: 74 public: 75 /// Constructor. NL_SystemVariable(Id id)76 NL_SystemVariable(Id id) 77 : SystemVariable(id) 78 {} 79 protected: 80 /// overloaded Symbol::push() push()81 virtual void push() {} 82 83 /// overloaded Symbol::push_label() push_label(Function_Line label)84 virtual void push_label(Function_Line label) {} 85 86 /// overloaded Symbol::push_function() push_function(Function * function)87 virtual void push_function(Function * function) {} 88 89 /// overloaded Symbol::push_value() push_value(Value_P value)90 virtual void push_value(Value_P value) {} 91 92 /// overloaded Symbol::pop() pop()93 virtual void pop() { } 94 }; 95 //----------------------------------------------------------------------------- 96 /** 97 A read-only system variable (push, pop, and assign are ignored). 98 */ 99 /// Base class for all read-only APL system variables 100 class RO_SystemVariable : public NL_SystemVariable 101 { 102 public: 103 /// Constructor. RO_SystemVariable(Id id)104 RO_SystemVariable(Id id) 105 : NL_SystemVariable(id) 106 {} 107 108 protected: 109 /// overloaded Symbol::assign() assign(Value_P value,bool clone,const char * loc)110 virtual void assign(Value_P value, bool clone, const char * loc) {} 111 112 /// overloaded Symbol::assign_indexed() assign_indexed(Value_P X,Value_P value)113 virtual void assign_indexed(Value_P X, Value_P value) {} 114 115 /// overloaded Symbol::is_readonly() is_readonly() const116 virtual bool is_readonly() const { return true; } 117 118 /// overloaded Symbol::resolve(). Since push(), pop(), and assign() 119 /// do nothing, we can call get_apl_value() directly. resolve(Token & token,bool left)120 virtual void resolve(Token & token, bool left) 121 { if (!left) new (&token) Token(TOK_APL_VALUE1, get_apl_value()); } 122 }; 123 //----------------------------------------------------------------------------- 124 /** 125 System variable Quad-AI (Account Information) 126 */ 127 /// The class implementing ⎕AI 128 class Quad_AI : public RO_SystemVariable 129 { 130 public: 131 /// Constructor. 132 Quad_AI(); 133 134 /// increase the time waiting for user input add_wait(APL_time_us diff)135 void add_wait(APL_time_us diff) 136 { user_wait += diff; } 137 138 protected: 139 /// when the interpreter was started 140 const APL_time_us session_start; 141 142 /// time waiting for user input. 143 APL_time_us user_wait; 144 145 /// overloaded Symbol::get_apl_value(). 146 virtual Value_P get_apl_value() const; 147 }; 148 //----------------------------------------------------------------------------- 149 /** 150 System variable Quad-ARG (command line arguments of the interpreter) 151 */ 152 /// The class implementing ⎕ARG 153 class Quad_ARG : public RO_SystemVariable 154 { 155 public: 156 /// Constructor. 157 Quad_ARG(); 158 159 protected: 160 /// overloaded Symbol::get_apl_value() 161 virtual Value_P get_apl_value() const; 162 }; 163 //----------------------------------------------------------------------------- 164 /** 165 System variable Quad-AV (Atomic Vector) 166 */ 167 /// The class implementing ⎕AV 168 class Quad_AV : public RO_SystemVariable 169 { 170 public: 171 /// Constructor. 172 Quad_AV(); 173 174 /// return ⎕AV[pos - ⎕IO] 175 static Unicode indexed_at(uint32_t pos); 176 177 /// a static ⎕AV 178 static Unicode qav[MAX_AV]; 179 }; 180 //----------------------------------------------------------------------------- 181 /** 182 System variable Quad-CT (Comparison Tolerance) 183 */ 184 /// The class implementing ⎕CT 185 class Quad_CT : public SystemVariable 186 { 187 public: 188 /// constructor 189 Quad_CT(); 190 191 /// return the current comparison tolerance. MUST NOT CALL get_apl_value() 192 /// because it can be called from parallel Cell functions current() const193 APL_Float current() const 194 { return get_first_cell()->get_real_value(); } 195 196 protected: 197 /// overloaded Symbol::assign() 198 virtual void assign(Value_P value, bool clone, const char * loc); 199 200 // overloaded Symbol::push() push()201 virtual void push() 202 { 203 Symbol::push(); 204 Symbol::assign(FloatScalar(DEFAULT_Quad_CT, LOC), false, LOC); 205 } 206 }; 207 //----------------------------------------------------------------------------- 208 /** 209 System variable Quad-EM (Event Message) 210 */ 211 /// The class implementing ⎕EM 212 class Quad_EM : public RO_SystemVariable 213 { 214 public: 215 /// Constructor. Quad_EM()216 Quad_EM() 217 : RO_SystemVariable(ID_Quad_EM) 218 {} 219 220 protected: 221 /// overloaded Symbol::get_apl_value() 222 virtual Value_P get_apl_value() const; 223 }; 224 //----------------------------------------------------------------------------- 225 /** 226 System variable Quad-ET (Event Type). 227 */ 228 /// The class implementing ⎕ET 229 class Quad_ET : public RO_SystemVariable 230 { 231 public: 232 /// Constructor. Quad_ET()233 Quad_ET() : RO_SystemVariable(ID_Quad_ET) 234 {} 235 236 protected: 237 /// overloaded Symbol::get_apl_value(). 238 virtual Value_P get_apl_value() const; 239 }; 240 //----------------------------------------------------------------------------- 241 /** 242 System variable Quad-FC (Format Control). 243 */ 244 /// The class implementing ⎕FC 245 class Quad_FC : public SystemVariable 246 { 247 public: 248 /// Constructor. 249 Quad_FC(); 250 251 /// return the current format control (used by Workspace::get_FC()) current() const252 const UCS_string current() const 253 { return UCS_string(*get_apl_value()); } 254 255 protected: 256 /// overloaded Symbol::assign(). 257 virtual void assign(Value_P value, bool clone, const char * loc); 258 259 /// overloaded Symbol::assign_indexed(). 260 virtual void assign_indexed(Value_P X, Value_P value); 261 262 /// overloaded Symbol::assign_indexed(). 263 virtual void assign_indexed(IndexExpr & IX, Value_P value); 264 265 // overloaded Symbol::push() 266 virtual void push(); 267 }; 268 //----------------------------------------------------------------------------- 269 /** 270 System variable Quad-IO (Index Origin). 271 */ 272 /// The class implementing ⎕IO 273 class Quad_IO : public SystemVariable 274 { 275 public: 276 /// Constructor. 277 Quad_IO(); 278 279 /// Return the current index origin. MUST NOT CALL get_apl_value() 280 /// because it can be called from parallel Cell functions current() const281 APL_Integer current() const 282 { return get_first_cell()->get_int_value(); } 283 284 protected: 285 /// overloaded Symbol::assign(). 286 virtual void assign(Value_P value, bool clone, const char * loc); 287 288 // overloaded Symbol::push() push()289 virtual void push() 290 { 291 Symbol::push(); 292 Symbol::assign(IntScalar(1, LOC), false, LOC); 293 } 294 }; 295 //----------------------------------------------------------------------------- 296 /** 297 System variable Quad-L (Left Argument). 298 */ 299 /// The class implementing ⎕L 300 class Quad_L : public NL_SystemVariable 301 { 302 public: 303 /// Constructor. 304 Quad_L(); 305 306 /// overloaded Symbol::save() save(ostream & out) const307 virtual void save(ostream & out) const {} 308 309 protected: 310 /// overloaded Symbol::assign() 311 virtual void assign(Value_P value, bool clone, const char * loc); 312 313 /// overloaded Symbol::get_apl_value(). 314 virtual Value_P get_apl_value() const; 315 }; 316 //----------------------------------------------------------------------------- 317 /** 318 System variable Quad-LC (Line Counter). 319 */ 320 /// The class implementing ⎕LC 321 class Quad_LC : public RO_SystemVariable 322 { 323 public: 324 /// Constructor. 325 Quad_LC(); 326 327 protected: 328 /// overloaded Symbol::get_apl_value(). 329 virtual Value_P get_apl_value() const; 330 }; 331 //----------------------------------------------------------------------------- 332 /** 333 System variable Quad-LX (Latent Expression). 334 */ 335 /// The class implementing ⎕LX 336 class Quad_LX : public NL_SystemVariable 337 { 338 public: 339 /// Constructor. 340 Quad_LX(); 341 342 protected: 343 /// overloaded Symbol::assign(). 344 virtual void assign(Value_P value, bool clone, const char * loc); 345 346 /// overloaded Symbol::assign_indexed() assign_indexed(Value_P X,Value_P value)347 virtual void assign_indexed(Value_P X, Value_P value) {} 348 349 }; 350 //----------------------------------------------------------------------------- 351 /** 352 System variable Quad-PP (Printing Precision). 353 */ 354 /// The class implementing ⎕PP 355 class Quad_PP : public SystemVariable 356 { 357 public: 358 /// Constructor. 359 Quad_PP(); 360 361 /// Return the current print precision. MUST NOT CALL get_apl_value() 362 /// because it can be called from parallel Cell functions current() const363 APL_Integer current() const 364 { return get_first_cell()->get_int_value(); } 365 366 protected: 367 /// overloaded Symbol::assign(). 368 virtual void assign(Value_P value, bool clone, const char * loc); 369 370 // overloaded Symbol::push() push()371 virtual void push() 372 { 373 Symbol::push(); 374 Symbol::assign(IntScalar(DEFAULT_Quad_PP, LOC), false, LOC); 375 } 376 }; 377 //----------------------------------------------------------------------------- 378 /** 379 System variable Quad-PR (Prompt Replacement). 380 */ 381 /// The class implementing ⎕PR 382 class Quad_PR : public SystemVariable 383 { 384 public: 385 /// Constructor. 386 Quad_PR(); 387 388 /// Return the current prompt replacement. current() const389 const UCS_string current() const 390 { return UCS_string(*get_apl_value()); } 391 392 protected: 393 /// overloaded Symbol::assign(). 394 virtual void assign(Value_P value, bool clone, const char * loc); 395 396 // overloaded Symbol::push() push()397 virtual void push() 398 { 399 Symbol::push(); 400 Symbol::assign(CharScalar(UNI_ASCII_SPACE, LOC), false, LOC); 401 } 402 }; 403 //----------------------------------------------------------------------------- 404 /** 405 System variable Quad-PS (Print Style). This variable controls the formatting 406 of APL values (classical APL or DISPLAY style). 407 */ 408 /// The class implementing ⎕PS 409 class Quad_PS : public SystemVariable 410 { 411 public: 412 /// Constructor. 413 Quad_PS(); 414 415 /// Return the current print style. MUST NOT CALL get_apl_value() 416 /// because it can be called from parallel Cell functions current() const417 PrintStyle current() const 418 { switch (style) 419 { 420 case 0: return PR_APL; 421 case 1: return PR_APL_FUN; 422 case 2: return PR_BOXED_CHAR; 423 case 3: return PR_BOXED_GRAPHIC; 424 default: return PST_NONE; 425 } 426 } 427 428 /// return the quotient print style get_print_quotients() const429 bool get_print_quotients() const 430 { return print_quotients; } 431 432 protected: 433 /// overloaded Symbol::assign(). 434 virtual void assign(Value_P value, bool clone, const char * loc); 435 436 /// overloaded Symbol::assign_indexed() 437 virtual void assign_indexed(Value_P X, Value_P value); 438 439 /// overloaded Symbol::push() push()440 virtual void push() 441 { 442 Symbol::push(); 443 Symbol::assign(IntScalar(0, LOC), false, LOC); 444 } 445 446 /// true if quotients shall be printed as A÷B 447 bool print_quotients; 448 449 /// the current style 450 int style; 451 }; 452 //----------------------------------------------------------------------------- 453 /** 454 System variable Quad-PW (Print Width). 455 */ 456 /// The class implementing ⎕PW 457 class Quad_PW : public SystemVariable 458 { 459 public: 460 /// Constructor. 461 Quad_PW(); 462 463 /// return the current ⎕PW. MUST NOT CALL get_apl_value() 464 /// because it can be called from parallel Cell functions current() const465 APL_Integer current() const 466 { return get_first_cell()->get_int_value(); } 467 468 /// overloaded Symbol::assign(). 469 virtual void assign(Value_P value, bool clone, const char * loc); 470 471 protected: 472 // overloaded Symbol::push() push()473 virtual void push() 474 { 475 Symbol::push(); 476 Symbol::assign(IntScalar(DEFAULT_Quad_PW, LOC), false, LOC); 477 } 478 }; 479 //----------------------------------------------------------------------------- 480 /** 481 System variable Quad-Quad (Evaluated Input/Output). 482 */ 483 /// The class implementing ⎕ 484 class Quad_Quad : public SystemVariable 485 { 486 public: 487 /// Constructor. 488 Quad_Quad(); 489 490 /// overloaded Symbol::resolve(). 491 virtual void resolve(Token & token, bool left); 492 493 protected: 494 virtual void assign(Value_P value, bool clone, const char * loc); 495 496 // should never be called due to overloaded resolve() get_apl_value() const497 virtual Value_P get_apl_value() const 498 { Assert(0); /* not reached */ return Value_P(); } 499 }; 500 //----------------------------------------------------------------------------- 501 /** 502 System variable Quote-Quad (Evaluated Input/Output). 503 */ 504 /// The class implementing ⍞ 505 class Quad_QUOTE : public SystemVariable 506 { 507 public: 508 /// Constructor. 509 Quad_QUOTE(); 510 511 /// end of ⍞ (output, but no input: clear prompt) 512 static void done(bool with_LF, const char * loc); 513 514 protected: 515 /// overloaded Symbol::assign(). 516 virtual void assign(Value_P value, bool clone, const char * loc); 517 518 /// overloaded Symbol::get_apl_value(). 519 virtual Value_P get_apl_value() const; 520 521 /// last line of output 522 static UCS_string prompt; 523 }; 524 //----------------------------------------------------------------------------- 525 /** 526 System variable Quad-R (Right Argment). 527 */ 528 /// The class implementing ⎕R 529 class Quad_R : public NL_SystemVariable 530 { 531 public: 532 /// Constructor. 533 Quad_R(); 534 535 /// overloaded Symbol::save() save(ostream & out) const536 virtual void save(ostream & out) const {} 537 538 protected: 539 /// overloaded Symbol::assign() 540 virtual void assign(Value_P value, bool clone, const char * loc); 541 542 /// overloaded Symbol::get_apl_value(). 543 virtual Value_P get_apl_value() const; 544 }; 545 //----------------------------------------------------------------------------- 546 /** 547 System variable Quad-SYL (System Limits). 548 */ 549 /// The class implementing ⎕SYL 550 class Quad_SYL : public NL_SystemVariable 551 { 552 public: 553 /// Constructor. Quad_SYL()554 Quad_SYL() : NL_SystemVariable(ID_Quad_SYL) 555 { assign(Value_P(), false, LOC); } 556 557 /// overloaded Symbol::assign() 558 virtual void assign(Value_P value, bool clone, const char * loc); 559 560 /// overloaded Symbol::assign_indexed() 561 virtual void assign_indexed(Value_P X, Value_P value); 562 563 /// overloaded Symbol::assign_indexed() 564 virtual void assign_indexed(IndexExpr & IDX, Value_P value); 565 566 virtual Value_P get_apl_value() const; 567 568 /// maximum depth of SI stack 569 static ShapeItem si_depth_limit; 570 571 /// maximum number of values 572 static ShapeItem value_count_limit; 573 574 /// maximum number of ravel bytes 575 static ShapeItem ravel_count_limit; 576 577 /// maximum number of ravel bytes in APL printout 578 static ShapeItem print_length_limit; 579 580 /// the system limits 581 enum SYL_INDEX 582 { 583 #define syl3(n, e, v) syl1(n, e, v) 584 #define syl2(n, e, v) syl1(n, e, v) 585 #define syl1(_n, e, _v) SYL_ ## e, ///< dito 586 #include "SystemLimits.def" 587 588 SYL_MAX ///< max. system limit value (excluding) 589 }; 590 591 protected: 592 }; 593 //----------------------------------------------------------------------------- 594 /** 595 System variable Quad-TC (Terminal Control Characters) 596 */ 597 /// The class implementing ⎕TC 598 class Quad_TC : public RO_SystemVariable 599 { 600 public: 601 /// Constructor. 602 Quad_TC(); 603 }; 604 //----------------------------------------------------------------------------- 605 /** 606 System variable Quad-TS (Time Stamp). 607 */ 608 /// The class implementing ⎕TS 609 class Quad_TS : public RO_SystemVariable 610 { 611 public: 612 /// Constructor. 613 Quad_TS(); 614 615 /// overloaded Symbol::get_apl_value(). 616 virtual Value_P get_apl_value() const; 617 }; 618 //----------------------------------------------------------------------------- 619 /** 620 System variable Quad-TZ (Time Zone). 621 */ 622 /// The class implementing ⎕TZ 623 class Quad_TZ : public SystemVariable 624 { 625 public: 626 /// Constructor. 627 Quad_TZ(); 628 629 /// return the offset from GMT of the current timezone (in seconds). 630 /// we make this int64_t rather than int so that conversion to usec 631 /// does not overflow get_offset() const632 int64_t get_offset() const { return offset_seconds; } 633 634 /// set the timezone offset set_offset(int offset)635 void set_offset(int offset) 636 { offset_seconds = offset; } 637 638 /// compute the offset (in seconds) from GMT 639 static int compute_offset(); 640 641 /// print e.g. 2017-05-17 15:09:12 (GMT+2) to out (no trailing endl) 642 ostream & print_timestamp(ostream & out, APL_time_us when) const; 643 644 protected: 645 /// overloaded Symbol::assign(). 646 virtual void assign(Value_P value, bool clone, const char * loc); 647 648 // overloaded Symbol::push() push()649 virtual void push() 650 { 651 Symbol::push(); 652 offset_seconds = compute_offset(); 653 if (offset_seconds % 3600 == 0) // full hour 654 Symbol::assign(IntScalar(offset_seconds/3600, LOC), false, LOC); 655 else 656 Symbol::assign(FloatScalar(offset_seconds/3600, LOC), false, LOC); 657 } 658 pop()659 virtual void pop() 660 { 661 Symbol::pop(); 662 offset_seconds = 3600 * get_apl_value()->get_ravel(0).get_int_value(); 663 } 664 665 /// the offset from GMT of the current timezone (in seconds) 666 int offset_seconds; 667 }; 668 //----------------------------------------------------------------------------- 669 /** 670 System variable Quad-UL (User Load). 671 */ 672 /// The class implementing ⎕UL 673 class Quad_UL : public RO_SystemVariable 674 { 675 public: 676 /// Constructor. 677 Quad_UL(); 678 679 protected: 680 /// overloaded Symbol::get_apl_value(). 681 virtual Value_P get_apl_value() const; 682 }; 683 //----------------------------------------------------------------------------- 684 /** 685 System variable Quad-X (Axis Argument). 686 */ 687 /// The class implementing ⎕X 688 class Quad_X : public NL_SystemVariable 689 { 690 public: 691 /// Constructor. 692 Quad_X(); 693 694 /// overloaded Symbol::save() save(ostream & out) const695 virtual void save(ostream & out) const {} 696 697 protected: 698 /// overloaded Symbol::assign() 699 virtual void assign(Value_P value, bool clone, const char * loc); 700 701 /// overloaded Symbol::get_apl_value(). 702 virtual Value_P get_apl_value() const; 703 }; 704 //----------------------------------------------------------------------------- 705 #endif // __SYSTEM_VARIABLE_HH_DEFINED__ 706