1 /*
2  *  cSymbolTable.h
3  *  Avida
4  *
5  *  Created by David on 2/2/06.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *
8  *
9  *  This file is part of Avida.
10  *
11  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13  *
14  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
18  *  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef cSymbolTable_h
23 #define cSymbolTable_h
24 
25 #include "AvidaScript.h"
26 #include "ASTree.h"
27 
28 #include "tArray.h"
29 #include "tDictionary.h"
30 
31 
32 // Active/inactive functions and variables within the scope of the current function (or globally)
33 
34 
35 class cSymbolTable
36 {
37 private:
38   // --------  Internal Type Declarations  --------
39   struct sSymbolEntry;
40   struct sFunctionEntry;
41 
42 
43   // --------  Internal Variables  --------
44   tArray<sSymbolEntry*> m_sym_tbl;
45   tDictionary<int> m_sym_dict;
46   tArray<sFunctionEntry*> m_fun_tbl;
47   tDictionary<int> m_fun_dict;
48 
49   int m_scope;
50   int m_deactivate_cycle;
51 
52   bool m_return;
53 
54 
55   // --------  Private Constructors  --------
56   cSymbolTable(const cSymbolTable&); // @not_implemented
57   cSymbolTable& operator=(const cSymbolTable&); // @not_implemented
58 
59 
60 public:
cSymbolTable()61   cSymbolTable() : m_scope(0), m_deactivate_cycle(0), m_return(false) { ; }
62   ~cSymbolTable();
63 
64 
65   // --------  Add/Lookup Methods  --------
66   bool AddVariable(const cString& name, const sASTypeInfo& type, int& var_id);
67   bool AddFunction(const cString& name, const sASTypeInfo& type, int& fun_id);
68 
LookupVariable(const cString & name,int & var_id)69   bool LookupVariable(const cString& name, int& var_id) { return m_sym_dict.Find(name, var_id); }
LookupFunction(const cString & name,int & fun_id)70   bool LookupFunction(const cString& name, int& fun_id) { return m_fun_dict.Find(name, fun_id); }
71 
GetNumVariables()72   inline int GetNumVariables() const { return m_sym_tbl.GetSize(); }
GetNumFunctions()73   inline int GetNumFunctions() const { return m_fun_tbl.GetSize(); }
74 
VariableNearMatch(const cString & name)75   inline cString VariableNearMatch(const cString& name) const { return m_sym_dict.NearMatch(name); }
FunctionNearMatch(const cString & name)76   inline cString FunctionNearMatch(const cString& name) const { return m_fun_dict.NearMatch(name); }
77 
78 
79   // --------  Scope Methods  --------
PushScope()80   inline void PushScope() { m_scope++; }
81   void PopScope();
GetScope()82   inline int GetScope() const { return m_scope; }
83 
SetScopeReturn()84   inline void SetScopeReturn() { m_return = true; }
ScopeHasReturn()85   inline bool ScopeHasReturn() const { return m_return; }
86 
87 
88   // --------  Variable Property Methods  --------
GetVariableType(int var_id)89   inline const sASTypeInfo& GetVariableType(int var_id) const { return m_sym_tbl[var_id]->type; }
90 
91 
92   // --------  Function Property Methods  --------
GetFunctionName(int fun_id)93   inline const cString& GetFunctionName(int fun_id) const { return m_fun_tbl[fun_id]->name; }
GetFunctionRType(int fun_id)94   inline const sASTypeInfo& GetFunctionRType(int fun_id) const { return m_fun_tbl[fun_id]->type; }
GetFunctionSymbolTable(int fun_id)95   inline cSymbolTable* GetFunctionSymbolTable(int fun_id) { return m_fun_tbl[fun_id]->symtbl; }
GetFunctionSignature(int fun_id)96   inline cASTVariableDefinitionList* GetFunctionSignature(int fun_id) { return m_fun_tbl[fun_id]->signature; }
GetFunctionDefinition(int fun_id)97   inline cASTNode* GetFunctionDefinition(int fun_id) { return m_fun_tbl[fun_id]->code; }
GetFunctionScope(int fun_id)98   inline int GetFunctionScope(int fun_id) const { return m_fun_tbl[fun_id]->scope; }
IsFunctionActive(int fun_id)99   inline bool IsFunctionActive(int fun_id) const { return !m_fun_tbl[fun_id]->deactivate; }
100 
SetFunctionSymbolTable(int fun_id,cSymbolTable * symtbl)101   inline void SetFunctionSymbolTable(int fun_id, cSymbolTable* symtbl) { m_fun_tbl[fun_id]->symtbl = symtbl; }
SetFunctionSignature(int fun_id,cASTVariableDefinitionList * vdl)102   inline void SetFunctionSignature(int fun_id, cASTVariableDefinitionList* vdl) { m_fun_tbl[fun_id]->signature = vdl; }
SetFunctionDefinition(int fun_id,cASTNode * code)103   inline void SetFunctionDefinition(int fun_id, cASTNode* code) { m_fun_tbl[fun_id]->code = code; }
104 
105 
106   // --------  Externally Visible Type Declarations  --------
107   class cFunctionIterator
108   {
109     friend class cSymbolTable;
110 
111   private:
112     cSymbolTable* m_symtbl;
113     int m_scope;
114     int m_idx;
115 
cFunctionIterator(cSymbolTable * symtbl)116     cFunctionIterator(cSymbolTable* symtbl)
117       : m_symtbl(symtbl), m_scope(symtbl->GetScope()), m_idx(symtbl->GetNumFunctions()) { ; }
118 
119   public:
Next()120     bool Next()
121     {
122       for (m_idx--; m_idx >= 0; m_idx--)
123         if (m_symtbl->GetFunctionScope(m_idx) == m_scope && m_symtbl->IsFunctionActive(m_idx)) return true;
124 
125       return false;
126     }
127 
HasCode()128     inline bool HasCode() const { return m_symtbl->GetFunctionDefinition(m_idx); }
GetName()129     inline const cString& GetName() const { return m_symtbl->GetFunctionName(m_idx); }
130   };
131 
132 
133   // --------  Externally Visible Type Dependent Methods  --------
ActiveFunctionIterator()134   inline cFunctionIterator ActiveFunctionIterator() { return cFunctionIterator(this); }
135 
136 
137 private:
138   // --------  Internal Type Definitions  --------
139   struct sSymbolEntry
140   {
141     cString name;
142     sASTypeInfo type;
143 
144     int scope;
145     int shadow;
146     int deactivate;
147 
sSymbolEntrysSymbolEntry148     sSymbolEntry(const cString& in_name, const sASTypeInfo& in_type, int in_scope)
149       : name(in_name), type(in_type), scope(in_scope), shadow(-1), deactivate(0) { ; }
150   };
151 
152   struct sFunctionEntry
153   {
154     cString name;
155     sASTypeInfo type;
156     cASTVariableDefinitionList* signature;
157     cSymbolTable* symtbl;
158     cASTNode* code;
159 
160     int scope;
161     int shadow;
162     int deactivate;
163 
sFunctionEntrysFunctionEntry164     sFunctionEntry(const cString& in_name, const sASTypeInfo& in_type, int in_scope)
165       : name(in_name), type(in_type), signature(NULL), symtbl(NULL), code(NULL), scope(in_scope), shadow(-1)
166       , deactivate(0) { ; }
~sFunctionEntrysFunctionEntry167     ~sFunctionEntry() { delete signature; delete symtbl; delete code; }
168   };
169 };
170 
171 
172 #endif
173