added '..^' and '..<' operators; 'nil' is allowed for 'len'; added plugin system to the compiler
This commit is contained in:
parent
54515241e3
commit
4be0d16520
10 changed files with 85 additions and 18 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
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,
|
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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.}
|
||||||
|
|
|
||||||
7
todo.txt
7
todo.txt
|
|
@ -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
|
||||||
===========
|
===========
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue