00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: SymbolTable.h,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.63 $ $Date: 2020年08月14日 18:58:35 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * Stores the functions available to get info from a molecule 00019 * Calls the atom selection parser to create a parse tree 00020 * 00021 ***************************************************************************/ 00022 #ifndef SYMBOLTABLE_H 00023 #define SYMBOLTABLE_H 00024 00025 #include <stddef.h> 00026 #include "NameList.h" 00027 #include "Command.h" 00028 00029 class VMDApp; 00030 class ParseTree; 00031 00033 class CmdAddAtomSelMacro : public Command { 00034 public: 00035 CmdAddAtomSelMacro(const char *theName, const char *theMacro) 00036 : Command(ATOMSEL_ADDMACRO) {} 00037 }; 00038 00039 00041 class CmdDelAtomSelMacro : public Command { 00042 public: 00043 CmdDelAtomSelMacro(const char *theName) 00044 : Command(ATOMSEL_DELMACRO) {} 00045 }; 00046 00047 00049 extern "C" { 00050 typedef double (*c_ddfunc)(double); 00051 } 00052 00053 00055 class SymbolTableElement { 00056 public: 00057 typedef int (*int_fctn)(void *, int, int *, int *); 00058 typedef int (*double_fctn)(void *, int, double *, int *); 00059 typedef int (*string_fctn)(void *, int, const char **, int *); 00060 typedef int (*single_fctn)(void *, int, int *); 00061 typedef int (*stringfctn_fctn)(void *, int, const char **, int *, int, int *); 00062 00063 typedef void (*void_fctn)(void); 00064 typedef int (*set_int_fctn)(void *, int, int *, int *); 00065 typedef int (*set_double_fctn)(void *, int, double *, int *); 00066 typedef int (*set_string_fctn)(void *, int, const char **, int *); 00067 typedef int (*set_single_fctn)(void *, int, int *, int *); 00068 00069 enum symtype {IS_INT, IS_FLOAT, IS_STRING}; 00070 enum symdesc {NOTHING, KEYWORD, FUNCTION, SINGLEWORD, STRINGFCTN}; 00071 00072 symdesc is_a; 00073 symtype returns_a; 00074 00076 union { 00077 c_ddfunc fctn; 00078 int_fctn keyword_int; 00079 double_fctn keyword_double; 00080 string_fctn keyword_string; 00081 single_fctn keyword_single; 00082 stringfctn_fctn keyword_stringfctn; 00083 }; 00084 00086 union { 00087 void_fctn set_fctn; // set this to NULL if there is nothing else 00088 set_int_fctn set_keyword_int; 00089 set_double_fctn set_keyword_double; 00090 set_string_fctn set_keyword_string; 00091 set_single_fctn set_keyword_single; 00092 }; 00093 00094 SymbolTableElement() // need for use in a NameList 00095 : is_a(NOTHING), fctn(NULL), set_fctn(NULL) {} 00096 00097 SymbolTableElement(c_ddfunc get) 00098 : is_a(FUNCTION), returns_a(IS_FLOAT), 00099 fctn(get), set_fctn(NULL) {} 00100 00101 SymbolTableElement(int_fctn get, set_int_fctn set) 00102 : is_a(KEYWORD), returns_a(IS_INT), 00103 keyword_int(get), set_keyword_int(set) {} 00104 00105 SymbolTableElement(double_fctn get, set_double_fctn set) 00106 : is_a(KEYWORD), returns_a(IS_FLOAT), 00107 keyword_double(get), set_keyword_double(set) {} 00108 00109 SymbolTableElement(string_fctn get, set_string_fctn set) 00110 : is_a(KEYWORD), returns_a(IS_STRING), 00111 keyword_string(get), set_keyword_string(set) {} 00112 00113 SymbolTableElement(stringfctn_fctn get) 00114 : is_a(STRINGFCTN), returns_a(IS_STRING), 00115 keyword_stringfctn(get), set_fctn(NULL) {} 00116 00117 SymbolTableElement(single_fctn get, set_single_fctn set) 00118 : is_a(SINGLEWORD), returns_a(IS_INT), 00119 keyword_single(get), set_keyword_single(set) {} 00120 }; 00121 00122 00124 class SymbolTable { 00125 private: 00127 NameList<char *> custom_singlewords; 00128 00129 public: 00130 VMDApp *app; 00131 NameList<SymbolTableElement *> fctns; 00132 00133 SymbolTable(VMDApp *vmdapp) : app(vmdapp) {}; 00134 ~SymbolTable(void); 00135 00137 ParseTree *parse(const char *seltext); 00138 00139 // 00140 // add functions and keywords ... 00141 // 00142 void add_keyword(const char *visible, 00143 SymbolTableElement::int_fctn get, 00144 SymbolTableElement::set_int_fctn set) { 00145 // if the name already exists, overwrite it with the new one 00146 int ind = fctns.typecode(visible); 00147 if (ind < 0) { 00148 fctns.add_name(visible, new SymbolTableElement(get, set)); 00149 } else { 00150 delete fctns.data(ind); 00151 fctns.set_data(ind, new SymbolTableElement(get, set)); 00152 } 00153 } 00154 void add_keyword(const char *visible, 00155 SymbolTableElement::double_fctn get, 00156 SymbolTableElement::set_double_fctn set) { 00157 // if the name already exists, overwrite it with the new one 00158 int ind = fctns.typecode(visible); 00159 if (ind < 0) { 00160 fctns.add_name(visible, new SymbolTableElement(get, set)); 00161 } else { 00162 delete fctns.data(ind); 00163 fctns.set_data(ind, new SymbolTableElement(get, set)); 00164 } 00165 } 00166 void add_keyword(const char *visible, 00167 SymbolTableElement::string_fctn get, 00168 SymbolTableElement::set_string_fctn set) { 00169 // if the name already exists, overwrite it with the new one 00170 int ind = fctns.typecode(visible); 00171 if (ind < 0) { 00172 fctns.add_name(visible, new SymbolTableElement(get, set)); 00173 } else { 00174 delete fctns.data(ind); 00175 fctns.set_data(ind, new SymbolTableElement(get, set)); 00176 } 00177 } 00178 void add_singleword(const char *visible, 00179 SymbolTableElement::single_fctn get, 00180 SymbolTableElement::set_single_fctn set) { 00181 // if the name already exists, overwrite it with the new one 00182 int ind = fctns.typecode(visible); 00183 if (ind < 0) { 00184 fctns.add_name(visible, new SymbolTableElement(get, set)); 00185 } else { 00186 delete fctns.data(ind); 00187 fctns.set_data(ind, new SymbolTableElement(get, set)); 00188 } 00189 } 00190 void add_stringfctn(const char *visible, 00191 SymbolTableElement::stringfctn_fctn get) { 00192 // if the name already exists, overwrite it with the new one 00193 int ind = fctns.typecode(visible); 00194 if (ind < 0) { 00195 fctns.add_name(visible, new SymbolTableElement(get)); 00196 } else { 00197 delete fctns.data(ind); 00198 fctns.set_data(ind, new SymbolTableElement(get)); 00199 } 00200 } 00201 00207 void add_cfunction(const char *visible, c_ddfunc fctn) { 00208 fctns.add_name(visible, new SymbolTableElement(fctn)); 00209 } 00210 00212 int find_attribute(const char *attrib) { 00213 return fctns.typecode(attrib); 00214 } 00215 00217 int is_changeable(int fctnidx); 00218 00223 int num_custom_singleword(); 00224 00226 const char *custom_singleword_name(int); 00227 00229 int add_custom_singleword(const char *name, const char *macro); 00230 00232 const char *get_custom_singleword(const char *name); 00233 00235 int remove_custom_singleword(const char *name); 00236 }; 00237 00238 #endif 00239