added '..^' and '..<' operators; 'nil' is allowed for 'len'; added plugin system to the compiler

This commit is contained in:
Araq 2015-04-22 11:49:41 +02:00
commit 4be0d16520
10 changed files with 85 additions and 18 deletions

View file

@ -530,12 +530,13 @@ type
TMagic* = enum # symbols that require compiler magic: TMagic* = enum # symbols that require compiler magic:
mNone, mNone,
mDefined, mDefinedInScope, mCompiles, 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, mEcho, mShallowCopy, mSlurp, mStaticExec,
mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst, mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
mUnaryLt, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray, mUnaryLt, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref, mLengthStr, mLengthArray, mLengthSeq, mXLenStr, mXLenSeq,
mGCunref, mIncl, mExcl, mCard, mChr,
mGCref, mGCunref,
mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
mDivI64, mModI64, mSucc, mPred, mDivI64, mModI64, mSucc, mPred,
@ -590,7 +591,8 @@ type
const const
ctfeWhitelist* = {mNone, mUnaryLt, mSucc, ctfeWhitelist* = {mNone, mUnaryLt, mSucc,
mPred, mInc, mDec, mOrd, mLengthOpenArray, 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, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
mDivI64, mModI64, mAddF64, mSubF64, mMulF64, mDivF64, mDivI64, mModI64, mAddF64, mSubF64, mMulF64, mDivF64,
mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,

View file

@ -1352,15 +1352,15 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
else: unaryExpr(p, e, d, "$1Len0") else: unaryExpr(p, e, d, "$1Len0")
of tyCString: of tyCString:
useStringh(p.module) useStringh(p.module)
if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)") if op == mHigh: unaryExpr(p, e, d, "($1 ? (strlen($1)-1) : -1)")
else: unaryExpr(p, e, d, "strlen($1)") else: unaryExpr(p, e, d, "($1 ? strlen($1) : 0)")
of tyString, tySequence: of tyString, tySequence:
if not p.module.compileToCpp: if not p.module.compileToCpp:
if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)") if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->Sup.len-1) : -1)")
else: unaryExpr(p, e, d, "$1->Sup.len") else: unaryExpr(p, e, d, "($1 ? $1->Sup.len : 0)")
else: else:
if op == mHigh: unaryExpr(p, e, d, "($1->len-1)") if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->len-1) : -1)")
else: unaryExpr(p, e, d, "$1->len") else: unaryExpr(p, e, d, "($1 ? $1->len : 0)")
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
# YYY: length(sideeffect) is optimized away incorrectly? # YYY: length(sideeffect) is optimized away incorrectly?
if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ))) 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 mOrd: genOrd(p, e, d)
of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray: of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
genArrayLen(p, e, d, op) 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 mGCref: unaryStmt(p, e, d, "#nimGCref($1);$n")
of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n") of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n")
of mSetLengthStr: genSetLengthStr(p, e, d) of mSetLengthStr: genSetLengthStr(p, e, d)

View file

@ -22,7 +22,8 @@ const
someLt = {mLtI, mLtI64, mLtF64, mLtU, mLtU64, mLtEnum, someLt = {mLtI, mLtI64, mLtF64, mLtU, mLtU64, mLtEnum,
mLtCh, mLtB, mLtPtr, mLtStr} mLtCh, mLtB, mLtPtr, mLtStr}
someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq} someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
mXLenStr, mXLenSeq}
someIn = {mInRange, mInSet} someIn = {mInRange, mInSet}

43
compiler/plugins.nim Normal file
View file

@ -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)

View file

@ -16,7 +16,7 @@ import
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch, procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity, evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
semparallel, lowerings semparallel, lowerings, plugins
when defined(nimfix): when defined(nimfix):
import nimfix.prettybase import nimfix.prettybase

View file

@ -286,9 +286,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of mNot: result = newIntNodeT(1 - getInt(a), n) of mNot: result = newIntNodeT(1 - getInt(a), n)
of mCard: result = newIntNodeT(nimsets.cardSet(a), n) of mCard: result = newIntNodeT(nimsets.cardSet(a), n)
of mBitnotI, mBitnotI64: result = newIntNodeT(not getInt(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 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 mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
of mToFloat, mToBiggestFloat: of mToFloat, mToBiggestFloat:
result = newFloatNodeT(toFloat(int(getInt(a))), n) result = newFloatNodeT(toFloat(int(getInt(a))), n)

View file

@ -196,4 +196,11 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
result.add newSymNode(createMagic("-", mSubI), n.info) result.add newSymNode(createMagic("-", mSubI), n.info)
result.add lenExprB result.add lenExprB
result.add n.sons[1] 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 else: result = n

View file

@ -742,9 +742,9 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
c.gABC(n, opcNewStr, dest, tmp) c.gABC(n, opcNewStr, dest, tmp)
c.freeTemp(tmp) c.freeTemp(tmp)
# XXX buggy # XXX buggy
of mLengthOpenArray, mLengthArray, mLengthSeq: of mLengthOpenArray, mLengthArray, mLengthSeq, mXLenSeq:
genUnaryABI(c, n, dest, opcLenSeq) genUnaryABI(c, n, dest, opcLenSeq)
of mLengthStr: of mLengthStr, mXLenStr:
genUnaryABI(c, n, dest, opcLenStr) genUnaryABI(c, n, dest, opcLenStr)
of mIncl, mExcl: of mIncl, mExcl:
unused(n, dest) unused(n, dest)

View file

@ -3266,4 +3266,9 @@ template `..<`*(a, b: expr): expr =
## '..' and '<' is required. ## '..' and '<' is required.
a .. <b a .. <b
proc xlen*(x: string): int {.magic: "XLenStr", noSideEffect.}
proc xlen*[T](x: seq[T]): int {.magic: "XLenSeq", noSideEffect.}
## returns the length of a sequence or a string without testing for 'nil'.
## This is an optimization that rarely makes sense.
{.pop.} #{.push warning[GcMem]: off.} {.pop.} #{.push warning[GcMem]: off.}

View file

@ -1,8 +1,11 @@
version 0.10.4 version 0.10.4
============== ==============
- make 'nil' work for 'add' and 'len' - make 'nil' work for 'add':
- add '..^' and '..<' operators to system - resizeString
- incrSeq
- addChar
version 1.0 version 1.0
=========== ===========