Merge branch 'master' of github.com:Araq/Nimrod

This commit is contained in:
Araq 2012-12-06 07:10:19 +01:00
commit 1d842e8b75
21 changed files with 174 additions and 55 deletions

View file

@ -624,6 +624,7 @@ type
loc*: TLoc loc*: TLoc
annex*: PLib # additional fields (seldom used, so we use a annex*: PLib # additional fields (seldom used, so we use a
# reference to another object to safe space) # reference to another object to safe space)
constraint*: PNode # additional constraints like 'lit|result'
TTypeSeq* = seq[PType] TTypeSeq* = seq[PType]
TType* = object of TIdObj # types are identical iff they have the TType* = object of TIdObj # types are identical iff they have the
@ -650,7 +651,6 @@ type
align*: int # the type's alignment requirements align*: int # the type's alignment requirements
containerID*: int # used for type checking of generics containerID*: int # used for type checking of generics
loc*: TLoc loc*: TLoc
constraint*: PNode # additional constraints like 'lit|result'
TPair*{.final.} = object TPair*{.final.} = object
key*, val*: PObject key*, val*: PObject

View file

@ -145,6 +145,9 @@ proc isVisible(n: PNode): bool =
var v = n.sons[0].ident var v = n.sons[0].ident
result = v.id == ord(wStar) or v.id == ord(wMinus) result = v.id == ord(wStar) or v.id == ord(wMinus)
elif n.kind == nkSym: elif n.kind == nkSym:
# we cannot generate code for forwarded symbols here as we have no
# exception tracking information here. Instead we copy over the comment
# from the proc header.
result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported} result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported}
elif n.kind == nkPragmaExpr: elif n.kind == nkPragmaExpr:
result = isVisible(n.sons[0]) result = isVisible(n.sons[0])

View file

@ -48,8 +48,8 @@ proc add(code: var TPatternCode, op: TOpcode) {.inline.} =
add(code, chr(ord(op))) add(code, chr(ord(op)))
proc whichAlias*(p: PSym): TAliasRequest = proc whichAlias*(p: PSym): TAliasRequest =
if p.typ.constraint != nil: if p.constraint != nil:
result = TAliasRequest(p.typ.constraint.strVal[0].ord) result = TAliasRequest(p.constraint.strVal[0].ord)
proc compileConstraints(p: PNode, result: var TPatternCode) = proc compileConstraints(p: PNode, result: var TPatternCode) =
case p.kind case p.kind

View file

@ -71,8 +71,8 @@ proc inSymChoice(sc, x: PNode): bool =
proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool = proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
# check param constraints first here as this is quite optimized: # check param constraints first here as this is quite optimized:
if p.typ.constraint != nil: if p.constraint != nil:
result = matchNodeKinds(p.typ.constraint, n) result = matchNodeKinds(p.constraint, n)
if not result: return if not result: return
if isNil(n.typ): if isNil(n.typ):
result = p.typ.kind in {tyEmpty, tyStmt} result = p.typ.kind in {tyEmpty, tyStmt}

View file

@ -330,9 +330,6 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
if r.s[r.pos] == '@': if r.s[r.pos] == '@':
inc(r.pos) inc(r.pos)
result.containerID = decodeVInt(r.s, r.pos) result.containerID = decodeVInt(r.s, r.pos)
if r.s[r.pos] == '`':
inc(r.pos)
result.constraint = decodeNode(r, UnknownLineInfo())
decodeLoc(r, result.loc, info) decodeLoc(r, result.loc, info)
while r.s[r.pos] == '^': while r.s[r.pos] == '^':
inc(r.pos) inc(r.pos)
@ -423,6 +420,9 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
result.offset = - 1 result.offset = - 1
decodeLoc(r, result.loc, result.info) decodeLoc(r, result.loc, result.info)
result.annex = decodeLib(r, info) result.annex = decodeLib(r, info)
if r.s[r.pos] == '#':
inc(r.pos)
result.constraint = decodeNode(r, UnknownLineInfo())
if r.s[r.pos] == '(': if r.s[r.pos] == '(':
if result.kind in routineKinds: if result.kind in routineKinds:
result.ast = decodeNodeLazyBody(r, result.info, result) result.ast = decodeNodeLazyBody(r, result.info, result)

View file

@ -233,9 +233,6 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t.containerID != 0: if t.containerID != 0:
add(result, '@') add(result, '@')
encodeVInt(t.containerID, result) encodeVInt(t.containerID, result)
if t.constraint != nil:
add(result, '`')
encodeNode(w, UnknownLineInfo(), t.constraint, result)
encodeLoc(w, t.loc, result) encodeLoc(w, t.loc, result)
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
if t.sons[i] == nil: if t.sons[i] == nil:
@ -295,6 +292,9 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
encodeVInt(s.offset, result) encodeVInt(s.offset, result)
encodeLoc(w, s.loc, result) encodeLoc(w, s.loc, result)
if s.annex != nil: encodeLib(w, s.annex, s.info, result) if s.annex != nil: encodeLib(w, s.annex, s.info, result)
if s.constraint != nil:
add(result, '#')
encodeNode(w, UnknownLineInfo(), s.constraint, result)
# lazy loading will soon reload the ast lazily, so the ast needs to be # lazy loading will soon reload the ast lazily, so the ast needs to be
# the last entry of a symbol: # the last entry of a symbol:
if s.ast != nil: if s.ast != nil:

View file

@ -84,6 +84,16 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym), getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
args]) args])
proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {.
noinline.}=
for i in 1 .. <n.len:
var a = n.sons[i]
if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
isGenericRoutine(a.sons[0].sym):
let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, n.info)
a.sons[0].sym = finalCallee
a.sons[0].typ = finalCallee.typ
proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
assert x.state == csMatch assert x.state == csMatch
var finalCallee = x.calleeSym var finalCallee = x.calleeSym
@ -101,6 +111,8 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
if ContainsGenericType(result.typ): result.typ = errorType(c) if ContainsGenericType(result.typ): result.typ = errorType(c)
return return
result = x.call result = x.call
if x.genericConverter:
instantiateGenericConverters(c, result, x)
result.sons[0] = newSymNode(finalCallee, result.sons[0].info) result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
result.typ = finalCallee.typ.sons[0] result.typ = finalCallee.typ.sons[0]

View file

@ -780,6 +780,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
n.sons[pragmasPos] = proto.ast.sons[pragmasPos] n.sons[pragmasPos] = proto.ast.sons[pragmasPos]
if n.sons[namePos].kind != nkSym: InternalError(n.info, "semProcAux") if n.sons[namePos].kind != nkSym: InternalError(n.info, "semProcAux")
n.sons[namePos].sym = proto n.sons[namePos].sym = proto
if gCmd == cmdDoc and not isNil(proto.ast.comment):
n.comment = proto.ast.comment
proto.ast = n # needed for code generation proto.ast = n # needed for code generation
popOwner() popOwner()
pushOwner(s) pushOwner(s)
@ -869,8 +871,6 @@ proc semMethod(c: PContext, n: PNode): PNode =
proc semConverterDef(c: PContext, n: PNode): PNode = proc semConverterDef(c: PContext, n: PNode): PNode =
if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "converter") if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "converter")
checkSonsLen(n, bodyPos + 1) checkSonsLen(n, bodyPos + 1)
if n.sons[genericParamsPos].kind != nkEmpty:
LocalError(n.info, errNoGenericParamsAllowedForX, "converter")
result = semProcAux(c, n, skConverter, converterPragmas) result = semProcAux(c, n, skConverter, converterPragmas)
var s = result.sons[namePos].sym var s = result.sons[namePos].sym
var t = s.typ var t = s.typ

View file

@ -635,6 +635,13 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
genericParams.addSon(newSymNode(s)) genericParams.addSon(newSymNode(s))
result = typeClass result = typeClass
proc semParamType(c: PContext, n: PNode, constraint: var PNode): PType =
if n.kind == nkCurlyExpr:
result = semTypeNode(c, n.sons[0], nil)
constraint = semNodeKindConstraints(n)
else:
result = semTypeNode(c, n, nil)
proc semProcTypeNode(c: PContext, n, genericParams: PNode, proc semProcTypeNode(c: PContext, n, genericParams: PNode,
prev: PType, kind: TSymKind): PType = prev: PType, kind: TSymKind): PType =
var var
@ -660,13 +667,14 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
checkMinSonsLen(a, 3) checkMinSonsLen(a, 3)
var var
typ: PType = nil typ: PType = nil
def: PNode = nil def: PNode = nil
constraint: PNode = nil
length = sonsLen(a) length = sonsLen(a)
hasType = a.sons[length-2].kind != nkEmpty hasType = a.sons[length-2].kind != nkEmpty
hasDefault = a.sons[length-1].kind != nkEmpty hasDefault = a.sons[length-1].kind != nkEmpty
if hasType: if hasType:
typ = semTypeNode(c, a.sons[length-2], nil) typ = semParamType(c, a.sons[length-2], constraint)
if hasDefault: if hasDefault:
def = semExprWithType(c, a.sons[length-1]) def = semExprWithType(c, a.sons[length-1])
@ -689,6 +697,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
arg.name.s, arg.info).skipIntLit arg.name.s, arg.info).skipIntLit
arg.typ = finalType arg.typ = finalType
arg.position = counter arg.position = counter
arg.constraint = constraint
inc(counter) inc(counter)
if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def) if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def)
if ContainsOrIncl(check, arg.name.id): if ContainsOrIncl(check, arg.name.id):
@ -787,6 +796,12 @@ proc semTypeExpr(c: PContext, n: PNode): PType =
else: else:
LocalError(n.info, errTypeExpected, n.renderTree) LocalError(n.info, errTypeExpected, n.renderTree)
proc freshType(res, prev: PType): PType {.inline.} =
if prev.isNil:
result = copyType(result, result.owner, keepId=false)
else:
result = res
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = nil result = nil
if gCmd == cmdIdeTools: suggestExpr(c, n) if gCmd == cmdIdeTools: suggestExpr(c, n)
@ -825,7 +840,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
checkSonsLen(n, 3) checkSonsLen(n, 3)
result = semTypeNode(c, n.sons[1], prev) result = semTypeNode(c, n.sons[1], prev)
if result.kind in NilableTypes and n.sons[2].kind == nkNilLit: if result.kind in NilableTypes and n.sons[2].kind == nkNilLit:
# XXX this is wrong for tyString at least result = freshType(result, prev)
result.flags.incl(tfNotNil) result.flags.incl(tfNotNil)
else: else:
LocalError(n.info, errGenerated, "invalid type") LocalError(n.info, errGenerated, "invalid type")
@ -833,11 +848,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = semTypeExpr(c, n) result = semTypeExpr(c, n)
else: else:
result = semTypeExpr(c, n) result = semTypeExpr(c, n)
of nkCurlyExpr:
result = semTypeNode(c, n.sons[0], nil)
if result != nil:
result = copyType(result, getCurrOwner(), true)
result.constraint = semNodeKindConstraints(n)
of nkWhenStmt: of nkWhenStmt:
var whenResult = semWhen(c, n, false) var whenResult = semWhen(c, n, false)
if whenResult.kind == nkStmtList: whenResult.kind = nkStmtListType if whenResult.kind == nkStmtList: whenResult.kind = nkStmtListType
@ -920,6 +930,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
of nkSharedTy: of nkSharedTy:
checkSonsLen(n, 1) checkSonsLen(n, 1)
result = semTypeNode(c, n.sons[0], prev) result = semTypeNode(c, n.sons[0], prev)
result = freshType(result, prev)
result.flags.incl(tfShared) result.flags.incl(tfShared)
else: else:
LocalError(n.info, errTypeExpected) LocalError(n.info, errTypeExpected)

View file

