File: Function.h

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (224 lines) | stat: -rw-r--r-- 6,128 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#pragma once
#include "Compiler/NamedThread.h"
#include "Compiler/Function.h"
#include "Compiler/Syntax/SStr.h"
#include "Compiler/Syntax/Node.h"
#include "Compiler/Doc.h"
#include "Return.h"
#include "Decl.h"
#include "Param.h"
#include "Block.h"

namespace storm {
	namespace bs {
		STORM_PKG(lang.bs);

		class FnBody;
		class BSFunction;

		/**
		 * Function declaration. This holds the needed information to create each function later
		 * on. Also acts as an intermediate store for types until we have found all types in the
		 * current package. Otherwise, we would behave like C, that the type declarations have to be
		 * before anything that uses them.
		 *
		 * If 'result' is null, then we assume that this function declares a setter function, since
		 * the return type is always 'null' for them.
		 */
		class FunctionDecl : public NamedDecl {
			STORM_CLASS;
		public:
			STORM_CTOR FunctionDecl(SrcPos pos,
									Scope scope,
									MAYBE(SrcName *) result,
									syntax::SStr *name,
									Array<NameParam> *params,
									syntax::Node *options,
									syntax::Node *body);

			// Values.
			SrcPos pos;
			Scope scope;
			syntax::SStr *name;
			MAYBE(SrcName *) result;
			Array<NameParam> *params;
			MAYBE(syntax::Node *) options;
			syntax::Node *body;

			// Temporary solution for updating a function.
			virtual MAYBE(Named *) STORM_FN update(Scope scope);
			void STORM_FN update(BSFunction *fn);

			// Get our name as a NamePart.
			NamePart *STORM_FN namePart() const;


			// To string.
			virtual void STORM_FN toS(StrBuf *to) const;

		private:
			// Create the actual function.
			virtual Named *STORM_FN doCreate();
		};

		// Declare setter functions.
		FunctionDecl *STORM_FN assignDecl(SrcPos pos,
										Scope scope,
										syntax::SStr *name,
										Array<NameParam> *params,
										syntax::Node *options,
										syntax::Node *body);


		/**
		 * Raw function that will not read syntax trees by parsing a string.
		 */
		class BSRawFn : public Function {
			STORM_CLASS;
		public:
			// Create.
			STORM_CTOR BSRawFn(Value result, syntax::SStr *name, Array<ValParam> *params, MAYBE(NamedThread *) thread);

			// Set the thread for this function. Should be done before code is generated for the
			// first time, and before someone else start depending on this function.
			void STORM_FN thread(Scope scope, SrcName *name);

			// Override this to create the syntax tree to compile. Expected to work until 'clearBody' is called.
			// TODO: Mark as abstract.
			virtual FnBody *STORM_FN createBody();

			// Called when we know we don't need the body anymore, i.e. 'createBody' may stop
			// returning sensible results.
			virtual void STORM_FN clearBody();

			// Make this function static by removing the 'this' parameter. Only do this before the
			// function is added to the name tree!
			void STORM_FN makeStatic();

			// Make the function inlineable. Only has affect before the function is compiled.
			void STORM_FN makeInline();

			// Add function parameters to a block. Mainly for internal use.
			Array<LocalVar *> *STORM_FN addParams(Block *block);

			// Get parameters as required by documentation.
			Array<DocParam> *STORM_FN docParams();

		protected:
			// Parameter names and values.
			Array<ValParam> *valParams;

			// Re-compile at next execution.
			void STORM_FN reset();

			// Override if you want to create a CodeGen object yourself.
			virtual CodeGen *STORM_FN createRawBody();

		private:
			// Generate code.
			CodeGen *CODECALL generateCode();

			// Generate code for inline usage.
			void CODECALL generateInlineCode(InlineParams params);

			// Initialize.
			void init(NamedThread *thread);

			// Remember if we have cleared body data.
			Bool bodyCleared;

			// Should we be an inline function?
			Bool isInline;
		};


		/**
		 * Function in the BS language.
		 */
		class BSFunction : public BSRawFn {
			STORM_CLASS;
		public:
			// Create a function.
			STORM_CTOR BSFunction(Value result, syntax::SStr *name, Array<ValParam> *params, Scope scope,
								MAYBE(NamedThread *) thread, syntax::Node *body);

			// Scope.
			Scope scope;

			// Code.
			MAYBE(syntax::Node *) body;

			// Create the body from our string.
			virtual FnBody *STORM_FN createBody();
			virtual void STORM_FN clearBody();

			// Temporary solution for updating a function.
			Bool STORM_FN update(Array<ValParam> *params, syntax::Node *body, SrcPos pos);
			Bool STORM_FN update(Array<ValParam> *params, syntax::Node *body);
			Bool STORM_FN update(Array<Str *> *params, syntax::Node *body);
			Bool STORM_FN update(BSFunction *from);
		};


		/**
		 * Function using a pre-created syntax tree.
		 */
		class BSTreeFn : public BSRawFn {
			STORM_CLASS;
		public:
			// Create.
			STORM_CTOR BSTreeFn(Value result, syntax::SStr *name, Array<ValParam> *params, MAYBE(NamedThread *) thread);

			// Set the root of the syntax tree. Resetting the body also makes the function re-compile.
			void STORM_ASSIGN body(FnBody *body);

			// Override to use the body.
			virtual FnBody *STORM_FN createBody();
			virtual void STORM_FN clearBody();

		private:
			// Body.
			MAYBE(FnBody *) root;
		};


		/**
		 * Abstract function that throws an exception when invoked.
		 */
		class BSAbstractFn : public BSRawFn {
			STORM_CLASS;
		public:
			STORM_CTOR BSAbstractFn(Value result, syntax::SStr *name, Array<ValParam> *params);

		protected:
			// Override to use the body.
			virtual CodeGen *STORM_FN createRawBody();
		};


		/**
		 * Body of a function.
		 */
		class FnBody : public ExprBlock {
			STORM_CLASS;
		public:
			STORM_CTOR FnBody(BSRawFn *owner, Scope scope);
			STORM_CTOR FnBody(BSFunction *owner);

			// Parameters, ordered as they appear in the list of formal parameters.
			Array<LocalVar *> *parameters;

			// Lookup information.
			ReturnInfo *info;

			// Get the type.
			Value STORM_FN type() const { return info->type; }

			// We don't need to create a separate block for the function body itself, we can just
			// use the root block.
			virtual void STORM_FN code(CodeGen *state, CodeResult *to);

		};

	}
}