summary refs log tree commit diff stats
path: root/nim/options.pas
diff options
context:
space:
mode:
Diffstat (limited to 'nim/options.pas')
-rwxr-xr-xnim/options.pas264
1 files changed, 264 insertions, 0 deletions
diff --git a/nim/options.pas b/nim/options.pas
new file mode 100755
index 000000000..e7ec0a1ce
--- /dev/null
+++ b/nim/options.pas
@@ -0,0 +1,264 @@
+//
+//
+//           The Nimrod Compiler
+//        (c) Copyright 2008 Andreas Rumpf
+//
+//    See the file "copying.txt", included in this
+//    distribution, for details about the copyright.
+//
+unit options;
+
+interface
+
+{$include 'config.inc'}
+
+uses
+  nsystem, nos, lists, strutils;
+
+type
+  // please make sure we have under 32 options
+  // (improves code efficiency a lot!)
+  TOption = (optNone, optRangeCheck,
+    optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
+    optWarns, optHints,
+    optOptimizeSpeed,
+    optOptimizeSize,
+    optStackTrace,     // stack tracing support
+    optLineTrace,      // line tracing support (includes stack tracing)
+    optEndb,           // embedded debugger
+    optByRef,          // use pass by ref for records (for interfacing with C)
+    optCheckpoints     // check for checkpoints (used for debugging)
+  );
+  TOptions = set of TOption;
+
+  TGlobalOption = (gloptNone, optForceFullMake, optBoehmGC,
+    optRefcGC, optDeadCodeElim, optListCmd, optCompileOnly, optNoLinking,
+    optSafeCode,       // only allow safe code
+                       // a new comment line
+    optCDebug,         // turn on debugging information
+    optGenDynLib,
+    optGenGuiApp,
+    optVerbose,        // be verbose
+    optGenScript,      // generate a script file to compile the *.c files
+    optGenMapping,     // generate a mapping file
+    optRun,            // run the compiled project
+    optCompileSys,     // compile system files
+
+    optMergeOutput,    // generate only one C output file
+    optSkipConfigFile, // skip the general config file
+    optSkipProjConfigFile, // skip the project's config file
+    optAstCache,
+    optCFileCache
+  );
+  TGlobalOptions = set of TGlobalOption;
+
+  TCommands = ( // Nimrod's commands
+    cmdNone,
+    cmdCompileToC,
+    cmdCompileToCpp,
+    cmdInterpret,
+    cmdPretty,
+    cmdDoc,
+    cmdPas,
+    cmdBoot,
+    cmdGenDepend,
+    cmdListDef,
+    cmdCheck,      // semantic checking for whole project
+    cmdParse,      // parse a single file (for debugging)
+    cmdScan,       // scan a single file (for debugging)
+    cmdDebugTrans, // debug a transformation pass
+    cmdRst2html    // convert a reStructuredText file to HTML
+  );
+
+  TNumericalBase = (base10, // base10 is listed as the first element,
+                            // so that it is the correct default value
+                    base2,
+                    base8,
+                    base16);
+
+
+const
+  ChecksOptions = {@set}[optRangeCheck, optNilCheck, optOverflowCheck,
+                         optBoundsCheck, optAssert];
+  optionToStr: array [TOption] of string = (
+    'optNone', 'optRangeCheck',
+    'optBoundsCheck', 'optOverflowCheck', 'optNilCheck', 'optAssert',
+    'optLineDir', 'optWarns', 'optHints', 'optOptimizeSpeed',
+    'optOptimizeSize', 'optStackTrace', 'optLineTrace', 'optEmdb',
+    'optByRef', 'optCheckpoints'
+  );
+var
+  gOptions: TOptions = {@set}[optRangeCheck, optBoundsCheck, optOverflowCheck,
+                              optAssert, optWarns, optHints, optLineDir,
+                              optStackTrace, optLineTrace];
+
+  gGlobalOptions: TGlobalOptions = {@set}[optRefcGC];
+
+  compilerArgs: int;
+  gExitcode: Byte;
+  searchPaths: TLinkedList;
+  outFile: string = '';
+  gIndexFile: string = '';
+
+  gCmd: TCommands = cmdNone; // the command
+
+  debugState: int; // a global switch used for better debugging...
+                   // not used for any program logic
+
+
+function FindFile(const f: string): string;
+
+const
+  genSubDir = 'rod_gen';
+  NimExt = 'nim';
+  RodExt = 'rod';
+  HtmlExt = 'html';
+
+function completeGeneratedFilePath(const f: string;
+                                   createSubDir: bool = true): string;
+
+function toGeneratedFile(const path, ext: string): string;
+// converts "/home/a/mymodule.nim", "rod" to "/home/a/rod_gen/mymodule.rod"
+
+function getPrefixDir: string;
+// gets the application directory
+
+// additional configuration variables:
+type
+  TPair = record
+    key, val: string;
+  end;
+  TPairs = array of TPair;
+
+  TStringSeq = array of string;
+var
+  gConfigVars: TPairs = {@ignore} nil {@emit []};
+  libpath: string = '';
+  gKeepComments: boolean = true; // whether the parser needs to keep comments
+  gImplicitMods: TStringSeq = {@ignore} nil {@emit []};
+    // modules that are to be implicitly imported
+
+procedure setConfigVar(const key, val: string);
+function getConfigVar(const key: string): string;
+
+procedure addImplicitMod(const filename: string);
+
+function getOutFile(const filename, ext: string): string;
+
+function binaryStrSearch(const x: array of string; const y: string): int;
+
+implementation
+
+function getOutFile(const filename, ext: string): string;
+begin
+  if options.outFile <> '' then result := options.outFile
+  else result := changeFileExt(filename, ext)
+end;
+
+procedure addImplicitMod(const filename: string);
+var
+  len: int;
+begin
+  len := length(gImplicitMods);
+  setLength(gImplicitMods, len+1);
+  gImplicitMods[len] := filename;
+end;
+
+function getPrefixDir: string;
+var
+  appdir, bin: string;
+begin
+  appdir := getApplicationDir();
+  SplitPath(appdir, result, bin);
+end;
+
+function getConfigIdx(const key: string): int;
+var
+  i: int;
+begin
+  for i := 0 to high(gConfigVars) do
+    if cmpIgnoreStyle(gConfigVars[i].key, key) = 0 then begin
+      result := i; exit end;
+  result := -1
+end;
+
+function getConfigVar(const key: string): string;
+var
+  i: int;
+begin
+  i := getConfigIdx(key);
+  if i >= 0 then result := gConfigVars[i].val
+  else result := ''
+end;
+
+procedure setConfigVar(const key, val: string);
+var
+  i: int;
+begin
+  i := getConfigIdx(key);
+  if i < 0 then begin
+    i := length(gConfigVars);
+    setLength(gConfigVars, i+1);
+    gConfigVars[i].key := key
+  end;
+  gConfigVars[i].val := val
+end;
+
+function toGeneratedFile(const path, ext: string): string;
+var
+  head, tail: string;
+begin
+  splitPath(path, head, tail);
+  result := joinPath([head, genSubDir, changeFileExt(tail, ext)])
+end;
+
+function completeGeneratedFilePath(const f: string;
+                                   createSubDir: bool = true): string;
+var
+  head, tail, subdir: string;
+begin
+  splitPath(f, head, tail);
+  subdir := joinPath(head, genSubDir);
+  if createSubDir then
+    createDir(subdir);
+  result := joinPath(subdir, tail)
+end;
+
+function FindFile(const f: string): string;
+var
+  it: PStrEntry;
+begin
+  if ExistsFile(f) then result := f
+  else begin
+    it := PStrEntry(SearchPaths.head);
+    while it <> nil do begin
+      result := JoinPath(it.data, f);
+      if ExistsFile(result) then exit;
+      it := PStrEntry(it.Next)
+    end;
+    result := ''
+  end
+end;
+
+function binaryStrSearch(const x: array of string; const y: string): int;
+var
+  a, b, mid, c: int;
+begin
+  a := 0;
+  b := length(x)-1;
+  while a <= b do begin
+    mid := (a + b) div 2;
+    c := cmpIgnoreCase(x[mid], y);
+    if c < 0 then
+      a := mid + 1
+    else if c > 0 then
+      b := mid - 1
+    else begin
+      result := mid;
+      exit
+    end
+  end;
+  result := -1
+end;
+
+end.