summary refs log tree commit diff stats
path: root/compiler/semexprs.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/semexprs.nim')
-rw-r--r--compiler/semexprs.nim67
1 files changed, 42 insertions, 25 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 7deb46af9..58cef36f9 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -185,13 +185,15 @@ proc isCastable(dst, src: PType): bool =
   #  castableTypeKinds = {tyInt, tyPtr, tyRef, tyCstring, tyString, 
   #                       tySequence, tyPointer, tyNil, tyOpenArray,
   #                       tyProc, tySet, tyEnum, tyBool, tyChar}
+  if skipTypes(dst, abstractInst-{tyOpenArray}).kind == tyOpenArray:
+    return false
   var dstSize, srcSize: BiggestInt
 
   dstSize = computeSize(dst)
   srcSize = computeSize(src)
   if dstSize < 0: 
     result = false
-  elif srcSize < 0: 
+  elif srcSize < 0:
     result = false
   elif not typeAllowed(dst, skParam):
     result = false
@@ -199,6 +201,8 @@ proc isCastable(dst, src: PType): bool =
     result = (dstSize >= srcSize) or
         (skipTypes(dst, abstractInst).kind in IntegralTypes) or
         (skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes)
+  if result and src.kind == tyNil:
+    result = dst.size <= platform.ptrSize
   
 proc isSymChoice(n: PNode): bool {.inline.} =
   result = n.kind in nkSymChoices
@@ -592,7 +596,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
   const 
     FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl, 
       mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, 
-      mAppendSeqElem, mNewSeq, mReset, mShallowCopy}
+      mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy}
   
   # get the real type of the callee
   # it may be a proc var with a generic alias type, so we skip over them
@@ -658,7 +662,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
 
   # optimization pass: not necessary for correctness of the semantic pass
   if {sfNoSideEffect, sfCompileTime} * callee.flags != {} and
-     {sfForward, sfImportc} * callee.flags == {}:
+     {sfForward, sfImportc} * callee.flags == {} and n.typ != nil:
     if sfCompileTime notin callee.flags and 
         optImplicitStatic notin gOptions: return
 
@@ -1370,20 +1374,19 @@ proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
     if onlyCurrentScope: return 
     checkSonsLen(n, 2)
     var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope)
-    if (m != nil) and (m.kind == skModule): 
-      if (n.sons[1].kind == nkIdent): 
-        var ident = n.sons[1].ident
-        if m == c.module: 
-          result = strTableGet(c.topLevelScope.symbols, ident)
-        else: 
-          result = strTableGet(m.tab, ident)
+    if m != nil and m.kind == skModule:
+      let ident = considerQuotedIdent(n[1])
+      if m == c.module:
+        result = strTableGet(c.topLevelScope.symbols, ident)
       else: 
-        localError(n.sons[1].info, errIdentifierExpected, "")
+        result = strTableGet(m.tab, ident)
   of nkAccQuoted:
     result = lookUpForDefined(c, considerQuotedIdent(n), onlyCurrentScope)
   of nkSym:
     result = n.sym
-  else: 
+  of nkOpenSymChoice, nkClosedSymChoice:
+    result = n.sons[0].sym
+  else:
     localError(n.info, errIdentifierExpected, renderTree(n))
     result = nil
 
@@ -1391,10 +1394,16 @@ proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
   checkSonsLen(n, 2)
   # we replace this node by a 'true' or 'false' node:
   result = newIntNode(nkIntLit, 0)
-  if lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil: 
-    result.intVal = 1
-  elif not onlyCurrentScope and (n.sons[1].kind == nkIdent) and
-      condsyms.isDefined(n.sons[1].ident): 
+  if not onlyCurrentScope and considerQuotedIdent(n[0]).s == "defined":
+    if n.sons[1].kind != nkIdent:
+      localError(n.info, "obsolete usage of 'defined', use 'declared' instead")
+    elif condsyms.isDefined(n.sons[1].ident):
+      result.intVal = 1
+    elif not condsyms.isDeclared(n.sons[1].ident):
+      message(n.info, warnUser,
+        "undeclared conditional symbol; use --symbol to declare it: " &
+        n[1].ident.s)
+  elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil: 
     result.intVal = 1
   result.info = n.info
   result.typ = getSysType(tyBool)
@@ -1605,6 +1614,11 @@ proc instantiateCreateFlowVarCall(c: PContext; t: PType;
   initIdTable(bindings)
   bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t)
   result = c.semGenerateInstance(c, sym, bindings, info)
+  # since it's an instantiation, we unmark it as a compilerproc. Otherwise
+  # codegen would fail:
+  if sfCompilerProc in result.flags:
+    result.flags = result.flags - {sfCompilerProc, sfExportC, sfImportC}
+    result.loc.r = nil
 
 proc setMs(n: PNode, s: PSym): PNode = 
   result = n
@@ -1643,10 +1657,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
     result = setMs(n, s)
     result.sons[1] = semExpr(c, n.sons[1])
     if not result[1].typ.isEmptyType:
-      if c.inParallelStmt > 0:
-        result.typ = result[1].typ
-      else:
+      if spawnResult(result[1].typ, c.inParallelStmt > 0) == srFlowVar:
         result.typ = createFlowVar(c, result[1].typ, n.info)
+      else:
+        result.typ = result[1].typ
       result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode
   else: result = semDirectOp(c, n, flags)
 
@@ -1758,8 +1772,9 @@ proc checkPar(n: PNode): TParKind =
   var length = sonsLen(n)
   if length == 0: 
     result = paTuplePositions # ()
-  elif length == 1: 
-    result = paSingle         # (expr)
+  elif length == 1:
+    if n.sons[0].kind == nkExprColonExpr: result = paTupleFields
+    else: result = paSingle         # (expr)
   else:
     if n.sons[0].kind == nkExprColonExpr: result = paTupleFields
     else: result = paTuplePositions
@@ -1920,11 +1935,13 @@ proc semExport(c: PContext, n: PNode): PNode =
     while s != nil:
       if s.kind in ExportableSymKinds+{skModule}:
         x.add(newSymNode(s, a.info))
+        strTableAdd(c.module.tab, s)
       s = nextOverloadIter(o, c, a)
-  if c.module.ast.isNil:
-    c.module.ast = newNodeI(nkStmtList, n.info)
-  assert c.module.ast.kind == nkStmtList
-  c.module.ast.add x
+  when false:
+    if c.module.ast.isNil:
+      c.module.ast = newNodeI(nkStmtList, n.info)
+    assert c.module.ast.kind == nkStmtList
+    c.module.ast.add x
   result = n
 
 proc setGenericParams(c: PContext, n: PNode) =