@ -33,6 +33,8 @@ type
baseTypeMatch: bool # needed for conversions from T to openarray[T] baseTypeMatch: bool # needed for conversions from T to openarray[T]
# for example # for example
proxyMatch*: bool # to prevent instantiations proxyMatch*: bool # to prevent instantiations
genericConverter*: bool # true if a generic converter needs to
# be instantiated
inheritancePenalty: int # to prefer closest father object type inheritancePenalty: int # to prefer closest father object type
TTypeRelation* = enum # order is important! TTypeRelation* = enum # order is important!
@ -57,6 +59,7 @@ proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} =
c.callee = callee c.callee = callee
c.call = nil c.call = nil
c.baseTypeMatch = false c.baseTypeMatch = false
c.genericConverter = false
c.inheritancePenalty = 0 c.inheritancePenalty = 0
proc initCandidate*(c: var TCandidate, callee: PType) = proc initCandidate*(c: var TCandidate, callee: PType) =
@ -571,16 +574,26 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
for i in countup(0, len(c.converters) - 1): for i in countup(0, len(c.converters) - 1):
var src = c.converters[i].typ.sons[1] var src = c.converters[i].typ.sons[1]
var dest = c.converters[i].typ.sons[0] var dest = c.converters[i].typ.sons[0]
if (typeRel(m, f, dest) == isEqual) and # for generic type converters we need to check 'src <- a' before
(typeRel(m, src, a) == isEqual): # 'f <- dest' in order to not break the unification:
# see tests/tgenericconverter:
let srca = typeRel(m, src, a)
if srca notin {isEqual, isGeneric}: continue
let destIsGeneric = containsGenericType(dest)
if destIsGeneric:
dest = generateTypeInstance(c, m.bindings, arg, dest)
let fdest = typeRel(m, f, dest)
if fdest in {isEqual, isGeneric}:
markUsed(arg, c.converters[i]) markUsed(arg, c.converters[i])
var s = newSymNode(c.converters[i]) var s = newSymNode(c.converters[i])
s.typ = c.converters[i].typ s.typ = c.converters[i].typ
s.info = arg.info s.info = arg.info
result = newNodeIT(nkHiddenCallConv, arg.info, s.typ.sons[0]) result = newNodeIT(nkHiddenCallConv, arg.info, dest)
addSon(result, s) addSon(result, s)
addSon(result, copyTree(arg)) addSon(result, copyTree(arg))
inc(m.convMatches) inc(m.convMatches)
m.genericConverter = srca == isGeneric or destIsGeneric
return return
proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
@ -837,10 +850,10 @@ proc matchesAux*(c: PContext, n, nOrig: PNode,
m.baseTypeMatch = false m.baseTypeMatch = false
var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ,
n.sons[a], nOrig.sons[a]) n.sons[a], nOrig.sons[a])
if arg == nil: if arg == nil:
m.state = csNoMatch m.state = csNoMatch
return return
if m.baseTypeMatch: if m.baseTypeMatch:
assert(container == nil) assert(container == nil)
container = newNodeI(nkBracket, n.sons[a].info) container = newNodeI(nkBracket, n.sons[a].info)
addSon(container, arg) addSon(container, arg)

View file

@ -36,7 +36,7 @@ path="$lib/windows"
path="$lib/posix" path="$lib/posix"
path="$lib/ecmas" path="$lib/ecmas"
path="$lib/pure/unidecode" path="$lib/pure/unidecode"
#recursivePath:"$home/.babel/lib" path="$home/.babel/libs/"
@if release or quick: @if release or quick:
obj_checks:off obj_checks:off

View file

@ -17,9 +17,7 @@
## module will therefore not work with any Linux kernel prior to that, unless ## module will therefore not work with any Linux kernel prior to that, unless
## it has been patched to support inotify. ## it has been patched to support inotify.
when defined(windows): when defined(linux) or defined(nimdoc):
{.error: "Windows is not yet supported by this module.".}
elif defined(linux):
from posix import read from posix import read
else: else:
{.error: "Your platform is not supported.".} {.error: "Your platform is not supported.".}

View file

@ -238,8 +238,15 @@ type
httpCONNECT ## Converts the request connection to a transparent httpCONNECT ## Converts the request connection to a transparent
## TCP/IP tunnel, usually used for proxies. ## TCP/IP tunnel, usually used for proxies.
when not defined(ssl):
type PSSLContext = ref object
let defaultSSLContext: PSSLContext = nil
else:
let defaultSSLContext = newContext(verifyMode = CVerifyNone)
proc request*(url: string, httpMethod = httpGET, extraHeaders = "", proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
body = ""): TResponse = body = "",
sslContext: PSSLContext = defaultSSLContext): TResponse =
## | Requests ``url`` with the specified ``httpMethod``. ## | Requests ``url`` with the specified ``httpMethod``.
## | 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)
@ -257,7 +264,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
var port = TPort(80) var port = TPort(80)
if r.scheme == "https": if r.scheme == "https":
when defined(ssl): when defined(ssl):
s.wrapSocket(verifyMode = CVerifyNone) sslContext.wrapSocket(s)
else: else:
raise newException(EHttpRequestErr, "SSL support was not compiled in. Cannot connect over SSL.") raise newException(EHttpRequestErr, "SSL support was not compiled in. Cannot connect over SSL.")
port = TPort(443) port = TPort(443)
@ -277,7 +284,7 @@ proc redirection(status: string): bool =
if status.startsWith(i): if status.startsWith(i):
return True return True
proc get*(url: string, maxRedirects = 5): TResponse = proc get*(url: string, maxRedirects = 5, sslContext: PSSLContext = defaultSSLContext): TResponse =
## | GET's the ``url`` and returns a ``TResponse`` object ## | GET's the ``url`` and returns a ``TResponse`` object
## | This proc also handles redirection ## | This proc also handles redirection
result = request(url) result = request(url)
@ -285,24 +292,24 @@ proc get*(url: string, maxRedirects = 5): TResponse =
if result.status.redirection(): if result.status.redirection():
var locationHeader = result.headers["Location"] var locationHeader = result.headers["Location"]
if locationHeader == "": httpError("location header expected") if locationHeader == "": httpError("location header expected")
result = request(locationHeader) result = request(locationHeader, sslContext = sslContext)
proc getContent*(url: string): string = proc getContent*(url: string, sslContext: PSSLContext = defaultSSLContext): string =
## | GET's the body and returns it as a string. ## | GET's the body and returns it as a string.
## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Raises exceptions for the status codes ``4xx`` and ``5xx``
var r = get(url) var r = get(url, sslContext = sslContext)
if r.status[0] in {'4','5'}: if r.status[0] in {'4','5'}:
raise newException(EHTTPRequestErr, r.status) raise newException(EHTTPRequestErr, r.status)
else: else:
return r.body return r.body
proc post*(url: string, extraHeaders = "", body = "", proc post*(url: string, extraHeaders = "", body = "",
maxRedirects = 5): TResponse = maxRedirects = 5, sslContext: PSSLContext = defaultSSLContext): TResponse =
## | POST's ``body`` to the ``url`` and returns a ``TResponse`` object. ## | POST's ``body`` to the ``url`` and returns a ``TResponse`` object.
## | This proc adds the necessary Content-Length header. ## | This proc adds the necessary Content-Length header.
## | This proc also handles redirection. ## | This proc also handles redirection.
var xh = extraHeaders & "Content-Length: " & $len(body) & "\c\L" var xh = extraHeaders & "Content-Length: " & $len(body) & "\c\L"
result = request(url, httpPOST, xh, body) result = request(url, httpPOST, xh, body, sslContext)
for i in 1..maxRedirects: for i in 1..maxRedirects:
if result.status.redirection(): if result.status.redirection():
var locationHeader = result.headers["Location"] var locationHeader = result.headers["Location"]
@ -310,7 +317,8 @@ proc post*(url: string, extraHeaders = "", body = "",
var meth = if result.status != "307": httpGet else: httpPost var meth = if result.status != "307": httpGet else: httpPost
result = request(locationHeader, meth, xh, body) result = request(locationHeader, meth, xh, body)
proc postContent*(url: string, extraHeaders = "", body = ""): string = proc postContent*(url: string, extraHeaders = "", body = "",
sslContext: PSSLContext = defaultSSLContext): string =
## | POST's ``body`` to ``url`` and returns the response's body as a string ## | POST's ``body`` to ``url`` and returns the response's body as a string
## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Raises exceptions for the status codes ``4xx`` and ``5xx``
var r = post(url, extraHeaders, body) var r = post(url, extraHeaders, body)
@ -319,11 +327,12 @@ proc postContent*(url: string, extraHeaders = "", body = ""): string =
else: else:
return r.body return r.body
proc downloadFile*(url: string, outputFilename: string) = proc downloadFile*(url: string, outputFilename: string,
sslContext: PSSLContext = defaultSSLContext) =
## Downloads ``url`` and saves it to ``outputFilename`` ## Downloads ``url`` and saves it to ``outputFilename``
var f: TFile var f: TFile
if open(f, outputFilename, fmWrite): if open(f, outputFilename, fmWrite):
f.write(getContent(url)) f.write(getContent(url, sslContext))
f.close() f.close()
else: else:
fileError("Unable to open file") fileError("Unable to open file")

View file

@ -554,7 +554,8 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {.
var dotPos = path.len var dotPos = path.len
for i in countdown(len(path)-1, 0): for i in countdown(len(path)-1, 0):
if path[i] == ExtSep: if path[i] == ExtSep:
if dotPos == path.len and i > 0: dotPos = i if dotPos == path.len and i > 0 and
path[i-1] notin {dirsep, altsep}: dotPos = i
elif path[i] in {dirsep, altsep}: elif path[i] in {dirsep, altsep}:
sepPos = i sepPos = i
break break

View file

@ -14,6 +14,8 @@
## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that ## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that
## most functions will then raise ``ESSL`` on SSL errors. ## most functions will then raise ``ESSL`` on SSL errors.
{.deadCodeElim: on.}
when hostos == "solaris": when hostos == "solaris":
{.passl: "-lsocket -lnsl".} {.passl: "-lsocket -lnsl".}
@ -256,7 +258,10 @@ when defined(ssl):
of protSSLv23: of protSSLv23:
newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support. newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support.
of protSSLv2: of protSSLv2:
newCTX = SSL_CTX_new(SSLv2_method()) when not defined(linux):
newCTX = SSL_CTX_new(SSLv2_method())
else:
SSLError()
of protSSLv3: of protSSLv3:
newCTX = SSL_CTX_new(SSLv3_method()) newCTX = SSL_CTX_new(SSLv3_method())
of protTLSv1: of protTLSv1:

View file

@ -39,6 +39,8 @@
## OpenSSL support ## OpenSSL support
{.deadCodeElim: on.}
when defined(WINDOWS): when defined(WINDOWS):
const const
DLLSSLName = "(ssleay32|libssl32).dll" DLLSSLName = "(ssleay32|libssl32).dll"

View file

@ -0,0 +1,28 @@
type
TFoo = object
data: array[0..100, int]
TSecond = distinct TFoo
proc `[]` (self: var TFoo, x: int): var int =
return self.data[x]
proc `[]=` (self: var TFoo, x, y: int) =
# only `[]` returning a 'var T' seems to not work for now :-/
self.data[x] = y
proc second(self: var TFoo): var TSecond =
return TSecond(self)
proc `[]`(self: var TSecond, x: int): var int =
return TFoo(self).data[2*x]
var f: TFoo
for i in 0..f.data.high: f[i] = 2 * i
echo f.second[1]
#echo `second[]`(f,1)
# this is the only way I could use it, but not what I expected

View file

@ -1,5 +1,5 @@
discard """ discard """
line: 11 line: 22
errormgs: "type mismatch" errormgs: "type mismatch"
""" """
@ -7,9 +7,17 @@ type
PObj = ref TObj not nil PObj = ref TObj not nil
TObj = object TObj = object
x: int x: int
MyString = string not nil
var x: PObj = nil #var x: PObj = nil
proc p(x: string not nil): int = proc p(x: string not nil): int =
result = 45 result = 45
proc q(x: MyString) = nil
proc q2(x: string) = nil
q2(nil)
q(nil)

View file

@ -0,0 +1,30 @@
discard """
output: '''666
666'''
"""
# test the new generic converters:
type
TFoo2[T] = object
x: T
TFoo[T] = object
data: array[0..100, T]
converter toFoo[T](a: TFoo2[T]): TFoo[T] =
result.data[0] = a.x
proc p(a: TFoo[int]) =
echo a.data[0]
proc q[T](a: TFoo[T]) =
echo a.data[0]
var
aa: TFoo2[int]
aa.x = 666
p aa
q aa

View file

@ -1,20 +1,18 @@
version 0.9.2 version 0.9.2
============= =============
- fix tfShared and tfNotNil - overloading based on ASTs
- test&finish first class iterators:
* nested iterators
* test generic iterators
- fix closure bug finally
- overloading based on ASTs: 'constraint' should not be in PType but for the
parameter *symbol*
- implement ``partial`` pragma for partial evaluation: easily done with AST - implement ``partial`` pragma for partial evaluation: easily done with AST
overloading overloading
- ``hoist`` pragma for loop hoisting: can be easily done with - ``hoist`` pragma for loop hoisting: can be easily done with
AST overloading + global AST overloading + global
- test&finish first class iterators:
* nested iterators
* test generic iterators
- fix closure bug finally
- fix marshal bug
version 0.9.X version 0.9.X
============= =============

View file

@ -34,6 +34,7 @@ Compiler Additions
- The compiler can now warn about shadowed local variables. However, this needs - The compiler can now warn about shadowed local variables. However, this needs
to be turned on explicitly via ``--warning[ShadowIdent]:on``. to be turned on explicitly via ``--warning[ShadowIdent]:on``.
- The compiler now supports almost every pragma in a ``push`` pragma. - The compiler now supports almost every pragma in a ``push`` pragma.
- Generic converters have been implemented.
Language Additions Language Additions