support for multiple modules of the same name; niminst supports 'platforms'; minor bugfixes
This commit is contained in:
parent
83584bf889
commit
8b5aa221ad
14 changed files with 132 additions and 48 deletions
|
|
@ -1210,7 +1210,7 @@ proc writeHeader(m: BModule) =
|
||||||
writeRope(result, m.filename)
|
writeRope(result, m.filename)
|
||||||
|
|
||||||
proc getCFile(m: BModule): string =
|
proc getCFile(m: BModule): string =
|
||||||
result = changeFileExt(completeCFilePath(m.cfilename), cExt)
|
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), cExt)
|
||||||
|
|
||||||
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
||||||
assert optSymbolFiles in gGlobalOptions
|
assert optSymbolFiles in gGlobalOptions
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,8 @@ var
|
||||||
proc evalWhile(c: PEvalContext, n: PNode): PNode =
|
proc evalWhile(c: PEvalContext, n: PNode): PNode =
|
||||||
while true:
|
while true:
|
||||||
evalX(n.sons[0], {})
|
evalX(n.sons[0], {})
|
||||||
if getOrdValue(result) == 0: break
|
if getOrdValue(result) == 0:
|
||||||
|
result = emptyNode; break
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
case result.kind
|
case result.kind
|
||||||
of nkBreakStmt:
|
of nkBreakStmt:
|
||||||
|
|
@ -304,7 +305,7 @@ proc allocSlot(c: PStackFrame; sym: PSym): int =
|
||||||
setLen(c.slots, max(result+1, c.slots.len))
|
setLen(c.slots, max(result+1, c.slots.len))
|
||||||
|
|
||||||
proc setSlot(c: PStackFrame, sym: PSym, val: PNode) =
|
proc setSlot(c: PStackFrame, sym: PSym, val: PNode) =
|
||||||
assert sym.owner == c.prc
|
assert sym.owner == c.prc or sfFromGeneric in sym.flags
|
||||||
let idx = allocSlot(c, sym)
|
let idx = allocSlot(c, sym)
|
||||||
c.slots[idx] = val
|
c.slots[idx] = val
|
||||||
|
|
||||||
|
|
@ -377,7 +378,7 @@ proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode =
|
||||||
#result = emptyNode
|
#result = emptyNode
|
||||||
|
|
||||||
proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
|
proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
|
||||||
if sfCompileTime in s.flags or c.mode == emRepl:
|
if sfCompileTime in s.flags or c.mode == emRepl or s.kind == skForVar:
|
||||||
result = IdNodeTableGet(c.globals, s)
|
result = IdNodeTableGet(c.globals, s)
|
||||||
if result != nil:
|
if result != nil:
|
||||||
if not aliasNeeded(result, flags):
|
if not aliasNeeded(result, flags):
|
||||||
|
|
@ -549,7 +550,9 @@ proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
of skProc, skConverter, skMacro, skType:
|
of skProc, skConverter, skMacro, skType:
|
||||||
result = n
|
result = n
|
||||||
#result = s.getBody
|
#result = s.getBody
|
||||||
of skVar, skLet, skForVar, skTemp, skResult:
|
of skForVar:
|
||||||
|
result = evalGlobalVar(c, s, flags)
|
||||||
|
of skVar, skLet, skTemp, skResult:
|
||||||
if sfGlobal notin s.flags:
|
if sfGlobal notin s.flags:
|
||||||
result = evalVariable(c.tos, s, flags)
|
result = evalVariable(c.tos, s, flags)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1396,7 +1399,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n)
|
of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n)
|
||||||
of nkStringToCString: result = evalConvStrToCStr(c, n)
|
of nkStringToCString: result = evalConvStrToCStr(c, n)
|
||||||
of nkCStringToString: result = evalConvCStrToStr(c, n)
|
of nkCStringToString: result = evalConvCStrToStr(c, n)
|
||||||
of nkStmtListExpr, nkStmtList, nkModule:
|
of nkStmtListExpr, nkStmtList:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = evalAux(c, n.sons[i], flags)
|
result = evalAux(c, n.sons[i], flags)
|
||||||
case result.kind
|
case result.kind
|
||||||
|
|
@ -1455,7 +1458,7 @@ proc evalConstExprAux*(p: PEvalContext, module, prc: PSym, e: PNode): PNode =
|
||||||
|
|
||||||
proc setupMacroParam(x: PNode): PNode =
|
proc setupMacroParam(x: PNode): PNode =
|
||||||
result = x
|
result = x
|
||||||
if result.kind == nkHiddenStdConv: result = result.sons[1]
|
if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1]
|
||||||
|
|
||||||
proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
|
proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
|
||||||
# XXX GlobalError() is ugly here, but I don't know a better solution for now
|
# XXX GlobalError() is ugly here, but I don't know a better solution for now
|
||||||
|
|
|
||||||
|
|
@ -298,12 +298,12 @@ const
|
||||||
gpp()]
|
gpp()]
|
||||||
|
|
||||||
const
|
const
|
||||||
hExt* = "h"
|
hExt* = ".h"
|
||||||
|
|
||||||
var
|
var
|
||||||
cCompiler* = ccGcc # the used compiler
|
cCompiler* = ccGcc # the used compiler
|
||||||
|
|
||||||
cExt* = "c" # extension of generated C/C++ files
|
cExt* = ".c" # extension of generated C/C++ files
|
||||||
# (can be changed to .cpp later)
|
# (can be changed to .cpp later)
|
||||||
|
|
||||||
cIncludes*: seq[string] = @[] # directories to search for included files
|
cIncludes*: seq[string] = @[] # directories to search for included files
|
||||||
|
|
@ -518,7 +518,7 @@ proc footprint(filename: string): TCrc32 =
|
||||||
getCompileCFileCmd(filename, true)
|
getCompileCFileCmd(filename, true)
|
||||||
|
|
||||||
proc externalFileChanged(filename: string): bool =
|
proc externalFileChanged(filename: string): bool =
|
||||||
var crcFile = toGeneratedFile(filename, "crc")
|
var crcFile = toGeneratedFile(filename.withPackageName, "crc")
|
||||||
var currentCrc = int(footprint(filename))
|
var currentCrc = int(footprint(filename))
|
||||||
var f: TFile
|
var f: TFile
|
||||||
if open(f, crcFile, fmRead):
|
if open(f, crcFile, fmRead):
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,16 @@
|
||||||
[Project]
|
[Project]
|
||||||
Name: "Nimrod"
|
Name: "Nimrod"
|
||||||
Version: "$version"
|
Version: "$version"
|
||||||
OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd"
|
Platforms: """
|
||||||
CPU: "i386;amd64;powerpc64;arm" # ;sparc
|
windows: i386;amd64
|
||||||
|
linux: i386;amd64;powerpc64;arm;sparc;mips
|
||||||
|
macosx: i386;amd64;powerpc64
|
||||||
|
solaris: i386;amd64;sparc
|
||||||
|
freebsd: i386;amd64
|
||||||
|
netbsd: i386;amd64
|
||||||
|
openbsd: i386;amd64
|
||||||
|
haiku: i386;amd64
|
||||||
|
"""
|
||||||
|
|
||||||
Authors: "Andreas Rumpf"
|
Authors: "Andreas Rumpf"
|
||||||
Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
|
Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,18 @@ proc getGeneratedPath: string =
|
||||||
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
|
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
|
||||||
genSubDir
|
genSubDir
|
||||||
|
|
||||||
|
proc withPackageName*(path: string): string =
|
||||||
|
var x = path
|
||||||
|
while true:
|
||||||
|
x = parentDir(x)
|
||||||
|
if x.len == 0: break
|
||||||
|
case x.normalize
|
||||||
|
of "lib", "src", "source", "package", "pckg", "library": discard
|
||||||
|
else:
|
||||||
|
let (path, file, ext) = path.splitFile
|
||||||
|
return (path / (x & '_' & file)) & ext
|
||||||
|
result = path
|
||||||
|
|
||||||
proc toGeneratedFile*(path, ext: string): string =
|
proc toGeneratedFile*(path, ext: string): string =
|
||||||
## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
|
## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
|
||||||
var (head, tail) = splitPath(path)
|
var (head, tail) = splitPath(path)
|
||||||
|
|
|
||||||
|
|
@ -1440,7 +1440,7 @@ proc parseSection(p: var TParser, kind: TNodeKind,
|
||||||
skipComment(p, result)
|
skipComment(p, result)
|
||||||
while sameInd(p):
|
while sameInd(p):
|
||||||
case p.tok.tokType
|
case p.tok.tokType
|
||||||
of tkSymbol, tkAccent:
|
of tkSymbol, tkAccent, tkParLe:
|
||||||
var a = defparser(p)
|
var a = defparser(p)
|
||||||
skipComment(p, a)
|
skipComment(p, a)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
|
|
|
||||||
|
|
@ -818,7 +818,7 @@ proc checkDep(fileIdx: int32): TReasonForRecompile =
|
||||||
gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles
|
gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles
|
||||||
result = rrNone
|
result = rrNone
|
||||||
var r: PRodReader = nil
|
var r: PRodReader = nil
|
||||||
var rodfile = toGeneratedFile(filename, RodExt)
|
var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
|
||||||
r = newRodReader(rodfile, crc, fileIdx)
|
r = newRodReader(rodfile, crc, fileIdx)
|
||||||
if r == nil:
|
if r == nil:
|
||||||
result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
|
result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,8 @@ proc addStmt(w: PRodWriter, n: PNode) =
|
||||||
proc writeRod(w: PRodWriter) =
|
proc writeRod(w: PRodWriter) =
|
||||||
processStacks(w, true)
|
processStacks(w, true)
|
||||||
var f: TFile
|
var f: TFile
|
||||||
if not open(f, completeGeneratedFilePath(changeFileExt(w.filename, "rod")),
|
if not open(f, completeGeneratedFilePath(changeFileExt(
|
||||||
|
w.filename.withPackageName, RodExt)),
|
||||||
fmWrite):
|
fmWrite):
|
||||||
#echo "couldn't write rod file for: ", w.filename
|
#echo "couldn't write rod file for: ", w.filename
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -890,7 +890,7 @@ proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode =
|
||||||
|
|
||||||
proc setupMacroParam(x: PNode): PNode =
|
proc setupMacroParam(x: PNode): PNode =
|
||||||
result = x
|
result = x
|
||||||
if result.kind == nkHiddenStdConv: result = result.sons[1]
|
if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1]
|
||||||
|
|
||||||
proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
|
proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
|
||||||
# XXX GlobalError() is ugly here, but I don't know a better solution for now
|
# XXX GlobalError() is ugly here, but I don't know a better solution for now
|
||||||
|
|
|
||||||
|
|
@ -104,11 +104,12 @@ exprStmt = simpleExpr
|
||||||
| IND{=} 'except' exprList ':' stmt
|
| IND{=} 'except' exprList ':' stmt
|
||||||
| IND{=} 'else' ':' stmt )*
|
| IND{=} 'else' ':' stmt )*
|
||||||
))?
|
))?
|
||||||
importStmt = 'import' optInd expr
|
moduleName = expr ('as' expr)?
|
||||||
((comma expr)*
|
importStmt = 'import' optInd moduleName
|
||||||
|
((comma moduleName)*
|
||||||
/ 'except' optInd (expr ^+ comma))
|
/ 'except' optInd (expr ^+ comma))
|
||||||
includeStmt = 'include' optInd expr ^+ comma
|
includeStmt = 'include' optInd expr ^+ comma
|
||||||
fromStmt = 'from' expr 'import' optInd expr (comma expr)*
|
fromStmt = 'from' moduleName 'import' optInd expr (comma expr)*
|
||||||
returnStmt = 'return' optInd expr?
|
returnStmt = 'return' optInd expr?
|
||||||
raiseStmt = 'raise' optInd expr?
|
raiseStmt = 'raise' optInd expr?
|
||||||
yieldStmt = 'yield' optInd expr?
|
yieldStmt = 'yield' optInd expr?
|
||||||
|
|
|
||||||
|
|
@ -2018,11 +2018,11 @@ Example:
|
||||||
The `when`:idx: statement is almost identical to the ``if`` statement with some
|
The `when`:idx: statement is almost identical to the ``if`` statement with some
|
||||||
exceptions:
|
exceptions:
|
||||||
|
|
||||||
* Each ``expr`` has to be a constant expression (of type ``bool``).
|
* Each condition (``expr``) has to be a constant expression (of type ``bool``).
|
||||||
* The statements do not open a new scope.
|
* The statements do not open a new scope.
|
||||||
* The statements that belong to the expression that evaluated to true are
|
* The statements that belong to the expression that evaluated to true are
|
||||||
translated by the compiler, the other statements are not checked for
|
translated by the compiler, the other statements are not checked for
|
||||||
semantics! However, each ``expr`` is checked for semantics.
|
semantics! However, each condition is checked for semantics.
|
||||||
|
|
||||||
The ``when`` statement enables conditional compilation techniques. As
|
The ``when`` statement enables conditional compilation techniques. As
|
||||||
a special syntactic extension, the ``when`` construct is also available
|
a special syntactic extension, the ``when`` construct is also available
|
||||||
|
|
@ -2268,7 +2268,7 @@ A `table constructor`:idx: is syntactic sugar for an array constructor:
|
||||||
{"key1": "value1", "key2", "key3": "value2"}
|
{"key1": "value1", "key2", "key3": "value2"}
|
||||||
|
|
||||||
# is the same as:
|
# is the same as:
|
||||||
[("key1", "value1"), ("key2", "value2"), ("key3", "value")]
|
[("key1", "value1"), ("key2", "value2"), ("key3", "value2")]
|
||||||
|
|
||||||
|
|
||||||
The empty table can be written ``{:}`` (in contrast to the empty set
|
The empty table can be written ``{:}`` (in contrast to the empty set
|
||||||
|
|
@ -2565,9 +2565,6 @@ Overloading of the subscript operator
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
|
The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
|
||||||
Overloading support is only possible if the first parameter has no type that
|
|
||||||
already supports the built-in ``[]`` notation. Currently the compiler
|
|
||||||
does not check this restriction.
|
|
||||||
|
|
||||||
|
|
||||||
Multi-methods
|
Multi-methods
|
||||||
|
|
@ -3301,13 +3298,11 @@ Specifically, the type class will be matched if:
|
||||||
a) all of the expressions within the body can be compiled for the tested type
|
a) all of the expressions within the body can be compiled for the tested type
|
||||||
b) all statically evaluatable boolean expressions in the body must be true
|
b) all statically evaluatable boolean expressions in the body must be true
|
||||||
|
|
||||||
Please note that the `is` operator allows you to easily verify the precise type
|
Please note that the ``is`` operator allows you to easily verify the precise type
|
||||||
signatures of the required operations, but since type inference and default
|
signatures of the required operations, but since type inference and default
|
||||||
parameters are still applied in the provided block, it's also possible to encode
|
parameters are still applied in the provided block, it's also possible to encode
|
||||||
usage protocols that doesn't reveal implementation details.
|
usage protocols that doesn't reveal implementation details.
|
||||||
|
|
||||||
.. code-block:: nimrod
|
|
||||||
|
|
||||||
Much like generics, the user defined type classes will be instantiated exactly
|
Much like generics, the user defined type classes will be instantiated exactly
|
||||||
once for each tested type and any static code included within them will also be
|
once for each tested type and any static code included within them will also be
|
||||||
executed once.
|
executed once.
|
||||||
|
|
@ -3327,7 +3322,7 @@ from the proc body. This is usually used with the ``auto`` type class:
|
||||||
The return type will be treated as additional generic param and can be
|
The return type will be treated as additional generic param and can be
|
||||||
explicitly specified at call sites as any other generic param.
|
explicitly specified at call sites as any other generic param.
|
||||||
|
|
||||||
Future versions of nimrod may also support overloading based on the return type
|
Future versions of Nimrod may also support overloading based on the return type
|
||||||
of the overloads. In such settings, the expected result type at call sites may
|
of the overloads. In such settings, the expected result type at call sites may
|
||||||
also influence the inferred return type.
|
also influence the inferred return type.
|
||||||
|
|
||||||
|
|
@ -3398,8 +3393,9 @@ templates:
|
||||||
|
|
||||||
The "types" of templates can be the symbols ``expr`` (stands for *expression*),
|
The "types" of templates can be the symbols ``expr`` (stands for *expression*),
|
||||||
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
|
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
|
||||||
description*). These are no real types, they just help the compiler parsing.
|
description*). These are "meta types", they can only be used in certain
|
||||||
Real types can be used too; this implies that expressions are expected.
|
contexts. Real types can be used too; this implies that expressions are
|
||||||
|
expected.
|
||||||
|
|
||||||
|
|
||||||
Ordinary vs immediate templates
|
Ordinary vs immediate templates
|
||||||
|
|
@ -3868,7 +3864,7 @@ values inside containers and so on. For example, here is how one can create
|
||||||
a type-safe wrapper for the unsafe `printf` function from C:
|
a type-safe wrapper for the unsafe `printf` function from C:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
macro safePrintF(formatString: string{lit}, args: vararg[expr]): expr =
|
macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr =
|
||||||
var i = 0
|
var i = 0
|
||||||
for c in formatChars(formatString):
|
for c in formatChars(formatString):
|
||||||
var expectedType = case c
|
var expectedType = case c
|
||||||
|
|
@ -4196,10 +4192,10 @@ implemented with term rewriting:
|
||||||
template optP2{p(x, y, false)}(x, y: expr): expr = x - y
|
template optP2{p(x, y, false)}(x, y: expr): expr = x - y
|
||||||
|
|
||||||
|
|
||||||
Example: hoisting
|
Example: Hoisting
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The following example how some form of hoisting can be implemented:
|
The following example shows how some form of hoisting can be implemented:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
import pegs
|
import pegs
|
||||||
|
|
@ -4267,7 +4263,7 @@ optimization for types that have copying semantics:
|
||||||
|
|
||||||
var t: TTable
|
var t: TTable
|
||||||
# overloading resolution ensures that the optimized []= is called here:
|
# overloading resolution ensures that the optimized []= is called here:
|
||||||
t["abc"] = "xyz"
|
t[f()] = g()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4326,6 +4322,36 @@ module name followed by an ``except`` to prevent some symbols to be imported:
|
||||||
echo "$1" % "abc"
|
echo "$1" % "abc"
|
||||||
|
|
||||||
|
|
||||||
|
Module names in imports
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A module alias can be introduced via the ``as`` keyword:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
import strutils as su, sequtils as qu
|
||||||
|
|
||||||
|
echo su.format("$1", "lalelu")
|
||||||
|
|
||||||
|
The original module name is then not accessible. The
|
||||||
|
notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"``
|
||||||
|
can be used to refer to a module in subdirectories:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
import lib.pure.strutils, lib/pure/os, "lib/pure/times"
|
||||||
|
|
||||||
|
Note that the module name is still ``strutils`` and not ``lib.pure.strutils``
|
||||||
|
and so one **cannot** do:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
import lib.pure.strutils
|
||||||
|
echo lib.pure.strutils
|
||||||
|
|
||||||
|
Likewise the following does not make sense as the name is ``strutils`` already:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
import lib.pure.strutils as strutils
|
||||||
|
|
||||||
|
|
||||||
From import statement
|
From import statement
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
@ -5085,9 +5111,9 @@ string expressions in general:
|
||||||
|
|
||||||
proc getDllName: string =
|
proc getDllName: string =
|
||||||
result = "mylib.dll"
|
result = "mylib.dll"
|
||||||
if ExistsFile(result): return
|
if existsFile(result): return
|
||||||
result = "mylib2.dll"
|
result = "mylib2.dll"
|
||||||
if ExistsFile(result): return
|
if existsFile(result): return
|
||||||
quit("could not load dynamic library")
|
quit("could not load dynamic library")
|
||||||
|
|
||||||
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
|
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ type
|
||||||
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
|
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
|
||||||
nnkStringToCString, nnkCStringToString, nnkAsgn,
|
nnkStringToCString, nnkCStringToString, nnkAsgn,
|
||||||
nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
|
nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
|
||||||
nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef,
|
nnkImportAs, nnkProcDef, nnkMethodDef, nnkConverterDef,
|
||||||
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
|
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
|
||||||
nnkElifBranch, nnkExceptBranch, nnkElse,
|
nnkElifBranch, nnkExceptBranch, nnkElse,
|
||||||
nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,
|
nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -1,6 +1,8 @@
|
||||||
version 0.9.4
|
version 0.9.4
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
- change search path algorithm to care about packages
|
||||||
|
- XXX how can 'lib_system' ever be generated?
|
||||||
- new VM:
|
- new VM:
|
||||||
- implement the glue to replace evals.nim
|
- implement the glue to replace evals.nim
|
||||||
- implement missing magics
|
- implement missing magics
|
||||||
|
|
@ -20,7 +22,6 @@ version 0.9.4
|
||||||
Bugs
|
Bugs
|
||||||
====
|
====
|
||||||
|
|
||||||
- 'quote' without 'do' doesn't work
|
|
||||||
- compilation of niminst takes way too long. looks like a regression
|
- compilation of niminst takes way too long. looks like a regression
|
||||||
- simple closure iterator doesn't work
|
- simple closure iterator doesn't work
|
||||||
- docgen: sometimes effects are listed twice
|
- docgen: sometimes effects are listed twice
|
||||||
|
|
@ -46,6 +47,7 @@ version 0.9.x
|
||||||
* test libffi on windows
|
* test libffi on windows
|
||||||
* test: times.format with the FFI
|
* test: times.format with the FFI
|
||||||
- document NimMain and check whether it works for threading
|
- document NimMain and check whether it works for threading
|
||||||
|
- 'quote' without 'do' doesn't work: parser/grammar issue; could be supported
|
||||||
|
|
||||||
|
|
||||||
version 0.9.X
|
version 0.9.X
|
||||||
|
|
@ -125,7 +127,7 @@ GC
|
||||||
CGEN
|
CGEN
|
||||||
====
|
====
|
||||||
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
|
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
|
||||||
- ``restrict`` pragma + backend support; computed goto support
|
- ``restrict`` pragma + backend support
|
||||||
- 'const' objects including case objects
|
- 'const' objects including case objects
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Installation Generator
|
# The Nimrod Installation Generator
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -52,10 +52,12 @@ type
|
||||||
cat: array[TFileCategory, seq[string]]
|
cat: array[TFileCategory, seq[string]]
|
||||||
binPaths, authors, oses, cpus: seq[string]
|
binPaths, authors, oses, cpus: seq[string]
|
||||||
cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]]
|
cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]]
|
||||||
|
platforms: array[1..maxOS, array[1..maxCPU, bool]]
|
||||||
ccompiler, linker, innosetup: tuple[path, flags: string]
|
ccompiler, linker, innosetup: tuple[path, flags: string]
|
||||||
name, displayName, version, description, license, infile, outdir: string
|
name, displayName, version, description, license, infile, outdir: string
|
||||||
libpath: string
|
libpath: string
|
||||||
innoSetupFlag, installScript, uninstallScript: bool
|
innoSetupFlag, installScript, uninstallScript: bool
|
||||||
|
explicitPlatforms: bool
|
||||||
vars: PStringTable
|
vars: PStringTable
|
||||||
app: TAppType
|
app: TAppType
|
||||||
nimrodArgs: string
|
nimrodArgs: string
|
||||||
|
|
@ -126,7 +128,7 @@ const
|
||||||
Version = "0.9"
|
Version = "0.9"
|
||||||
Usage = "niminst - Nimrod Installation Generator Version " & version & """
|
Usage = "niminst - Nimrod Installation Generator Version " & version & """
|
||||||
|
|
||||||
(c) 2012 Andreas Rumpf
|
(c) 2013 Andreas Rumpf
|
||||||
Usage:
|
Usage:
|
||||||
niminst [options] command[;command2...] ini-file[.ini] [compile_options]
|
niminst [options] command[;command2...] ini-file[.ini] [compile_options]
|
||||||
Command:
|
Command:
|
||||||
|
|
@ -221,6 +223,23 @@ proc yesno(p: var TCfgParser, v: string): bool =
|
||||||
result = false
|
result = false
|
||||||
else: quit(errorStr(p, "unknown value; use: yes|no"))
|
else: quit(errorStr(p, "unknown value; use: yes|no"))
|
||||||
|
|
||||||
|
proc incl(s: var seq[string], x: string): int =
|
||||||
|
for i in 0.. <s.len:
|
||||||
|
if cmpIgnoreStyle(s[i], x) == 0: return i
|
||||||
|
s.add(x)
|
||||||
|
result = s.len-1
|
||||||
|
|
||||||
|
proc platforms(c: var TConfigData, v: string) =
|
||||||
|
for line in splitLines(v):
|
||||||
|
let p = line.find(": ")
|
||||||
|
if p <= 1: continue
|
||||||
|
let os = line.substr(0, p-1).strip
|
||||||
|
let cpus = line.substr(p+1).strip
|
||||||
|
c.oses.add(os)
|
||||||
|
for cpu in cpus.split(';'):
|
||||||
|
let cpuIdx = c.cpus.incl(cpu)
|
||||||
|
c.platforms[c.oses.len][cpuIdx+1] = true
|
||||||
|
|
||||||
proc parseIniFile(c: var TConfigData) =
|
proc parseIniFile(c: var TConfigData) =
|
||||||
var
|
var
|
||||||
p: TCfgParser
|
p: TCfgParser
|
||||||
|
|
@ -244,8 +263,19 @@ proc parseIniFile(c: var TConfigData) =
|
||||||
of "name": c.name = v
|
of "name": c.name = v
|
||||||
of "displayname": c.displayName = v
|
of "displayname": c.displayName = v
|
||||||
of "version": c.version = v
|
of "version": c.version = v
|
||||||
of "os": c.oses = split(v, {';'})
|
of "os":
|
||||||
of "cpu": c.cpus = split(v, {';'})
|
c.oses = split(v, {';'})
|
||||||
|
if c.explicitPlatforms:
|
||||||
|
quit(errorStr(p, "you cannot have both 'platforms' and 'os'"))
|
||||||
|
of "cpu":
|
||||||
|
c.cpus = split(v, {';'})
|
||||||
|
if c.explicitPlatforms:
|
||||||
|
quit(errorStr(p, "you cannot have both 'platforms' and 'cpu'"))
|
||||||
|
of "platforms":
|
||||||
|
platforms(c, v)
|
||||||
|
c.explicitPlatforms = true
|
||||||
|
if c.cpus.len > 0 or c.oses.len > 0:
|
||||||
|
quit(errorStr(p, "you cannot have both 'platforms' and 'os'"))
|
||||||
of "authors": c.authors = split(v, {';'})
|
of "authors": c.authors = split(v, {';'})
|
||||||
of "description": c.description = v
|
of "description": c.description = v
|
||||||
of "app":
|
of "app":
|
||||||
|
|
@ -409,6 +439,7 @@ proc srcdist(c: var TConfigData) =
|
||||||
let osname = c.oses[osA-1]
|
let osname = c.oses[osA-1]
|
||||||
if osname.cmpIgnoreStyle("windows") == 0: winIndex = osA-1
|
if osname.cmpIgnoreStyle("windows") == 0: winIndex = osA-1
|
||||||
for cpuA in 1..c.cpus.len:
|
for cpuA in 1..c.cpus.len:
|
||||||
|
if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue
|
||||||
let cpuname = c.cpus[cpuA-1]
|
let cpuname = c.cpus[cpuA-1]
|
||||||
if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA-1
|
if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA-1
|
||||||
elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA-1
|
elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA-1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue