mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-09 13:18:11 +00:00
added '..^' and '..<' operators; 'nil' is allowed for 'len'; added plugin system to the compiler
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
43
compiler/plugins.nim
Normal file
43
compiler/plugins.nim
Normal 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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -3266,4 +3266,9 @@ template `..<`*(a, b: expr): expr =
|
||||
## '..' and '<' is required.
|
||||
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.}
|
||||
|
||||
Reference in New Issue
Block a user