summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndrey Sobolev <andrey.sobolev@xored.com>2015-09-14 11:50:39 +0600
committerAndrey Sobolev <andrey.sobolev@xored.com>2015-09-14 11:50:39 +0600
commit2f6dc8c47f836b66c1a28fd0b90a9e591b6c9be5 (patch)
tree0676259b78fba9788d6dffd441de1d7f5b0df140 /compiler
parenta1aa7da37612eac6f961f0daaf5454f936b4e295 (diff)
parent148bbee05f31802666dbf1730e0df328ff57a384 (diff)
downloadNim-2f6dc8c47f836b66c1a28fd0b90a9e591b6c9be5.tar.gz
Merge remote-tracking branch 'nim-lang/devel' into emscripten-support
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim10
-rw-r--r--compiler/parampatterns.nim5
-rw-r--r--compiler/seminst.nim3
-rw-r--r--compiler/semstmts.nim2
-rw-r--r--compiler/semtempl.nim36
-rw-r--r--compiler/semtypes.nim1
-rw-r--r--compiler/vm.nim2
7 files changed, 32 insertions, 27 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 7b6f39cbc..860bf67e8 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -537,7 +537,7 @@ const
 type
   TMagic* = enum # symbols that require compiler magic:
     mNone,
-    mDefined, mDefinedInScope, mCompiles,
+    mDefined, mDefinedInScope, mCompiles, mArrGet, mArrPut, mAsgn,
     mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof, mPlugin,
     mEcho, mShallowCopy, mSlurp, mStaticExec,
     mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
@@ -614,6 +614,7 @@ const
   ctfeWhitelist* = {mNone, mUnaryLt, mSucc,
     mPred, mInc, mDec, mOrd, mLengthOpenArray,
     mLengthStr, mLengthArray, mLengthSeq, mXLenStr, mXLenSeq,
+    mArrGet, mArrPut, mAsgn,
     mIncl, mExcl, mCard, mChr,
     mAddI, mSubI, mMulI, mDivI, mModI,
     mAddF64, mSubF64, mMulF64, mDivF64,
@@ -1586,3 +1587,10 @@ proc createMagic*(name: string, m: TMagic): PSym =
 let
   opNot* = createMagic("not", mNot)
   opContains* = createMagic("contains", mInSet)
+
+when false:
+  proc containsNil*(n: PNode): bool =
+    # only for debugging
+    if n.isNil: return true
+    for i in 0 ..< n.safeLen:
+      if n[i].containsNil: return true
diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim
index ae391945a..978583c14 100644
--- a/compiler/parampatterns.nim
+++ b/compiler/parampatterns.nim
@@ -225,8 +225,11 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
     result = isAssignable(owner, n.sons[0], isUnsafeAddr)
   of nkCallKinds:
     # builtin slice keeps lvalue-ness:
-    if getMagic(n) == mSlice:
+    if getMagic(n) in {mArrGet, mSlice}:
       result = isAssignable(owner, n.sons[1], isUnsafeAddr)
+  of nkStmtList, nkStmtListExpr:
+    if n.typ != nil:
+      result = isAssignable(owner, n.lastSon, isUnsafeAddr)
   else:
     discard
 
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 370990326..42a39d0df 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -221,6 +221,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   # NOTE: for access of private fields within generics from a different module
   # we set the friend module:
   c.friendModules.add(getModule(fn))
+  let oldInTypeClass = c.inTypeClass
+  c.inTypeClass = 0
   let oldScope = c.currentScope
   while not isTopLevel(c): c.currentScope = c.currentScope.parent
   result = copySym(fn, false)
@@ -269,4 +271,5 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   c.currentScope = oldScope
   discard c.friendModules.pop()
   dec(c.instCounter)
+  c.inTypeClass = oldInTypeClass
   if result.kind == skMethod: finishMethod(c, result)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index ffda6a1bb..4399c0ab0 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1425,7 +1425,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
             localError(result.info, "type class predicate failed")
         of tyUnknown: continue
         else: discard
-      if n.sons[i].typ == enforceVoidContext or usesResult(n.sons[i]):
+      if n.sons[i].typ == enforceVoidContext: #or usesResult(n.sons[i]):
         voidContext = true
         n.typ = enforceVoidContext
       if i == last and (length == 1 or efWantValue in flags):
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 4d1eae48f..371abe1e3 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -471,27 +471,6 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
     for i in countup(0, sonsLen(n) - 1):
       result.sons[i] = semTemplBodyDirty(c, n.sons[i])
 
-proc transformToExpr(n: PNode): PNode =
-  var realStmt: int
-  result = n
-  case n.kind
-  of nkStmtList:
-    realStmt = - 1
-    for i in countup(0, sonsLen(n) - 1):
-      case n.sons[i].kind
-      of nkCommentStmt, nkEmpty, nkNilLit:
-        discard
-      else:
-        if realStmt == - 1: realStmt = i
-        else: realStmt = - 2
-    if realStmt >= 0: result = transformToExpr(n.sons[realStmt])
-    else: n.kind = nkStmtListExpr
-  of nkBlockStmt:
-    n.kind = nkBlockExpr
-    #nkIfStmt: n.kind = nkIfExpr // this is not correct!
-  else:
-    discard
-
 proc semTemplateDef(c: PContext, n: PNode): PNode =
   var s: PSym
   if isTopLevel(c):
@@ -549,9 +528,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
     n.sons[bodyPos] = semTemplBodyDirty(ctx, n.sons[bodyPos])
   else:
     n.sons[bodyPos] = semTemplBody(ctx, n.sons[bodyPos])
-  if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}:
-    n.sons[bodyPos] = transformToExpr(n.sons[bodyPos])
-    # only parameters are resolved, no type checking is performed
+  # only parameters are resolved, no type checking is performed
   semIdeForTemplateOrGeneric(c, n.sons[bodyPos], ctx.cursorInBody)
   closeScope(c)
   popOwner()
@@ -604,6 +581,11 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
       localError(n.info, errInvalidExpression)
       result = n
 
+  proc stupidStmtListExpr(n: PNode): bool =
+    for i in 0 .. n.len-2:
+      if n[i].kind notin {nkEmpty, nkCommentStmt}: return false
+    result = true
+
   result = n
   case n.kind
   of nkIdent:
@@ -629,6 +611,12 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
         localError(n.info, errInvalidExpression)
     else:
       localError(n.info, errInvalidExpression)
+  of nkStmtList, nkStmtListExpr:
+    if stupidStmtListExpr(n):
+      result = semPatternBody(c, n.lastSon)
+    else:
+      for i in countup(0, sonsLen(n) - 1):
+        result.sons[i] = semPatternBody(c, n.sons[i])
   of nkCallKinds:
     let s = qualifiedLookUp(c.c, n.sons[0], {})
     if s != nil:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 5ae3d16c0..2ee17fcaf 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -970,6 +970,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
   elif kind == skIterator:
     # XXX This is special magic we should likely get rid of
     r = newTypeS(tyExpr, c)
+    message(n.info, warnDeprecated, "implicit return type for 'iterator'")
 
   if r != nil:
     # turn explicit 'void' return type into 'nil' because the rest of the
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 05d00c19f..0db287c6a 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1461,6 +1461,8 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode =
   let n = transformExpr(module, n)
   setupGlobalCtx(module)
   var c = globalCtx
+  let oldMode = c.mode
+  defer: c.mode = oldMode
   c.mode = mode
   let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
   if c.code[start].opcode == opcEof: return emptyNode