00001
00013
00014 #include <string.h>
00015 #include <errno.h>
00016
00017 #include "version.h"
00018 #include "NewtEnv.h"
00019 #include "NewtObj.h"
00020 #include "NewtFns.h"
00021 #include "NewtGC.h"
00022 #include "NewtStr.h"
00023 #include "NewtFile.h"
00024
00025
00026
00027 #define SYM_TABLE (newt_env.sym_table)
00028 #define ROOT (newt_env.root)
00029 #define GLOBALS (newt_env.globals)
00030 #define GLOBAL_FNS (newt_env.global_fns)
00031 #define MAGIC_POINTERS (newt_env.magic_pointers)
00032
00033 #define INITSYM2(sym, str) sym = NewtMakeSymbol(str)
00034 #define INITSYM(name) INITSYM2(newt_sym.name, #name)
00035
00036
00037
00038 newt_env_t newt_env;
00039 newt_sym_t newt_sym;
00040
00041
00042
00043 char * replacechr(char * str, char srch, char repl);
00044
00045 static void NewtInitSYM(void);
00046 static void NewtInitSysEnv(void);
00047 static void NewtInitARGV(int argc, const char * argv[], int n);
00048 static void NewtInitVersInfo(void);
00049 static void NewtInitEnv(int argc, const char * argv[], int n);
00050
00051
00052 #pragma mark -
00053
00063 char * replacechr(char * str, char src, char dest)
00064 {
00065 char * s;
00066
00067 for (s = str; *s; s++)
00068 {
00069 if (*s == src) *s = dest;
00070 }
00071
00072 return str;
00073 }
00074
00075
00076 #pragma mark -
00077
00083 char * NewtDefaultEncoding(void)
00084 {
00085 char * encoding = NULL;
00086 char * lang;
00087
00088 lang = (char *)getenv("LANG");
00089 if (! lang) lang = (char *)getenv("LC_ALL");
00090 if (lang) encoding = strchr(lang, '.');
00091
00092 if (encoding)
00093 encoding++;
00094 else
00095 encoding = NEWT_DEFAULT_ENCODING;
00096
00097 return encoding;
00098 }
00099
00100
00101 #pragma mark -
00102
00108 void NewtInitSYM(void)
00109 {
00110
00111 INITSYM(_proto);
00112 INITSYM(_parent);
00113
00114
00115 INITSYM(_implementor);
00116 INITSYM(_nextArgFrame);
00117 INITSYM(CodeBlock);
00118 INITSYM2(NS_CLASS, "class");
00119 INITSYM(instructions);
00120 INITSYM(literals);
00121 INITSYM(argFrame);
00122 INITSYM(numArgs);
00123 INITSYM(indefinite);
00124
00125
00126 INITSYM(_function.native0);
00127 INITSYM(_function.native);
00128 INITSYM(funcPtr);
00129 INITSYM(docString);
00130
00131
00132 INITSYM(binary);
00133 INITSYM(string);
00134 INITSYM(real);
00135 INITSYM(array);
00136 INITSYM(frame);
00137 INITSYM2(NS_INT, "int");
00138 INITSYM(int32);
00139 INITSYM(pathExpr);
00140
00141
00142 INITSYM(collect);
00143 INITSYM(deeply);
00144
00145
00146 INITSYM2(NS_CHAR, "char");
00147 INITSYM(boolean);
00148 INITSYM(weird_immediate);
00149 INITSYM(forEachState);
00150
00151
00152 INITSYM(hasVariable);
00153 INITSYM(hasVar);
00154 INITSYM(defGlobalFn);
00155 INITSYM(defGlobalVar);
00156
00157
00158 INITSYM(mod);
00159 INITSYM(shiftLeft);
00160 INITSYM(shiftRight);
00161 INITSYM(objectEqual);
00162 INITSYM(defMagicPointer);
00163 INITSYM(makeRegex);
00164
00165
00166 INITSYM(type.ref);
00167 INITSYM(ext.ex.msg);
00168
00169
00170 INITSYM(name);
00171 INITSYM(data);
00172 INITSYM(message);
00173 INITSYM(error);
00174
00175 INITSYM(errorCode);
00176 INITSYM(symbol);
00177 INITSYM(value);
00178 INITSYM(index);
00179
00180
00181 INITSYM(sym_table);
00182 INITSYM(globals);
00183 INITSYM(global_fns);
00184 INITSYM(magic_pointers);
00185
00186
00187 INITSYM(printDepth);
00188 INITSYM(printLength);
00189
00190
00191 INITSYM(protoREGEX);
00192 INITSYM(regex);
00193 INITSYM(pattern);
00194 INITSYM(option);
00195
00196
00197 INITSYM(requires);
00198
00199
00200 INITSYM(_ENV_);
00201 INITSYM(NEWTLIB);
00202
00203
00204 INITSYM(_ARGV_);
00205 INITSYM(_EXEDIR_);
00206
00207
00208 INITSYM(_STDOUT_);
00209 INITSYM(_STDERR_);
00210 }
00211
00212
00213
00219 void NewtInitSysEnv(void)
00220 {
00221 struct {
00222 char * name;
00223 newtRefVar slot;
00224 char * defaultValue;
00225 bool ispath;
00226 } envs[] = {
00227 {"NEWTLIB", NSSYM0(NEWTLIB), NULL, true},
00228 {"PLATFORM", NSSYM(PLATFORM), __PLATFORM__, false},
00229 {"DYLIBSUFFIX", NSSYM(DYLIBSUFFIX), __DYLIBSUFFIX__, false},
00230 {NULL, kNewtRefUnbind, NULL, false}
00231 };
00232
00233 newtRefVar env;
00234 newtRefVar proto;
00235 newtRefVar v;
00236 uint16_t i;
00237
00238 env = NcMakeFrame();
00239 proto = NcMakeFrame();
00240
00241 for (i = 0; envs[i].name != NULL; i++)
00242 {
00243 v = NewtGetEnv(envs[i].name);
00244
00245 if (NewtRefIsString(v))
00246 {
00247 if (envs[i].ispath)
00248 v = NcSplit(v, NewtMakeCharacter(':'));
00249
00250 NcSetSlot(proto, envs[i].slot, v);
00251 }
00252 else if (envs[i].defaultValue)
00253 {
00254 NcSetSlot(proto, envs[i].slot, NewtMakeString(envs[i].defaultValue, true));
00255 }
00256 }
00257
00258 NcSetSlot(env, NSSYM0(_proto), NewtPackLiteral(proto));
00259 NcSetSlot(GLOBALS, NSSYM0(_ENV_), env);
00260 }
00261
00262
00263
00273 void NewtInitARGV(int argc, const char * argv[], int n)
00274 {
00275 newtRefVar exepath = kNewtRefUnbind;
00276 newtRefVar r;
00277 uint16_t j;
00278 uint16_t i;
00279
00280 r = NewtMakeArray(kNewtRefUnbind, argc - n);
00281 NcSetSlot(GLOBALS, NSSYM0(_ARGV_), r);
00282
00283 for (i = n, j = 0; i < argc; i++, j++)
00284 {
00285 NewtSetArraySlot(r, j, NewtMakeString(argv[i], true));
00286 }
00287
00288 #ifdef __WIN32__
00289 {
00290 char sep;
00291
00292 sep = NewtGetFileSeparator();
00293
00294 if (sep != '')
00295 {
00296 char * path;
00297
00298 path = strdup(argv[0]);
00299
00300 if (path)
00301 {
00302 replacechr(path, '', sep);
00303 exepath = NewtExpandPath(path);
00304 free(path);
00305 }
00306 else
00307 {
00308 exit(errno);
00309 }
00310 }
00311 }
00312 #endif
00313
00314 if (NewtRefIsNIL(exepath))
00315 exepath = NewtExpandPath(argv[0]);
00316
00317 NcSetSlot(GLOBALS, NSSYM0(_EXEDIR_), NcDirName(exepath));
00318 }
00319
00320
00321
00327 void NewtInitVersInfo(void)
00328 {
00329 newtRefVar versInfo;
00330
00331 versInfo = NcMakeFrame();
00332
00333
00334 NcSetSlot(versInfo, NSSYM(name), NewtMakeString(NEWT_NAME, true));
00335
00336 NcSetSlot(versInfo, NSSYM(proto), NewtMakeString(NEWT_PROTO, true));
00337
00338 NcSetSlot(versInfo, NSSYM(version), NewtMakeString(NEWT_VERSION, true));
00339
00340 NcSetSlot(versInfo, NSSYM(build), NewtMakeString(NEWT_BUILD, true));
00341
00342 NcSetSlot(versInfo, NSSYM(copyright), NewtMakeString(NEWT_COPYRIGHT, true));
00343
00344 NcSetSlot(versInfo, NSSYM(staff), NewtMakeString(NEWT_STAFF, true));
00345
00346
00347 NcSetSlot(GLOBALS, NSSYM(_VERSION_), NewtPackLiteral(versInfo));
00348 }
00349
00350
00351
00361 void NewtInitEnv(int argc, const char * argv[], int n)
00362 {
00363
00364 SYM_TABLE = NewtMakeArray(kNewtRefUnbind, 0);
00365 NewtInitSYM();
00366
00367
00368 ROOT = NcMakeFrame();
00369
00370 GLOBALS = NcMakeFrame();
00371
00372 GLOBAL_FNS = NcMakeFrame();
00373
00374 #ifdef __NAMED_MAGIC_POINTER__
00375 MAGIC_POINTERS = NcMakeFrame();
00376 #else
00377 MAGIC_POINTERS = NewtMakeArray(kNewtRefUnbind, 0);
00378 #endif
00379
00380
00381 NcSetSlot(ROOT, NSSYM0(globals), GLOBALS);
00382 NcSetSlot(ROOT, NSSYM0(global_fns), GLOBAL_FNS);
00383 NcSetSlot(ROOT, NSSYM0(magic_pointers), MAGIC_POINTERS);
00384 NcSetSlot(ROOT, NSSYM0(sym_table), SYM_TABLE);
00385
00386
00387 NewtInitSysEnv();
00388
00389 NewtInitARGV(argc, argv, n);
00390
00391 NewtInitVersInfo();
00392 }
00393
00394
00395
00405 void NewtInit(int argc, const char * argv[], int n)
00406 {
00407
00408 NEWT_POOL = NewtPoolAlloc(NEWT_POOL_EXPANDSPACE);
00409
00410 NewtInitEnv(argc, argv, n);
00411 }
00412
00413
00414
00420 void NewtCleanup(void)
00421 {
00422
00423
00424
00425 if (NEWT_POOL != NULL)
00426 {
00427 NewtPoolRelease(NEWT_POOL);
00428 NewtMemFree(NEWT_POOL);
00429 NEWT_POOL = NULL;
00430 }
00431 }
00432
00433
00434 #pragma mark -
00435
00443 newtRef NewtLookupSymbolTable(const char * name)
00444 {
00445 return NewtLookupSymbol(SYM_TABLE, name, 0, 0);
00446 }
00447
00448
00449 #pragma mark -
00450
00459 bool NewtHasGlobalFn(newtRefArg r)
00460 {
00461 return NewtHasSlot(GLOBAL_FNS, r);
00462 }
00463
00464
00465
00474 bool NewtHasGlobalVar(newtRefArg r)
00475 {
00476 return NewtHasSlot(GLOBALS, r);
00477 }
00478
00479
00480 #pragma mark -
00481
00493 newtRef NsGlobalFnExists(newtRefArg rcvr, newtRefArg r)
00494 {
00495 return NewtMakeBoolean(NewtHasGlobalFn(r));
00496 }
00497
00498
00499 #ifdef __USE_OBSOLETE_STYLE__
00500
00512 newtRef NsHasGlobalFn(newtRefArg rcvr, newtRefArg r)
00513 {
00514 return NewtMakeBoolean(NewtHasGlobalFn(r));
00515 }
00516 #endif
00517
00518
00519
00528 newtRef NsGetGlobalFn(newtRefArg rcvr, newtRefArg r)
00529 {
00530 return NcGetSlot(GLOBAL_FNS, r);
00531 }
00532
00533
00534
00544 newtRef NsDefGlobalFn(newtRefArg rcvr, newtRefArg r, newtRefArg fn)
00545 {
00546 return NcSetSlot(GLOBAL_FNS, r, fn);
00547 }
00548
00549
00550
00559 newtRef NsUndefGlobalFn(newtRefArg rcvr, newtRefArg r)
00560 {
00561 (void) NcRemoveSlot(GLOBAL_FNS, r);
00562 return kNewtRefNIL;
00563 }
00564
00565
00566
00578 newtRef NsGlobalVarExists(newtRefArg rcvr, newtRefArg r)
00579 {
00580 return NewtMakeBoolean(NewtHasGlobalVar(r));
00581 }
00582
00583
00584 #ifdef __USE_OBSOLETE_STYLE__
00585
00597 newtRef NsHasGlobalVar(newtRefArg rcvr, newtRefArg r)
00598 {
00599 return NsGlobalVarExists(rcvr, r);
00600 }
00601 #endif
00602
00603
00604
00613 newtRef NsGetGlobalVar(newtRefArg rcvr, newtRefArg r)
00614 {
00615 return NcGetSlot(GLOBALS, r);
00616 }
00617
00618
00619
00629 newtRef NsDefGlobalVar(newtRefArg rcvr, newtRefArg r, newtRefArg v)
00630 {
00631 return NcSetSlot(GLOBALS, r, v);
00632 }
00633
00634
00635 #ifdef __USE_OBSOLETE_STYLE__
00636
00646 newtRef NsSetGlobalVar(newtRefArg rcvr, newtRefArg r, newtRefArg v)
00647 {
00648 return NcSetSlot(GLOBALS, r, v);
00649 }
00650 #endif
00651
00652
00653
00662 newtRef NsUndefGlobalVar(newtRefArg rcvr, newtRefArg r)
00663 {
00664 (void) NcRemoveSlot(GLOBALS, r);
00665 return kNewtRefNIL;
00666 }
00667
00668
00669 #ifdef __NAMED_MAGIC_POINTER__
00670
00671
00679 newtRef NcResolveMagicPointer(newtRefArg r)
00680 {
00681 newtRefVar sym;
00682
00683 if (! NewtRefIsMagicPointer(r))
00684 return r;
00685
00686 sym = NewtMPToSymbol(r);
00687
00688 if (NewtHasSlot(MAGIC_POINTERS, sym))
00689 return NcGetSlot(MAGIC_POINTERS, sym);
00690 else
00691 return r;
00692 }
00693
00694
00695
00705 newtRef NsDefMagicPointer(newtRefArg rcvr, newtRefArg r, newtRefArg v)
00706 {
00707 newtRefVar sym;
00708
00709 if (NewtRefIsMagicPointer(r))
00710 {
00711 sym = NewtMPToSymbol(r);
00712 }
00713 else if (NewtRefIsSymbol(r))
00714 {
00715 sym = r;
00716 }
00717 else
00718 {
00719 return r;
00720 }
00721
00722 return NcSetSlot(MAGIC_POINTERS, sym, v);
00723 }
00724
00725
00726 #else
00727
00728
00736 newtRef NcResolveMagicPointer(newtRefArg r)
00737 {
00738 int32_t table = 0;
00739 int32_t index;
00740
00741 if (! NewtRefIsMagicPointer(r))
00742 return r;
00743
00744 table = NewtMPToTable(r);
00745 index = NewtMPToIndex(r);
00746
00747 if (table != 0)
00748 {
00749 return r;
00750 }
00751
00752 if (index < NewtLength(MAGIC_POINTERS))
00753 {
00754 newtRefVar result;
00755
00756 result = NewtGetArraySlot(MAGIC_POINTERS, index);
00757
00758 if (result != kNewtRefUnbind)
00759 return result;
00760 }
00761
00762 return r;
00763 }
00764
00765
00766
00776 newtRef NsDefMagicPointer(newtRefArg rcvr, newtRefArg r, newtRefArg v)
00777 {
00778 int32_t table = 0;
00779 int32_t index;
00780
00781 if (NewtRefIsMagicPointer(r))
00782 {
00783 table = NewtMPToTable(r);
00784 index = NewtMPToIndex(r);
00785
00786 if (table != 0)
00787 {
00788 return kNewtRefUnbind;
00789 }
00790 }
00791 else if (NewtRefIsInteger(r))
00792 {
00793 index = NewtRefToInteger(r);
00794 }
00795 else
00796 {
00797 return kNewtRefUnbind;
00798 }
00799
00800 if (NewtLength(MAGIC_POINTERS) <= index)
00801 {
00802 NewtSetLength(MAGIC_POINTERS, index + 1);
00803 }
00804
00805 return NewtSetArraySlot(MAGIC_POINTERS, index, v);
00806 }
00807
00808 #endif
00809
00810
00811 #pragma mark -
00812
00820 newtRef NsGetRoot(newtRefArg rcvr)
00821 {
00822 return ROOT;
00823 }
00824
00825
00826
00834 newtRef NsGetGlobals(newtRefArg rcvr)
00835 {
00836 return GLOBALS;
00837 }
00838
00839
00840
00848 newtRef NsGetGlobalFns(newtRefArg rcvr)
00849 {
00850 return GLOBAL_FNS;
00851 }
00852
00853
00854
00862 newtRef NsGetMagicPointers(newtRefArg rcvr)
00863 {
00864 return MAGIC_POINTERS;
00865 }
00866
00867
00868
00876 newtRef NsGetSymTable(newtRefArg rcvr)
00877 {
00878 return SYM_TABLE;
00879 }
00880