diff --git a/compiler/ast.nim b/compiler/ast.nim index f4ba1ef70..82a20c312 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -624,6 +624,7 @@ type loc*: TLoc annex*: PLib # additional fields (seldom used, so we use a # reference to another object to safe space) + constraint*: PNode # additional constraints like 'lit|result' TTypeSeq* = seq[PType] TType* = object of TIdObj # types are identical iff they have the @@ -650,7 +651,6 @@ type align*: int # the type's alignment requirements containerID*: int # used for type checking of generics loc*: TLoc - constraint*: PNode # additional constraints like 'lit|result' TPair*{.final.} = object key*, val*: PObject diff --git a/compiler/docgen.nim b/compiler/docgen.nim index e06277f91..aff77cc1f 100755 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -145,6 +145,9 @@ proc isVisible(n: PNode): bool = var v = n.sons[0].ident result = v.id == ord(wStar) or v.id == ord(wMinus) 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} elif n.kind == nkPragmaExpr: result = isVisible(n.sons[0]) diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index ee1f69818..21c7faf19 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -48,8 +48,8 @@ proc add(code: var TPatternCode, op: TOpcode) {.inline.} = add(code, chr(ord(op))) proc whichAlias*(p: PSym): TAliasRequest = - if p.typ.constraint != nil: - result = TAliasRequest(p.typ.constraint.strVal[0].ord) + if p.constraint != nil: + result = TAliasRequest(p.constraint.strVal[0].ord) proc compileConstraints(p: PNode, result: var TPatternCode) = case p.kind diff --git a/compiler/patterns.nim b/compiler/patterns.nim index af259c916..b7792100f 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -71,8 +71,8 @@ proc inSymChoice(sc, x: PNode): bool = proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool = # check param constraints first here as this is quite optimized: - if p.typ.constraint != nil: - result = matchNodeKinds(p.typ.constraint, n) + if p.constraint != nil: + result = matchNodeKinds(p.constraint, n) if not result: return if isNil(n.typ): result = p.typ.kind in {tyEmpty, tyStmt} diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 4461641db..722887299 100755 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -330,9 +330,6 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType = if r.s[r.pos] == '@': inc(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) while r.s[r.pos] == '^': inc(r.pos) @@ -423,6 +420,9 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym = result.offset = - 1 decodeLoc(r, result.loc, result.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 result.kind in routineKinds: result.ast = decodeNodeLazyBody(r, result.info, result) diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 5be9a2439..0a361d4dd 100755 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -233,9 +233,6 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) = if t.containerID != 0: add(result, '@') encodeVInt(t.containerID, result) - if t.constraint != nil: - add(result, '`') - encodeNode(w, UnknownLineInfo(), t.constraint, result) encodeLoc(w, t.loc, result) for i in countup(0, sonsLen(t) - 1): if t.sons[i] == nil: @@ -295,6 +292,9 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = encodeVInt(s.offset, result) encodeLoc(w, s.loc, 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 # the last entry of a symbol: if s.ast != nil: diff --git a/compiler/semcall.nim b/compiler/semcall.nim index a5107bf64..962e4d3cc 100755 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -84,6 +84,16 @@ proc resolveOverloads(c: PContext, n, orig: PNode, getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym), args]) +proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {. + noinline.}= + for i in 1 .. 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}: sepPos = i break diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 371641b06..01b97197e 100755 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -14,6 +14,8 @@ ## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that ## most functions will then raise ``ESSL`` on SSL errors. +{.deadCodeElim: on.} + when hostos == "solaris": {.passl: "-lsocket -lnsl".} @@ -256,7 +258,10 @@ when defined(ssl): of protSSLv23: newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support. of protSSLv2: - newCTX = SSL_CTX_new(SSLv2_method()) + when not defined(linux): + newCTX = SSL_CTX_new(SSLv2_method()) + else: + SSLError() of protSSLv3: newCTX = SSL_CTX_new(SSLv3_method()) of protTLSv1: diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 1063f401d..752e594d1 100755 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -39,6 +39,8 @@ ## OpenSSL support +{.deadCodeElim: on.} + when defined(WINDOWS): const DLLSSLName = "(ssleay32|libssl32).dll" diff --git a/tests/compile/tsecondarrayproperty.nim b/tests/compile/tsecondarrayproperty.nim new file mode 100644 index 000000000..07fdac1c4 --- /dev/null +++ b/tests/compile/tsecondarrayproperty.nim @@ -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 + diff --git a/tests/reject/tnotnil.nim b/tests/reject/tnotnil.nim index 8676aedf8..b02e33713 100644 --- a/tests/reject/tnotnil.nim +++ b/tests/reject/tnotnil.nim @@ -1,5 +1,5 @@ discard """ - line: 11 + line: 22 errormgs: "type mismatch" """ @@ -7,9 +7,17 @@ type PObj = ref TObj not nil TObj = object x: int + + MyString = string not nil -var x: PObj = nil +#var x: PObj = nil proc p(x: string not nil): int = result = 45 +proc q(x: MyString) = nil +proc q2(x: string) = nil + +q2(nil) +q(nil) + diff --git a/tests/run/tgenericconverter.nim b/tests/run/tgenericconverter.nim new file mode 100644 index 000000000..e1c9f7c4c --- /dev/null +++ b/tests/run/tgenericconverter.nim @@ -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 diff --git a/todo.txt b/todo.txt index ca2def6aa..870265ac3 100755 --- a/todo.txt +++ b/todo.txt @@ -1,20 +1,18 @@ version 0.9.2 ============= -- fix tfShared and tfNotNil -- 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* - +- overloading based on ASTs - implement ``partial`` pragma for partial evaluation: easily done with AST overloading - ``hoist`` pragma for loop hoisting: can be easily done with AST overloading + global +- test&finish first class iterators: + * nested iterators + * test generic iterators +- fix closure bug finally +- fix marshal bug + version 0.9.X ============= diff --git a/web/news.txt b/web/news.txt index 1650bd562..254e9a57a 100755 --- a/web/news.txt +++ b/web/news.txt @@ -34,6 +34,7 @@ Compiler Additions - The compiler can now warn about shadowed local variables. However, this needs to be turned on explicitly via ``--warning[ShadowIdent]:on``. - The compiler now supports almost every pragma in a ``push`` pragma. +- Generic converters have been implemented. Language Additions