Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
commit
4fd42d5150
43 changed files with 262 additions and 177 deletions
|
|
@ -337,7 +337,9 @@ type
|
||||||
mFields, mFieldPairs,
|
mFields, mFieldPairs,
|
||||||
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
||||||
mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, mAssert,
|
mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, mAssert,
|
||||||
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mReset,
|
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
|
||||||
|
mNewString, mNewStringOfCap,
|
||||||
|
mReset,
|
||||||
mArray, mOpenArray, mRange, mSet, mSeq,
|
mArray, mOpenArray, mRange, mSet, mSeq,
|
||||||
mOrdinal, mInt, mInt8, mInt16, mInt32,
|
mOrdinal, mInt, mInt8, mInt16, mInt32,
|
||||||
mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring,
|
mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring,
|
||||||
|
|
|
||||||
|
|
@ -1457,7 +1457,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
|
of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
|
||||||
mInSet:
|
mInSet:
|
||||||
genSetOp(p, e, d, op)
|
genSetOp(p, e, d, op)
|
||||||
of mNewString, mCopyStr, mCopyStrLast, mExit: genCall(p, e, d)
|
of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit:
|
||||||
|
genCall(p, e, d)
|
||||||
of mReset: genReset(p, e)
|
of mReset: genReset(p, e)
|
||||||
of mEcho: genEcho(p, e)
|
of mEcho: genEcho(p, e)
|
||||||
of mArrToSeq: genArrToSeq(p, e, d)
|
of mArrToSeq: genArrToSeq(p, e, d)
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
|
||||||
inc(i)
|
inc(i)
|
||||||
var j = i
|
var j = i
|
||||||
while frmt[j] in IdentChars: inc(j)
|
while frmt[j] in IdentChars: inc(j)
|
||||||
var ident = copy(frmt, i, j-1)
|
var ident = substr(frmt, i, j-1)
|
||||||
i = j
|
i = j
|
||||||
app(result, cgsym(m, ident))
|
app(result, cgsym(m, ident))
|
||||||
elif frmt[i] == '#' and frmt[i+1] == '$':
|
elif frmt[i] == '#' and frmt[i+1] == '$':
|
||||||
|
|
@ -225,7 +225,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: openarray[PRope]): PRope =
|
||||||
if frmt[i] != '$' and frmt[i] != '#': inc(i)
|
if frmt[i] != '$' and frmt[i] != '#': inc(i)
|
||||||
else: break
|
else: break
|
||||||
if i - 1 >= start:
|
if i - 1 >= start:
|
||||||
app(result, copy(frmt, start, i - 1))
|
app(result, substr(frmt, start, i - 1))
|
||||||
|
|
||||||
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
|
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
|
||||||
args: openarray[PRope]) =
|
args: openarray[PRope]) =
|
||||||
|
|
@ -489,9 +489,9 @@ proc libCandidates(s: string, dest: var TStringSeq) =
|
||||||
var le = strutils.find(s, '(')
|
var le = strutils.find(s, '(')
|
||||||
var ri = strutils.find(s, ')', le+1)
|
var ri = strutils.find(s, ')', le+1)
|
||||||
if le >= 0 and ri > le:
|
if le >= 0 and ri > le:
|
||||||
var prefix = copy(s, 0, le - 1)
|
var prefix = substr(s, 0, le - 1)
|
||||||
var suffix = copy(s, ri + 1)
|
var suffix = substr(s, ri + 1)
|
||||||
for middle in split(copy(s, le + 1, ri - 1), '|'):
|
for middle in split(substr(s, le + 1, ri - 1), '|'):
|
||||||
libCandidates(prefix & middle & suffix, dest)
|
libCandidates(prefix & middle & suffix, dest)
|
||||||
else:
|
else:
|
||||||
add(dest, s)
|
add(dest, s)
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass,
|
||||||
else: break
|
else: break
|
||||||
inc(i)
|
inc(i)
|
||||||
if i >= len(switch): arg = ""
|
if i >= len(switch): arg = ""
|
||||||
elif switch[i] in {':', '=', '['}: arg = copy(switch, i + 1)
|
elif switch[i] in {':', '=', '['}: arg = substr(switch, i + 1)
|
||||||
else: InvalidCmdLineOption(pass, switch, info)
|
else: InvalidCmdLineOption(pass, switch, info)
|
||||||
|
|
||||||
proc ProcessOnOffSwitch(op: TOptions, arg: string, pass: TCmdlinePass,
|
proc ProcessOnOffSwitch(op: TOptions, arg: string, pass: TCmdlinePass,
|
||||||
|
|
@ -215,7 +215,7 @@ proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
|
||||||
var x = findStr(msgs.WarningsToStr, id)
|
var x = findStr(msgs.WarningsToStr, id)
|
||||||
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
if x >= 0: n = TNoteKind(x + ord(warnMin))
|
||||||
else: InvalidCmdLineOption(pass, arg, info)
|
else: InvalidCmdLineOption(pass, arg, info)
|
||||||
case whichKeyword(copy(arg, i))
|
case whichKeyword(substr(arg, i))
|
||||||
of wOn: incl(gNotes, n)
|
of wOn: incl(gNotes, n)
|
||||||
of wOff: excl(gNotes, n)
|
of wOff: excl(gNotes, n)
|
||||||
else: LocalError(info, errOnOrOffExpectedButXFound, arg)
|
else: LocalError(info, errOnOrOffExpectedButXFound, arg)
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
|
||||||
while i < L:
|
while i < L:
|
||||||
if (frmt[i] != '$'): inc(i)
|
if (frmt[i] != '$'): inc(i)
|
||||||
else: break
|
else: break
|
||||||
if i - 1 >= start: app(result, copy(frmt, start, i - 1))
|
if i - 1 >= start: app(result, substr(frmt, start, i - 1))
|
||||||
|
|
||||||
proc addXmlChar(dest: var string, c: Char) =
|
proc addXmlChar(dest: var string, c: Char) =
|
||||||
case c
|
case c
|
||||||
|
|
@ -581,10 +581,10 @@ proc renderCodeBlock(d: PDoc, n: PRstNode): PRope =
|
||||||
case g.kind
|
case g.kind
|
||||||
of gtEof: break
|
of gtEof: break
|
||||||
of gtNone, gtWhitespace:
|
of gtNone, gtWhitespace:
|
||||||
app(result, copy(m.text, g.start + 0, g.length + g.start - 1 + 0))
|
app(result, substr(m.text, g.start + 0, g.length + g.start - 1))
|
||||||
else:
|
else:
|
||||||
dispA(result, "<span class=\"$2\">$1</span>", "\\span$2{$1}", [
|
dispA(result, "<span class=\"$2\">$1</span>", "\\span$2{$1}", [
|
||||||
toRope(esc(copy(m.text, g.start + 0, g.length + g.start - 1 + 0))),
|
toRope(esc(substr(m.text, g.start + 0, g.length + g.start - 1))),
|
||||||
toRope(tokenClassToStr[g.kind])])
|
toRope(tokenClassToStr[g.kind])])
|
||||||
deinitGeneralTokenizer(g)
|
deinitGeneralTokenizer(g)
|
||||||
if result != nil:
|
if result != nil:
|
||||||
|
|
|
||||||
|
|
@ -990,6 +990,12 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
var a = result
|
var a = result
|
||||||
result = newNodeIT(nkStrLit, n.info, n.typ)
|
result = newNodeIT(nkStrLit, n.info, n.typ)
|
||||||
result.strVal = newString(int(getOrdValue(a)))
|
result.strVal = newString(int(getOrdValue(a)))
|
||||||
|
of mNewStringOfCap:
|
||||||
|
result = evalAux(c, n.sons[1], {})
|
||||||
|
if isSpecial(result): return
|
||||||
|
var a = result
|
||||||
|
result = newNodeIT(nkStrLit, n.info, n.typ)
|
||||||
|
result.strVal = newString(0)
|
||||||
else:
|
else:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,14 @@ proc parseLine(p: var TTmplParser) =
|
||||||
of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator,
|
of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator,
|
||||||
wConverter, wMacro, wTemplate, wMethod:
|
wConverter, wMacro, wTemplate, wMethod:
|
||||||
LLStreamWrite(p.outp, repeatChar(p.indent))
|
LLStreamWrite(p.outp, repeatChar(p.indent))
|
||||||
LLStreamWrite(p.outp, copy(p.x, d))
|
LLStreamWrite(p.outp, substr(p.x, d))
|
||||||
inc(p.indent, 2)
|
inc(p.indent, 2)
|
||||||
of wElif, wOf, wElse, wExcept, wFinally:
|
of wElif, wOf, wElse, wExcept, wFinally:
|
||||||
LLStreamWrite(p.outp, repeatChar(p.indent - 2))
|
LLStreamWrite(p.outp, repeatChar(p.indent - 2))
|
||||||
LLStreamWrite(p.outp, copy(p.x, d))
|
LLStreamWrite(p.outp, substr(p.x, d))
|
||||||
else:
|
else:
|
||||||
LLStreamWrite(p.outp, repeatChar(p.indent))
|
LLStreamWrite(p.outp, repeatChar(p.indent))
|
||||||
LLStreamWrite(p.outp, copy(p.x, d))
|
LLStreamWrite(p.outp, substr(p.x, d))
|
||||||
p.state = psDirective
|
p.state = psDirective
|
||||||
else:
|
else:
|
||||||
# data line
|
# data line
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ proc LLStreamReadAll(s: PLLStream): string =
|
||||||
result = ""
|
result = ""
|
||||||
of llsString:
|
of llsString:
|
||||||
if s.rd == 0: result = s.s
|
if s.rd == 0: result = s.s
|
||||||
else: result = copy(s.s, s.rd + 0)
|
else: result = substr(s.s, s.rd)
|
||||||
s.rd = len(s.s)
|
s.rd = len(s.s)
|
||||||
of llsFile:
|
of llsFile:
|
||||||
result = newString(bufSize)
|
result = newString(bufSize)
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||||
# we fix this here
|
# we fix this here
|
||||||
var bracketLe = strutils.find(p.key, '[')
|
var bracketLe = strutils.find(p.key, '[')
|
||||||
if bracketLe >= 0:
|
if bracketLe >= 0:
|
||||||
var key = copy(p.key, 0, bracketLe - 1)
|
var key = substr(p.key, 0, bracketLe - 1)
|
||||||
var val = copy(p.key, bracketLe + 1) & ':' & p.val
|
var val = substr(p.key, bracketLe + 1) & ':' & p.val
|
||||||
ProcessSwitch(key, val, pass, cmdLineInfo)
|
ProcessSwitch(key, val, pass, cmdLineInfo)
|
||||||
else:
|
else:
|
||||||
ProcessSwitch(p.key, p.val, pass, cmdLineInfo)
|
ProcessSwitch(p.key, p.val, pass, cmdLineInfo)
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,13 @@ proc `%`(f: string, t: PStringTable, flags: TFormatFlags = {}): string =
|
||||||
of '{':
|
of '{':
|
||||||
var j = i + 1
|
var j = i + 1
|
||||||
while (j <= len(f) + 0 - 1) and (f[j] != '}'): inc(j)
|
while (j <= len(f) + 0 - 1) and (f[j] != '}'): inc(j)
|
||||||
var key = copy(f, i + 2 + 0 - 1, j - 1 + 0 - 1)
|
var key = substr(f, i + 2 + 0 - 1, j - 1 + 0 - 1)
|
||||||
add(result, getValue(t, flags, key))
|
add(result, getValue(t, flags, key))
|
||||||
i = j + 1
|
i = j + 1
|
||||||
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_':
|
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_':
|
||||||
var j = i + 1
|
var j = i + 1
|
||||||
while (j <= len(f) + 0 - 1) and (f[j] in PatternChars): inc(j)
|
while (j <= len(f) + 0 - 1) and (f[j] in PatternChars): inc(j)
|
||||||
var key = copy(f, i + 1 + 0 - 1, j - 1 + 0 - 1)
|
var key = substr(f, i + 1 + 0 - 1, j - 1 + 0 - 1)
|
||||||
add(result, getValue(t, flags, key))
|
add(result, getValue(t, flags, key))
|
||||||
i = j
|
i = j
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -138,19 +138,19 @@ proc shortenDir(dir: string): string =
|
||||||
# returns the interesting part of a dir
|
# returns the interesting part of a dir
|
||||||
var prefix = getPrefixDir() & dirSep
|
var prefix = getPrefixDir() & dirSep
|
||||||
if startsWith(dir, prefix):
|
if startsWith(dir, prefix):
|
||||||
return copy(dir, len(prefix))
|
return substr(dir, len(prefix))
|
||||||
prefix = getCurrentDir() & dirSep
|
prefix = getCurrentDir() & dirSep
|
||||||
if startsWith(dir, prefix):
|
if startsWith(dir, prefix):
|
||||||
return copy(dir, len(prefix))
|
return substr(dir, len(prefix))
|
||||||
prefix = projectPath & dirSep #writeln(output, prefix);
|
prefix = projectPath & dirSep #writeln(output, prefix);
|
||||||
#writeln(output, dir);
|
#writeln(output, dir);
|
||||||
if startsWith(dir, prefix):
|
if startsWith(dir, prefix):
|
||||||
return copy(dir, len(prefix))
|
return substr(dir, len(prefix))
|
||||||
result = dir
|
result = dir
|
||||||
|
|
||||||
proc removeTrailingDirSep*(path: string): string =
|
proc removeTrailingDirSep*(path: string): string =
|
||||||
if (len(path) > 0) and (path[len(path) - 1] == dirSep):
|
if (len(path) > 0) and (path[len(path) - 1] == dirSep):
|
||||||
result = copy(path, 0, len(path) - 2)
|
result = substr(path, 0, len(path) - 2)
|
||||||
else:
|
else:
|
||||||
result = path
|
result = path
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ proc processMagic(c: PContext, n: PNode, s: PSym) =
|
||||||
# treat them as imported, instead of modifing a lot of working code
|
# treat them as imported, instead of modifing a lot of working code
|
||||||
# BUGFIX: magic does not imply ``lfNoDecl`` anymore!
|
# BUGFIX: magic does not imply ``lfNoDecl`` anymore!
|
||||||
for m in countup(low(TMagic), high(TMagic)):
|
for m in countup(low(TMagic), high(TMagic)):
|
||||||
if copy($m, 1) == v:
|
if substr($m, 1) == v:
|
||||||
s.magic = m
|
s.magic = m
|
||||||
return
|
return
|
||||||
Message(n.info, warnUnknownMagic, v)
|
Message(n.info, warnUnknownMagic, v)
|
||||||
|
|
@ -333,12 +333,12 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
|
||||||
var a = 0
|
var a = 0
|
||||||
while true:
|
while true:
|
||||||
var b = strutils.find(str, marker, a)
|
var b = strutils.find(str, marker, a)
|
||||||
var sub = if b < 0: copy(str, a) else: copy(str, a, b - 1)
|
var sub = if b < 0: substr(str, a) else: substr(str, a, b - 1)
|
||||||
if sub != "": addSon(result, newStrNode(nkStrLit, sub))
|
if sub != "": addSon(result, newStrNode(nkStrLit, sub))
|
||||||
if b < 0: break
|
if b < 0: break
|
||||||
var c = strutils.find(str, marker, b + 1)
|
var c = strutils.find(str, marker, b + 1)
|
||||||
if c < 0: sub = copy(str, b + 1)
|
if c < 0: sub = substr(str, b + 1)
|
||||||
else: sub = copy(str, b + 1, c - 1)
|
else: sub = substr(str, b + 1, c - 1)
|
||||||
if sub != "":
|
if sub != "":
|
||||||
var e = SymtabGet(con.tab, getIdent(sub))
|
var e = SymtabGet(con.tab, getIdent(sub))
|
||||||
if e != nil:
|
if e != nil:
|
||||||
|
|
|
||||||
|
|
@ -1106,7 +1106,7 @@ proc getNextTok(r: var TSrcGen, kind: var TTokType, literal: var string) =
|
||||||
if r.idx < len(r.tokens):
|
if r.idx < len(r.tokens):
|
||||||
kind = r.tokens[r.idx].kind
|
kind = r.tokens[r.idx].kind
|
||||||
var length = r.tokens[r.idx].length
|
var length = r.tokens[r.idx].length
|
||||||
literal = copy(r.buf, r.pos + 0, r.pos + 0 + length - 1)
|
literal = substr(r.buf, r.pos + 0, r.pos + 0 + length - 1)
|
||||||
inc(r.pos, length)
|
inc(r.pos, length)
|
||||||
inc(r.idx)
|
inc(r.idx)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ proc ropef(frmt: TFormatStr, args: openarray[PRope]): PRope =
|
||||||
if (frmt[i] != '$'): inc(i)
|
if (frmt[i] != '$'): inc(i)
|
||||||
else: break
|
else: break
|
||||||
if i - 1 >= start:
|
if i - 1 >= start:
|
||||||
app(result, copy(frmt, start, i - 1))
|
app(result, substr(frmt, start, i - 1))
|
||||||
assert(RopeInvariant(result))
|
assert(RopeInvariant(result))
|
||||||
|
|
||||||
proc appf(c: var PRope, frmt: TFormatStr, args: openarray[PRope]) =
|
proc appf(c: var PRope, frmt: TFormatStr, args: openarray[PRope]) =
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2010 Andreas Rumpf
|
# (c) Copyright 2011 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.
|
||||||
|
|
@ -189,9 +189,9 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
of mBoolToStr:
|
of mBoolToStr:
|
||||||
if getOrdValue(a) == 0: result = newStrNodeT("false", n)
|
if getOrdValue(a) == 0: result = newStrNodeT("false", n)
|
||||||
else: result = newStrNodeT("true", n)
|
else: result = newStrNodeT("true", n)
|
||||||
of mCopyStr: result = newStrNodeT(copy(getStr(a), int(getOrdValue(b))), n)
|
of mCopyStr: result = newStrNodeT(substr(getStr(a), int(getOrdValue(b))), n)
|
||||||
of mCopyStrLast:
|
of mCopyStrLast:
|
||||||
result = newStrNodeT(copy(getStr(a), int(getOrdValue(b)),
|
result = newStrNodeT(substr(getStr(a), int(getOrdValue(b)),
|
||||||
int(getOrdValue(c))), n)
|
int(getOrdValue(c))), n)
|
||||||
of mFloatToStr: result = newStrNodeT($(getFloat(a)), n)
|
of mFloatToStr: result = newStrNodeT($(getFloat(a)), n)
|
||||||
of mCStrToStr, mCharToStr: result = newStrNodeT(getStrOrChar(a), n)
|
of mCStrToStr, mCharToStr: result = newStrNodeT(getStrOrChar(a), n)
|
||||||
|
|
@ -205,7 +205,8 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||||
of mCompileOptionArg:
|
of mCompileOptionArg:
|
||||||
result = newIntNodeT(Ord(
|
result = newIntNodeT(Ord(
|
||||||
testCompileOptionArg(getStr(a), getStr(b), n.info)), n)
|
testCompileOptionArg(getStr(a), getStr(b), n.info)), n)
|
||||||
of mNewString, mExit, mInc, ast.mDec, mEcho, mAssert, mSwap, mAppendStrCh,
|
of mNewString, mNewStringOfCap,
|
||||||
|
mExit, mInc, ast.mDec, mEcho, mAssert, mSwap, mAppendStrCh,
|
||||||
mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq,
|
mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq,
|
||||||
mNLen..mNError, mEqRef:
|
mNLen..mNError, mEqRef:
|
||||||
nil
|
nil
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ type
|
||||||
|
|
||||||
TTypeRelation* = enum # order is important!
|
TTypeRelation* = enum # order is important!
|
||||||
isNone, isConvertible, isIntConv, isSubtype,
|
isNone, isConvertible, isIntConv, isSubtype,
|
||||||
isLifted, # match, but do not change argument type to formal's type!
|
|
||||||
isGeneric,
|
isGeneric,
|
||||||
isEqual
|
isEqual
|
||||||
|
|
||||||
|
|
@ -185,9 +184,6 @@ proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
var x = f.n.sons[i].sym
|
var x = f.n.sons[i].sym
|
||||||
var y = a.n.sons[i].sym
|
var y = a.n.sons[i].sym
|
||||||
if x.name.id != y.name.id: return isNone
|
if x.name.id != y.name.id: return isNone
|
||||||
elif sonsLen(f) == 0:
|
|
||||||
idTablePut(mapping, f, a)
|
|
||||||
result = isLifted
|
|
||||||
|
|
||||||
proc constraintRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
proc constraintRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
result = isNone
|
result = isNone
|
||||||
|
|
@ -226,7 +222,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
of tyFloat64: result = handleFloatRange(f, a)
|
of tyFloat64: result = handleFloatRange(f, a)
|
||||||
of tyFloat128: result = handleFloatRange(f, a)
|
of tyFloat128: result = handleFloatRange(f, a)
|
||||||
of tyVar:
|
of tyVar:
|
||||||
if (a.kind == f.kind): result = typeRel(mapping, base(f), base(a))
|
if a.kind == f.kind: result = typeRel(mapping, base(f), base(a))
|
||||||
else: result = typeRel(mapping, base(f), a)
|
else: result = typeRel(mapping, base(f), a)
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
# tyArrayConstr cannot happen really, but
|
# tyArrayConstr cannot happen really, but
|
||||||
|
|
@ -493,9 +489,6 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
of isSubtype:
|
of isSubtype:
|
||||||
inc(m.subtypeMatches)
|
inc(m.subtypeMatches)
|
||||||
result = implicitConv(nkHiddenSubConv, f, copyTree(arg), m, c)
|
result = implicitConv(nkHiddenSubConv, f, copyTree(arg), m, c)
|
||||||
of isLifted:
|
|
||||||
inc(m.genericMatches)
|
|
||||||
result = copyTree(arg)
|
|
||||||
of isGeneric:
|
of isGeneric:
|
||||||
inc(m.genericMatches)
|
inc(m.genericMatches)
|
||||||
result = copyTree(arg)
|
result = copyTree(arg)
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode =
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
while line[i] in WhiteSpace: inc(i)
|
while line[i] in WhiteSpace: inc(i)
|
||||||
var q: TParser
|
var q: TParser
|
||||||
OpenParser(q, filename, LLStreamOpen(copy(line, i)))
|
OpenParser(q, filename, LLStreamOpen(substr(line, i)))
|
||||||
result = parser.parseAll(q)
|
result = parser.parseAll(q)
|
||||||
CloseParser(q)
|
CloseParser(q)
|
||||||
LLStreamClose(s)
|
LLStreamClose(s)
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ get get, ``[]`` consider overloading ``[]`` for get;
|
||||||
prefix: ``len`` instead of ``getLen``
|
prefix: ``len`` instead of ``getLen``
|
||||||
length len also used for *number of elements*
|
length len also used for *number of elements*
|
||||||
size size, len size should refer to a byte size
|
size size, len size should refer to a byte size
|
||||||
|
capacity cap
|
||||||
memory mem implies a low-level operation
|
memory mem implies a low-level operation
|
||||||
items items default iterator over a collection
|
items items default iterator over a collection
|
||||||
pairs pairs iterator over (key, value) pairs
|
pairs pairs iterator over (key, value) pairs
|
||||||
|
|
@ -69,6 +70,7 @@ coordinate coord
|
||||||
rectangle rect
|
rectangle rect
|
||||||
point point
|
point point
|
||||||
symbol sym
|
symbol sym
|
||||||
|
string str
|
||||||
identifier ident
|
identifier ident
|
||||||
indentation indent
|
indentation indent
|
||||||
------------------- ------------ --------------------------------------
|
------------------- ------------ --------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ proc matchOrFind(s: string, pattern: TRegEx, matches: var openarray[string],
|
||||||
for i in 1..int(res)-1:
|
for i in 1..int(res)-1:
|
||||||
var a = rawMatches[i * 2]
|
var a = rawMatches[i * 2]
|
||||||
var b = rawMatches[i * 2 + 1]
|
var b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32: matches[i-1] = copy(s, int(a), int(b)-1)
|
if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
|
||||||
else: matches[i-1] = ""
|
else: matches[i-1] = ""
|
||||||
return rawMatches[1] - rawMatches[0]
|
return rawMatches[1] - rawMatches[0]
|
||||||
|
|
||||||
|
|
@ -106,7 +106,7 @@ proc findBounds*(s: string, pattern: TRegEx, matches: var openarray[string],
|
||||||
for i in 1..int(res)-1:
|
for i in 1..int(res)-1:
|
||||||
var a = rawMatches[i * 2]
|
var a = rawMatches[i * 2]
|
||||||
var b = rawMatches[i * 2 + 1]
|
var b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32: matches[i-1] = copy(s, int(a), int(b)-1)
|
if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
|
||||||
else: matches[i-1] = ""
|
else: matches[i-1] = ""
|
||||||
return (rawMatches[0].int, rawMatches[1].int - 1)
|
return (rawMatches[0].int, rawMatches[1].int - 1)
|
||||||
|
|
||||||
|
|
@ -186,7 +186,7 @@ proc find*(s: string, pattern: TRegEx, matches: var openarray[string],
|
||||||
for i in 1..int(res)-1:
|
for i in 1..int(res)-1:
|
||||||
var a = rawMatches[i * 2]
|
var a = rawMatches[i * 2]
|
||||||
var b = rawMatches[i * 2 + 1]
|
var b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32: matches[i-1] = copy(s, int(a), int(b)-1)
|
if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
|
||||||
else: matches[i-1] = ""
|
else: matches[i-1] = ""
|
||||||
return rawMatches[0]
|
return rawMatches[0]
|
||||||
|
|
||||||
|
|
@ -277,10 +277,10 @@ proc replace*(s: string, sub: TRegEx, by = ""): string =
|
||||||
while true:
|
while true:
|
||||||
var match = findBounds(s, sub, prev)
|
var match = findBounds(s, sub, prev)
|
||||||
if match.first < 0: break
|
if match.first < 0: break
|
||||||
add(result, copy(s, prev, match.first-1))
|
add(result, substr(s, prev, match.first-1))
|
||||||
add(result, by)
|
add(result, by)
|
||||||
prev = match.last + 1
|
prev = match.last + 1
|
||||||
add(result, copy(s, prev))
|
add(result, substr(s, prev))
|
||||||
|
|
||||||
proc replacef*(s: string, sub: TRegEx, by: string): string =
|
proc replacef*(s: string, sub: TRegEx, by: string): string =
|
||||||
## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by`
|
## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by`
|
||||||
|
|
@ -300,10 +300,10 @@ proc replacef*(s: string, sub: TRegEx, by: string): string =
|
||||||
while true:
|
while true:
|
||||||
var match = findBounds(s, sub, caps, prev)
|
var match = findBounds(s, sub, caps, prev)
|
||||||
if match.first < 0: break
|
if match.first < 0: break
|
||||||
add(result, copy(s, prev, match.first-1))
|
add(result, substr(s, prev, match.first-1))
|
||||||
addf(result, by, caps)
|
addf(result, by, caps)
|
||||||
prev = match.last + 1
|
prev = match.last + 1
|
||||||
add(result, copy(s, prev))
|
add(result, substr(s, prev))
|
||||||
when false:
|
when false:
|
||||||
result = ""
|
result = ""
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -316,8 +316,8 @@ proc replacef*(s: string, sub: TRegEx, by: string): string =
|
||||||
else:
|
else:
|
||||||
addf(result, by, caps)
|
addf(result, by, caps)
|
||||||
inc(i, x)
|
inc(i, x)
|
||||||
# copy the rest:
|
# substr the rest:
|
||||||
add(result, copy(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
proc parallelReplace*(s: string, subs: openArray[
|
proc parallelReplace*(s: string, subs: openArray[
|
||||||
tuple[pattern: TRegEx, repl: string]]): string =
|
tuple[pattern: TRegEx, repl: string]]): string =
|
||||||
|
|
@ -337,7 +337,7 @@ proc parallelReplace*(s: string, subs: openArray[
|
||||||
add(result, s[i])
|
add(result, s[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
# copy the rest:
|
# copy the rest:
|
||||||
add(result, copy(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
proc transformFile*(infile, outfile: string,
|
proc transformFile*(infile, outfile: string,
|
||||||
subs: openArray[tuple[pattern: TRegEx, repl: string]]) =
|
subs: openArray[tuple[pattern: TRegEx, repl: string]]) =
|
||||||
|
|
@ -385,7 +385,7 @@ iterator split*(s: string, sep: TRegEx): string =
|
||||||
x = matchLen(s, sep, last)
|
x = matchLen(s, sep, last)
|
||||||
if x > 0: break
|
if x > 0: break
|
||||||
if first < last:
|
if first < last:
|
||||||
yield copy(s, first, last-1)
|
yield substr(s, first, last-1)
|
||||||
|
|
||||||
proc split*(s: string, sep: TRegEx): seq[string] =
|
proc split*(s: string, sep: TRegEx): seq[string] =
|
||||||
## Splits the string `s` into substrings.
|
## Splits the string `s` into substrings.
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ proc URLencode*(s: string): string =
|
||||||
## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result,
|
## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result,
|
||||||
## a space is converted to ``'+'`` and every other character is encoded as
|
## a space is converted to ``'+'`` and every other character is encoded as
|
||||||
## ``'%xx'`` where ``xx`` denotes its hexadecimal value.
|
## ``'%xx'`` where ``xx`` denotes its hexadecimal value.
|
||||||
result = ""
|
result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars
|
||||||
for i in 0..s.len-1:
|
for i in 0..s.len-1:
|
||||||
case s[i]
|
case s[i]
|
||||||
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i])
|
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i])
|
||||||
|
|
@ -57,8 +57,9 @@ proc URLdecode*(s: string): string =
|
||||||
## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal
|
## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal
|
||||||
## value) is converted to the character with ordinal number ``xx``, and
|
## value) is converted to the character with ordinal number ``xx``, and
|
||||||
## and every other character is carried over.
|
## and every other character is carried over.
|
||||||
result = ""
|
result = newString(s.len)
|
||||||
var i = 0
|
var i = 0
|
||||||
|
var j = 0
|
||||||
while i < s.len:
|
while i < s.len:
|
||||||
case s[i]
|
case s[i]
|
||||||
of '%':
|
of '%':
|
||||||
|
|
@ -66,10 +67,12 @@ proc URLdecode*(s: string): string =
|
||||||
handleHexChar(s[i+1], x)
|
handleHexChar(s[i+1], x)
|
||||||
handleHexChar(s[i+2], x)
|
handleHexChar(s[i+2], x)
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
add(result, chr(x))
|
result[j] = chr(x)
|
||||||
of '+': add(result, ' ')
|
of '+': result[j] = ' '
|
||||||
else: add(result, s[i])
|
else: result[j] = s[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
|
inc(j)
|
||||||
|
setLen(result, j)
|
||||||
|
|
||||||
proc addXmlChar(dest: var string, c: Char) {.inline.} =
|
proc addXmlChar(dest: var string, c: Char) {.inline.} =
|
||||||
case c
|
case c
|
||||||
|
|
@ -86,7 +89,7 @@ proc XMLencode*(s: string): string =
|
||||||
## * ``>`` is replaced by ``>``
|
## * ``>`` is replaced by ``>``
|
||||||
## * ``&`` is replaced by ``&``
|
## * ``&`` is replaced by ``&``
|
||||||
## * every other character is carried over.
|
## * every other character is carried over.
|
||||||
result = ""
|
result = newStringOfCap(s.len + s.len shr 2)
|
||||||
for i in 0..len(s)-1: addXmlChar(result, s[i])
|
for i in 0..len(s)-1: addXmlChar(result, s[i])
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -367,4 +370,8 @@ proc existsCookie*(name: string): bool =
|
||||||
if gcookies == nil: gcookies = parseCookies(getHttpCookie())
|
if gcookies == nil: gcookies = parseCookies(getHttpCookie())
|
||||||
result = hasKey(gcookies, name)
|
result = hasKey(gcookies, name)
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
const test1 = "abc\L+def xyz"
|
||||||
|
assert UrlEncode(test1) == "abc%0A%2Bdef+xyz"
|
||||||
|
assert UrlDecode(UrlEncode(test1)) == test1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2010 Andreas Rumpf
|
# (c) Copyright 2011 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.
|
||||||
|
|
@ -24,7 +24,7 @@ proc parseCookies*(s: string): PStringTable =
|
||||||
inc(i) # skip '='
|
inc(i) # skip '='
|
||||||
var valstart = i
|
var valstart = i
|
||||||
while s[i] != ';' and s[i] != '\0': inc(i)
|
while s[i] != ';' and s[i] != '\0': inc(i)
|
||||||
result[copy(s, keystart, keyend)] = copy(s, valstart, i-1)
|
result[substr(s, keystart, keyend)] = substr(s, valstart, i-1)
|
||||||
if s[i] == '\0': break
|
if s[i] == '\0': break
|
||||||
inc(i) # skip ';'
|
inc(i) # skip ';'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ proc parseChunks(d: var string, start: int, s: TSocket): string =
|
||||||
if charAt(d, i, s) == '\L': inc(i)
|
if charAt(d, i, s) == '\L': inc(i)
|
||||||
else: httpError("CR-LF after chunksize expected")
|
else: httpError("CR-LF after chunksize expected")
|
||||||
|
|
||||||
var x = copy(d, i, i+chunkSize-1)
|
var x = substr(d, i, i+chunkSize-1)
|
||||||
var size = x.len
|
var size = x.len
|
||||||
result.add(x)
|
result.add(x)
|
||||||
inc(i, size)
|
inc(i, size)
|
||||||
|
|
@ -133,7 +133,7 @@ proc parseBody(d: var string, start: int, s: TSocket,
|
||||||
if headers["Transfer-Encoding"] == "chunked":
|
if headers["Transfer-Encoding"] == "chunked":
|
||||||
result = parseChunks(d, start, s)
|
result = parseChunks(d, start, s)
|
||||||
else:
|
else:
|
||||||
result = copy(d, start)
|
result = substr(d, start)
|
||||||
# -REGION- Content-Length
|
# -REGION- Content-Length
|
||||||
# (http://tools.ietf.org/html/rfc2616#section-4.4) NR.3
|
# (http://tools.ietf.org/html/rfc2616#section-4.4) NR.3
|
||||||
var contentLengthHeader = headers["Content-Length"]
|
var contentLengthHeader = headers["Content-Length"]
|
||||||
|
|
@ -236,7 +236,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
|
||||||
## | Extra headers can be specified and must be seperated by ``\c\L``
|
## | Extra headers can be specified and must be seperated by ``\c\L``
|
||||||
var r = parseUrl(url)
|
var r = parseUrl(url)
|
||||||
|
|
||||||
var headers = copy($httpMethod, len("http"))
|
var headers = substr($httpMethod, len("http"))
|
||||||
headers.add(" /" & r.path & r.query)
|
headers.add(" /" & r.path & r.query)
|
||||||
headers.add(" HTTP/1.1\c\L")
|
headers.add(" HTTP/1.1\c\L")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) =
|
||||||
if L.startsWith("content-length:"):
|
if L.startsWith("content-length:"):
|
||||||
var i = len("content-length:")
|
var i = len("content-length:")
|
||||||
while L[i] in Whitespace: inc(i)
|
while L[i] in Whitespace: inc(i)
|
||||||
contentLength = parseInt(copy(L, i))
|
contentLength = parseInt(substr(L, i))
|
||||||
|
|
||||||
if contentLength < 0:
|
if contentLength < 0:
|
||||||
badRequest(client)
|
badRequest(client)
|
||||||
|
|
@ -165,7 +165,7 @@ proc acceptRequest(client: TSocket) =
|
||||||
# extract path
|
# extract path
|
||||||
if q >= 0:
|
if q >= 0:
|
||||||
# strip "?..." from path, this may be found in both POST and GET
|
# strip "?..." from path, this may be found in both POST and GET
|
||||||
path = "." & data[1].copy(0, q-1)
|
path = "." & data[1].substr(0, q-1)
|
||||||
else:
|
else:
|
||||||
path = "." & data[1]
|
path = "." & data[1]
|
||||||
# path starts with "/", by adding "." in front of it we serve files from cwd
|
# path starts with "/", by adding "." in front of it we serve files from cwd
|
||||||
|
|
@ -173,7 +173,7 @@ proc acceptRequest(client: TSocket) =
|
||||||
if cmpIgnoreCase(data[0], "GET") == 0:
|
if cmpIgnoreCase(data[0], "GET") == 0:
|
||||||
if q >= 0:
|
if q >= 0:
|
||||||
cgi = true
|
cgi = true
|
||||||
query = data[1].copy(q+1)
|
query = data[1].substr(q+1)
|
||||||
elif cmpIgnoreCase(data[0], "POST") == 0:
|
elif cmpIgnoreCase(data[0], "POST") == 0:
|
||||||
cgi = true
|
cgi = true
|
||||||
meth = reqPost
|
meth = reqPost
|
||||||
|
|
@ -250,11 +250,11 @@ proc next*(s: var TServer) =
|
||||||
if data[last] == '?' and query == 0: query = last
|
if data[last] == '?' and query == 0: query = last
|
||||||
inc(last)
|
inc(last)
|
||||||
if query > 0:
|
if query > 0:
|
||||||
s.query = data.copy(query+1, last-1)
|
s.query = data.substr(query+1, last-1)
|
||||||
s.path = data.copy(i, query-1)
|
s.path = data.substr(i, query-1)
|
||||||
else:
|
else:
|
||||||
s.query = ""
|
s.query = ""
|
||||||
s.path = data.copy(i, last-1)
|
s.path = data.substr(i, last-1)
|
||||||
|
|
||||||
proc close*(s: TServer) =
|
proc close*(s: TServer) =
|
||||||
## closes the server (and the socket the server uses).
|
## closes the server (and the socket the server uses).
|
||||||
|
|
|
||||||
|
|
@ -649,7 +649,8 @@ proc nl(s: var string, ml: bool) =
|
||||||
|
|
||||||
proc escapeJson*(s: string): string =
|
proc escapeJson*(s: string): string =
|
||||||
## Converts a string `s` to its JSON representation.
|
## Converts a string `s` to its JSON representation.
|
||||||
result = "\""
|
result = newStringOfCap(s.len + s.len shr 3)
|
||||||
|
result.add("\"")
|
||||||
for x in runes(s):
|
for x in runes(s):
|
||||||
var r = int(x)
|
var r = int(x)
|
||||||
if r >= 32 and r <= 127:
|
if r >= 32 and r <= 127:
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ proc JoinPath*(head, tail: string): string {.
|
||||||
result = tail
|
result = tail
|
||||||
elif head[len(head)-1] in {DirSep, AltSep}:
|
elif head[len(head)-1] in {DirSep, AltSep}:
|
||||||
if tail[0] in {DirSep, AltSep}:
|
if tail[0] in {DirSep, AltSep}:
|
||||||
result = head & copy(tail, 1)
|
result = head & substr(tail, 1)
|
||||||
else:
|
else:
|
||||||
result = head & tail
|
result = head & tail
|
||||||
else:
|
else:
|
||||||
|
|
@ -362,8 +362,8 @@ proc SplitPath*(path: string, head, tail: var string) {.noSideEffect,
|
||||||
sepPos = i
|
sepPos = i
|
||||||
break
|
break
|
||||||
if sepPos >= 0:
|
if sepPos >= 0:
|
||||||
head = copy(path, 0, sepPos-1)
|
head = substr(path, 0, sepPos-1)
|
||||||
tail = copy(path, sepPos+1)
|
tail = substr(path, sepPos+1)
|
||||||
else:
|
else:
|
||||||
head = ""
|
head = ""
|
||||||
tail = path # make a string copy here
|
tail = path # make a string copy here
|
||||||
|
|
@ -388,8 +388,8 @@ proc SplitPath*(path: string): tuple[head, tail: string] {.
|
||||||
sepPos = i
|
sepPos = i
|
||||||
break
|
break
|
||||||
if sepPos >= 0:
|
if sepPos >= 0:
|
||||||
result.head = copy(path, 0, sepPos-1)
|
result.head = substr(path, 0, sepPos-1)
|
||||||
result.tail = copy(path, sepPos+1)
|
result.tail = substr(path, sepPos+1)
|
||||||
else:
|
else:
|
||||||
result.head = ""
|
result.head = ""
|
||||||
result.tail = path
|
result.tail = path
|
||||||
|
|
@ -412,7 +412,7 @@ proc parentDir*(path: string): string {.
|
||||||
sepPos = i
|
sepPos = i
|
||||||
break
|
break
|
||||||
if sepPos >= 0:
|
if sepPos >= 0:
|
||||||
result = copy(path, 0, sepPos-1)
|
result = substr(path, 0, sepPos-1)
|
||||||
else:
|
else:
|
||||||
result = path
|
result = path
|
||||||
|
|
||||||
|
|
@ -462,9 +462,9 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {.
|
||||||
elif path[i] in {dirsep, altsep}:
|
elif path[i] in {dirsep, altsep}:
|
||||||
sepPos = i
|
sepPos = i
|
||||||
break
|
break
|
||||||
result.dir = copy(path, 0, sepPos-1)
|
result.dir = substr(path, 0, sepPos-1)
|
||||||
result.name = copy(path, sepPos+1, dotPos-1)
|
result.name = substr(path, sepPos+1, dotPos-1)
|
||||||
result.ext = copy(path, dotPos)
|
result.ext = substr(path, dotPos)
|
||||||
|
|
||||||
proc extractDir*(path: string): string {.noSideEffect, deprecated.} =
|
proc extractDir*(path: string): string {.noSideEffect, deprecated.} =
|
||||||
## Extracts the directory of a given path. This is almost the
|
## Extracts the directory of a given path. This is almost the
|
||||||
|
|
@ -507,8 +507,8 @@ proc SplitFilename*(filename: string, name, extension: var string) {.
|
||||||
## **Deprecated since version 0.8.2**: Use ``splitFile(filename)`` instead.
|
## **Deprecated since version 0.8.2**: Use ``splitFile(filename)`` instead.
|
||||||
var extPos = searchExtPos(filename)
|
var extPos = searchExtPos(filename)
|
||||||
if extPos >= 0:
|
if extPos >= 0:
|
||||||
name = copy(filename, 0, extPos-1)
|
name = substr(filename, 0, extPos-1)
|
||||||
extension = copy(filename, extPos)
|
extension = substr(filename, extPos)
|
||||||
else:
|
else:
|
||||||
name = filename # make a string copy here
|
name = filename # make a string copy here
|
||||||
extension = ""
|
extension = ""
|
||||||
|
|
@ -537,7 +537,7 @@ proc ChangeFileExt*(filename, ext: string): string {.
|
||||||
## of none such beast.)
|
## of none such beast.)
|
||||||
var extPos = searchExtPos(filename)
|
var extPos = searchExtPos(filename)
|
||||||
if extPos < 0: result = filename & normExt(ext)
|
if extPos < 0: result = filename & normExt(ext)
|
||||||
else: result = copy(filename, 0, extPos-1) & normExt(ext)
|
else: result = substr(filename, 0, extPos-1) & normExt(ext)
|
||||||
|
|
||||||
proc addFileExt*(filename, ext: string): string {.
|
proc addFileExt*(filename, ext: string): string {.
|
||||||
noSideEffect, rtl, extern: "nos$1".} =
|
noSideEffect, rtl, extern: "nos$1".} =
|
||||||
|
|
@ -748,7 +748,7 @@ proc getEnv*(key: string): string =
|
||||||
## `existsEnv(key)`.
|
## `existsEnv(key)`.
|
||||||
var i = findEnvVar(key)
|
var i = findEnvVar(key)
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
return copy(environment[i], find(environment[i], '=')+1)
|
return substr(environment[i], find(environment[i], '=')+1)
|
||||||
else:
|
else:
|
||||||
var env = cgetenv(key)
|
var env = cgetenv(key)
|
||||||
if env == nil: return ""
|
if env == nil: return ""
|
||||||
|
|
@ -788,7 +788,7 @@ iterator iterOverEnvironment*(): tuple[key, value: string] {.deprecated.} =
|
||||||
getEnvVarsC()
|
getEnvVarsC()
|
||||||
for i in 0..high(environment):
|
for i in 0..high(environment):
|
||||||
var p = find(environment[i], '=')
|
var p = find(environment[i], '=')
|
||||||
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
yield (substr(environment[i], 0, p-1), substr(environment[i], p+1))
|
||||||
|
|
||||||
iterator envPairs*(): tuple[key, value: string] =
|
iterator envPairs*(): tuple[key, value: string] =
|
||||||
## Iterate over all `environments variables`:idx:. In the first component
|
## Iterate over all `environments variables`:idx:. In the first component
|
||||||
|
|
@ -797,7 +797,7 @@ iterator envPairs*(): tuple[key, value: string] =
|
||||||
getEnvVarsC()
|
getEnvVarsC()
|
||||||
for i in 0..high(environment):
|
for i in 0..high(environment):
|
||||||
var p = find(environment[i], '=')
|
var p = find(environment[i], '=')
|
||||||
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
yield (substr(environment[i], 0, p-1), substr(environment[i], p+1))
|
||||||
|
|
||||||
iterator walkFiles*(pattern: string): string =
|
iterator walkFiles*(pattern: string): string =
|
||||||
## Iterate over all the files that match the `pattern`. On POSIX this uses
|
## Iterate over all the files that match the `pattern`. On POSIX this uses
|
||||||
|
|
@ -944,14 +944,14 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1".} =
|
||||||
## fail if the path already exists because for most usages this does not
|
## fail if the path already exists because for most usages this does not
|
||||||
## indicate an error.
|
## indicate an error.
|
||||||
for i in 1.. dir.len-1:
|
for i in 1.. dir.len-1:
|
||||||
if dir[i] in {dirsep, altsep}: rawCreateDir(copy(dir, 0, i-1))
|
if dir[i] in {dirsep, altsep}: rawCreateDir(substr(dir, 0, i-1))
|
||||||
rawCreateDir(dir)
|
rawCreateDir(dir)
|
||||||
|
|
||||||
proc copyDir*(source, dest: string) {.rtl, extern: "nos$1".} =
|
proc copyDir*(source, dest: string) {.rtl, extern: "nos$1".} =
|
||||||
## Copies a directory from `source` to `dest`. If this fails, `EOS` is raised.
|
## Copies a directory from `source` to `dest`. If this fails, `EOS` is raised.
|
||||||
createDir(dest)
|
createDir(dest)
|
||||||
for kind, path in walkDir(source):
|
for kind, path in walkDir(source):
|
||||||
var noSource = path.copy(source.len()+1)
|
var noSource = path.substr(source.len()+1)
|
||||||
case kind
|
case kind
|
||||||
of pcFile:
|
of pcFile:
|
||||||
copyFile(path, dest / noSource)
|
copyFile(path, dest / noSource)
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ proc next*(p: var TOptParser) {.
|
||||||
proc cmdLineRest*(p: TOptParser): string {.
|
proc cmdLineRest*(p: TOptParser): string {.
|
||||||
rtl, extern: "npo$1".} =
|
rtl, extern: "npo$1".} =
|
||||||
## retrieves the rest of the command line that has not been parsed yet.
|
## retrieves the rest of the command line that has not been parsed yet.
|
||||||
result = strip(copy(p.cmd, p.pos, len(p.cmd) - 1))
|
result = strip(substr(p.cmd, p.pos, len(p.cmd) - 1))
|
||||||
|
|
||||||
proc getRestOfCommandLine*(p: TOptParser): string {.deprecated.} =
|
proc getRestOfCommandLine*(p: TOptParser): string {.deprecated.} =
|
||||||
## **Deprecated since version 0.8.2**: Use `cmdLineRest` instead.
|
## **Deprecated since version 0.8.2**: Use `cmdLineRest` instead.
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ proc parseIdent*(s: string, ident: var string, start = 0): int =
|
||||||
if s[i] in IdentStartChars:
|
if s[i] in IdentStartChars:
|
||||||
inc(i)
|
inc(i)
|
||||||
while s[i] in IdentChars: inc(i)
|
while s[i] in IdentChars: inc(i)
|
||||||
ident = copy(s, start, i-1)
|
ident = substr(s, start, i-1)
|
||||||
result = i-start
|
result = i-start
|
||||||
|
|
||||||
proc parseToken*(s: string, token: var string, validChars: set[char],
|
proc parseToken*(s: string, token: var string, validChars: set[char],
|
||||||
|
|
@ -86,7 +86,7 @@ proc parseToken*(s: string, token: var string, validChars: set[char],
|
||||||
var i = start
|
var i = start
|
||||||
while s[i] in validChars: inc(i)
|
while s[i] in validChars: inc(i)
|
||||||
result = i-start
|
result = i-start
|
||||||
token = copy(s, start, i-1)
|
token = substr(s, start, i-1)
|
||||||
|
|
||||||
proc skipWhitespace*(s: string, start = 0): int {.inline.} =
|
proc skipWhitespace*(s: string, start = 0): int {.inline.} =
|
||||||
## skips the whitespace starting at ``s[start]``. Returns the number of
|
## skips the whitespace starting at ``s[start]``. Returns the number of
|
||||||
|
|
@ -120,7 +120,7 @@ proc parseUntil*(s: string, token: var string, until: set[char],
|
||||||
var i = start
|
var i = start
|
||||||
while s[i] notin until: inc(i)
|
while s[i] notin until: inc(i)
|
||||||
result = i-start
|
result = i-start
|
||||||
token = copy(s, start, i-1)
|
token = substr(s, start, i-1)
|
||||||
|
|
||||||
proc parseWhile*(s: string, token: var string, validChars: set[char],
|
proc parseWhile*(s: string, token: var string, validChars: set[char],
|
||||||
start = 0): int {.inline.} =
|
start = 0): int {.inline.} =
|
||||||
|
|
@ -130,7 +130,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char],
|
||||||
var i = start
|
var i = start
|
||||||
while s[i] in validChars: inc(i)
|
while s[i] in validChars: inc(i)
|
||||||
result = i-start
|
result = i-start
|
||||||
token = copy(s, start, i-1)
|
token = substr(s, start, i-1)
|
||||||
|
|
||||||
{.push overflowChecks: on.}
|
{.push overflowChecks: on.}
|
||||||
# this must be compiled with overflow checking turned on:
|
# this must be compiled with overflow checking turned on:
|
||||||
|
|
|
||||||
|
|
@ -736,7 +736,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
|
||||||
var (a, b) = c.matches[p.index]
|
var (a, b) = c.matches[p.index]
|
||||||
var n: TPeg
|
var n: TPeg
|
||||||
n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef))
|
n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef))
|
||||||
n.term = s.copy(a, b)
|
n.term = s.substr(a, b)
|
||||||
result = rawMatch(s, n, start, c)
|
result = rawMatch(s, n, start, c)
|
||||||
of pkStartAnchor:
|
of pkStartAnchor:
|
||||||
if c.origStart == start: result = 0
|
if c.origStart == start: result = 0
|
||||||
|
|
@ -754,7 +754,7 @@ proc match*(s: string, pattern: TPeg, matches: var openarray[string],
|
||||||
result = rawMatch(s, pattern, start, c) == len(s) - start
|
result = rawMatch(s, pattern, start, c) == len(s) - start
|
||||||
if result:
|
if result:
|
||||||
for i in 0..c.ml-1:
|
for i in 0..c.ml-1:
|
||||||
matches[i] = copy(s, c.matches[i][0], c.matches[i][1])
|
matches[i] = substr(s, c.matches[i][0], c.matches[i][1])
|
||||||
|
|
||||||
proc match*(s: string, pattern: TPeg,
|
proc match*(s: string, pattern: TPeg,
|
||||||
start = 0): bool {.nosideEffect, rtl, extern: "npegs$1".} =
|
start = 0): bool {.nosideEffect, rtl, extern: "npegs$1".} =
|
||||||
|
|
@ -774,7 +774,7 @@ proc matchLen*(s: string, pattern: TPeg, matches: var openarray[string],
|
||||||
result = rawMatch(s, pattern, start, c)
|
result = rawMatch(s, pattern, start, c)
|
||||||
if result >= 0:
|
if result >= 0:
|
||||||
for i in 0..c.ml-1:
|
for i in 0..c.ml-1:
|
||||||
matches[i] = copy(s, c.matches[i][0], c.matches[i][1])
|
matches[i] = substr(s, c.matches[i][0], c.matches[i][1])
|
||||||
|
|
||||||
proc matchLen*(s: string, pattern: TPeg,
|
proc matchLen*(s: string, pattern: TPeg,
|
||||||
start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} =
|
start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} =
|
||||||
|
|
@ -903,7 +903,7 @@ proc replacef*(s: string, sub: TPeg, by: string): string {.
|
||||||
else:
|
else:
|
||||||
addf(result, by, caps)
|
addf(result, by, caps)
|
||||||
inc(i, x)
|
inc(i, x)
|
||||||
add(result, copy(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
proc replace*(s: string, sub: TPeg, by = ""): string {.
|
proc replace*(s: string, sub: TPeg, by = ""): string {.
|
||||||
nosideEffect, rtl, extern: "npegs$1".} =
|
nosideEffect, rtl, extern: "npegs$1".} =
|
||||||
|
|
@ -920,7 +920,7 @@ proc replace*(s: string, sub: TPeg, by = ""): string {.
|
||||||
else:
|
else:
|
||||||
addf(result, by, caps)
|
addf(result, by, caps)
|
||||||
inc(i, x)
|
inc(i, x)
|
||||||
add(result, copy(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
proc parallelReplace*(s: string, subs: openArray[
|
proc parallelReplace*(s: string, subs: openArray[
|
||||||
tuple[pattern: TPeg, repl: string]]): string {.
|
tuple[pattern: TPeg, repl: string]]): string {.
|
||||||
|
|
@ -941,7 +941,7 @@ proc parallelReplace*(s: string, subs: openArray[
|
||||||
add(result, s[i])
|
add(result, s[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
# copy the rest:
|
# copy the rest:
|
||||||
add(result, copy(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
proc transformFile*(infile, outfile: string,
|
proc transformFile*(infile, outfile: string,
|
||||||
subs: openArray[tuple[pattern: TPeg, repl: string]]) {.
|
subs: openArray[tuple[pattern: TPeg, repl: string]]) {.
|
||||||
|
|
@ -990,7 +990,7 @@ iterator split*(s: string, sep: TPeg): string =
|
||||||
x = matchLen(s, sep, last)
|
x = matchLen(s, sep, last)
|
||||||
if x > 0: break
|
if x > 0: break
|
||||||
if first < last:
|
if first < last:
|
||||||
yield copy(s, first, last-1)
|
yield substr(s, first, last-1)
|
||||||
|
|
||||||
proc split*(s: string, sep: TPeg): seq[string] {.
|
proc split*(s: string, sep: TPeg): seq[string] {.
|
||||||
nosideEffect, rtl, extern: "npegs$1".} =
|
nosideEffect, rtl, extern: "npegs$1".} =
|
||||||
|
|
@ -1688,7 +1688,7 @@ when isMainModule:
|
||||||
assert rawMatch(s, expr.rule, 0, c) == len(s)
|
assert rawMatch(s, expr.rule, 0, c) == len(s)
|
||||||
var a = ""
|
var a = ""
|
||||||
for i in 0..c.ml-1:
|
for i in 0..c.ml-1:
|
||||||
a.add(copy(s, c.matches[i][0], c.matches[i][1]))
|
a.add(substr(s, c.matches[i][0], c.matches[i][1]))
|
||||||
assert a == "abcdef"
|
assert a == "abcdef"
|
||||||
#echo expr.rule
|
#echo expr.rule
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ proc matchOrFind(s: string, pattern: PPcre, matches: var openarray[string],
|
||||||
var
|
var
|
||||||
a = rawMatches[i * 2]
|
a = rawMatches[i * 2]
|
||||||
b = rawMatches[i * 2 + 1]
|
b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32: matches[i] = copy(s, a, int(b)-1)
|
if a >= 0'i32: matches[i] = substr(s, a, int(b)-1)
|
||||||
else: matches[i] = ""
|
else: matches[i] = ""
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ when false:
|
||||||
if frmt[i] != '$': inc(i)
|
if frmt[i] != '$': inc(i)
|
||||||
else: break
|
else: break
|
||||||
if i - 1 >= start:
|
if i - 1 >= start:
|
||||||
add(result, copy(frmt, start, i-1))
|
add(result, substr(frmt, start, i-1))
|
||||||
|
|
||||||
proc `%`*(frmt: string, args: openarray[PRope]): PRope {.
|
proc `%`*(frmt: string, args: openarray[PRope]): PRope {.
|
||||||
rtl, extern: "nroFormat".} =
|
rtl, extern: "nroFormat".} =
|
||||||
|
|
@ -330,7 +330,7 @@ proc `%`*(frmt: string, args: openarray[PRope]): PRope {.
|
||||||
if frmt[i] != '$': inc(i)
|
if frmt[i] != '$': inc(i)
|
||||||
else: break
|
else: break
|
||||||
if i - 1 >= start:
|
if i - 1 >= start:
|
||||||
add(result, copy(frmt, start, i - 1))
|
add(result, substr(frmt, start, i - 1))
|
||||||
|
|
||||||
proc addf*(c: var PRope, frmt: string, args: openarray[PRope]) {.
|
proc addf*(c: var PRope, frmt: string, args: openarray[PRope]) {.
|
||||||
rtl, extern: "nro$1".} =
|
rtl, extern: "nro$1".} =
|
||||||
|
|
|
||||||
|
|
@ -181,12 +181,12 @@ proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {.
|
||||||
of '{':
|
of '{':
|
||||||
var j = i + 1
|
var j = i + 1
|
||||||
while j < f.len and f[j] != '}': inc(j)
|
while j < f.len and f[j] != '}': inc(j)
|
||||||
add(result, getValue(t, flags, copy(f, i+2, j-1)))
|
add(result, getValue(t, flags, substr(f, i+2, j-1)))
|
||||||
i = j + 1
|
i = j + 1
|
||||||
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_':
|
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_':
|
||||||
var j = i + 1
|
var j = i + 1
|
||||||
while j < f.len and f[j] in PatternChars: inc(j)
|
while j < f.len and f[j] in PatternChars: inc(j)
|
||||||
add(result, getValue(t, flags, copy(f, i+1, j-1)))
|
add(result, getValue(t, flags, substr(f, i+1, j-1)))
|
||||||
i = j
|
i = j
|
||||||
else:
|
else:
|
||||||
add(result, f[i])
|
add(result, f[i])
|
||||||
|
|
|
||||||
|
|
@ -83,18 +83,22 @@ proc capitalize*(s: string): string {.noSideEffect, procvar,
|
||||||
rtl, extern: "nsuCapitalize".} =
|
rtl, extern: "nsuCapitalize".} =
|
||||||
## Converts the first character of `s` into upper case.
|
## Converts the first character of `s` into upper case.
|
||||||
## This works only for the letters a-z.
|
## This works only for the letters a-z.
|
||||||
result = toUpper(s[0]) & copy(s, 1)
|
result = toUpper(s[0]) & substr(s, 1)
|
||||||
|
|
||||||
proc normalize*(s: string): string {.noSideEffect, procvar,
|
proc normalize*(s: string): string {.noSideEffect, procvar,
|
||||||
rtl, extern: "nsuNormalize".} =
|
rtl, extern: "nsuNormalize".} =
|
||||||
## Normalizes the string `s`. That means to convert it to lower case and
|
## Normalizes the string `s`. That means to convert it to lower case and
|
||||||
## remove any '_'. This is needed for Nimrod identifiers for example.
|
## remove any '_'. This is needed for Nimrod identifiers for example.
|
||||||
result = ""
|
result = newString(s.len)
|
||||||
|
var j = 0
|
||||||
for i in 0..len(s) - 1:
|
for i in 0..len(s) - 1:
|
||||||
if s[i] in {'A'..'Z'}:
|
if s[i] in {'A'..'Z'}:
|
||||||
add result, Chr(Ord(s[i]) + (Ord('a') - Ord('A')))
|
result[j] = Chr(Ord(s[i]) + (Ord('a') - Ord('A')))
|
||||||
|
inc j
|
||||||
elif s[i] != '_':
|
elif s[i] != '_':
|
||||||
add result, s[i]
|
result[j] = s[i]
|
||||||
|
inc j
|
||||||
|
if j != s.len: setLen(result, j)
|
||||||
|
|
||||||
proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,
|
proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,
|
||||||
rtl, extern: "nsuCmpIgnoreCase", procvar.} =
|
rtl, extern: "nsuCmpIgnoreCase", procvar.} =
|
||||||
|
|
@ -171,14 +175,14 @@ proc addf*(s: var string, formatstr: string, a: openarray[string]) {.
|
||||||
of '{':
|
of '{':
|
||||||
var j = i+1
|
var j = i+1
|
||||||
while formatstr[j] notin {'\0', '}'}: inc(j)
|
while formatstr[j] notin {'\0', '}'}: inc(j)
|
||||||
var x = findNormalized(copy(formatstr, i+2, j-1), a)
|
var x = findNormalized(substr(formatstr, i+2, j-1), a)
|
||||||
if x >= 0 and x < high(a): add s, a[x+1]
|
if x >= 0 and x < high(a): add s, a[x+1]
|
||||||
else: raise newException(EInvalidValue, "invalid format string")
|
else: raise newException(EInvalidValue, "invalid format string")
|
||||||
i = j+1
|
i = j+1
|
||||||
of 'a'..'z', 'A'..'Z', '\128'..'\255', '_':
|
of 'a'..'z', 'A'..'Z', '\128'..'\255', '_':
|
||||||
var j = i+1
|
var j = i+1
|
||||||
while formatstr[j] in PatternChars: inc(j)
|
while formatstr[j] in PatternChars: inc(j)
|
||||||
var x = findNormalized(copy(formatstr, i+1, j-1), a)
|
var x = findNormalized(substr(formatstr, i+1, j-1), a)
|
||||||
if x >= 0 and x < high(a): add s, a[x+1]
|
if x >= 0 and x < high(a): add s, a[x+1]
|
||||||
else: raise newException(EInvalidValue, "invalid format string")
|
else: raise newException(EInvalidValue, "invalid format string")
|
||||||
i = j
|
i = j
|
||||||
|
|
@ -226,13 +230,14 @@ proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect,
|
||||||
##
|
##
|
||||||
## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is
|
## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is
|
||||||
## raised if an ill-formed format string has been passed to the `%` operator.
|
## raised if an ill-formed format string has been passed to the `%` operator.
|
||||||
result = ""
|
result = newStringOfCap(formatstr.len + a.len shl 4)
|
||||||
addf(result, formatstr, a)
|
addf(result, formatstr, a)
|
||||||
|
|
||||||
proc `%` *(formatstr, a: string): string {.noSideEffect,
|
proc `%` *(formatstr, a: string): string {.noSideEffect,
|
||||||
rtl, extern: "nsuFormatSingleElem".} =
|
rtl, extern: "nsuFormatSingleElem".} =
|
||||||
## This is the same as ``formatstr % [a]``.
|
## This is the same as ``formatstr % [a]``.
|
||||||
return formatstr % [a]
|
result = newStringOfCap(formatstr.len + a.len)
|
||||||
|
addf(result, formatstr, [a])
|
||||||
|
|
||||||
proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
|
proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
|
||||||
rtl, extern: "nsuStrip".} =
|
rtl, extern: "nsuStrip".} =
|
||||||
|
|
@ -248,7 +253,7 @@ proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
|
||||||
while s[first] in chars: inc(first)
|
while s[first] in chars: inc(first)
|
||||||
if trailing:
|
if trailing:
|
||||||
while last >= 0 and s[last] in chars: dec(last)
|
while last >= 0 and s[last] in chars: dec(last)
|
||||||
result = copy(s, first, last)
|
result = substr(s, first, last)
|
||||||
|
|
||||||
proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} =
|
proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} =
|
||||||
## Converts a character `c` to its octal representation. The resulting
|
## Converts a character `c` to its octal representation. The resulting
|
||||||
|
|
@ -288,7 +293,7 @@ iterator split*(s: string, seps: set[char] = Whitespace): string =
|
||||||
var first = last
|
var first = last
|
||||||
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
||||||
if first <= last-1:
|
if first <= last-1:
|
||||||
yield copy(s, first, last-1)
|
yield substr(s, first, last-1)
|
||||||
|
|
||||||
iterator split*(s: string, sep: char): string =
|
iterator split*(s: string, sep: char): string =
|
||||||
## Splits the string `s` into substrings.
|
## Splits the string `s` into substrings.
|
||||||
|
|
@ -321,7 +326,7 @@ iterator split*(s: string, sep: char): string =
|
||||||
while last <= len(s):
|
while last <= len(s):
|
||||||
var first = last
|
var first = last
|
||||||
while last < len(s) and s[last] != sep: inc(last)
|
while last < len(s) and s[last] != sep: inc(last)
|
||||||
yield copy(s, first, last-1)
|
yield substr(s, first, last-1)
|
||||||
inc(last)
|
inc(last)
|
||||||
|
|
||||||
iterator splitLines*(s: string): string =
|
iterator splitLines*(s: string): string =
|
||||||
|
|
@ -349,7 +354,7 @@ iterator splitLines*(s: string): string =
|
||||||
var last = 0
|
var last = 0
|
||||||
while true:
|
while true:
|
||||||
while s[last] notin {'\0', '\c', '\l'}: inc(last)
|
while s[last] notin {'\0', '\c', '\l'}: inc(last)
|
||||||
yield copy(s, first, last-1)
|
yield substr(s, first, last-1)
|
||||||
# skip newlines:
|
# skip newlines:
|
||||||
if s[last] == '\l': inc(last)
|
if s[last] == '\l': inc(last)
|
||||||
elif s[last] == '\c':
|
elif s[last] == '\c':
|
||||||
|
|
@ -499,7 +504,7 @@ iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[
|
||||||
var isSep = s[j] in seps
|
var isSep = s[j] in seps
|
||||||
while j < s.len and (s[j] in seps) == isSep: inc(j)
|
while j < s.len and (s[j] in seps) == isSep: inc(j)
|
||||||
if j > i:
|
if j > i:
|
||||||
yield (copy(s, i, j-1), isSep)
|
yield (substr(s, i, j-1), isSep)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
i = j
|
i = j
|
||||||
|
|
@ -510,19 +515,19 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||||
newLine = "\n"): string {.
|
newLine = "\n"): string {.
|
||||||
noSideEffect, rtl, extern: "nsuWordWrap".} =
|
noSideEffect, rtl, extern: "nsuWordWrap".} =
|
||||||
## word wraps `s`.
|
## word wraps `s`.
|
||||||
result = ""
|
result = newStringOfCap(s.len + s.len shr 6)
|
||||||
var SpaceLeft = maxLineWidth
|
var SpaceLeft = maxLineWidth
|
||||||
for word, isSep in tokenize(s, seps):
|
for word, isSep in tokenize(s, seps):
|
||||||
if len(word) > SpaceLeft:
|
if len(word) > SpaceLeft:
|
||||||
if splitLongWords and len(word) > maxLineWidth:
|
if splitLongWords and len(word) > maxLineWidth:
|
||||||
result.add(copy(word, 0, spaceLeft-1))
|
result.add(substr(word, 0, spaceLeft-1))
|
||||||
var w = spaceLeft+1
|
var w = spaceLeft+1
|
||||||
var wordLeft = len(word) - spaceLeft
|
var wordLeft = len(word) - spaceLeft
|
||||||
while wordLeft > 0:
|
while wordLeft > 0:
|
||||||
result.add(newLine)
|
result.add(newLine)
|
||||||
var L = min(maxLineWidth, wordLeft)
|
var L = min(maxLineWidth, wordLeft)
|
||||||
SpaceLeft = maxLineWidth - L
|
SpaceLeft = maxLineWidth - L
|
||||||
result.add(copy(word, w, w+L-1))
|
result.add(substr(word, w, w+L-1))
|
||||||
inc(w, L)
|
inc(w, L)
|
||||||
dec(wordLeft, L)
|
dec(wordLeft, L)
|
||||||
else:
|
else:
|
||||||
|
|
@ -700,11 +705,11 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect,
|
||||||
while true:
|
while true:
|
||||||
var j = findAux(s, sub, i, a)
|
var j = findAux(s, sub, i, a)
|
||||||
if j < 0: break
|
if j < 0: break
|
||||||
add result, copy(s, i, j - 1)
|
add result, substr(s, i, j - 1)
|
||||||
add result, by
|
add result, by
|
||||||
i = j + len(sub)
|
i = j + len(sub)
|
||||||
# copy the rest:
|
# copy the rest:
|
||||||
add result, copy(s, i)
|
add result, substr(s, i)
|
||||||
|
|
||||||
proc replace*(s: string, sub, by: char): string {.noSideEffect,
|
proc replace*(s: string, sub, by: char): string {.noSideEffect,
|
||||||
rtl, extern: "nsuReplaceChar".} =
|
rtl, extern: "nsuReplaceChar".} =
|
||||||
|
|
@ -804,7 +809,8 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||||
## The procedure has been designed so that its output is usable for many
|
## The procedure has been designed so that its output is usable for many
|
||||||
## different common syntaxes. The resulting string is prefixed with
|
## different common syntaxes. The resulting string is prefixed with
|
||||||
## `prefix` and suffixed with `suffix`. Both may be empty strings.
|
## `prefix` and suffixed with `suffix`. Both may be empty strings.
|
||||||
result = prefix
|
result = newStringOfCap(s.len + s.len shr 2)
|
||||||
|
result.add(prefix)
|
||||||
for c in items(s):
|
for c in items(s):
|
||||||
case c
|
case c
|
||||||
of '\0'..'\31', '\128'..'\255':
|
of '\0'..'\31', '\128'..'\255':
|
||||||
|
|
@ -837,7 +843,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect,
|
||||||
while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i)
|
while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i)
|
||||||
if s[i] != '\0': return false
|
if s[i] != '\0': return false
|
||||||
|
|
||||||
var x = copy(s, j+1)
|
var x = substr(s, j+1)
|
||||||
if len(x) == 2 and x[0] in Letters and x[1] in Letters: return true
|
if len(x) == 2 and x[0] in Letters and x[1] in Letters: return true
|
||||||
case toLower(x)
|
case toLower(x)
|
||||||
of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name",
|
of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name",
|
||||||
|
|
|
||||||
|
|
@ -1021,9 +1021,9 @@ proc splitData*(TextNode: PText, offset: int): PText =
|
||||||
if offset > TextNode.data.len():
|
if offset > TextNode.data.len():
|
||||||
raise newException(EIndexSizeErr, "Index out of bounds")
|
raise newException(EIndexSizeErr, "Index out of bounds")
|
||||||
|
|
||||||
var left: string = TextNode.data.copy(0, offset)
|
var left: string = TextNode.data.substr(0, offset)
|
||||||
TextNode.data = left
|
TextNode.data = left
|
||||||
var right: string = TextNode.data.copy(offset, TextNode.data.len())
|
var right: string = TextNode.data.substr(offset, TextNode.data.len())
|
||||||
|
|
||||||
if TextNode.FParentNode != nil:
|
if TextNode.FParentNode != nil:
|
||||||
for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes):
|
for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes):
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ type
|
||||||
typeDesc* {.magic: TypeDesc.} ## meta type to denote
|
typeDesc* {.magic: TypeDesc.} ## meta type to denote
|
||||||
## a type description (for templates)
|
## a type description (for templates)
|
||||||
|
|
||||||
|
const
|
||||||
|
hasThreadSupport = false # deactivate for now: thread stack walking
|
||||||
|
# is missing!
|
||||||
|
|
||||||
proc defined*[T](x: T): bool {.magic: "Defined", noSideEffect.}
|
proc defined*[T](x: T): bool {.magic: "Defined", noSideEffect.}
|
||||||
## Special compile-time procedure that checks whether `x` is
|
## Special compile-time procedure that checks whether `x` is
|
||||||
## defined. `x` has to be an identifier or a qualified identifier.
|
## defined. `x` has to be an identifier or a qualified identifier.
|
||||||
|
|
@ -685,7 +689,13 @@ proc newString*(len: int): string {.
|
||||||
## content. One needs to fill the string character after character
|
## content. One needs to fill the string character after character
|
||||||
## with the index operator ``s[i]``. This procedure exists only for
|
## with the index operator ``s[i]``. This procedure exists only for
|
||||||
## optimization purposes; the same effect can be achieved with the
|
## optimization purposes; the same effect can be achieved with the
|
||||||
## ``&`` operator.
|
## ``&`` operator or with ``add``.
|
||||||
|
|
||||||
|
proc newStringOfCap*(cap: int): string {.
|
||||||
|
magic: "NewStringOfCap", importc: "rawNewString", noSideEffect.}
|
||||||
|
## returns a new string of length ``0`` but with capacity `cap`.This
|
||||||
|
## procedure exists only for optimization purposes; the same effect can
|
||||||
|
## be achieved with the ``&`` operator or with ``add``.
|
||||||
|
|
||||||
proc `&` * (x: string, y: char): string {.
|
proc `&` * (x: string, y: char): string {.
|
||||||
magic: "ConStrStr", noSideEffect, merge.}
|
magic: "ConStrStr", noSideEffect, merge.}
|
||||||
|
|
@ -899,8 +909,19 @@ proc addQuitProc*(QuitProc: proc {.noconv.}) {.importc: "atexit", nodecl.}
|
||||||
# not be called explicitly! The user may decide to do this manually though.
|
# not be called explicitly! The user may decide to do this manually though.
|
||||||
|
|
||||||
proc copy*(s: string, first = 0): string {.
|
proc copy*(s: string, first = 0): string {.
|
||||||
magic: "CopyStr", importc: "copyStr", noSideEffect.}
|
magic: "CopyStr", importc: "copyStr", noSideEffect, deprecated.}
|
||||||
proc copy*(s: string, first, last: int): string {.
|
proc copy*(s: string, first, last: int): string {.
|
||||||
|
magic: "CopyStrLast", importc: "copyStrLast", noSideEffect,
|
||||||
|
deprecated.}
|
||||||
|
## copies a slice of `s` into a new string and returns this new
|
||||||
|
## string. The bounds `first` and `last` denote the indices of
|
||||||
|
## the first and last characters that shall be copied. If ``last``
|
||||||
|
## is omitted, it is treated as ``high(s)``.
|
||||||
|
## **Deprecated since version 0.8.12**: Use ``substr`` instead.
|
||||||
|
|
||||||
|
proc substr*(s: string, first = 0): string {.
|
||||||
|
magic: "CopyStr", importc: "copyStr", noSideEffect.}
|
||||||
|
proc substr*(s: string, first, last: int): string {.
|
||||||
magic: "CopyStrLast", importc: "copyStrLast", noSideEffect.}
|
magic: "CopyStrLast", importc: "copyStrLast", noSideEffect.}
|
||||||
## copies a slice of `s` into a new string and returns this new
|
## copies a slice of `s` into a new string and returns this new
|
||||||
## string. The bounds `first` and `last` denote the indices of
|
## string. The bounds `first` and `last` denote the indices of
|
||||||
|
|
@ -1219,21 +1240,21 @@ proc each*[T](data: var openArray[T], op: proc (x: var T)) =
|
||||||
## `op` to every item in `data`.
|
## `op` to every item in `data`.
|
||||||
for i in 0..data.len-1: op(data[i])
|
for i in 0..data.len-1: op(data[i])
|
||||||
|
|
||||||
iterator fields*(x: tuple[]): expr {.magic: "Fields", noSideEffect.}
|
iterator fields*[T: tuple](x: T): expr {.magic: "Fields", noSideEffect.}
|
||||||
## iterates over every field of `x`. Warning: This is really transforms
|
## iterates over every field of `x`. Warning: This is really transforms
|
||||||
## the 'for' and unrolls the loop. The current implementation also has a bug
|
## the 'for' and unrolls the loop. The current implementation also has a bug
|
||||||
## that affects symbol binding in the loop body.
|
## that affects symbol binding in the loop body.
|
||||||
iterator fields*(x, y: tuple[]): tuple[a, b: expr] {.
|
iterator fields*[S: tuple, T: tuple](x: S, y: T): tuple[a, b: expr] {.
|
||||||
magic: "Fields", noSideEffect.}
|
magic: "Fields", noSideEffect.}
|
||||||
## iterates over every field of `x` and `y`.
|
## iterates over every field of `x` and `y`.
|
||||||
## Warning: This is really transforms the 'for' and unrolls the loop.
|
## Warning: This is really transforms the 'for' and unrolls the loop.
|
||||||
## The current implementation also has a bug that affects symbol binding
|
## The current implementation also has a bug that affects symbol binding
|
||||||
## in the loop body.
|
## in the loop body.
|
||||||
iterator fieldPairs*(x: tuple[]): expr {.magic: "FieldPairs", noSideEffect.}
|
iterator fieldPairs*[T: tuple](x: T): expr {.magic: "FieldPairs", noSideEffect.}
|
||||||
## iterates over every field of `x`. Warning: This is really transforms
|
## iterates over every field of `x`. Warning: This is really transforms
|
||||||
## the 'for' and unrolls the loop. The current implementation also has a bug
|
## the 'for' and unrolls the loop. The current implementation also has a bug
|
||||||
## that affects symbol binding in the loop body.
|
## that affects symbol binding in the loop body.
|
||||||
iterator fieldPairs*(x, y: tuple[]): tuple[a, b: expr] {.
|
iterator fieldPairs*[S: tuple, T: tuple](x: S, y: T): tuple[a, b: expr] {.
|
||||||
magic: "FieldPairs", noSideEffect.}
|
magic: "FieldPairs", noSideEffect.}
|
||||||
## iterates over every field of `x` and `y`.
|
## iterates over every field of `x` and `y`.
|
||||||
## Warning: This is really transforms the 'for' and unrolls the loop.
|
## Warning: This is really transforms the 'for' and unrolls the loop.
|
||||||
|
|
@ -1773,7 +1794,7 @@ template `-|`(b, s: expr): expr =
|
||||||
|
|
||||||
proc `[]`*(s: string, x: TSlice[int]): string {.inline.} =
|
proc `[]`*(s: string, x: TSlice[int]): string {.inline.} =
|
||||||
## slice operation for strings. Negative indexes are supported.
|
## slice operation for strings. Negative indexes are supported.
|
||||||
result = s.copy(x.a-|s, x.b-|s)
|
result = s.substr(x.a-|s, x.b-|s)
|
||||||
|
|
||||||
proc `[]=`*(s: var string, x: TSlice[int], b: string) =
|
proc `[]=`*(s: var string, x: TSlice[int], b: string) =
|
||||||
## slice assignment for strings. Negative indexes are supported.
|
## slice assignment for strings. Negative indexes are supported.
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,9 @@ proc nimLoadLibraryError(path: string) {.compilerproc, noinline.}
|
||||||
|
|
||||||
proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline.}
|
proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline.}
|
||||||
|
|
||||||
# Support for thread local storage:
|
when false:
|
||||||
when defined(windows):
|
# Support for thread local storage:
|
||||||
|
when defined(windows):
|
||||||
type
|
type
|
||||||
TThreadVarSlot {.compilerproc.} = distinct int32
|
TThreadVarSlot {.compilerproc.} = distinct int32
|
||||||
|
|
||||||
|
|
@ -37,12 +38,14 @@ when defined(windows):
|
||||||
|
|
||||||
proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} =
|
proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} =
|
||||||
result = TlsAlloc()
|
result = TlsAlloc()
|
||||||
proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {.compilerproc.} =
|
proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {.
|
||||||
|
compilerproc, inline.} =
|
||||||
TlsSetValue(s, value)
|
TlsSetValue(s, value)
|
||||||
proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.compilerproc.} =
|
proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.
|
||||||
|
compilerproc, inline.} =
|
||||||
result = TlsGetValue(s)
|
result = TlsGetValue(s)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
Tpthread_key {.importc: "pthread_key_t",
|
Tpthread_key {.importc: "pthread_key_t",
|
||||||
header: "<sys/types.h>".} = distinct int
|
header: "<sys/types.h>".} = distinct int
|
||||||
|
|
@ -59,3 +62,11 @@ else:
|
||||||
proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {.
|
proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {.
|
||||||
importc: "pthread_setspecific", header: "<pthread.h>".}
|
importc: "pthread_setspecific", header: "<pthread.h>".}
|
||||||
|
|
||||||
|
proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} =
|
||||||
|
discard pthread_key_create(addr(result), nil)
|
||||||
|
proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {.
|
||||||
|
compilerproc, inline.} =
|
||||||
|
discard pthread_setspecific(s, value)
|
||||||
|
proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.compilerproc, inline.} =
|
||||||
|
result = pthread_getspecific(s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ type
|
||||||
exc: ref E_Base # XXX only needed for bootstrapping; unused
|
exc: ref E_Base # XXX only needed for bootstrapping; unused
|
||||||
context: C_JmpBuf
|
context: C_JmpBuf
|
||||||
|
|
||||||
|
#when hasThreadSupport: nil
|
||||||
|
|
||||||
var
|
var
|
||||||
excHandler {.threadvar, compilerproc.}: PSafePoint = nil
|
excHandler {.threadvar, compilerproc.}: PSafePoint = nil
|
||||||
# list of exception handlers
|
# list of exception handlers
|
||||||
|
|
|
||||||
|
|
@ -626,10 +626,23 @@ else:
|
||||||
# We use a jmp_buf buffer that is in the C stack.
|
# We use a jmp_buf buffer that is in the C stack.
|
||||||
# Used to traverse the stack and registers assuming
|
# Used to traverse the stack and registers assuming
|
||||||
# that 'setjmp' will save registers in the C stack.
|
# that 'setjmp' will save registers in the C stack.
|
||||||
|
type PStackSlice = ptr array [0..7, pointer]
|
||||||
var registers: C_JmpBuf
|
var registers: C_JmpBuf
|
||||||
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||||
var max = cast[TAddress](stackBottom)
|
var max = cast[TAddress](stackBottom)
|
||||||
var sp = cast[TAddress](addr(registers))
|
var sp = cast[TAddress](addr(registers))
|
||||||
|
# loop unrolled:
|
||||||
|
while sp <% max - 8*sizeof(pointer):
|
||||||
|
gcMark(cast[PStackSlice](sp)[0])
|
||||||
|
gcMark(cast[PStackSlice](sp)[1])
|
||||||
|
gcMark(cast[PStackSlice](sp)[2])
|
||||||
|
gcMark(cast[PStackSlice](sp)[3])
|
||||||
|
gcMark(cast[PStackSlice](sp)[4])
|
||||||
|
gcMark(cast[PStackSlice](sp)[5])
|
||||||
|
gcMark(cast[PStackSlice](sp)[6])
|
||||||
|
gcMark(cast[PStackSlice](sp)[7])
|
||||||
|
sp = sp +% sizeof(pointer)*8
|
||||||
|
# last few entries:
|
||||||
while sp <=% max:
|
while sp <=% max:
|
||||||
gcMark(cast[ppointer](sp)[])
|
gcMark(cast[ppointer](sp)[])
|
||||||
sp = sp +% sizeof(pointer)
|
sp = sp +% sizeof(pointer)
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ type
|
||||||
TReprClosure {.final.} = object # we cannot use a global variable here
|
TReprClosure {.final.} = object # we cannot use a global variable here
|
||||||
# as this wouldn't be thread-safe
|
# as this wouldn't be thread-safe
|
||||||
marked: TCellSet
|
marked: TCellSet
|
||||||
recdepth: int # do not recurse endless
|
recdepth: int # do not recurse endlessly
|
||||||
indent: int # indentation
|
indent: int # indentation
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
const
|
const
|
||||||
hasThreadSupport = false # deactivate for now: thread stack walking
|
|
||||||
# is missing!
|
|
||||||
maxThreads = 256
|
maxThreads = 256
|
||||||
|
|
||||||
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||||
|
|
|
||||||
19
tests/accept/compile/teval1.nim
Normal file
19
tests/accept/compile/teval1.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import macros
|
||||||
|
|
||||||
|
proc testProc: string {.compileTime.} =
|
||||||
|
result = ""
|
||||||
|
result = result & ""
|
||||||
|
|
||||||
|
when true:
|
||||||
|
macro test(n: stmt): stmt =
|
||||||
|
result = newNimNode(nnkStmtList)
|
||||||
|
echo "#", testProc(), "#"
|
||||||
|
test:
|
||||||
|
"hi"
|
||||||
|
|
||||||
|
const
|
||||||
|
x = testProc()
|
||||||
|
|
||||||
|
echo "##", x, "##"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -15,7 +15,7 @@ import
|
||||||
lua, lualib, lauxlib, mysql, sqlite3, python, tcl,
|
lua, lualib, lauxlib, mysql, sqlite3, python, tcl,
|
||||||
db_postgres, db_mysql, db_sqlite, ropes, sockets, browsers, httpserver,
|
db_postgres, db_mysql, db_sqlite, ropes, sockets, browsers, httpserver,
|
||||||
httpclient, parseutils, unidecode, xmldom, xmldomparser, xmltree, xmlparser,
|
httpclient, parseutils, unidecode, xmldom, xmldomparser, xmltree, xmlparser,
|
||||||
htmlparser, re, graphics, colors
|
htmlparser, re, graphics, colors, pegs
|
||||||
|
|
||||||
when defined(linux):
|
when defined(linux):
|
||||||
import
|
import
|
||||||
|
|
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -1,6 +1,6 @@
|
||||||
* thread support: threadvar on Windows seems broken;
|
* thread support: threadvar on Windows seems broken;
|
||||||
add --deadlock_prevention:on|off switch
|
add --deadlock_prevention:on|off switch
|
||||||
- implicit ref/ptr->var conversion
|
* implicit ref/ptr->var conversion
|
||||||
|
|
||||||
|
|
||||||
High priority (version 0.9.0)
|
High priority (version 0.9.0)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Changes affecting backwards compatibility
|
||||||
priority.
|
priority.
|
||||||
- Deprecated ``os.getApplicationFilename``: Use ``os.getAppFilename`` instead.
|
- Deprecated ``os.getApplicationFilename``: Use ``os.getAppFilename`` instead.
|
||||||
- Deprecated ``os.getApplicationDir``: Use ``os.getAppDir`` instead.
|
- Deprecated ``os.getApplicationDir``: Use ``os.getAppDir`` instead.
|
||||||
|
- Deprecated ``system.copy``: Use ``substr`` or string slicing instead.
|
||||||
- Changed and documented how generalized string literals work: The syntax
|
- Changed and documented how generalized string literals work: The syntax
|
||||||
``module.re"abc"`` is now supported.
|
``module.re"abc"`` is now supported.
|
||||||
- Changed the behaviour of ``strutils.%``, ``ropes.%``
|
- Changed the behaviour of ``strutils.%``, ``ropes.%``
|
||||||
|
|
@ -74,10 +75,11 @@ Additions
|
||||||
- Added the ``linearScanEnd``, ``unroll``, ``shallow`` pragmas.
|
- Added the ``linearScanEnd``, ``unroll``, ``shallow`` pragmas.
|
||||||
- Added ``system.reset`` and a version of ``system.open`` that
|
- Added ``system.reset`` and a version of ``system.open`` that
|
||||||
returns a ``TFile`` and raises an exception in case of an error.
|
returns a ``TFile`` and raises an exception in case of an error.
|
||||||
- The compiler now might use a hashing for string case statements depending
|
- The compiler now might use hashing for string case statements depending
|
||||||
on the number of string literals in the case statement.
|
on the number of string literals in the case statement.
|
||||||
- Added a wrapper for ``redis``.
|
- Added a wrapper for ``redis``.
|
||||||
- The compiler now supports array, sequence and string slicing.
|
- The compiler now supports array, sequence and string slicing.
|
||||||
|
- Added ``system.newStringOfCap``.
|
||||||
|
|
||||||
|
|
||||||
2010-10-20 Version 0.8.10 released
|
2010-10-20 Version 0.8.10 released
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue