:= templatable; lexer improvements
This commit is contained in:
parent
e487c0a249
commit
48dd9679bd
11 changed files with 117 additions and 166 deletions
|
|
@ -513,14 +513,15 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
|
||||||
rettype, params: PRope
|
rettype, params: PRope
|
||||||
check: TIntSet
|
check: TIntSet
|
||||||
# using static is needed for inline procs
|
# using static is needed for inline procs
|
||||||
if (prc.typ.callConv == ccInline): result = toRope("static ")
|
if (prc.typ.callConv == ccInline): result = toRope"static "
|
||||||
else: result = nil
|
|
||||||
IntSetInit(check)
|
IntSetInit(check)
|
||||||
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
|
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
|
||||||
genProcParams(m, prc.typ, rettype, params, check)
|
genProcParams(m, prc.typ, rettype, params, check)
|
||||||
appf(result, "$1($2, $3)$4",
|
appf(result, "$1($2, $3)$4",
|
||||||
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r, params])
|
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r, params])
|
||||||
|
|
||||||
|
# ------------------ type info generation -------------------------------------
|
||||||
|
|
||||||
proc genTypeInfo(m: BModule, typ: PType): PRope
|
proc genTypeInfo(m: BModule, typ: PType): PRope
|
||||||
proc getNimNode(m: BModule): PRope =
|
proc getNimNode(m: BModule): PRope =
|
||||||
result = ropef("$1[$2]", [m.typeNodesName, toRope(m.typeNodes)])
|
result = ropef("$1[$2]", [m.typeNodesName, toRope(m.typeNodes)])
|
||||||
|
|
@ -743,10 +744,10 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
|
||||||
[result, toRope(typeToString(t))])
|
[result, toRope(typeToString(t))])
|
||||||
if dataGenerated: return
|
if dataGenerated: return
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyEmpty: result = toRope("0")
|
of tyEmpty: result = toRope"0"
|
||||||
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyFloat128,
|
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyFloat128,
|
||||||
tyVar:
|
tyVar:
|
||||||
genTypeInfoAuxBase(gNimDat, t, result, toRope("0"))
|
genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
|
||||||
of tyRef, tyPtr, tySequence, tyRange: genTypeInfoAux(gNimDat, t, result)
|
of tyRef, tyPtr, tySequence, tyRange: genTypeInfoAux(gNimDat, t, result)
|
||||||
of tyArrayConstr, tyArray: genArrayInfo(gNimDat, t, result)
|
of tyArrayConstr, tyArray: genArrayInfo(gNimDat, t, result)
|
||||||
of tySet: genSetInfo(gNimDat, t, result)
|
of tySet: genSetInfo(gNimDat, t, result)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2009 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.
|
||||||
|
|
@ -20,29 +20,17 @@ type
|
||||||
PHash* = ref THash
|
PHash* = ref THash
|
||||||
THashFunc* = proc (str: cstring): THash
|
THashFunc* = proc (str: cstring): THash
|
||||||
|
|
||||||
proc GetHash*(str: cstring): THash
|
proc concHash*(h: THash, val: int): THash {.inline.} =
|
||||||
proc GetHashCI*(str: cstring): THash
|
|
||||||
proc GetDataHash*(Data: Pointer, Size: int): THash
|
|
||||||
proc hashPtr*(p: Pointer): THash
|
|
||||||
proc GetHashStr*(s: string): THash
|
|
||||||
proc GetHashStrCI*(s: string): THash
|
|
||||||
proc getNormalizedHash*(s: string): THash
|
|
||||||
#function nextPowerOfTwo(x: int): int;
|
|
||||||
proc concHash*(h: THash, val: int): THash
|
|
||||||
proc finishHash*(h: THash): THash
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
proc concHash(h: THash, val: int): THash =
|
|
||||||
result = h +% val
|
result = h +% val
|
||||||
result = result +% result shl 10
|
result = result +% result shl 10
|
||||||
result = result xor (result shr 6)
|
result = result xor (result shr 6)
|
||||||
|
|
||||||
proc finishHash(h: THash): THash =
|
proc finishHash*(h: THash): THash {.inline.} =
|
||||||
result = h +% h shl 3
|
result = h +% h shl 3
|
||||||
result = result xor (result shr 11)
|
result = result xor (result shr 11)
|
||||||
result = result +% result shl 15
|
result = result +% result shl 15
|
||||||
|
|
||||||
proc GetDataHash(Data: Pointer, Size: int): THash =
|
proc GetDataHash*(Data: Pointer, Size: int): THash =
|
||||||
var
|
var
|
||||||
h: THash
|
h: THash
|
||||||
p: cstring
|
p: cstring
|
||||||
|
|
@ -62,10 +50,10 @@ proc GetDataHash(Data: Pointer, Size: int): THash =
|
||||||
h = h +% h shl 15
|
h = h +% h shl 15
|
||||||
result = THash(h)
|
result = THash(h)
|
||||||
|
|
||||||
proc hashPtr(p: Pointer): THash =
|
proc hashPtr*(p: Pointer): THash =
|
||||||
result = (cast[THash](p)) shr 3 # skip the alignment
|
result = (cast[THash](p)) shr 3 # skip the alignment
|
||||||
|
|
||||||
proc GetHash(str: cstring): THash =
|
proc GetHash*(str: cstring): THash =
|
||||||
var
|
var
|
||||||
h: THash
|
h: THash
|
||||||
i: int
|
i: int
|
||||||
|
|
@ -81,7 +69,7 @@ proc GetHash(str: cstring): THash =
|
||||||
h = h +% h shl 15
|
h = h +% h shl 15
|
||||||
result = THash(h)
|
result = THash(h)
|
||||||
|
|
||||||
proc GetHashStr(s: string): THash =
|
proc GetHashStr*(s: string): THash =
|
||||||
var h: THash
|
var h: THash
|
||||||
h = 0
|
h = 0
|
||||||
for i in countup(1, len(s)):
|
for i in countup(1, len(s)):
|
||||||
|
|
@ -93,7 +81,7 @@ proc GetHashStr(s: string): THash =
|
||||||
h = h +% h shl 15
|
h = h +% h shl 15
|
||||||
result = THash(h)
|
result = THash(h)
|
||||||
|
|
||||||
proc getNormalizedHash(s: string): THash =
|
proc getNormalizedHash*(s: string): THash =
|
||||||
var
|
var
|
||||||
h: THash
|
h: THash
|
||||||
c: Char
|
c: Char
|
||||||
|
|
@ -112,7 +100,7 @@ proc getNormalizedHash(s: string): THash =
|
||||||
h = h +% h shl 15
|
h = h +% h shl 15
|
||||||
result = THash(h)
|
result = THash(h)
|
||||||
|
|
||||||
proc GetHashStrCI(s: string): THash =
|
proc GetHashStrCI*(s: string): THash =
|
||||||
var
|
var
|
||||||
h: THash
|
h: THash
|
||||||
c: Char
|
c: Char
|
||||||
|
|
@ -129,7 +117,7 @@ proc GetHashStrCI(s: string): THash =
|
||||||
h = h +% h shl 15
|
h = h +% h shl 15
|
||||||
result = THash(h)
|
result = THash(h)
|
||||||
|
|
||||||
proc GetHashCI(str: cstring): THash =
|
proc GetHashCI*(str: cstring): THash =
|
||||||
var
|
var
|
||||||
h: THash
|
h: THash
|
||||||
c: Char
|
c: Char
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,13 @@ import
|
||||||
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, scanner,
|
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, scanner,
|
||||||
options, idents, wordrecg
|
options, idents, wordrecg
|
||||||
|
|
||||||
proc LoadConfig*(project: string)
|
|
||||||
proc LoadSpecialConfig*(configfilename: string)
|
|
||||||
# implementation
|
|
||||||
# ---------------- configuration file parser -----------------------------
|
# ---------------- configuration file parser -----------------------------
|
||||||
# we use Nimrod's scanner here to safe space and work
|
# we use Nimrod's scanner here to safe space and work
|
||||||
|
|
||||||
proc ppGetTok(L: var TLexer, tok: PToken) =
|
proc ppGetTok(L: var TLexer, tok: PToken) =
|
||||||
# simple filter
|
# simple filter
|
||||||
rawGetTok(L, tok[] )
|
rawGetTok(L, tok[])
|
||||||
while (tok.tokType == tkInd) or (tok.tokType == tkSad) or
|
while tok.tokType in {tkInd, tkSad, tkDed, tkComment}: rawGetTok(L, tok[])
|
||||||
(tok.tokType == tkDed) or (tok.tokType == tkComment):
|
|
||||||
rawGetTok(L, tok[] )
|
|
||||||
|
|
||||||
proc parseExpr(L: var TLexer, tok: PToken): bool
|
proc parseExpr(L: var TLexer, tok: PToken): bool
|
||||||
proc parseAtom(L: var TLexer, tok: PToken): bool =
|
proc parseAtom(L: var TLexer, tok: PToken): bool =
|
||||||
|
|
@ -37,24 +32,21 @@ proc parseAtom(L: var TLexer, tok: PToken): bool =
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
result = not parseAtom(L, tok)
|
result = not parseAtom(L, tok)
|
||||||
else:
|
else:
|
||||||
result = isDefined(tok.ident) #condsyms.listSymbols();
|
result = isDefined(tok.ident)
|
||||||
#writeln(tok.ident.s + ' has the value: ', result);
|
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
||||||
proc parseAndExpr(L: var TLexer, tok: PToken): bool =
|
proc parseAndExpr(L: var TLexer, tok: PToken): bool =
|
||||||
var b: bool
|
|
||||||
result = parseAtom(L, tok)
|
result = parseAtom(L, tok)
|
||||||
while tok.ident.id == ord(wAnd):
|
while tok.ident.id == ord(wAnd):
|
||||||
ppGetTok(L, tok) # skip "and"
|
ppGetTok(L, tok) # skip "and"
|
||||||
b = parseAtom(L, tok)
|
var b = parseAtom(L, tok)
|
||||||
result = result and b
|
result = result and b
|
||||||
|
|
||||||
proc parseExpr(L: var TLexer, tok: PToken): bool =
|
proc parseExpr(L: var TLexer, tok: PToken): bool =
|
||||||
var b: bool
|
|
||||||
result = parseAndExpr(L, tok)
|
result = parseAndExpr(L, tok)
|
||||||
while tok.ident.id == ord(wOr):
|
while tok.ident.id == ord(wOr):
|
||||||
ppGetTok(L, tok) # skip "or"
|
ppGetTok(L, tok) # skip "or"
|
||||||
b = parseAndExpr(L, tok)
|
var b = parseAndExpr(L, tok)
|
||||||
result = result or b
|
result = result or b
|
||||||
|
|
||||||
proc EvalppIf(L: var TLexer, tok: PToken): bool =
|
proc EvalppIf(L: var TLexer, tok: PToken): bool =
|
||||||
|
|
@ -63,9 +55,8 @@ proc EvalppIf(L: var TLexer, tok: PToken): bool =
|
||||||
if tok.tokType == tkColon: ppGetTok(L, tok)
|
if tok.tokType == tkColon: ppGetTok(L, tok)
|
||||||
else: lexMessage(L, errTokenExpected, "\':\'")
|
else: lexMessage(L, errTokenExpected, "\':\'")
|
||||||
|
|
||||||
var condStack: seq[bool]
|
var condStack: seq[bool] = @[]
|
||||||
|
|
||||||
condStack = @ []
|
|
||||||
proc doEnd(L: var TLexer, tok: PToken) =
|
proc doEnd(L: var TLexer, tok: PToken) =
|
||||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||||
ppGetTok(L, tok) # skip 'end'
|
ppGetTok(L, tok) # skip 'end'
|
||||||
|
|
@ -83,15 +74,13 @@ proc doElse(L: var TLexer, tok: PToken) =
|
||||||
if condStack[high(condStack)]: jumpToDirective(L, tok, jdEndif)
|
if condStack[high(condStack)]: jumpToDirective(L, tok, jdEndif)
|
||||||
|
|
||||||
proc doElif(L: var TLexer, tok: PToken) =
|
proc doElif(L: var TLexer, tok: PToken) =
|
||||||
var res: bool
|
|
||||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||||
res = EvalppIf(L, tok)
|
var res = EvalppIf(L, tok)
|
||||||
if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif)
|
if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif)
|
||||||
else: condStack[high(condStack)] = true
|
else: condStack[high(condStack)] = true
|
||||||
|
|
||||||
proc jumpToDirective(L: var TLexer, tok: PToken, dest: TJumpDest) =
|
proc jumpToDirective(L: var TLexer, tok: PToken, dest: TJumpDest) =
|
||||||
var nestedIfs: int
|
var nestedIfs = 0
|
||||||
nestedIfs = 0
|
|
||||||
while True:
|
while True:
|
||||||
if (tok.ident != nil) and (tok.ident.s == "@"):
|
if (tok.ident != nil) and (tok.ident.s == "@"):
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
@ -120,42 +109,35 @@ proc jumpToDirective(L: var TLexer, tok: PToken, dest: TJumpDest) =
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
||||||
proc parseDirective(L: var TLexer, tok: PToken) =
|
proc parseDirective(L: var TLexer, tok: PToken) =
|
||||||
var
|
|
||||||
res: bool
|
|
||||||
key: string
|
|
||||||
ppGetTok(L, tok) # skip @
|
ppGetTok(L, tok) # skip @
|
||||||
case whichKeyword(tok.ident)
|
case whichKeyword(tok.ident)
|
||||||
of wIf:
|
of wIf:
|
||||||
setlen(condStack, len(condStack) + 1)
|
setlen(condStack, len(condStack) + 1)
|
||||||
res = EvalppIf(L, tok)
|
var res = EvalppIf(L, tok)
|
||||||
condStack[high(condStack)] = res
|
condStack[high(condStack)] = res
|
||||||
if not res:
|
if not res: jumpToDirective(L, tok, jdElseEndif)
|
||||||
jumpToDirective(L, tok, jdElseEndif)
|
of wElif: doElif(L, tok)
|
||||||
of wElif:
|
of wElse: doElse(L, tok)
|
||||||
doElif(L, tok)
|
of wEnd: doEnd(L, tok)
|
||||||
of wElse:
|
|
||||||
doElse(L, tok)
|
|
||||||
of wEnd:
|
|
||||||
doEnd(L, tok)
|
|
||||||
of wWrite:
|
of wWrite:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
msgs.MsgWriteln(tokToStr(tok))
|
msgs.MsgWriteln(tokToStr(tok))
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
of wPutEnv:
|
of wPutEnv:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
key = tokToStr(tok)
|
var key = tokToStr(tok)
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
os.putEnv(key, tokToStr(tok))
|
os.putEnv(key, tokToStr(tok))
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
of wPrependEnv:
|
of wPrependEnv:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
key = tokToStr(tok)
|
var key = tokToStr(tok)
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
os.putEnv(key, tokToStr(tok) & os.getenv(key))
|
os.putEnv(key, tokToStr(tok) & os.getenv(key))
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
of wAppendenv:
|
of wAppendenv:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
key = tokToStr(tok)
|
var key = tokToStr(tok)
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
os.putEnv(key, os.getenv(key) & tokToStr(tok))
|
os.putEnv(key, os.getenv(key) & tokToStr(tok))
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
|
|
@ -163,24 +145,21 @@ proc parseDirective(L: var TLexer, tok: PToken) =
|
||||||
|
|
||||||
proc confTok(L: var TLexer, tok: PToken) =
|
proc confTok(L: var TLexer, tok: PToken) =
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
while (tok.ident != nil) and (tok.ident.s == "@"):
|
while tok.ident != nil and tok.ident.s == "@":
|
||||||
parseDirective(L, tok) # else: give the token to the parser
|
parseDirective(L, tok) # else: give the token to the parser
|
||||||
|
|
||||||
proc checkSymbol(L: TLexer, tok: PToken) =
|
proc checkSymbol(L: TLexer, tok: PToken) =
|
||||||
if not (tok.tokType in {tkSymbol..pred(tkIntLit), tkStrLit..tkTripleStrLit}):
|
if tok.tokType notin {tkSymbol..pred(tkIntLit), tkStrLit..tkTripleStrLit}:
|
||||||
lexMessage(L, errIdentifierExpected, tokToStr(tok))
|
lexMessage(L, errIdentifierExpected, tokToStr(tok))
|
||||||
|
|
||||||
proc parseAssignment(L: var TLexer, tok: PToken) =
|
proc parseAssignment(L: var TLexer, tok: PToken) =
|
||||||
var
|
if tok.ident.id == getIdent("-").id or tok.ident.id == getIdent("--").id:
|
||||||
s, val: string
|
|
||||||
info: TLineInfo
|
|
||||||
if (tok.ident.id == getIdent("-").id) or (tok.ident.id == getIdent("--").id):
|
|
||||||
confTok(L, tok) # skip unnecessary prefix
|
confTok(L, tok) # skip unnecessary prefix
|
||||||
info = getLineInfo(L) # safe for later in case of an error
|
var info = getLineInfo(L) # safe for later in case of an error
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
s = tokToStr(tok)
|
var s = tokToStr(tok)
|
||||||
confTok(L, tok) # skip symbol
|
confTok(L, tok) # skip symbol
|
||||||
val = ""
|
var val = ""
|
||||||
while tok.tokType == tkDot:
|
while tok.tokType == tkDot:
|
||||||
add(s, '.')
|
add(s, '.')
|
||||||
confTok(L, tok)
|
confTok(L, tok)
|
||||||
|
|
@ -197,14 +176,13 @@ proc parseAssignment(L: var TLexer, tok: PToken) =
|
||||||
if tok.tokType == tkBracketRi: confTok(L, tok)
|
if tok.tokType == tkBracketRi: confTok(L, tok)
|
||||||
else: lexMessage(L, errTokenExpected, "\']\'")
|
else: lexMessage(L, errTokenExpected, "\']\'")
|
||||||
add(val, ']')
|
add(val, ']')
|
||||||
if (tok.tokType == tkColon) or (tok.tokType == tkEquals):
|
if tok.tokType in {tkColon, tkEquals}:
|
||||||
if len(val) > 0:
|
if len(val) > 0: add(val, ':')
|
||||||
add(val, ':') # BUGFIX
|
|
||||||
confTok(L, tok) # skip ':' or '='
|
confTok(L, tok) # skip ':' or '='
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
confTok(L, tok) # skip symbol
|
confTok(L, tok) # skip symbol
|
||||||
while (tok.ident != nil) and (tok.ident.id == getIdent("&").id):
|
while tok.ident != nil and tok.ident.id == getIdent("&").id:
|
||||||
confTok(L, tok)
|
confTok(L, tok)
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
|
|
@ -234,24 +212,22 @@ proc getConfigPath(filename: string): string =
|
||||||
# try standard configuration file (installation did not distribute files
|
# try standard configuration file (installation did not distribute files
|
||||||
# the UNIX way)
|
# the UNIX way)
|
||||||
result = joinPath([getPrefixDir(), "config", filename])
|
result = joinPath([getPrefixDir(), "config", filename])
|
||||||
if not ExistsFile(result):
|
if not ExistsFile(result): result = "/etc/" & filename
|
||||||
result = "/etc/" & filename
|
|
||||||
|
|
||||||
proc LoadSpecialConfig(configfilename: string) =
|
proc LoadSpecialConfig*(configfilename: string) =
|
||||||
if not (optSkipConfigFile in gGlobalOptions):
|
if optSkipConfigFile notin gGlobalOptions:
|
||||||
readConfigFile(getConfigPath(configfilename))
|
readConfigFile(getConfigPath(configfilename))
|
||||||
|
|
||||||
proc LoadConfig(project: string) =
|
proc LoadConfig*(project: string) =
|
||||||
var conffile, prefix: string
|
|
||||||
# set default value (can be overwritten):
|
# set default value (can be overwritten):
|
||||||
if libpath == "":
|
if libpath == "":
|
||||||
# choose default libpath:
|
# choose default libpath:
|
||||||
prefix = getPrefixDir()
|
var prefix = getPrefixDir()
|
||||||
if (prefix == "/usr"): libpath = "/usr/lib/nimrod"
|
if (prefix == "/usr"): libpath = "/usr/lib/nimrod"
|
||||||
elif (prefix == "/usr/local"): libpath = "/usr/local/lib/nimrod"
|
elif (prefix == "/usr/local"): libpath = "/usr/local/lib/nimrod"
|
||||||
else: libpath = joinPath(prefix, "lib")
|
else: libpath = joinPath(prefix, "lib")
|
||||||
LoadSpecialConfig("nimrod.cfg") # read project config file:
|
LoadSpecialConfig("nimrod.cfg") # read project config file:
|
||||||
if not (optSkipProjConfigFile in gGlobalOptions) and (project != ""):
|
if optSkipProjConfigFile notin gGlobalOptions and project != "":
|
||||||
conffile = changeFileExt(project, "cfg")
|
var conffile = changeFileExt(project, "cfg")
|
||||||
if existsFile(conffile): readConfigFile(conffile)
|
if existsFile(conffile): readConfigFile(conffile)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ proc newStrNodeP*(kind: TNodeKind, strVal: string, p: TParser): PNode
|
||||||
proc newIdentNodeP*(ident: PIdent, p: TParser): PNode
|
proc newIdentNodeP*(ident: PIdent, p: TParser): PNode
|
||||||
proc expectIdentOrKeyw*(p: TParser)
|
proc expectIdentOrKeyw*(p: TParser)
|
||||||
proc ExpectIdent*(p: TParser)
|
proc ExpectIdent*(p: TParser)
|
||||||
proc expectIdentOrOpr*(p: TParser)
|
|
||||||
proc parLineInfo*(p: TParser): TLineInfo
|
proc parLineInfo*(p: TParser): TLineInfo
|
||||||
proc Eat*(p: var TParser, TokType: TTokType)
|
proc Eat*(p: var TParser, TokType: TTokType)
|
||||||
proc skipInd*(p: var TParser)
|
proc skipInd*(p: var TParser)
|
||||||
|
|
@ -101,10 +100,6 @@ proc ExpectIdent(p: TParser) =
|
||||||
if p.tok.tokType != tkSymbol:
|
if p.tok.tokType != tkSymbol:
|
||||||
lexMessage(p.lex[], errIdentifierExpected, tokToStr(p.tok))
|
lexMessage(p.lex[], errIdentifierExpected, tokToStr(p.tok))
|
||||||
|
|
||||||
proc expectIdentOrOpr(p: TParser) =
|
|
||||||
if not (p.tok.tokType in tokOperators):
|
|
||||||
lexMessage(p.lex[], errOperatorExpected, tokToStr(p.tok))
|
|
||||||
|
|
||||||
proc Eat(p: var TParser, TokType: TTokType) =
|
proc Eat(p: var TParser, TokType: TTokType) =
|
||||||
if p.tok.TokType == TokType: getTok(p)
|
if p.tok.TokType == TokType: getTok(p)
|
||||||
else: lexMessage(p.lex[], errTokenExpected, TokTypeToStr[tokType])
|
else: lexMessage(p.lex[], errTokenExpected, TokTypeToStr[tokType])
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ proc app(a: var PRope, b: PRope) = a = con(a, b)
|
||||||
proc app(a: var PRope, b: string) = a = con(a, b)
|
proc app(a: var PRope, b: string) = a = con(a, b)
|
||||||
proc prepend(a: var PRope, b: PRope) = a = con(b, a)
|
proc prepend(a: var PRope, b: PRope) = a = con(b, a)
|
||||||
|
|
||||||
proc writeRope*(f: var tfile, c: PRope) =
|
proc writeRope*(f: TFile, c: PRope) =
|
||||||
var stack = @[c]
|
var stack = @[c]
|
||||||
while len(stack) > 0:
|
while len(stack) > 0:
|
||||||
var it = pop(stack)
|
var it = pop(stack)
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -25,27 +25,12 @@ const
|
||||||
SymChars*: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'}
|
SymChars*: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'}
|
||||||
SymStartChars*: TCharSet = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
|
SymStartChars*: TCharSet = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
|
||||||
OpChars*: TCharSet = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^', '.',
|
OpChars*: TCharSet = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^', '.',
|
||||||
'|', '=', '%', '&', '$', '@', '~', '\x80'..'\xFF'}
|
'|', '=', '%', '&', '$', '@', '~', ':', '\x80'..'\xFF'}
|
||||||
|
|
||||||
type
|
type
|
||||||
TTokType* = enum
|
TTokType* = enum
|
||||||
tkInvalid, tkEof, # order is important here!
|
tkInvalid, tkEof, # order is important here!
|
||||||
tkSymbol, # keywords:
|
tkSymbol, # keywords:
|
||||||
#[[[cog
|
|
||||||
#from string import split, capitalize
|
|
||||||
#keywords = split(open("data/keywords.txt").read())
|
|
||||||
#idents = ""
|
|
||||||
#strings = ""
|
|
||||||
#i = 1
|
|
||||||
#for k in keywords:
|
|
||||||
# idents = idents + "tk" + capitalize(k) + ", "
|
|
||||||
# strings = strings + "'" + k + "', "
|
|
||||||
# if i % 4 == 0:
|
|
||||||
# idents = idents + "\n"
|
|
||||||
# strings = strings + "\n"
|
|
||||||
# i = i + 1
|
|
||||||
#cog.out(idents)
|
|
||||||
#]]]
|
|
||||||
tkAddr, tkAnd, tkAs, tkAsm, tkAtomic,
|
tkAddr, tkAnd, tkAs, tkAsm, tkAtomic,
|
||||||
tkBind, tkBlock, tkBreak, tkCase, tkCast,
|
tkBind, tkBlock, tkBreak, tkCase, tkCast,
|
||||||
tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif,
|
tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif,
|
||||||
|
|
@ -55,7 +40,7 @@ type
|
||||||
tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr,
|
tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr,
|
||||||
tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkTemplate,
|
tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkTemplate,
|
||||||
tkTry, tkTuple, tkType, tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
|
tkTry, tkTuple, tkType, tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
|
||||||
tkYield, #[[[end]]]
|
tkYield, # end of keywords
|
||||||
tkIntLit, tkInt8Lit, tkInt16Lit, tkInt32Lit, tkInt64Lit, tkFloatLit,
|
tkIntLit, tkInt8Lit, tkInt16Lit, tkInt32Lit, tkInt64Lit, tkFloatLit,
|
||||||
tkFloat32Lit, tkFloat64Lit, tkStrLit, tkRStrLit, tkTripleStrLit,
|
tkFloat32Lit, tkFloat64Lit, tkStrLit, tkRStrLit, tkTripleStrLit,
|
||||||
tkGStrLit, tkGTripleStrLit, tkCharLit, tkParLe, tkParRi, tkBracketLe,
|
tkGStrLit, tkGTripleStrLit, tkCharLit, tkParLe, tkParRi, tkBracketLe,
|
||||||
|
|
@ -63,8 +48,8 @@ type
|
||||||
tkBracketDotLe, tkBracketDotRi, # [. and .]
|
tkBracketDotLe, tkBracketDotRi, # [. and .]
|
||||||
tkCurlyDotLe, tkCurlyDotRi, # {. and .}
|
tkCurlyDotLe, tkCurlyDotRi, # {. and .}
|
||||||
tkParDotLe, tkParDotRi, # (. and .)
|
tkParDotLe, tkParDotRi, # (. and .)
|
||||||
tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot, tkHat, tkOpr,
|
tkComma, tkSemiColon, tkColon, tkColonColon, tkEquals, tkDot, tkDotDot,
|
||||||
tkComment, tkAccent, tkInd, tkSad,
|
tkHat, tkOpr, tkComment, tkAccent, tkInd, tkSad,
|
||||||
tkDed, # pseudo token types used by the source renderers:
|
tkDed, # pseudo token types used by the source renderers:
|
||||||
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr
|
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr
|
||||||
TTokTypes* = set[TTokType]
|
TTokTypes* = set[TTokType]
|
||||||
|
|
@ -72,13 +57,8 @@ type
|
||||||
const
|
const
|
||||||
tokKeywordLow* = succ(tkSymbol)
|
tokKeywordLow* = succ(tkSymbol)
|
||||||
tokKeywordHigh* = pred(tkIntLit)
|
tokKeywordHigh* = pred(tkIntLit)
|
||||||
tokOperators*: TTokTypes = {tkOpr, tkSymbol, tkBracketLe, tkBracketRi, tkIn,
|
|
||||||
tkIs, tkIsNot, tkEquals, tkDot, tkHat, tkNot, tkAnd, tkOr, tkXor, tkShl,
|
|
||||||
tkShr, tkDiv, tkMod, tkNotIn}
|
|
||||||
TokTypeToStr*: array[TTokType, string] = ["tkInvalid", "[EOF]",
|
TokTypeToStr*: array[TTokType, string] = ["tkInvalid", "[EOF]",
|
||||||
"tkSymbol", #[[[cog
|
"tkSymbol",
|
||||||
#cog.out(strings)
|
|
||||||
#]]]
|
|
||||||
"addr", "and", "as", "asm", "atomic",
|
"addr", "and", "as", "asm", "atomic",
|
||||||
"bind", "block", "break", "case", "cast",
|
"bind", "block", "break", "case", "cast",
|
||||||
"const", "continue", "converter", "discard", "distinct", "div", "elif",
|
"const", "continue", "converter", "discard", "distinct", "div", "elif",
|
||||||
|
|
@ -88,11 +68,12 @@ const
|
||||||
"macro", "method", "mod", "nil", "not", "notin", "object", "of", "or",
|
"macro", "method", "mod", "nil", "not", "notin", "object", "of", "or",
|
||||||
"out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template",
|
"out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template",
|
||||||
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
|
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
|
||||||
"yield", #[[[end]]]
|
"yield",
|
||||||
"tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit",
|
"tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit",
|
||||||
"tkFloatLit", "tkFloat32Lit", "tkFloat64Lit", "tkStrLit", "tkRStrLit",
|
"tkFloatLit", "tkFloat32Lit", "tkFloat64Lit", "tkStrLit", "tkRStrLit",
|
||||||
"tkTripleStrLit", "tkGStrLit", "tkGTripleStrLit", "tkCharLit", "(",
|
"tkTripleStrLit", "tkGStrLit", "tkGTripleStrLit", "tkCharLit", "(",
|
||||||
")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)", ",", ";", ":",
|
")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)", ",", ";",
|
||||||
|
":", "::",
|
||||||
"=", ".", "..", "^", "tkOpr", "tkComment", "`", "[new indentation]",
|
"=", ".", "..", "^", "tkOpr", "tkComment", "`", "[new indentation]",
|
||||||
"[same indentation]", "[dedentation]", "tkSpaces", "tkInfixOpr",
|
"[same indentation]", "[dedentation]", "tkSpaces", "tkInfixOpr",
|
||||||
"tkPrefixOpr", "tkPostfixOpr"]
|
"tkPrefixOpr", "tkPostfixOpr"]
|
||||||
|
|
@ -414,8 +395,7 @@ proc handleHexChar(L: var TLexer, xi: var int) =
|
||||||
of 'A'..'F':
|
of 'A'..'F':
|
||||||
xi = (xi shl 4) or (ord(L.buf[L.bufpos]) - ord('A') + 10)
|
xi = (xi shl 4) or (ord(L.buf[L.bufpos]) - ord('A') + 10)
|
||||||
inc(L.bufpos)
|
inc(L.bufpos)
|
||||||
else:
|
else: nil
|
||||||
nil
|
|
||||||
|
|
||||||
proc handleDecChars(L: var TLexer, xi: var int) =
|
proc handleDecChars(L: var TLexer, xi: var int) =
|
||||||
while L.buf[L.bufpos] in {'0'..'9'}:
|
while L.buf[L.bufpos] in {'0'..'9'}:
|
||||||
|
|
@ -508,7 +488,7 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) =
|
||||||
of CR, LF:
|
of CR, LF:
|
||||||
pos = HandleCRLF(L, pos)
|
pos = HandleCRLF(L, pos)
|
||||||
buf = L.buf
|
buf = L.buf
|
||||||
tok.literal = tok.literal & tnl
|
add(tok.literal, tnl)
|
||||||
of lexbase.EndOfFile:
|
of lexbase.EndOfFile:
|
||||||
var line2 = L.linenumber
|
var line2 = L.linenumber
|
||||||
L.LineNumber = line
|
L.LineNumber = line
|
||||||
|
|
@ -563,23 +543,17 @@ proc getSymbol(L: var TLexer, tok: var TToken) =
|
||||||
var c = buf[pos]
|
var c = buf[pos]
|
||||||
case c
|
case c
|
||||||
of 'a'..'z', '0'..'9', '\x80'..'\xFF':
|
of 'a'..'z', '0'..'9', '\x80'..'\xFF':
|
||||||
h = h +% Ord(c)
|
h = concHash(h, ord(c))
|
||||||
h = h +% h shl 10
|
|
||||||
h = h xor (h shr 6)
|
|
||||||
of 'A'..'Z':
|
of 'A'..'Z':
|
||||||
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
|
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
|
||||||
h = h +% Ord(c)
|
h = concHash(h, ord(c))
|
||||||
h = h +% h shl 10
|
|
||||||
h = h xor (h shr 6)
|
|
||||||
of '_':
|
of '_':
|
||||||
if buf[pos+1] notin SymChars:
|
if buf[pos+1] notin SymChars:
|
||||||
lexMessage(L, errInvalidToken, "_")
|
lexMessage(L, errInvalidToken, "_")
|
||||||
break
|
break
|
||||||
else: break
|
else: break
|
||||||
Inc(pos)
|
Inc(pos)
|
||||||
h = h +% h shl 3
|
h = finishHash(h)
|
||||||
h = h xor (h shr 11)
|
|
||||||
h = h +% h shl 15
|
|
||||||
tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
|
tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
|
||||||
L.bufpos = pos
|
L.bufpos = pos
|
||||||
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
|
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
|
||||||
|
|
@ -588,26 +562,24 @@ proc getSymbol(L: var TLexer, tok: var TToken) =
|
||||||
else:
|
else:
|
||||||
tok.tokType = TTokType(tok.ident.id + ord(tkSymbol))
|
tok.tokType = TTokType(tok.ident.id + ord(tkSymbol))
|
||||||
|
|
||||||
|
proc endOperator(L: var TLexer, tok: var TToken, pos: int,
|
||||||
|
hash: THash) {.inline.} =
|
||||||
|
var h = finishHash(hash)
|
||||||
|
tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
|
||||||
|
if (tok.ident.id < oprLow) or (tok.ident.id > oprHigh): tok.tokType = tkOpr
|
||||||
|
else: tok.tokType = TTokType(tok.ident.id - oprLow + ord(tkColon))
|
||||||
|
L.bufpos = pos
|
||||||
|
|
||||||
proc getOperator(L: var TLexer, tok: var TToken) =
|
proc getOperator(L: var TLexer, tok: var TToken) =
|
||||||
var pos = L.bufpos
|
var pos = L.bufpos
|
||||||
var buf = L.buf
|
var buf = L.buf
|
||||||
var h: THash = 0
|
var h: THash = 0
|
||||||
while true:
|
while true:
|
||||||
var c = buf[pos]
|
var c = buf[pos]
|
||||||
if c in OpChars:
|
if c notin OpChars: break
|
||||||
h = h +% Ord(c)
|
h = concHash(h, Ord(c))
|
||||||
h = h +% h shl 10
|
|
||||||
h = h xor (h shr 6)
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
Inc(pos)
|
Inc(pos)
|
||||||
h = h +% h shl 3
|
endOperator(L, tok, pos, h)
|
||||||
h = h xor (h shr 11)
|
|
||||||
h = h +% h shl 15
|
|
||||||
tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
|
|
||||||
if (tok.ident.id < oprLow) or (tok.ident.id > oprHigh): tok.tokType = tkOpr
|
|
||||||
else: tok.tokType = TTokType(tok.ident.id - oprLow + ord(tkColon))
|
|
||||||
L.bufpos = pos
|
|
||||||
|
|
||||||
proc handleIndentation(L: var TLexer, tok: var TToken, indent: int) =
|
proc handleIndentation(L: var TLexer, tok: var TToken, indent: int) =
|
||||||
tok.indent = indent
|
tok.indent = indent
|
||||||
|
|
@ -699,9 +671,14 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
|
||||||
case c
|
case c
|
||||||
of '#':
|
of '#':
|
||||||
scanComment(L, tok)
|
scanComment(L, tok)
|
||||||
of ':':
|
of '*':
|
||||||
tok.tokType = tkColon
|
# '*:' is unfortunately a special case, because it is two tokens in
|
||||||
inc(L.bufpos)
|
# 'var v*: int'.
|
||||||
|
if L.buf[L.bufpos+1] == ':' and L.buf[L.bufpos+2] notin OpChars:
|
||||||
|
var h = concHash(0, ord('*'))
|
||||||
|
endOperator(L, tok, L.bufpos+1, h)
|
||||||
|
else:
|
||||||
|
getOperator(L, tok)
|
||||||
of ',':
|
of ',':
|
||||||
tok.toktype = tkComma
|
tok.toktype = tkComma
|
||||||
Inc(L.bufpos)
|
Inc(L.bufpos)
|
||||||
|
|
@ -751,7 +728,7 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
|
||||||
getOperator(L, tok)
|
getOperator(L, tok)
|
||||||
of '{':
|
of '{':
|
||||||
Inc(L.bufpos)
|
Inc(L.bufpos)
|
||||||
if (L.buf[L.bufPos] == '.') and (L.buf[L.bufPos + 1] != '.'):
|
if (L.buf[L.bufPos] == '.') and (L.buf[L.bufPos+1] != '.'):
|
||||||
tok.toktype = tkCurlyDotLe
|
tok.toktype = tkCurlyDotLe
|
||||||
Inc(L.bufpos)
|
Inc(L.bufpos)
|
||||||
else:
|
else:
|
||||||
|
|
@ -777,11 +754,11 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
|
||||||
tok.tokType = tkCharLit
|
tok.tokType = tkCharLit
|
||||||
getCharacter(L, tok)
|
getCharacter(L, tok)
|
||||||
tok.tokType = tkCharLit
|
tok.tokType = tkCharLit
|
||||||
of lexbase.EndOfFile:
|
|
||||||
tok.toktype = tkEof
|
|
||||||
else:
|
else:
|
||||||
if c in OpChars:
|
if c in OpChars:
|
||||||
getOperator(L, tok)
|
getOperator(L, tok)
|
||||||
|
elif c == lexbase.EndOfFile:
|
||||||
|
tok.toktype = tkEof
|
||||||
else:
|
else:
|
||||||
tok.literal = c & ""
|
tok.literal = c & ""
|
||||||
tok.tokType = tkInvalid
|
tok.tokType = tkInvalid
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ type
|
||||||
wShl, wShr, wTemplate, wTry, wTuple, wType, wVar, wWhen, wWhile, wWith,
|
wShl, wShr, wTemplate, wTry, wTuple, wType, wVar, wWhen, wWhile, wWith,
|
||||||
wWithout, wXor, wYield,
|
wWithout, wXor, wYield,
|
||||||
|
|
||||||
wColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
|
wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
|
||||||
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc,
|
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc,
|
||||||
wExtern,
|
wExtern,
|
||||||
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
|
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
|
||||||
|
|
@ -78,7 +78,7 @@ const
|
||||||
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
|
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
|
||||||
"yield",
|
"yield",
|
||||||
|
|
||||||
":", "=", ".", "..", "^", "*", "-",
|
":", "::", "=", ".", "..", "^", "*", "-",
|
||||||
"magic", "typecheck", "final", "profiler", "objchecks", "importc",
|
"magic", "typecheck", "final", "profiler", "objchecks", "importc",
|
||||||
"exportc", "extern",
|
"exportc", "extern",
|
||||||
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
|
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
|
||||||
|
|
|
||||||
|
|
@ -952,7 +952,7 @@ type
|
||||||
TFloatFormat* = enum
|
TFloatFormat* = enum
|
||||||
ffDefault, ## use the shorter floating point notation
|
ffDefault, ## use the shorter floating point notation
|
||||||
ffDecimal, ## use decimal floating point notation
|
ffDecimal, ## use decimal floating point notation
|
||||||
ffScientific ## use scientific notation (using ``e``) character
|
ffScientific ## use scientific notation (using ``e`` character)
|
||||||
|
|
||||||
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
||||||
precision = 16): string {.noSideEffect,
|
precision = 16): string {.noSideEffect,
|
||||||
|
|
|
||||||
|
|
@ -650,13 +650,15 @@ proc setLen*[T](s: var seq[T], newlen: int) {.
|
||||||
## sets the length of `s` to `newlen`.
|
## sets the length of `s` to `newlen`.
|
||||||
## ``T`` may be any sequence type.
|
## ``T`` may be any sequence type.
|
||||||
## If the current length is greater than the new length,
|
## If the current length is greater than the new length,
|
||||||
## ``s`` will be truncated.
|
## ``s`` will be truncated. `s` cannot be nil! To initialize a sequence with
|
||||||
|
## a size, use ``newSeq`` instead.
|
||||||
|
|
||||||
proc setLen*(s: var string, newlen: int) {.
|
proc setLen*(s: var string, newlen: int) {.
|
||||||
magic: "SetLengthStr", noSideEffect.}
|
magic: "SetLengthStr", noSideEffect.}
|
||||||
## sets the length of `s` to `newlen`.
|
## sets the length of `s` to `newlen`.
|
||||||
## If the current length is greater than the new length,
|
## If the current length is greater than the new length,
|
||||||
## ``s`` will be truncated.
|
## ``s`` will be truncated. `s` cannot be nil! To initialize a string with
|
||||||
|
## a size, use ``newString`` instead.
|
||||||
|
|
||||||
proc newString*(len: int): string {.
|
proc newString*(len: int): string {.
|
||||||
magic: "NewString", importc: "mnewString", noSideEffect.}
|
magic: "NewString", importc: "mnewString", noSideEffect.}
|
||||||
|
|
|
||||||
|
|
@ -642,7 +642,11 @@ proc unmarkStackAndRegisters(gch: var TGcHeap) =
|
||||||
var d = gch.decStack.d
|
var d = gch.decStack.d
|
||||||
for i in 0..gch.decStack.len-1:
|
for i in 0..gch.decStack.len-1:
|
||||||
assert isAllocatedPtr(allocator, d[i])
|
assert isAllocatedPtr(allocator, d[i])
|
||||||
decRef(d[i]) # OPT: cannot create a cycle!
|
# decRef(d[i]) inlined: cannot create a cycle
|
||||||
|
var c = d[i]
|
||||||
|
if atomicDec(c.refcount, rcIncrement) <% rcIncrement:
|
||||||
|
rtlAddZCT(c)
|
||||||
|
assert c.typ != nil
|
||||||
gch.decStack.len = 0
|
gch.decStack.len = 0
|
||||||
|
|
||||||
proc collectCT(gch: var TGcHeap) =
|
proc collectCT(gch: var TGcHeap) =
|
||||||
|
|
|
||||||
8
tests/accept/compile/ttempl4.nim
Normal file
8
tests/accept/compile/ttempl4.nim
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
template `:=`(name, val: expr): stmt =
|
||||||
|
var name = val
|
||||||
|
|
||||||
|
ha := 1
|
||||||
|
hu := "ta-da"
|
||||||
|
echo ha, hu
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue