mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 18:02:05 +00:00
newStringOfCap implemented and used to optimize some procs
This commit is contained in:
@@ -337,7 +337,9 @@ type
|
||||
mFields, mFieldPairs,
|
||||
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
||||
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,
|
||||
mOrdinal, mInt, mInt8, mInt16, mInt32,
|
||||
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,
|
||||
mInSet:
|
||||
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 mEcho: genEcho(p, e)
|
||||
of mArrToSeq: genArrToSeq(p, e, d)
|
||||
|
||||
@@ -990,7 +990,13 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||
var a = result
|
||||
result = newNodeIT(nkStrLit, n.info, n.typ)
|
||||
result.strVal = newString(int(getOrdValue(a)))
|
||||
else:
|
||||
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:
|
||||
result = evalAux(c, n.sons[1], {})
|
||||
if isSpecial(result): return
|
||||
var a = result
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -205,7 +205,8 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
||||
of mCompileOptionArg:
|
||||
result = newIntNodeT(Ord(
|
||||
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,
|
||||
mNLen..mNError, mEqRef:
|
||||
nil
|
||||
|
||||
@@ -32,6 +32,7 @@ get get, ``[]`` consider overloading ``[]`` for get;
|
||||
prefix: ``len`` instead of ``getLen``
|
||||
length len also used for *number of elements*
|
||||
size size, len size should refer to a byte size
|
||||
capacity cap
|
||||
memory mem implies a low-level operation
|
||||
items items default iterator over a collection
|
||||
pairs pairs iterator over (key, value) pairs
|
||||
|
||||
@@ -36,7 +36,7 @@ proc URLencode*(s: string): string =
|
||||
## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result,
|
||||
## a space is converted to ``'+'`` and every other character is encoded as
|
||||
## ``'%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:
|
||||
case 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
|
||||
## value) is converted to the character with ordinal number ``xx``, and
|
||||
## and every other character is carried over.
|
||||
result = ""
|
||||
result = newString(s.len)
|
||||
var i = 0
|
||||
var j = 0
|
||||
while i < s.len:
|
||||
case s[i]
|
||||
of '%':
|
||||
@@ -66,10 +67,12 @@ proc URLdecode*(s: string): string =
|
||||
handleHexChar(s[i+1], x)
|
||||
handleHexChar(s[i+2], x)
|
||||
inc(i, 2)
|
||||
add(result, chr(x))
|
||||
of '+': add(result, ' ')
|
||||
else: add(result, s[i])
|
||||
result[j] = chr(x)
|
||||
of '+': result[j] = ' '
|
||||
else: result[j] = s[i]
|
||||
inc(i)
|
||||
inc(j)
|
||||
setLen(result, j)
|
||||
|
||||
proc addXmlChar(dest: var string, c: Char) {.inline.} =
|
||||
case c
|
||||
@@ -86,7 +89,7 @@ proc XMLencode*(s: string): string =
|
||||
## * ``>`` is replaced by ``>``
|
||||
## * ``&`` is replaced by ``&``
|
||||
## * 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])
|
||||
|
||||
type
|
||||
@@ -367,4 +370,8 @@ proc existsCookie*(name: string): bool =
|
||||
if gcookies == nil: gcookies = parseCookies(getHttpCookie())
|
||||
result = hasKey(gcookies, name)
|
||||
|
||||
when isMainModule:
|
||||
const test1 = "abc\L+def xyz"
|
||||
assert UrlEncode(test1) == "abc%0A%2Bdef+xyz"
|
||||
assert UrlDecode(UrlEncode(test1)) == test1
|
||||
|
||||
|
||||
@@ -620,7 +620,8 @@ proc nl(s: var string, ml: bool) =
|
||||
|
||||
proc escapeJson*(s: string): string =
|
||||
## Converts a string `s` to its JSON representation.
|
||||
result = "\""
|
||||
result = newStringOfCap(s.len + s.len shr 3)
|
||||
result.add("\"")
|
||||
for x in runes(s):
|
||||
var r = int(x)
|
||||
if r >= 32 and r <= 127:
|
||||
|
||||
@@ -89,12 +89,16 @@ proc normalize*(s: string): string {.noSideEffect, procvar,
|
||||
rtl, extern: "nsuNormalize".} =
|
||||
## Normalizes the string `s`. That means to convert it to lower case and
|
||||
## 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:
|
||||
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] != '_':
|
||||
add result, s[i]
|
||||
result[j] = s[i]
|
||||
inc j
|
||||
if j != s.len: setLen(result, j)
|
||||
|
||||
proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,
|
||||
rtl, extern: "nsuCmpIgnoreCase", procvar.} =
|
||||
@@ -226,13 +230,14 @@ proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect,
|
||||
##
|
||||
## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is
|
||||
## 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)
|
||||
|
||||
proc `%` *(formatstr, a: string): string {.noSideEffect,
|
||||
rtl, extern: "nsuFormatSingleElem".} =
|
||||
## 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,
|
||||
rtl, extern: "nsuStrip".} =
|
||||
@@ -510,7 +515,7 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||
newLine = "\n"): string {.
|
||||
noSideEffect, rtl, extern: "nsuWordWrap".} =
|
||||
## word wraps `s`.
|
||||
result = ""
|
||||
result = newStringOfCap(s.len + s.len shr 6)
|
||||
var SpaceLeft = maxLineWidth
|
||||
for word, isSep in tokenize(s, seps):
|
||||
if len(word) > SpaceLeft:
|
||||
@@ -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
|
||||
## different common syntaxes. The resulting string is prefixed with
|
||||
## `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):
|
||||
case c
|
||||
of '\0'..'\31', '\128'..'\255':
|
||||
|
||||
@@ -685,7 +685,13 @@ proc newString*(len: int): string {.
|
||||
## content. One needs to fill the string character after character
|
||||
## with the index operator ``s[i]``. This procedure exists only for
|
||||
## 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 {.
|
||||
magic: "ConStrStr", noSideEffect, merge.}
|
||||
|
||||
@@ -74,10 +74,11 @@ Additions
|
||||
- Added the ``linearScanEnd``, ``unroll``, ``shallow`` pragmas.
|
||||
- Added ``system.reset`` and a version of ``system.open`` that
|
||||
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.
|
||||
- Added a wrapper for ``redis``.
|
||||
- The compiler now supports array, sequence and string slicing.
|
||||
- Added ``system.newStringOfCap``.
|
||||
|
||||
|
||||
2010-10-20 Version 0.8.10 released
|
||||
|
||||
Reference in New Issue
Block a user