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-2016 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 __USERFUNCTION__HEADER_HH_DEFINED__ 22 #define __USERFUNCTION__HEADER_HH_DEFINED__ 23 24 #include <sys/types.h> 25 #include <vector> 26 27 #include "Error.hh" 28 #include "Executable.hh" 29 #include "Function.hh" 30 #include "Symbol.hh" 31 #include "UTF8_string.hh" 32 33 //----------------------------------------------------------------------------- 34 /// The (symbols in the) header of a defined function 35 class UserFunction_header 36 { 37 public: 38 /// constructor from first line in \b txt (for normal defined functions) 39 UserFunction_header(const UCS_string & txt, bool macro); 40 41 /// constructor from signature (for lambdas) 42 UserFunction_header(Fun_signature sig, int lambda_num); 43 44 /// return the number of value arguments get_fun_valence() const45 int get_fun_valence() const 46 { 47 if (sym_A) return 2; // dyadic function 48 if (sym_B) return 1; // monadic function 49 return 0; // niladic function 50 } 51 52 /// return the number of operator arguments get_oper_valence() const53 int get_oper_valence() const 54 { 55 if (sym_RO) return 2; // dyadic operator 56 if (sym_LO) return 1; // monadic operator 57 return 0; // niladic function 58 } 59 60 /// return source location where error was detected get_error_info() const61 const char * get_error_info() const { return error_info; } 62 63 /// return true if the header indicates a result (Z←) has_result() const64 bool has_result() const { return sym_Z != 0; } 65 66 /// return true if the header contains variables (result, arguments, 67 /// or local variables has_vars() const68 bool has_vars() const 69 { return sym_Z || sym_A || sym_LO || sym_X || sym_RO || sym_B || 70 local_vars.size(); } 71 72 /// return true iff the function returns a value has_axis() const73 int has_axis() const { return sym_X != 0; } 74 75 /// return true if this defined function header is an operator is_operator() const76 bool is_operator() const { return sym_LO != 0; } 77 78 /// return the name of the function get_name() const79 UCS_string get_name() const { return function_name; } 80 81 /// return the Symbol for the function result Z() const82 Symbol * Z() const { return sym_Z; } 83 84 /// return the Symbol for the left argument A() const85 Symbol * A() const { return sym_A; } 86 87 /// return the Symbol for the left function argument LO() const88 Symbol * LO() const { return sym_LO; } 89 90 /// return the Symbol for the left function argument FUN() const91 Symbol * FUN() const { return sym_FUN; } 92 93 /// return the Symbol for the right argument X() const94 Symbol * X() const { return sym_X; } 95 96 /// return the Symbol for the right function argument RO() const97 Symbol * RO() const { return sym_RO; } 98 99 /// return the Symbol for the right argument B() const100 Symbol * B() const { return sym_B; } 101 102 /// return error if header was not parsed successfully get_error() const103 ErrorCode get_error() const { return error; } 104 105 /// print local vars etc. 106 void print_properties(ostream & out, int indent) const; 107 108 /// add a local variable 109 void add_local_var(Symbol * sym); 110 111 /// pop all local vars, labels, and parameters 112 void pop_local_vars() const; 113 114 /// print the local variables for command )SINL 115 void print_local_vars(ostream & out) const; 116 117 /// reverse the order of the local vars (if parsed back-to-front) 118 void reverse_local_vars(); 119 120 /// add a label add_label(Symbol * sym,Function_Line line)121 void add_label(Symbol * sym, Function_Line line) 122 { 123 labVal label = { sym, line }; 124 label_values.push_back(label); 125 } 126 127 /// Check that all function params, local vars. and labels are unique. 128 void remove_duplicate_local_variables(); 129 130 /// the header (as per SIG_xxx and local_vars) 131 static UCS_string lambda_header(Fun_signature sig, int lambda_num); 132 133 /// push Z (if defined), local variables, and labels. 134 void eval_common(); 135 136 /// return the number of local variables local_var_count() const137 ShapeItem local_var_count() const 138 { return local_vars.size(); } 139 140 /// return the idx'th local variable get_local_var(ShapeItem idx) const141 const Symbol * get_local_var(ShapeItem idx) const 142 { return local_vars[idx]; } 143 144 protected: 145 /// remove \b sym from local_vars if it occurs at pos or above 146 void remove_duplicate_local_var(const Symbol * sym, size_t pos); 147 148 /// error if header was not parsed successfully 149 ErrorCode error; 150 151 /// source location where error was detected 152 const char * error_info; 153 154 /// the name of this function 155 UCS_string function_name; 156 157 /// optional result 158 Symbol * sym_Z; 159 160 /// optional left function arg 161 Symbol * sym_A; 162 163 /// optional left operator function 164 Symbol * sym_LO; 165 166 /// optional symbol for function name (0 for lambdas) 167 Symbol * sym_FUN; 168 169 /// optional right operator function 170 Symbol * sym_RO; 171 172 /// optional right operator function axis 173 Symbol * sym_X; 174 175 /// optional right function arg 176 Symbol * sym_B; 177 178 /// The local variables of \b this function. 179 std::vector<Symbol *> local_vars; 180 181 /// The labels of \b this function. 182 std::vector<labVal> label_values; 183 }; 184 //----------------------------------------------------------------------------- 185 186 #endif // __USERFUNCTION__HEADER_HH_DEFINED__ 187