summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-04-22 11:49:41 +0200
committerAraq <rumpf_a@web.de>2015-04-22 12:04:11 +0200
commit4be0d16520ce89a8590090b4216d626f445abff1 (patch)
treec1cdf4b28ef6ee7501f00bdcb30d73b6a8563eb1 /compiler
parent54515241e302309a665ca820a331cc2126c15305 (diff)
downloadNim-4be0d16520ce89a8590090b4216d626f445abff1.tar.gz
added '..^' and '..<' operators; 'nil' is allowed for 'len'; added plugin system to the compiler
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim10
-rw-r--r--compiler/ccgexprs.nim17
-rw-r--r--compiler/guards.nim3
-rw-r--r--compiler/plugins.nim43
-rw-r--r--compiler/sem.nim2
-rw-r--r--compiler/semfold.nim5
-rw-r--r--compiler/semmagic.nim7
-rw-r--r--compiler/vmgen.nim4
8 files changed, 75 insertions, 16 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 8556977a1..3798410e8 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -530,12 +530,13 @@ type
   TMagic* = enum # symbols that require compiler magic:
     mNone,
     mDefined, mDefinedInScope, mCompiles,
-    mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof,
+    mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof, mPlugin,
     mEcho, mShallowCopy, mSlurp, mStaticExec,
     mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
     mUnaryLt, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
-    mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
-    mGCunref,
+    mLengthStr, mLengthArray, mLengthSeq, mXLenStr, mXLenSeq,
+    mIncl, mExcl, mCard, mChr,
+    mGCref, mGCunref,
 
     mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
     mDivI64, mModI64, mSucc, mPred,
@@ -590,7 +591,8 @@ type
 const
   ctfeWhitelist* = {mNone, mUnaryLt, mSucc,
     mPred, mInc, mDec, mOrd, mLengthOpenArray,
-    mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr,
+    mLengthStr, mLengthArray, mLengthSeq, mXLenStr, mXLenSeq,
+    mIncl, mExcl, mCard, mChr,
     mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
     mDivI64, mModI64, mAddF64, mSubF64, mMulF64, mDivF64,
     mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 54fd3cffd..93a9dd65d 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1352,15 +1352,15 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     else: unaryExpr(p, e, d, "$1Len0")
   of tyCString:
     useStringh(p.module)
-    if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
-    else: unaryExpr(p, e, d, "strlen($1)")
+    if op == mHigh: unaryExpr(p, e, d, "($1 ? (strlen($1)-1) : -1)")
+    else: unaryExpr(p, e, d, "($1 ? strlen($1) : 0)")
   of tyString, tySequence:
     if not p.module.compileToCpp:
-      if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)")
-      else: unaryExpr(p, e, d, "$1->Sup.len")
+      if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->Sup.len-1) : -1)")
+      else: unaryExpr(p, e, d, "($1 ? $1->Sup.len : 0)")
     else:
-      if op == mHigh: unaryExpr(p, e, d, "($1->len-1)")
-      else: unaryExpr(p, e, d, "$1->len")
+      if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->len-1) : -1)")
+      else: unaryExpr(p, e, d, "($1 ? $1->len : 0)")
   of tyArray, tyArrayConstr:
     # YYY: length(sideeffect) is optimized away incorrectly?
     if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ)))
@@ -1721,6 +1721,11 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mOrd: genOrd(p, e, d)
   of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
     genArrayLen(p, e, d, op)
+  of mXLenStr, mXLenSeq:
+    if not p.module.compileToCpp:
+      unaryExpr(p, e, d, "($1->Sup.len-1)")
+    else:
+      unaryExpr(p, e, d, "$1->len")
   of mGCref: unaryStmt(p, e, d, "#nimGCref($1);$n")
   of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n")
   of mSetLengthStr: genSetLengthStr(p, e, d)
diff --git a/compiler/guards.nim b/compiler/guards.nim
index 1217bc6f1..dc2b24add 100644
--- a/compiler/guards.nim
+++ b/compiler/guards.nim
@@ -22,7 +22,8 @@ const
   someLt = {mLtI, mLtI64, mLtF64, mLtU, mLtU64, mLtEnum,
             mLtCh, mLtB, mLtPtr, mLtStr}
 
