fixes #1120
This commit is contained in:
parent
8325c71172
commit
9280473eb1
11 changed files with 34 additions and 39 deletions
|
|
@ -1560,3 +1560,9 @@ proc isEmptyType*(t: PType): bool {.inline.} =
|
||||||
## 'void' and 'stmt' types are often equivalent to 'nil' these days:
|
## 'void' and 'stmt' types are often equivalent to 'nil' these days:
|
||||||
result = t == nil or t.kind in {tyEmpty, tyStmt}
|
result = t == nil or t.kind in {tyEmpty, tyStmt}
|
||||||
|
|
||||||
|
proc makeStmtList*(n: PNode): PNode =
|
||||||
|
if n.kind == nkStmtList:
|
||||||
|
result = n
|
||||||
|
else:
|
||||||
|
result = newNodeI(nkStmtList, n.info)
|
||||||
|
result.add n
|
||||||
|
|
|
||||||
|
|
@ -894,7 +894,8 @@ proc parseParamList(p: var TParser, retColon = true): PNode =
|
||||||
var a: PNode
|
var a: PNode
|
||||||
result = newNodeP(nkFormalParams, p)
|
result = newNodeP(nkFormalParams, p)
|
||||||
addSon(result, ast.emptyNode) # return type
|
addSon(result, ast.emptyNode) # return type
|
||||||
if p.tok.tokType == tkParLe and p.tok.indent < 0:
|
let hasParLe = p.tok.tokType == tkParLe and p.tok.indent < 0
|
||||||
|
if hasParLe:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -918,6 +919,9 @@ proc parseParamList(p: var TParser, retColon = true): PNode =
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
result.sons[0] = parseTypeDesc(p)
|
result.sons[0] = parseTypeDesc(p)
|
||||||
|
elif not retColon and not hasParle:
|
||||||
|
# Mark as "not there" in order to mark for deprecation in the semantic pass:
|
||||||
|
result = ast.emptyNode
|
||||||
|
|
||||||
proc optPragmas(p: var TParser): PNode =
|
proc optPragmas(p: var TParser): PNode =
|
||||||
if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)):
|
if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)):
|
||||||
|
|
@ -1130,7 +1134,7 @@ proc parseMacroColon(p: var TParser, x: PNode): PNode =
|
||||||
skipComment(p, result)
|
skipComment(p, result)
|
||||||
if p.tok.tokType notin {tkOf, tkElif, tkElse, tkExcept}:
|
if p.tok.tokType notin {tkOf, tkElif, tkElse, tkExcept}:
|
||||||
let body = parseStmt(p)
|
let body = parseStmt(p)
|
||||||
addSon(result, newProcNode(nkDo, body.info, body))
|
addSon(result, makeStmtList(body))
|
||||||
while sameInd(p):
|
while sameInd(p):
|
||||||
var b: PNode
|
var b: PNode
|
||||||
case p.tok.tokType
|
case p.tok.tokType
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind)
|
||||||
proc maybeAddResult(c: PContext, s: PSym, n: PNode)
|
proc maybeAddResult(c: PContext, s: PSym, n: PNode)
|
||||||
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
|
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
|
||||||
proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||||
proc fixImmediateParams(n: PNode): PNode
|
|
||||||
proc activate(c: PContext, n: PNode)
|
proc activate(c: PContext, n: PNode)
|
||||||
proc semQuoteAst(c: PContext, n: PNode): PNode
|
proc semQuoteAst(c: PContext, n: PNode): PNode
|
||||||
proc finishMethod(c: PContext, s: PSym)
|
proc finishMethod(c: PContext, s: PSym)
|
||||||
|
|
|
||||||
|
|
@ -1505,11 +1505,11 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
doBlk.sons[namePos] = newAnonSym(skTemplate, n.info).newSymNode
|
doBlk.sons[namePos] = newAnonSym(skTemplate, n.info).newSymNode
|
||||||
if ids.len > 0:
|
if ids.len > 0:
|
||||||
doBlk[paramsPos].sons.setLen(2)
|
doBlk.sons[paramsPos] = newNodeI(nkFormalParams, n.info)
|
||||||
doBlk[paramsPos].sons[0] = getSysSym("stmt").newSymNode # return type
|
doBlk[paramsPos].add getSysSym("stmt").newSymNode # return type
|
||||||
ids.add getSysSym("expr").newSymNode # params type
|
ids.add getSysSym("expr").newSymNode # params type
|
||||||
ids.add emptyNode # no default value
|
ids.add emptyNode # no default value
|
||||||
doBlk[paramsPos].sons[1] = newNode(nkIdentDefs, n.info, ids)
|
doBlk[paramsPos].add newNode(nkIdentDefs, n.info, ids)
|
||||||
|
|
||||||
var tmpl = semTemplateDef(c, doBlk)
|
var tmpl = semTemplateDef(c, doBlk)
|
||||||
quotes[0] = tmpl[namePos]
|
quotes[0] = tmpl[namePos]
|
||||||
|
|
@ -1892,19 +1892,6 @@ proc semBlock(c: PContext, n: PNode): PNode =
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
dec(c.p.nestedBlockCounter)
|
dec(c.p.nestedBlockCounter)
|
||||||
|
|
||||||
proc doBlockIsStmtList(n: PNode): bool =
|
|
||||||
result = n.kind == nkDo and
|
|
||||||
n[paramsPos].sonsLen == 1 and
|
|
||||||
n[paramsPos][0].kind == nkEmpty
|
|
||||||
|
|
||||||
proc fixImmediateParams(n: PNode): PNode =
|
|
||||||
# XXX: Temporary work-around until we carry out
|
|
||||||
# the planned overload resolution reforms
|
|
||||||
for i in 1 .. <safeLen(n):
|
|
||||||
if doBlockIsStmtList(n[i]):
|
|
||||||
n.sons[i] = n[i][bodyPos]
|
|
||||||
result = n
|
|
||||||
|
|
||||||
proc semExport(c: PContext, n: PNode): PNode =
|
proc semExport(c: PContext, n: PNode): PNode =
|
||||||
var x = newNodeI(n.kind, n.info)
|
var x = newNodeI(n.kind, n.info)
|
||||||
#let L = if n.kind == nkExportExceptStmt: L = 1 else: n.len
|
#let L = if n.kind == nkExportExceptStmt: L = 1 else: n.len
|
||||||
|
|
@ -2022,14 +2009,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if sfImmediate notin s.flags:
|
if sfImmediate notin s.flags:
|
||||||
result = semDirectOp(c, n, flags)
|
result = semDirectOp(c, n, flags)
|
||||||
else:
|
else:
|
||||||
var p = fixImmediateParams(n)
|
result = semMacroExpr(c, n, n, s, flags)
|
||||||
result = semMacroExpr(c, p, p, s, flags)
|
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if sfImmediate notin s.flags:
|
if sfImmediate notin s.flags:
|
||||||
result = semDirectOp(c, n, flags)
|
result = semDirectOp(c, n, flags)
|
||||||
else:
|
else:
|
||||||
var p = fixImmediateParams(n)
|
result = semTemplateExpr(c, n, s, flags)
|
||||||
result = semTemplateExpr(c, p, s, flags)
|
|
||||||
of skType:
|
of skType:
|
||||||
# XXX think about this more (``set`` procs)
|
# XXX think about this more (``set`` procs)
|
||||||
if n.len == 2:
|
if n.len == 2:
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
let n = fixImmediateParams(n)
|
|
||||||
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
||||||
result = semGenericStmt(c, result, {}, ctx)
|
result = semGenericStmt(c, result, {}, ctx)
|
||||||
else:
|
else:
|
||||||
|
|
@ -185,7 +184,6 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
styleCheckUse(fn.info, s)
|
styleCheckUse(fn.info, s)
|
||||||
let n = fixImmediateParams(n)
|
|
||||||
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
||||||
result = semGenericStmt(c, result, {}, ctx)
|
result = semGenericStmt(c, result, {}, ctx)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -776,7 +776,7 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode =
|
||||||
if it.kind == nkExprColonExpr:
|
if it.kind == nkExprColonExpr:
|
||||||
# pass pragma argument to the macro too:
|
# pass pragma argument to the macro too:
|
||||||
x.add(it.sons[1])
|
x.add(it.sons[1])
|
||||||
x.add(newProcNode(nkDo, prc.info, prc))
|
x.add(prc)
|
||||||
# recursion assures that this works for multiple macro annotations too:
|
# recursion assures that this works for multiple macro annotations too:
|
||||||
return semStmt(c, x)
|
return semStmt(c, x)
|
||||||
|
|
||||||
|
|
@ -804,6 +804,9 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
gp = newNodeI(nkGenericParams, n.info)
|
gp = newNodeI(nkGenericParams, n.info)
|
||||||
|
|
||||||
if n.sons[paramsPos].kind != nkEmpty:
|
if n.sons[paramsPos].kind != nkEmpty:
|
||||||
|
#if n.kind == nkDo and not experimentalMode(c):
|
||||||
|
# localError(n.sons[paramsPos].info,
|
||||||
|
# "use the {.experimental.} pragma to enable 'do' with parameters")
|
||||||
semParamList(c, n.sons[paramsPos], gp, s)
|
semParamList(c, n.sons[paramsPos], gp, s)
|
||||||
# paramsTypeCheck(c, s.typ)
|
# paramsTypeCheck(c, s.typ)
|
||||||
if sonsLen(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty:
|
if sonsLen(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty:
|
||||||
|
|
|
||||||
|
|
@ -1153,8 +1153,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
|
||||||
of isEqual: inc(m.exactMatches)
|
of isEqual: inc(m.exactMatches)
|
||||||
of isNone: discard
|
of isNone: discard
|
||||||
|
|
||||||
if f.kind == tyStmt and argOrig.kind == nkDo:
|
if f.kind == tyStmt:
|
||||||
return argOrig[bodyPos]
|
return arg
|
||||||
elif f.kind == tyTypeDesc:
|
elif f.kind == tyTypeDesc:
|
||||||
return arg
|
return arg
|
||||||
elif f.kind == tyStatic:
|
elif f.kind == tyStatic:
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,8 @@ executable code.
|
||||||
Do notation
|
Do notation
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
**Note:** The future of the ``do`` notation is uncertain.
|
||||||
|
|
||||||
As a special more convenient notation, proc expressions involved in procedure
|
As a special more convenient notation, proc expressions involved in procedure
|
||||||
calls can use the ``do`` keyword:
|
calls can use the ``do`` keyword:
|
||||||
|
|
||||||
|
|
@ -224,11 +226,6 @@ More than one ``do`` block can appear in a single call:
|
||||||
do:
|
do:
|
||||||
# code to undo it
|
# code to undo it
|
||||||
|
|
||||||
For compatibility with ``stmt`` templates and macros, the ``do`` keyword can be
|
|
||||||
omitted if the supplied proc doesn't have any parameters and return value.
|
|
||||||
The compatibility works in the other direction too as the ``do`` syntax can be
|
|
||||||
used with macros and templates expecting ``stmt`` blocks.
|
|
||||||
|
|
||||||
|
|
||||||
Nonoverloadable builtins
|
Nonoverloadable builtins
|
||||||
------------------------
|
------------------------
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ OBJ 2 bar
|
||||||
|
|
||||||
type
|
type
|
||||||
# these are the signatures of the virtual procs for each type
|
# these are the signatures of the virtual procs for each type
|
||||||
fooProc[T] = proc (o: var T): int
|
fooProc[T] = proc (o: var T): int {.nimcall.}
|
||||||
barProc[T] = proc (o: var T)
|
barProc[T] = proc (o: var T) {.nimcall.}
|
||||||
|
|
||||||
# an untyped table to store the proc pointers
|
# an untyped table to store the proc pointers
|
||||||
# it's also possible to use a strongly typed tuple here
|
# it's also possible to use a strongly typed tuple here
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -3,8 +3,6 @@ version 0.10
|
||||||
|
|
||||||
- The bitwise 'not' operator will be renamed to 'bnot' to
|
- The bitwise 'not' operator will be renamed to 'bnot' to
|
||||||
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
|
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
|
||||||
- The 'do' notation might be trimmed so that its only purpose is to pass
|
|
||||||
multiple multi line constructs to a macro.
|
|
||||||
|
|
||||||
- c2nim depends on the compiler
|
- c2nim depends on the compiler
|
||||||
- make nimble part of the distribution
|
- make nimble part of the distribution
|
||||||
|
|
@ -62,6 +60,8 @@ version 0.9.x
|
||||||
- we need a magic thisModule symbol
|
- we need a magic thisModule symbol
|
||||||
- ensure (ref T)(a, b) works as a type conversion and type constructor
|
- ensure (ref T)(a, b) works as a type conversion and type constructor
|
||||||
- optimize 'genericReset'; 'newException' leads to code bloat
|
- optimize 'genericReset'; 'newException' leads to code bloat
|
||||||
|
- The 'do' notation might be trimmed so that its only purpose is to pass
|
||||||
|
multiple multi line constructs to a macro.
|
||||||
|
|
||||||
|
|
||||||
version 0.9.X
|
version 0.9.X
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ News
|
||||||
compiler changed from ``nimrod`` to ``nim`` too.
|
compiler changed from ``nimrod`` to ``nim`` too.
|
||||||
- ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to
|
- ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to
|
||||||
prevent name conflicts with the new type ``FileHandle``.
|
prevent name conflicts with the new type ``FileHandle``.
|
||||||
- Comments are now not part of the AST, as such you cannot use them in place
|
- Comments are now not part of the AST anymore, as such you cannot use them
|
||||||
of ``discard``.
|
in place of ``discard``.
|
||||||
- Large parts of the stdlib got rid of the T/P type prefixes. Instead most
|
- Large parts of the stdlib got rid of the T/P type prefixes. Instead most
|
||||||
types now simply start with an uppercased letter. The
|
types now simply start with an uppercased letter. The
|
||||||
so called "partial case sensitivity" rule is now active allowing for code
|
so called "partial case sensitivity" rule is now active allowing for code
|
||||||
|
|
@ -51,6 +51,9 @@ News
|
||||||
work better.
|
work better.
|
||||||
- Field names in tuples are now ignored for type comparisons. This allows
|
- Field names in tuples are now ignored for type comparisons. This allows
|
||||||
for greater interoperability between different modules.
|
for greater interoperability between different modules.
|
||||||
|
- Statement lists are not converted to an implicit ``do`` block anymore. This
|
||||||
|
means the confusing ``nnkDo`` nodes when working with macros are gone for
|
||||||
|
good.
|
||||||
|
|
||||||
|
|
||||||
Language Additions
|
Language Additions
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue