diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 15 | ||||
-rwxr-xr-x | compiler/ccgexprs.nim | 2 | ||||
-rwxr-xr-x | compiler/ecmasgen.nim | 2 | ||||
-rwxr-xr-x | compiler/evals.nim | 44 | ||||
-rwxr-xr-x | compiler/msgs.nim | 3 | ||||
-rwxr-xr-x | compiler/sem.nim | 11 | ||||
-rwxr-xr-x | compiler/semdata.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 8 | ||||
-rwxr-xr-x | compiler/semfold.nim | 2 | ||||
-rw-r--r-- | compiler/semmagic.nim | 14 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 2 |
11 files changed, 68 insertions, 37 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 949c28c5f..c59c47453 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -370,7 +370,7 @@ type TMagic* = enum # symbols that require compiler magic: mNone, mDefined, mDefinedInScope, mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, - mEcho, mShallowCopy, mSlurp, + mEcho, mShallowCopy, mSlurp, mStaticExec, mParseExprToAst, mParseStmtToAst, mExpandToAst, mUnaryLt, mSucc, mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray, @@ -541,6 +541,9 @@ type # for easy generation of proper error messages # for variant record fields the discriminant # expression + # for modules, it's a placeholder for compiler + # generated code that will be appended to the + # module after the sem pass (see appendToModule) options*: TOptions position*: int # used for many different things: # for enum fields its position; @@ -742,6 +745,16 @@ proc linkTo*(s: PSym, t: PType): PSym {.discardable.} = s.typ = t result = s +proc appendToModule*(m: PSym, n: PNode) = + ## The compiler will use this internally to add nodes that will be + ## appended to the module after the sem pass + if m.ast == nil: + m.ast = newNode(nkStmtList) + m.ast.sons = @[n] + else: + assert m.ast.kind == nkStmtList + m.ast.sons.add(n) + const # for all kind of hash tables: GrowthFactor* = 2 # must be power of 2, > 0 StartSize* = 8 # must be power of 2, > 0 diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 34418f353..eb20153fc 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1436,6 +1436,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mArrToSeq: genArrToSeq(p, e, d) of mNLen..mNError: localError(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s) + of mSlurp, mStaticExec: + localError(e.info, errXMustBeCompileTime, e.sons[0].sym.name.s) else: internalError(e.info, "genMagicExpr: " & $op) proc genConstExpr(p: BProc, n: PNode): PRope diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim index 3ab4303c2..9c9c01734 100755 --- a/compiler/ecmasgen.nim +++ b/compiler/ecmasgen.nim @@ -1173,6 +1173,8 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) = localError(n.info, errCannotGenerateCodeForX, n.sons[0].sym.name.s) of mNewSeq: binaryStmt(p, n, r, "", "$1 = new Array($2)") of mEcho: genEcho(p, n, r) + of mSlurp, mStaticExec: + localError(n.info, errXMustBeCompileTime, n.sons[0].sym.name.s) else: genCall(p, n, r) #else internalError(e.info, 'genMagic: ' + magicToStr[op]); diff --git a/compiler/evals.nim b/compiler/evals.nim index a4d4cdd9e..002fed194 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -16,7 +16,7 @@ import strutils, magicsys, lists, options, ast, astalgo, trees, treetab, nimsets, msgs, os, condsyms, idents, renderer, types, passes, semfold, transf, - parser, ropes, rodread, idgen + parser, ropes, rodread, idgen, osproc, streams type PStackFrame* = ref TStackFrame @@ -910,6 +910,43 @@ proc evalTypeTrait*(n: PNode, context: PSym): PNode = else: internalAssert false +proc expectString(n: PNode) = + if n.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit}: + GlobalError(n.info, errStringLiteralExpected) + +proc evalSlurp*(e: PNode, module: PSym): PNode = + expectString(e) + try: + var filename = e.strVal.FindFile + var content = readFile(filename) + result = newStrNode(nkStrLit, content) + result.typ = getSysType(tyString) + result.info = e.info + # we produce a fake include statement for every slurped filename, so that + # the module dependencies are accurate: + appendToModule(module, newNode(nkIncludeStmt, e.info, @[ + newStrNode(nkStrLit, filename)])) + except EIO: + GlobalError(e.info, errCannotOpenFile, e.strVal) + +proc readOutput(p: PProcess): string = + result = "" + var output = p.outputStream + discard p.waitForExit + while not output.atEnd: + result.add(output.readLine) + +proc evalStaticExec*(cmd, input: PNode): PNode = + expectString(cmd) + var p = startCmd(cmd.strVal) + if input != nil: + expectString(input) + p.inputStream.write(input.strVal) + p.inputStream.close() + result = newStrNode(nkStrLit, p.readOutput) + result.typ = getSysType(tyString) + result.info = cmd.info + proc evalExpandToAst(c: PEvalContext, original: PNode): PNode = var n = original.copyTree @@ -960,6 +997,11 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = of mParseStmtToAst: result = evalParseStmt(c, n) of mExpandToAst: result = evalExpandToAst(c, n) of mTypeTrait: result = evalTypeTrait(n, c.module) + of mSlurp: result = evalSlurp(evalAux(c, n.sons[1], {}), c.module) + of mStaticExec: + let cmd = evalAux(c, n.sons[1], {}) + let input = if n.sonsLen == 3: evalAux(c, n.sons[2], {}) else: nil + result = evalStaticExec(cmd, input) of mNLen: result = evalAux(c, n.sons[1], {efLValue}) if isSpecial(result): return diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 17cfeae4d..2af512af7 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -94,7 +94,7 @@ type errUnhandledExceptionX, errCyclicTree, errXisNoMacroOrTemplate, errXhasSideEffects, errIteratorExpected, errLetNeedsInit, errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX, - errXCannotBeClosure, + errXCannotBeClosure, errXMustBeCompileTime, errUser, warnCannotOpenFile, warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit, @@ -327,6 +327,7 @@ const errWrongSymbolX: "usage of \'$1\' is a user-defined error", errIllegalCaptureX: "illegal capture '$1'", errXCannotBeClosure: "'$1' cannot have 'closure' calling convention", + errXMustBeCompileTime: "'$1' can only be used in compile-time context", errUser: "$1", warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]", warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]", diff --git a/compiler/sem.nim b/compiler/sem.nim index 8afbe3c51..721b4b040 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -89,9 +89,6 @@ proc semConstExpr(c: PContext, n: PNode): PNode = return nil result = evalTypedExpr(c, e) -proc semAndEvalConstExpr(c: PContext, n: PNode): PNode = - result = semConstExpr(c, n) - include seminst, semcall proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = @@ -219,12 +216,8 @@ proc myClose(context: PPassContext, n: PNode): PNode = else: InternalError(n.info, "n is not nil") #result := n; addCodeForGenerics(c, result) - # we produce a fake include statement for every slurped filename, so that - # the module dependencies are accurate: - var ics = newNode(nkIncludeStmt) - for s in items(c.slurpedFiles): ics.add(newStrNode(nkStrLit, s)) - result.add(ics) - + if c.module.ast != nil: + result.add(c.module.ast) checkThreads(c) popOwner() popProcCon(c) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index f97da4717..81e45f71c 100755 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -73,7 +73,6 @@ type filename*: string # the module's filename userPragmas*: TStrTable evalContext*: PEvalContext - slurpedFiles*: seq[string] var gGenericsCache: PGenericsCache # save for modularity @@ -153,7 +152,6 @@ proc newContext(module: PSym, nimfile: string): PContext = result.filename = nimfile result.includedFiles = initIntSet() initStrTable(result.userPragmas) - result.slurpedFiles = @[] if optSymbolFiles notin gGlobalOptions: # re-usage of generic instantiations across module boundaries is # very nice for code size: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index fe35607cb..ac9075d4f 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -491,12 +491,6 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = skipTypes(t.sons[i], abstractInst).kind == tyVar: n.sons[i] = analyseIfAddressTaken(c, n.sons[i]) - -proc expectStringArg(c: PContext, n: PNode, i: int): PNode = - result = c.semAndEvalConstExpr(n.sons[i+1]) - if result.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit}: - GlobalError(result.info, errStringLiteralExpected) - include semmagic proc evalAtCompileTime(c: PContext, n: PNode): PNode = @@ -901,7 +895,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = checkSonsLen(n, 2) n.sons[0] = makeDeref(n.sons[0]) # [] operator for tuples requires constant expression: - n.sons[1] = semAndEvalConstExpr(c, n.sons[1]) + n.sons[1] = semConstExpr(c, n.sons[1]) if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal}).kind in {tyInt..tyInt64}: var idx = getOrdValue(n.sons[1]) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 82ee7de13..565155791 100755 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -207,7 +207,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = mExit, mInc, ast.mDec, mEcho, mSwap, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq, mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait, - mNLen..mNError, mEqRef: + mNLen..mNError, mEqRef, mSlurp, mStaticExec: nil of mRand: result = newIntNodeT(math.random(a.getInt.int), n) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index e6861f2e4..b7e890e67 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -14,19 +14,6 @@ proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode = var r = isPartOf(n[1], n[2]) result = newIntNodeT(ord(r), n) -proc semSlurp(c: PContext, n: PNode, flags: TExprFlags): PNode = - assert sonsLen(n) == 2 - var a = expectStringArg(c, n, 0) - try: - var filename = a.strVal.FindFile - var content = readFile(filename) - result = newStrNode(nkStrLit, content) - result.typ = getSysType(tyString) - result.info = n.info - c.slurpedFiles.add(a.strVal) - except EIO: - GlobalError(a.info, errCannotOpenFile, a.strVal) - proc expectIntLit(c: PContext, n: PNode): int = let x = c.semConstExpr(c, n) case x.kind @@ -56,7 +43,6 @@ proc semTypeTraits(c: PContext, n: PNode): PNode = proc magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags): PNode = case n[0].sym.magic - of mSlurp: result = semSlurp(c, n, flags) of mIsPartOf: result = semIsPartOf(c, n, flags) of mTypeTrait: result = semTypeTraits(c, n) of mAstToStr: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f10c56880..943c49bad 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -27,7 +27,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = case it.kind of nkElifBranch, nkElifExpr: checkSonsLen(it, 2) - var e = semAndEvalConstExpr(c, it.sons[0]) + var e = semConstExpr(c, it.sons[0]) if e.kind != nkIntLit: InternalError(n.info, "semWhen") if e.intVal != 0 and result == nil: setResult(it.sons[1]) |