-  someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq}
+  someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
+             mXLenStr, mXLenSeq}
 
   someIn = {mInRange, mInSet}
 
diff --git a/compiler/plugins.nim b/compiler/plugins.nim
new file mode 100644
index 000000000..1c9b7b77b
--- /dev/null
+++ b/compiler/plugins.nim
@@ -0,0 +1,43 @@
+#
+#
+#           The Nim Compiler
+#        (c) Copyright 2015 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Plugin support for the Nim compiler. Right now there are no plugins and they
+## need to be build with the compiler, no DLL support.
+
+import ast, semdata, idents
+
+type
+  Transformation* = proc (c: PContext; n: PNode): PNode {.nimcall.}
+  Plugin = ref object
+    fn, module, package: PIdent
+    t: Transformation
+    next: Plugin
+
+proc pluginMatches(p: Plugin; s: PSym): bool =
+  if s.name.id != p.fn.id: return false
+  let module = s.owner
+  if module == nil or module.kind != skModule or
+      module.name.id != p.module.id: return false
+  let package = module.owner
+  if package == nil or package.kind != skPackage or
+      package.name.id != p.package.id: return false
+  return true
+
+var head: Plugin
+
+proc getPlugin*(fn: PSym): Transformation =
+  var it = head
+  while it != nil:
+    if pluginMatches(it, fn): return it.t
+    it = it.next
+
+proc registerPlugin*(package, module, fn: string; t: Transformation) =
+  let oldHead = head
+  head = Plugin(fn: getIdent(fn), module: getIdent(module),
+                 package: getIdent(package), t: t, next: oldHead)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 7eabaf491..965556a36 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -16,7 +16,7 @@ import
   procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
   intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
   evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
-  semparallel, lowerings
+  semparallel, lowerings, plugins
 
 when defined(nimfix):
   import nimfix.prettybase
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 29e5d8aa2..0150a3405 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -286,9 +286,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
   of mNot: result = newIntNodeT(1 - getInt(a), n)
   of mCard: result = newIntNodeT(nimsets.cardSet(a), n)
   of mBitnotI, mBitnotI64: result = newIntNodeT(not getInt(a), n)
-  of mLengthStr: result = newIntNodeT(len(getStr(a)), n)
+  of mLengthStr, mXLenStr: result = newIntNodeT(len(getStr(a)), n)
   of mLengthArray: result = newIntNodeT(lengthOrd(a.typ), n)
-  of mLengthSeq, mLengthOpenArray: result = newIntNodeT(sonsLen(a), n) # BUGFIX
+  of mLengthSeq, mLengthOpenArray, mXLenSeq:
+    result = newIntNodeT(sonsLen(a), n) # BUGFIX
   of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
   of mToFloat, mToBiggestFloat:
     result = newFloatNodeT(toFloat(int(getInt(a))), n)
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index de7700be6..f15a55832 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -196,4 +196,11 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
         result.add newSymNode(createMagic("-", mSubI), n.info)
         result.add lenExprB
         result.add n.sons[1]
+  of mPlugin:
+    let plugin = getPlugin(n[0].sym)
+    if plugin.isNil:
+      localError(n.info, "cannot find plugin " & n[0].sym.name.s)
+      result = n
+    else:
+      result = plugin(c, n)
   else: result = n
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index f1cbe70b6..b354061a9 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -742,9 +742,9 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     c.gABC(n, opcNewStr, dest, tmp)
     c.freeTemp(tmp)
     # XXX buggy
-  of mLengthOpenArray, mLengthArray, mLengthSeq:
+  of mLengthOpenArray, mLengthArray, mLengthSeq, mXLenSeq:
     genUnaryABI(c, n, dest, opcLenSeq)
-  of mLengthStr:
+  of mLengthStr, mXLenStr:
     genUnaryABI(c, n, dest, opcLenStr)
   of mIncl, mExcl:
     unused(n, dest)