4
* Copyright (c) 2000, 2006 Michael J. Roberts
6
* This file is part of TADS 3.
12
/* ------------------------------------------------------------------------ */
14
* Main reflection services object.
16
* During pre-initialization, we'll plug this into the _main module's
17
* globals so that the _main module will know it can use reflection
20
reflectionServices: PreinitObject
21
/* execute preinitialization */
24
/* plug ourselves into the main globals */
25
mainGlobal.reflectionObj = self;
27
/* store the main symbol table */
28
symtab_ = t3GetGlobalSymbols();
30
/* create a reverse lookup table from the main symbol table */
34
* create a lookup table for the reverse table - it'll be
35
* the same size as the original table, so create it using
38
reverseSymtab_ = new LookupTable(symtab_.getBucketCount(),
39
symtab_.getEntryCount());
42
* for each entry in the main table, create an entry in the
43
* reverse table with the role of key and value reversed -
44
* this will allow us to look up any value and find its
45
* global symbol, if it has one
47
symtab_.forEachAssoc({key, val: reverseSymtab_[val] = key});
52
* Convert a value to a symbol, or to a string representation if
53
* it's not of a symbolic type.
59
/* the representation depends on the type */
75
* If we're asking about 'self', inherit the handling. Note
76
* that, for any object type, x.ofKind(x) is always true, so
77
* there's no need for a separate test to see if val equals
83
/* use our special value-to-symbol method on the object itself */
84
return val.valToSymbol();
88
* this should usually convert to a symbol, but might have
89
* been allocated dynamically
91
sym = reverseSymtab_[val];
92
return (sym != nil ? sym : '(prop)');
96
/* these should always convert directly to symbols */
97
sym = reverseSymtab_[val];
98
return (sym != nil ? sym : '???');
101
return '(native code)';
109
* Format a stack frame object (of class T3StackInfo).
111
formatStackFrame(fr, includeSourcePos)
115
/* see what kind of frame we have */
118
/* it's a function */
119
ret = valToSymbol(fr.func_);
121
else if (fr.obj_ != nil)
124
* It's an object.property. Check for one special case we
125
* want to show specially: if the object is an AnonFuncPtr
126
* object, ignore the property and just show it as an
127
* anonymous function.
129
if (fr.obj_.ofKind(AnonFuncPtr))
132
ret = valToSymbol(fr.self_) + '.' + valToSymbol(fr.prop_);
136
/* no function or object - must be a system routine */
140
/* if it's not a system routine, add the argument list */
143
/* add the open paren */
146
/* add the arguments */
147
for (local i = 1, local len = fr.argList_.length() ;
150
/* if it's not the first one, add a comma */
155
ret += valToSymbol(fr.argList_[i]);
158
/* add the close paren */
161
/* if desired, add the source location */
162
if (includeSourcePos && fr.srcInfo_ != nil)
163
ret += ' ' + fr.srcInfo_[1] + ', line ' + fr.srcInfo_[2];
166
/* return the result */
170
/* the global symbol table */
173
/* the global reverse-lookup symbol table */
177
/* ------------------------------------------------------------------------ */
179
* Modify the basic Object class to provide a to-symbol mapping
187
/* get my symbol from the global reflection table */
188
sym = reflectionServices.reverseSymtab_[self];
190
/* if we got a symbol, return it */
195
* We didn't get a symbol, so there's no source file name. See
196
* if we can find source-file names for the superclasses, though.
200
foreach (local sc in getSuperclassList())
204
/* add a comma to the list if this isn't the first element */
208
/* if we have a name here, add it to the list */
209
if ((scSym = reflectionServices.reverseSymtab_[sc]) != nil)
211
/* note that we found a named superclass */
214
/* add the superclass name to the list */
219
/* we don't have a name for this superclass; say so */
220
sym += '(anonymous)';
225
* if we found any named superclasses, return the list of names;
226
* otherwise, just say (obj)
228
return (found ? sym + ')' : '(obj)');
232
/* ------------------------------------------------------------------------ */
234
* Modify the String intrinsic class to provide a to-symbol mapping
243
/* start with an open quote */
246
/* loop through the string to find each special character */
247
for (i = 1, local len = length(), start = 1 ;
252
/* presume we won't add a quoted character on this round */
255
/* see what we have here */
292
* if we have a quoted character, add the part up to the
293
* quoted character plus the quoted character
297
/* add the part up to here but not including this char */
299
ret += substr(start, i - start);
301
/* add the quoted form of the character */
304
/* start again after this character */
309
/* add the trailing unquoted part if we haven't already */
311
ret += substr(start, i - start);
313
/* add a close quote and return the result */
318
/* ------------------------------------------------------------------------ */
320
* Modify the List intrinsic class to provide a to-symbol mapping
327
/* start off with an open bracket */
330
/* convert each element to symbolic form */
331
for (local i = 1, local len = length() ; i <= len ; ++i)
333
/* add a comma if this isn't the first element */
337
/* add this element converted to symbolic form */
338
ret += reflectionServices.valToSymbol(self[i]);
341
/* add the close bracket and return the result */
347
/* ------------------------------------------------------------------------ */
349
* If desired, modify the BigNumber intrinsic class to provide a
350
* to-symbol mapping. We only include this modification if the program
351
* is compiled with REFLECT_BIGNUM defined.
353
#ifdef REFLECT_BIGNUM
359
/* use the default formatting */
360
return formatString(12);
364
#endif /* REFLECT_BIGNUM */