compiler support for babel

This commit is contained in:
Araq
2012-12-07 17:20:51 +01:00
parent 05b05be9f8
commit 1dc362dcd4
5 changed files with 108 additions and 22 deletions

76
compiler/babelcmd.nim Normal file
View File

@@ -0,0 +1,76 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Implements some helper procs for Babel (Nimrod's package manager) support.
import parseutils, strtabs, os, options, msgs, lists
proc addPath*(path: string, info: TLineInfo) =
if not contains(options.searchPaths, path):
lists.PrependStr(options.searchPaths, path)
proc versionSplitPos(s: string): int =
result = s.len-2
while result > 1 and s[result] in {'0'..'9', '.'}: dec result
if s[result] != '-': result = s.len
const
latest = "head"
proc `<.`(a, b: string): bool =
# wether a has a smaller version than b:
if a == latest: return false
var i = 0
var j = 0
var verA = 0
var verB = 0
while true:
let ii = parseInt(a, verA, i)
let jj = parseInt(b, verB, j)
# if A has no number left, but B has, B is prefered: 0.8 vs 0.8.3
if ii <= 0 or jj <= 0: return jj > 0
if verA < verB: return true
elif verA > verB: return false
# else: same version number; continue:
inc i, ii
inc j, jj
if a[i] == '.': inc i
if b[j] == '.': inc j
proc addPackage(packages: PStringTable, p: string) =
let x = versionSplitPos(p)
let name = p.subStr(0, x-1)
if x < p.len:
let version = p.subStr(x+1)
if packages[name] <. version:
packages[name] = version
else:
packages[name] = latest
iterator chosen(packages: PStringTable): string =
for key, val in pairs(packages):
let res = if val == latest: key else: key & '-' & val
yield res
proc addPathRec(dir: string, info: TLineInfo) =
var packages = newStringTable(modeStyleInsensitive)
var pos = dir.len-1
if dir[pos] in {DirSep, AltSep}: inc(pos)
for k,p in os.walkDir(dir):
if k == pcDir and p[pos] != '.':
addPackage(packages, p)
for p in packages.chosen:
if not contains(options.searchPaths, p):
Message(info, hintPath, p)
lists.PrependStr(options.searchPaths, p)
proc babelPath*(path: string, info: TLineInfo) =
addPathRec(path, info)
addPath(path, info)

View File

@@ -11,7 +11,7 @@
import
os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists,
wordrecg, parseutils
wordrecg, parseutils, babelcmd
proc writeCommandLineUsage*()
@@ -193,19 +193,6 @@ proc processPath(path: string): string =
"projectname", options.gProjectName,
"projectpath", options.gProjectPath])
proc addPath(path: string, info: TLineInfo) =
if not contains(options.searchPaths, path):
lists.PrependStr(options.searchPaths, path)
proc addPathRec(dir: string, info: TLineInfo) =
var pos = dir.len-1
if dir[pos] in {DirSep, AltSep}: inc(pos)
for k,p in os.walkDir(dir):
if k == pcDir and p[pos] != '.':
if not contains(options.searchPaths, p):
#Message(info, hintPath, p)
lists.PrependStr(options.searchPaths, p)
proc track(arg: string, info: TLineInfo) =
var a = arg.split(',')
if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLUMN")
@@ -225,11 +212,15 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
of "path", "p":
expectArg(switch, arg, pass, info)
addPath(processPath(arg), info)
of "shallowpath":
of "babelpath":
if pass in {passCmd2, passPP}:
expectArg(switch, arg, pass, info)
let path = processPath(arg)
babelpath(path, info)
of "excludepath":
expectArg(switch, arg, pass, info)
var path = processPath(arg)
addPathRec(path, info)
addPath(path, info)
let path = processPath(arg)
lists.ExcludeStr(options.searchPaths, path)
of "nimcache":
expectArg(switch, arg, pass, info)
options.nimcacheDir = processPath(arg)

View File

@@ -89,7 +89,14 @@ proc Remove*(list: var TLinkedList, entry: PListEntry) =
list.head = entry.next
if entry.next != nil: entry.next.prev = entry.prev
if entry.prev != nil: entry.prev.next = entry.next
proc ExcludeStr*(list: var TLinkedList, data: string) =
var it = list.head
while it != nil:
let nxt = it.next
if PStrEntry(it).data == data: remove(list, it)
it = nxt
proc Find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry =
result = list.head
while result != nil:

View File

@@ -25,8 +25,6 @@ Advanced options:
--warning[X]:on|off turn specific warning X on|off
--hints:on|off turn all hints on|off
--hint[X]:on|off turn specific hint X on|off
--shallowPath:PATH add a path and all of its subdirectories (but
not recursively)
--lib:PATH set the system library path
--import:PATH add an automatically imported module
--include:PATH add an automatically included module
@@ -65,6 +63,8 @@ Advanced options:
--gc:refc|boehm|none use Nimrod's native GC|Boehm GC|no GC
--index:on|off turn index file generation on|off
--putenv:key=value set an environment variable
--babelPath:PATH add a path for Babel support
--excludePath:PATH exclude a path from the list of search paths
--listCmd list the commands used to execute external programs
--parallelBuild=0|1|... perform a parallel build
value = number of processors (0 for auto-detect)

View File

@@ -36,11 +36,23 @@ proc len*(t: PStringTable): int {.rtl, extern: "nst$1".} =
result = t.counter
iterator pairs*(t: PStringTable): tuple[key, value: string] =
## iterates over any (key, value) pair in the table `t`.
## iterates over every (key, value) pair in the table `t`.
for h in 0..high(t.data):
if not isNil(t.data[h].key):
yield (t.data[h].key, t.data[h].val)
iterator keys*(t: PStringTable): string =
## iterates over every key in the table `t`.
for h in 0..high(t.data):
if not isNil(t.data[h].key):
yield t.data[h].key
iterator values*(t: PStringTable): string =
## iterates over every value in the table `t`.
for h in 0..high(t.data):
if not isNil(t.data[h].key):
yield t.data[h].val
type
TFormatFlag* = enum ## flags for the `%` operator
useEnvironment, ## use environment variable if the ``$key``