001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2006-2007 Robert Grimm
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.type;
020:
021: import java.util.ArrayList;
022:
023: import xtc.Constants;
024:
025: import xtc.util.SymbolTable;
026:
027: /**
028: * A factory for programmatically and concisely creating C types.
029: *
030: * @author Robert Grimm
031: * @version $Revision: 1.1 $
032: */
033: public class CFactory {
034:
035: /** A constant void. */
036: private static final Type CONST_VOID;
037:
038: /** A constant char. */
039: private static final Type CONST_CHAR;
040:
041: /** A pointer to char. */
042: private static final Type PTR_2_CHAR;
043:
044: static {
045: CONST_VOID = VoidT.TYPE.annotate().attribute(
046: Constants.ATT_CONSTANT).seal();
047: CONST_CHAR = NumberT.CHAR.annotate().attribute(
048: Constants.ATT_CONSTANT).seal();
049: PTR_2_CHAR = new PointerT(NumberT.CHAR).seal();
050: }
051:
052: // =========================================================================
053:
054: /** The prefix for declarations. */
055: private String prefix;
056:
057: /** The symbol table scope. */
058: private SymbolTable.Scope scope;
059:
060: /**
061: * Create a new C factory.
062: *
063: * @param prefix The prefix for declarations.
064: * @param scope The symbol table scope.
065: */
066: public CFactory(String prefix, SymbolTable.Scope scope) {
067: this .prefix = prefix;
068: this .scope = scope;
069: }
070:
071: // =========================================================================
072:
073: /**
074: * Get the canonical void type.
075: *
076: * @return <code>VoidT.TYPE</code>.
077: */
078: public Type v() {
079: return VoidT.TYPE;
080: }
081:
082: /**
083: * Get a constant void type.
084: *
085: * @return A sealed constant void type.
086: */
087: public Type vc() {
088: return CONST_VOID;
089: }
090:
091: /**
092: * Get the canonical char type.
093: *
094: * @return <code>NumberT.CHAR</code>.
095: */
096: public Type c() {
097: return NumberT.CHAR;
098: }
099:
100: /**
101: * Get a constant char type.
102: *
103: * @return A sealed constant char type.
104: */
105: public Type cc() {
106: return CONST_CHAR;
107: }
108:
109: /**
110: * Get the canonical int type.
111: *
112: * @return <code>NumberT.INT</code>.
113: */
114: public Type i() {
115: return NumberT.INT;
116: }
117:
118: /**
119: * Get the canonical sizeof type.
120: *
121: * @return <code>NumberT.SIZEOF</code>.
122: */
123: public Type size() {
124: return C.SIZEOF;
125: }
126:
127: /**
128: * Create a new pointer type.
129: *
130: * @param type The pointed-to type.
131: * @return The new pointer type.
132: */
133: public PointerT p(Type type) {
134: return new PointerT(type);
135: }
136:
137: /**
138: * Create a new restricted pointer type.
139: *
140: * @param type The pointed-to type.
141: * @return The new restricted pointer type.
142: */
143: public Type pr(Type type) {
144: return new PointerT(type).annotate().attribute(
145: Constants.ATT_RESTRICT);
146: }
147:
148: /**
149: * Get a pointer to void.
150: *
151: * @return A sealed pointer to void.
152: */
153: public Type p2v() {
154: return PointerT.TO_VOID;
155: }
156:
157: /**
158: * Get a pointer to char.
159: *
160: * @return A sealed pointer to char.
161: */
162: public Type p2c() {
163: return PTR_2_CHAR;
164: }
165:
166: /**
167: * Create a new function type with no parameters and a void return
168: * type.
169: *
170: * @return The new function type.
171: */
172: public Type f() {
173: return f(v());
174: }
175:
176: /**
177: * Create a new function type with no parameters.
178: *
179: * @param result The result type.
180: * @return The new function type.
181: */
182: public Type f(Type result) {
183: return new FunctionT(result, new ArrayList<Type>(0), false)
184: .attribute(Constants.ATT_STYLE_NEW);
185: }
186:
187: /**
188: * Create a new function type.
189: *
190: * @param result The result type.
191: * @param param The parameter type.
192: * @return The new function type.
193: */
194: public Type f(Type result, Type param) {
195: ArrayList<Type> params = new ArrayList<Type>(1);
196: params.add(param);
197: FunctionT function = new FunctionT(result, params, false);
198: function.addAttribute(Constants.ATT_STYLE_NEW);
199: return function;
200: }
201:
202: /**
203: * Create a new function type.
204: *
205: * @param result The result type.
206: * @param param1 The first parameter type.
207: * @param param2 The second parameter type.
208: * @return The new function type.
209: */
210: public Type f(Type result, Type param1, Type param2) {
211: ArrayList<Type> params = new ArrayList<Type>(2);
212: params.add(param1);
213: params.add(param2);
214: FunctionT function = new FunctionT(result, params, false);
215: function.addAttribute(Constants.ATT_STYLE_NEW);
216: return function;
217: }
218:
219: /**
220: * Create a new function type.
221: *
222: * @param result The result type.
223: * @param param1 The first parameter type.
224: * @param param2 The second parameter type.
225: * @param param3 The third parameter type.
226: * @return The new function type.
227: */
228: public Type f(Type result, Type param1, Type param2, Type param3) {
229: ArrayList<Type> params = new ArrayList<Type>(3);
230: params.add(param1);
231: params.add(param2);
232: params.add(param3);
233: FunctionT function = new FunctionT(result, params, false);
234: function.addAttribute(Constants.ATT_STYLE_NEW);
235: return function;
236: }
237:
238: // =========================================================================
239:
240: /**
241: * Mark the specified type as constant. Note that this method
242: * directly modifies the specified type.
243: *
244: * @param type The type.
245: * @return The constant type.
246: */
247: public Type constant(Type type) {
248: return type.attribute(Constants.ATT_CONSTANT);
249: }
250:
251: /**
252: * Mark the specified type as builtin. Note that this method
253: * directly modifies the specified type.
254: *
255: * @param type The type.
256: * @return The builtin type.
257: */
258: public Type builtin(Type type) {
259: return type.attribute(Constants.ATT_BUILTIN);
260: }
261:
262: // =========================================================================
263:
264: /**
265: * Add the specified declaration to this factory's symbol table
266: * scope. The specified name is prefixed with this factory's
267: * prefix. The specified type is marked as a built-in type. If the
268: * <code>nofix</code> flag is set, this method also adds a
269: * declaration without this factory's prefix.
270: *
271: * @param nofix The nofix flag.
272: * @param name The name.
273: * @param type The type.
274: * @return This factory.
275: */
276: public CFactory decl(boolean nofix, String name, Type type) {
277: if (nofix) {
278: scope.define(name, builtin(type));
279: }
280: scope.define(prefix + name, builtin(type));
281: return this ;
282: }
283:
284: // =========================================================================
285:
286: /**
287: * Declare built-in functions for C in this factory's symbol table
288: * scope.
289: *
290: * @param nofix The flag for whether to also declare symbols without
291: * this factory's prefix.
292: */
293: public void declareBuiltIns(boolean nofix) {
294:
295: // C99 7.20.3
296: decl(nofix, "calloc", f(p2v(), size(), size()));
297: decl(nofix, "free", f(v(), p2v()));
298: decl(nofix, "malloc", f(p2v(), size()));
299: decl(nofix, "realloc", f(p2v(), p2v(), size()));
300:
301: // C99 7.20.4
302: decl(nofix, "abort", f());
303: decl(nofix, "atexit", f(i(), p(f())));
304: decl(nofix, "exit", f(v(), i()));
305: decl(nofix, "_Exit", f(v(), i()));
306: decl(nofix, "getenv", f(p2c(), p(cc())));
307: decl(nofix, "system", f(i(), p(cc())));
308:
309: // C99 7.21.2
310: decl(nofix, "memcpy", f(p2v(), pr(v()), pr(vc()), size()));
311:
312: // C99 7.21.6
313: decl(nofix, "memset", f(p2v(), p2v(), i(), size()));
314:
315: // GCC extension
316: decl(nofix, "stpcpy", f(p2c(), p2c(), p(cc())));
317:
318: }
319:
320: }
|