1 /* compiler.h -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2009 */
2 
3 /*
4 
5 Copyright (c) 2005-2009 Made to Order Software Corp.
6 
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16 
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31 
32 */
33 
34 
35 #include	"sswf/libsswf_as.h"
36 #include	"optimizer.h"
37 
38 namespace sswf
39 {
40 namespace as
41 {
42 
43 
44 
45 
46 class IntCompiler : public Compiler
47 {
48 public:
49 				IntCompiler(InputRetriever *input);
50 	virtual			~IntCompiler();
51 
52 	virtual InputRetriever *SetInputRetriever(InputRetriever *retriever);
53 	virtual void		SetErrorStream(ErrorStream& error_stream);
54 	virtual void		SetOptions(Options& options);
55 	virtual int		Compile(NodePtr& root);
56 
57 private:
58 	enum {
59 		MATCH_ANY_ANCESTOR = 0x0001,
60 
61 		SEARCH_ERROR_PRIVATE			= 0x00000001,
62 		SEARCH_ERROR_PROTECTED			= 0x00000002,
63 		SEARCH_ERROR_PROTOTYPE			= 0x00000004,
64 		SEARCH_ERROR_WRONG_PRIVATE		= 0x00000008,
65 		SEARCH_ERROR_WRONG_PROTECTED		= 0x00000010,
66 		SEARCH_ERROR_PRIVATE_PACKAGE		= 0x00000020,
67 		SEARCH_ERROR_EXPECTED_STATIC_MEMBER	= 0x00000040,
68 		SEARCH_ERROR_last = 0
69 	};
70 
71 	enum {
72 		SEARCH_FLAG_NO_PARSING			= 0x00000001,	// avoid parsing variables
73 		SEARCH_FLAG_GETTER			= 0x00000002,	// accept getters (reading)
74 		SEARCH_FLAG_SETTER			= 0x00000004,	// accept setters (writing)
75 		SEARCH_FLAG_PACKAGE_MUST_EXIST		= 0x00000008,	// weather the package has to exist
76 		SEARCH_FLAG_last = 0
77 	};
78 
79 	class rc_t {
80 	public:
rc_t(void)81 				rc_t(void)
82 				{
83 					f_f = 0;
84 					f_filename[0] = '\0';
85 				}
~rc_t()86 				~rc_t()
87 				{
88 					Close();
89 				}
90 		void		FindRC(const String& home, bool accept_if_missing);
91 		void		ReadRC(void);
Close(void)92 		void		Close(void)
93 				{
94 					if(f_f != 0) {
95 						fclose(f_f);
96 						f_f = 0;
97 					}
98 				}
99 
GetPath(void)100 		const String&	GetPath(void) const
101 				{
102 					return f_path;
103 				}
GetDB(void)104 		const String&	GetDB(void) const
105 				{
106 					return f_db;
107 				}
108 
109 	private:
110 		FILE *		f_f;
111 		char		f_filename[256];
112 		String		f_path;
113 		String		f_db;
114 	};
115 
116 	struct module_t {
117 		String		f_filename;
118 		NodePtr		f_node;
119 	};
120 
121 	// automate the restoration of the error flags
122 	class RestoreFlags
123 	{
124 	public:
RestoreFlags(IntCompiler * compiler)125 				RestoreFlags(IntCompiler *compiler)
126 				{
127 					f_compiler = compiler;
128 					f_org_flags = f_compiler->GetErrFlags();
129 					f_compiler->SetErrFlags(0);
130 				}
~RestoreFlags()131 				~RestoreFlags()
132 				{
133 					f_compiler->SetErrFlags(f_org_flags);
134 				}
135 
136 	private:
137 		IntCompiler *	f_compiler;
138 		int		f_org_flags;
139 	};
140 
141 
142 	// functions used to load the internal imports
143 	void			InternalImports(void);
144 	NodePtr			LoadModule(const char *module, const char *file);
145 	void			LoadInternalPackages(const char *module);
146 	void			ReadDB(void);
147 	void			WriteDB(void);
148 	static bool		isspace(int c);
149 	bool			FindModule(const String& filename, NodePtr& n);
150 	const char *		FindElement(const String& package_name, const String& element_name, NodePtr *element, const char *type);
151 	void			FindPackages_AddDatabaseEntry(const String& package_name, NodePtr& element, const char *type);
152 	void			FindPackages_SavePackageElements(NodePtr& package, const String& package_name);
153 	void			FindPackages_DirectiveList(NodePtr& list);
154 	void			FindPackages(NodePtr& program);
155 	String			GetPackageFilename(const char *package_info);
156 
157 	void			AddVariable(NodePtr& variable);
158 	bool			AreObjectsDerivedFromOneAnother(NodePtr& derived_class, NodePtr& super_class, Data *& data);
159 	void			AssignmentOperator(NodePtr& expr);
160 	bool			BestParamMatch(NodePtr& best, NodePtr& match);
161 	bool			BestParamMatchDerivedFrom(NodePtr& best, NodePtr& match);
162 	void			BinaryOperator(NodePtr& expr);
163 	void			BreakContinue(NodePtr& break_node);
164 	void			CallAddMissingParams(NodePtr& call, NodePtr& params);
165 	void			CanInstantiateType(NodePtr& expr);
166 	void			Case(NodePtr& case_node);
167 	void			Catch(NodePtr& catch_node);
168 	bool			CheckField(NodePtr& link, NodePtr& field, int& funcs, NodePtr& resolution, NodePtr *params, int search_flags);
169 	bool			CheckFinalFunctions(NodePtr& function, NodePtr& class_node);
170 	bool			CheckFunction(NodePtr& func, NodePtr& resolution, const String& name, NodePtr *params, int search_flags);
171 	int			CheckFunctionWithParams(NodePtr& func, NodePtr *params);
172 	bool			CheckImport(NodePtr& child, NodePtr& resolution, const String& name, NodePtr *params, int search_flags);
173 	void			CheckMember(NodePtr& obj, NodePtr& field, NodePtr& field_name);
174 	bool			CheckName(NodePtr& list, int idx, NodePtr& resolution, NodePtr& id, NodePtr *params, int search_flags);
175 	void			CheckSuperValidity(NodePtr& expr);
176 	void			CheckThisValidity(NodePtr& expr);
177 	bool			CheckUniqueFunctions(NodePtr& function, NodePtr& class_node, bool all_levels);
178 	void			Class(NodePtr& class_node);
179 	NodePtr			ClassOfMember(NodePtr parent, Data *& data);
180 	bool			CompareParameters(NodePtr& lfunction, NodePtr& rfunction);
181 	void			DeclareClass(NodePtr& class_node);
182 	void			Default(NodePtr& default_node);
183 	bool			DefineFunctionType(NodePtr& func);
184 	void			Directive(NodePtr& directive);
185 	NodePtr			DirectiveList(NodePtr& directive_list);
186 	void			Do(NodePtr& do_node);
187 	void			Enum(NodePtr& enum_node);
188 	void			Expression(NodePtr& expr, NodePtr *params = 0);
189 	bool			ExpressionNew(NodePtr& expr);
190 	void			ExtendClass(NodePtr& class_node, NodePtr& extend_name);
191 	void			Finally(NodePtr& finally_node);
192 	bool			FindAnyField(NodePtr& link, NodePtr& field, int& funcs, NodePtr& resolution, NodePtr *params, int search_flags);
193 	int			FindClass(NodePtr& class_type, NodePtr& type, int depth);
194 	bool			FindExternalPackage(NodePtr& import, const String& name, NodePtr& program);
195 	bool			FindField(NodePtr& link, NodePtr& field, int& funcs, NodePtr& resolution, NodePtr *params, int search_flags);
196 	bool			FindFinalFunctions(NodePtr& function, NodePtr& super);
197 	bool			FindInExtends(NodePtr& link, NodePtr& field, int& funcs, NodePtr& resolution, NodePtr *params, int search_flags);
198 	void			FindLabels(NodePtr& function, NodePtr& node);
199 	bool			FindMember(NodePtr& member, NodePtr& resolution, NodePtr *params, int search_flags);
200 	bool			FindOverloadedFunction(NodePtr& class_node, NodePtr& function);
201 	NodePtr			FindPackage(NodePtr& list, const String& name);
202 	bool			FindPackageItem(NodePtr& program, NodePtr& import, NodePtr& resolution, const String& name, NodePtr *params, int search_flags);
203 	void			For(NodePtr& for_node);
204 	bool			FuncsName(int& funcs, NodePtr& resolution, bool increment = true);
205 	void			Function(NodePtr& parameters);
206 	unsigned long		GetAttributes(NodePtr& node);
GetErrFlags(void)207 	int			GetErrFlags(void) const { return f_err_flags; }
208 	void			Goto(NodePtr& goto_node);
209 	bool			HasAbstractFunctions(NodePtr& class_node, NodePtr& list, NodePtr& func);
210 	void			IdentifierToAttrs(NodePtr& node, NodePtr& a, unsigned long& attrs);
211 	void			If(NodePtr& if_node);
212 	void			Import(NodePtr& import);
213 	bool			IsConstructor(NodePtr& func);
214 	bool			IsDerivedFrom(NodePtr& derived_class, NodePtr& super_class);
215 	bool			IsDynamicClass(NodePtr& class_node);
216 	bool			IsFunctionAbstract(NodePtr& function);
217 	bool			IsFunctionOverloaded(NodePtr& class_node, NodePtr& function);
218 	void			LinkType(NodePtr& type);
219 	int			MatchType(NodePtr& t1, NodePtr t2, int match);
220 	void			NodeToAttrs(NodePtr& node, NodePtr& a, unsigned long& attrs);
221 	void			ObjectLiteral(NodePtr& expr);
222 	void			Offsets(NodePtr& node);		// that should probably be in the NodePtr realm
223 	void			Parameters(NodePtr& parameters);
224 	void			PrintSearchErrors(const NodePtr& name);
225 	void			Program(NodePtr& program);
226 	bool			ReplaceConstantVariable(NodePtr& replace, NodePtr& resolution);
227 	bool			ResolveCall(NodePtr& call);
228 	bool			ResolveField(NodePtr& object, NodePtr& field, NodePtr& resolution, NodePtr *params, int search_flags);
229 	void			ResolveInternalType(NodePtr& parent, const char *type, NodePtr& resolution);
230 	void			ResolveMember(NodePtr& expr, NodePtr *params, int search_flags);
231 	bool			ResolveName(NodePtr list, NodePtr& id, NodePtr& resolution, NodePtr *params, int search_flags);
232 	NodePtr			Return(NodePtr& return_node);
233 	bool			SelectBestFunc(NodePtr *params, NodePtr& resolution);
234 	void			SetAttr(NodePtr& node, unsigned long& list_attrs, unsigned long set, unsigned long group, const char *names);
SetErrFlags(int flags)235 	void			SetErrFlags(int flags) { f_err_flags = flags; }
236 	bool			SpecialIdentifier(NodePtr& expr);
237 	void			Switch(NodePtr& switch_node);
238 	void			Throw(NodePtr& throw_node);
239 	void			Try(NodePtr& try_node);
240 	void			TypeExpr(NodePtr& expr);
241 	void			UnaryOperator(NodePtr& expr);
242 	void			UseNamespace(NodePtr& use_namespace);
243 	void			Var(NodePtr& var);
244 	void			Variable(NodePtr& variable, bool side_effects_only);
245 	void			VariableToAttrs(NodePtr& node, NodePtr& var, unsigned long& attrs);
246 	void			While(NodePtr& while_node);
247 	void			With(NodePtr& with);
248 
249 // The following globals are read only once and you can compile
250 // many times without having to reload them.
251 	// the resource file information
252 	static rc_t		g_rc;
253 
254 	// the global imports (those which are automatic and
255 	// define the intrinsic functions and types of the language)
256 	static NodePtr		g_global_import;
257 
258 	// the system imports (this is specific to the system you
259 	// are using this compiler for; it defines the system)
260 	static NodePtr		g_system_import;
261 
262 	// the native imports (this is specific to your system
263 	// environment, it defines objects in your environment)
264 	static NodePtr		g_native_import;
265 
266 	const char *		f_home;		// $HOME value
267 	ErrorStream		f_default_error_stream;
268 	ErrorStream *		f_error_stream;
269 	IntOptimizer		f_optimizer;
270 	Options *		f_options;
271 	InputRetriever *	f_input_retriever;
272 	NodePtr			f_program;
273 	time_t			f_time;		// time when the compiler is created
274 	int			f_err_flags;	// when searching a name and it doesn't get resolve, emit these errors
275 	NodePtr			f_scope;	// with() and use namespace list
276 	FILE *			f_db;
277 	size_t			f_db_size;
278 	char *			f_db_data;
279 	size_t			f_db_count;	// valid entries
280 	size_t			f_db_max;	// total # of slots available
281 	char **			f_db_packages;
282 	size_t			f_mod_count;
283 	size_t			f_mod_max;
284 	module_t *		f_modules;	// already loaded files (modules)
285 };
286 
287 
288 
289 
290 
291 };	// namespace as
292 };	// namespace sswf
293