1 /** 2 ** Ucfun.h - Usecode compiler function. 3 ** 4 ** Written: 1/2/01 - JSF 5 **/ 6 7 /* 8 Copyright (C) 2000 The Exult Team 9 10 This program is free software; you can redistribute it and/or 11 modify it under the terms of the GNU General Public License 12 as published by the Free Software Foundation; either version 2 13 of the License, or (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 */ 24 25 #ifndef INCL_UCFUN 26 #define INCL_UCFUN 27 28 #include <set> 29 #include "ucsym.h" 30 #include "opcodes.h" 31 32 class Uc_location; 33 class Uc_statement; 34 35 #include <iosfwd> 36 37 /* 38 * This represents a usecode function: 39 */ 40 class Uc_function : public Uc_design_unit { 41 static Uc_scope globals; // For finding intrinsics, funs. 42 // Intrinsics, indexed by number: 43 static std::vector<Uc_intrinsic_symbol *> intrinsics; 44 // Some intrinsic numbers: 45 static int add_answer, remove_answer, push_answers, pop_answers, 46 show_face, remove_face, get_item_shape, get_usecode_fun; 47 static int num_global_statics; 48 Uc_scope top; // Top-level scope. 49 Uc_function_symbol *proto; // Function declaration. 50 Uc_scope *cur_scope; // Current scope. 51 int num_parms; // # parameters. 52 int num_locals; // Counts locals. 53 int num_statics; // Counts local statics. 54 // Links to called functions: 55 std::vector<Uc_function_symbol *> links; 56 std::set<std::string> labels; 57 char *text_data; // All strings. 58 int text_data_size; 59 // Map string to its offset. 60 std::map<std::string, int> text_map; 61 Uc_statement *statement; // Statement(s) in function. 62 public: 63 enum Intrinsic_type { 64 unset, 65 bg, // Black gate. 66 si, // Serpent isle. 67 sib // Serpent Isle Beta. 68 }; 69 private: 70 static Intrinsic_type intrinsic_type; 71 public: 72 Uc_function(Uc_function_symbol *p, Uc_scope *parent = nullptr); 73 ~Uc_function() override; 74 static void set_intrinsics(); setup_intrinsics()75 static void setup_intrinsics() { // Init. the 1st time. 76 if (intrinsics.empty()) 77 set_intrinsics(); 78 } set_intrinsic_type(Intrinsic_type ty)79 static void set_intrinsic_type(Intrinsic_type ty) { 80 intrinsic_type = ty; 81 if (ty != Uc_function::unset) 82 set_intrinsics(); 83 } set_statement(Uc_statement * s)84 void set_statement(Uc_statement *s) { 85 statement = s; 86 } get_name()87 const char *get_name() { 88 return proto->get_name(); 89 } is_externed()90 bool is_externed() { 91 return proto->is_externed(); 92 } is_inherited()93 bool is_inherited() { 94 return proto->is_inherited(); 95 } set_inherited()96 void set_inherited() { 97 proto->set_inherited(); 98 } get_usecode_num()99 int get_usecode_num() { 100 return proto->get_usecode_num(); 101 } set_method_num(int n)102 void set_method_num(int n) { 103 proto->set_method_num(n); 104 } get_method_num()105 int get_method_num() { 106 return proto->get_method_num(); 107 } has_ret()108 bool has_ret() const { 109 return proto->has_ret(); 110 } get_ret_type()111 Uc_function_symbol::Function_ret get_ret_type() const { 112 return proto->get_ret_type(); 113 } get_cls()114 Uc_class *get_cls() const { 115 return proto->get_cls(); 116 } get_struct()117 Uc_struct_symbol *get_struct() const { 118 return proto->get_struct(); 119 } get_function_type()120 Uc_function_symbol::Function_kind get_function_type() const { 121 return proto->get_function_type(); 122 } get_parent()123 Uc_scope *get_parent() { 124 return cur_scope->get_parent(); 125 } push_scope()126 void push_scope() { // Start a new scope. 127 cur_scope = cur_scope->add_scope(); 128 } pop_scope()129 void pop_scope() { // End scope. 130 cur_scope = cur_scope->get_parent(); 131 } search(const char * nm)132 Uc_symbol *search(const char *nm) { // Search current scope. 133 return cur_scope->search(nm); 134 } search_up(const char * nm)135 Uc_symbol *search_up(const char *nm) { 136 Uc_symbol *sym = cur_scope->search_up(nm); 137 if (sym) 138 return sym; 139 setup_intrinsics(); 140 return globals.search(nm); 141 } search_globals(const char * nm)142 static Uc_symbol *search_globals(const char *nm) { 143 return globals.search(nm); 144 } get_intrinsic(int i)145 static Uc_intrinsic_symbol *get_intrinsic(int i) { 146 setup_intrinsics(); 147 return (i >= 0 && static_cast<unsigned>(i) < intrinsics.size()) ? intrinsics[i] : nullptr; 148 } get_add_answer()149 static Uc_intrinsic_symbol *get_add_answer() { 150 return get_intrinsic(add_answer); 151 } get_remove_answer()152 static Uc_intrinsic_symbol *get_remove_answer() { 153 return get_intrinsic(remove_answer); 154 } get_push_answers()155 static Uc_intrinsic_symbol *get_push_answers() { 156 return get_intrinsic(push_answers); 157 } get_pop_answers()158 static Uc_intrinsic_symbol *get_pop_answers() { 159 return get_intrinsic(pop_answers); 160 } get_show_face()161 static Uc_intrinsic_symbol *get_show_face() { 162 return get_intrinsic(show_face); 163 } get_remove_face()164 static Uc_intrinsic_symbol *get_remove_face() { 165 return get_intrinsic(remove_face); 166 } get_get_usecode_fun()167 static Uc_intrinsic_symbol *get_get_usecode_fun() { 168 return get_intrinsic(get_usecode_fun); 169 } get_get_item_shape()170 static Uc_intrinsic_symbol *get_get_item_shape() { 171 return get_intrinsic(get_item_shape); 172 } 173 Uc_var_symbol *add_symbol(char *nm);// Add var. to current scope. 174 Uc_var_symbol *add_symbol(char *nm, Uc_class *c);// Add var. to current scope. 175 Uc_var_symbol *add_symbol(char *nm, Uc_struct_symbol *s);// Add var. to current scope. 176 Uc_var_symbol *add_symbol(Uc_var_symbol *var);// Add var. to current scope. 177 // Add alias to current scope. 178 Uc_var_symbol *add_alias(char *nm, Uc_var_symbol *var); 179 // Add class alias to current scope. 180 Uc_var_symbol *add_alias(char *nm, Uc_var_symbol *var, Uc_class *c); 181 // Add struct alias to current scope. 182 Uc_var_symbol *add_alias(char *nm, Uc_var_symbol *var, Uc_struct_symbol *s); 183 void add_static(char *nm); // Add static var. to current scope. 184 void add_static(char *nm, Uc_struct_symbol *type); // Add static struct to current scope. 185 void add_static(char *nm, Uc_class *c); // Add static cls. to current scope. 186 int add_function_symbol(Uc_function_symbol *fun, Uc_scope *parent = nullptr) { 187 return cur_scope->add_function_symbol(fun, parent); 188 } 189 static int add_global_function_symbol(Uc_function_symbol *fun, 190 Uc_scope *parent = nullptr) { 191 return globals.add_function_symbol(fun, parent); 192 } add_global_class_symbol(Uc_class_symbol * c)193 static void add_global_class_symbol(Uc_class_symbol *c) { 194 globals.add(c); 195 } add_global_struct_symbol(Uc_struct_symbol * s)196 static void add_global_struct_symbol(Uc_struct_symbol *s) { 197 globals.add(s); 198 } 199 // Add string constant. 200 Uc_symbol *add_string_symbol(char *nm, char *text); 201 // Add int constant. 202 Uc_symbol *add_int_const_symbol(char *nm, int value, int opcode = UC_PUSHI); 203 static Uc_symbol *add_global_int_const_symbol(char *nm, int val, 204 int opcode = UC_PUSHI); 205 static void add_global_static(char *nm); 206 static void add_global_static(char *nm, Uc_struct_symbol *type); 207 static void add_global_static(char *nm, Uc_class *c); 208 int add_string(char *text); 209 int find_string_prefix(Uc_location &loc, const char *text); 210 // Start/end loop. add_label(char * nm)211 void add_label(char *nm) { 212 labels.insert(nm); 213 } search_label(char * nm)214 bool search_label(char *nm) { 215 return labels.find(nm) != labels.end(); 216 } 217 218 int link(Uc_function_symbol *fun); 219 void gen(std::ostream &out) override; // Generate Usecode. 220 Usecode_symbol *create_sym() override; 221 }; 222 223 #endif 224