1 /* 2 * ucsymtbl.h - Usecode symbol table 3 * 4 * Copyright (C) 2006 The Exult Team 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21 #ifndef UCSYMTBL_H 22 #define UCSYMTBL_H 23 24 #include <iosfwd> 25 #include <string> 26 #include <vector> 27 #include <map> 28 29 #define UCSYMTBL_MAGIC0 0xffffffffu 30 #define UCSYMTBL_MAGIC1 ((static_cast<uint32>('U')<<24)+(static_cast<uint32>('C')<<16)+(static_cast<uint32>('S')<<8)+'Y') 31 32 class Usecode_class_symbol; 33 class Usecode_symbol_table; 34 35 class Usecode_symbol { 36 public: 37 enum Symbol_kind { 38 fun_defined = 1, 39 fun_externed, 40 fun_extern_defined, // External, but fun. # was given. 41 class_scope, 42 table_scope, 43 shape_fun, 44 object_fun 45 }; 46 private: 47 friend class Usecode_symbol_table; 48 friend class Usecode_scope_symbol; 49 std::string name; 50 Symbol_kind kind; 51 int value; // Function #. 52 int extra; // Extra symbol info. 53 public: 54 Usecode_symbol(const char *nm, Symbol_kind k, int v, int e = -1) name(nm)55 : name(nm), kind(k), value(v), extra(e) 56 { } 57 virtual ~Usecode_symbol() = default; get_name()58 const char *get_name() const { 59 return name.c_str(); 60 } get_kind()61 Symbol_kind get_kind() const { 62 return kind; 63 } get_val()64 int get_val() const { 65 return value; 66 } get_extra()67 int get_extra() const { 68 return extra; 69 } 70 }; 71 72 class Usecode_scope_symbol : public Usecode_symbol { 73 public: 74 using Syms_vector = std::vector<Usecode_symbol *>; 75 private: 76 Syms_vector symbols; // All symbols. 77 std::vector<Usecode_class_symbol *> classes; // Just the classes. 78 using Name_table = std::map<std::string, Usecode_symbol *>; 79 using Val_table = std::map<int, Usecode_symbol *>; 80 using Class_name_table = std::map<std::string, Usecode_class_symbol *>; 81 using Shape_table = std::map<int, int>; 82 Name_table by_name; 83 Val_table by_val; 84 Class_name_table class_names; 85 Shape_table shape_funs; 86 void setup_by_name(int start = 0); 87 void setup_by_val(int start = 0); 88 void setup_class_names(int start = 0); 89 public: 90 Usecode_scope_symbol(const char *nm = "_usecode_", 91 Symbol_kind k = table_scope, int v = -1) Usecode_symbol(nm,k,v)92 : Usecode_symbol(nm, k, v) 93 { } 94 ~Usecode_scope_symbol() override; 95 void read(std::istream &in); 96 void write(std::ostream &out); 97 void add_sym(Usecode_symbol *sym); 98 Usecode_symbol *operator[](const char *nm); 99 Usecode_symbol *operator[](int val); get_class(int n)100 Usecode_class_symbol *get_class(int n) { 101 return static_cast<unsigned>(n) < classes.size() ? classes[n] : nullptr; 102 } get_num_classes()103 int get_num_classes() const { 104 return static_cast<int>(classes.size()); 105 } 106 Usecode_class_symbol *get_class(const char *nm); 107 int get_high_shape_fun(int val); 108 bool is_object_fun(int val); get_symbols()109 const Syms_vector &get_symbols() { 110 return symbols; 111 } 112 }; 113 114 class Usecode_class_symbol : public Usecode_scope_symbol { 115 using Ints_vector = std::vector<int>; 116 Ints_vector methods; // List of method usecode #'s. 117 int num_vars; // # of class variables. 118 public: 119 Usecode_class_symbol(const char *nm, Symbol_kind k, 120 int v, int nvars = 0) Usecode_scope_symbol(nm,k,v)121 : Usecode_scope_symbol(nm, k, v), num_vars(nvars) 122 { } add_method_num(int val)123 void add_method_num(int val) { 124 methods.push_back(val); 125 } get_method_id(int i)126 int get_method_id(int i) { 127 return (i >= 0 && static_cast<unsigned>(i) < methods.size()) ? methods[i] : -1; 128 } get_num_vars()129 int get_num_vars() { 130 return num_vars; 131 } get_num_methods()132 int get_num_methods() { 133 return static_cast<int>(methods.size()); 134 } 135 void read(std::istream &in); 136 void write(std::ostream &out); 137 }; 138 139 /* 140 * This class represents a symbol table read in from a Usecode file. This 141 * is an Exult construct; ie, U7's 'usecode' file doesn't have a symbol- 142 * table. 143 */ 144 class Usecode_symbol_table : public Usecode_scope_symbol { 145 public: 146 static bool has_symbol_table(std::istream &in); 147 }; 148 149 #endif 150