Skip to content

Commit

Permalink
internals: leaf nodes do not have sons
Browse files Browse the repository at this point in the history
- pulls nkEmpty and nkNone into a branch without sons
- various small fixes to get bootstrap working
- no tests failed, so that's a good{?} sign
  • Loading branch information
saem committed Aug 2, 2022
1 parent 980b073 commit e40ddb4
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 34 deletions.
40 changes: 27 additions & 13 deletions compiler/ast/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,10 @@ proc addSonNilAllowed*(father, son: PNode) =
father.sons.add(son)

proc delSon*(father: PNode, idx: int) =
if father.len == 0: return
for i in idx..<father.len - 1: father[i] = father[i + 1]
if father.len == 0:
return
for i in idx..<father.len - 1:
father[i] = father[i + 1]
father.sons.setLen(father.len - 1)

template copyNodeImpl(dst, src, processSonsStmt) =
Expand Down Expand Up @@ -506,23 +508,35 @@ proc shallowCopy*(src: PNode): PNode =
proc copyTree*(src: PNode): PNode =
# copy a whole syntax tree; performs deep copying
copyNodeImpl(result, src):
newSeq(result.sons, src.len)
for i in 0..<src.len:
result[i] = copyTree(src[i])
case src.kind
of nkWithoutSons:
discard
else:
newSeq(result.sons, src.len)
for i in 0..<src.len:
result[i] = copyTree(src[i])

proc copyTreeWithoutNode*(src, skippedNode: PNode): PNode =
copyNodeImpl(result, src):
result.sons = newSeqOfCap[PNode](src.len)
for n in src.sons:
if n != skippedNode:
result.sons.add copyTreeWithoutNode(n, skippedNode)
case src.kind
of nkWithoutSons:
discard
else:
result.sons = newSeqOfCap[PNode](src.len)
for n in src.sons:
if n != skippedNode:
result.sons.add copyTreeWithoutNode(n, skippedNode)

proc copyTreeWithoutNodes*(src: PNode; skippedNodes: varargs[PNode]): PNode =
copyNodeImpl(result, src):
result.sons = newSeqOfCap[PNode](src.len)
for n in src.sons:
if n notin skippedNodes:
result.sons.add copyTreeWithoutNodes(n, skippedNodes)
case src.kind
of nkWithoutSons:
discard
else:
result.sons = newSeqOfCap[PNode](src.len)
for n in src.sons:
if n notin skippedNodes:
result.sons.add copyTreeWithoutNodes(n, skippedNodes)

proc makeStmtList*(n: PNode): PNode =
if n.kind == nkStmtList:
Expand Down
21 changes: 15 additions & 6 deletions compiler/ast/ast_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,8 @@ type
sym*: PSym
of nkIdent:
ident*: PIdent
of nkEmpty, nkNone:
discard
else:
sons*: TNodeSeq

Expand Down Expand Up @@ -890,8 +892,6 @@ type

PScope* = ref TScope



PLib* = ref TLib
TSym* {.acyclic.} = object of TIdObj # Keep in sync with PackedSym
## proc and type instantiations are cached in the generic symbol
Expand Down Expand Up @@ -1032,7 +1032,14 @@ type
TImplication* = enum
impUnknown, impNo, impYes


const
nkWithoutSons* =
{nkCharLit..nkUInt64Lit} +
{nkFloatLit..nkFloat128Lit} +
{nkStrLit..nkTripleStrLit} +
{nkSym} +
{nkIdent} +
{nkEmpty, nkNone}

type
EffectsCompat* = enum
Expand Down Expand Up @@ -1118,7 +1125,7 @@ type

type Indexable* = PNode | PType

proc len*(n: Indexable): int {.inline.} =
func len*(n: Indexable): int {.inline.} =
result = n.sons.len

proc add*(father, son: Indexable) =
Expand All @@ -1128,8 +1135,10 @@ proc add*(father, son: Indexable) =
template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x

template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x
template `[]`*(n: Indexable, i: BackwardsIndex): Indexable =
n[n.len - i.int]
template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) =
n[n.len - i.int] = x

const emptyReportId* = ReportId(0)

Expand Down
3 changes: 1 addition & 2 deletions compiler/ast/trees.nim
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ proc findPragma*(n: PNode, which: TSpecialWord): PNode =
return son

proc effectSpec*(n: PNode, effectType: TSpecialWord): PNode =
for i in 0..<n.len:
var it = n[i]
for it in n:
if it.kind == nkExprColonExpr and whichPragma(it) == effectType:
result = it[1]
if result.kind notin {nkCurly, nkBracket}:
Expand Down
2 changes: 1 addition & 1 deletion compiler/sem/evaltempl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
# wiser to just deprecate immediate templates and macros
# now that we have working untyped parameters.
genericParams = if fromHlo: 0
else: s.ast[genericParamsPos].len
else: s.ast[genericParamsPos].safeLen
expectedRegularParams = s.typ.len-1
givenRegularParams = totalParams - genericParams
if givenRegularParams < 0: givenRegularParams = 0
Expand Down
3 changes: 1 addition & 2 deletions compiler/sem/pragmas.nim
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,7 @@ proc pragmaAsm*(c: PContext, n: PNode): tuple[marker: char, err: PNode] =
## Returns ` as the default marker if no other markers are found
result.marker = '`'
if n != nil:
for i in 0..<n.len:
let it = n[i]
for it in n:
if it.kind in nkPragmaCallKinds and it.len == 2 and it[0].kind == nkIdent:
case whichKeyword(it[0].ident)
of wSubsChar:
Expand Down
7 changes: 4 additions & 3 deletions compiler/sem/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,9 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
if sym == c.p.owner:
globalReport(c.config, info, reportSym(rsemCyclicDependency, sym))

let genericParams = sym.ast[genericParamsPos].len
let suppliedParams = max(n.safeLen - 1, 0)
let
genericParams = sym.ast[genericParamsPos].safeLen
suppliedParams = max(n.safeLen - 1, 0)

if suppliedParams < genericParams:
globalReport(
Expand All @@ -604,7 +605,7 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
c.config.localReport(n.info, SemReport(
sym: sym,
kind: rsemExpandMacro,
ast: n,
ast: original,
expandedAst: result))

result = wrapInComesFrom(n.info, sym, result)
Expand Down
5 changes: 3 additions & 2 deletions compiler/sem/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1711,13 +1711,14 @@ proc maybeInstantiateGeneric(c: PContext, n: PNode, s: PSym): PNode =
## Instantiates generic if not lacking implicit generics,
## otherwise returns n.
let
neededGenParams = s.ast[genericParamsPos].len
neededGenParams = s.ast[genericParamsPos].safeLen # might be an nkEmpty
heldGenParams = n.len - 1
var implicitParams = 0
for x in s.ast[genericParamsPos]:
if tfImplicitTypeParam in x.typ.flags:
inc implicitParams
if heldGenParams != neededGenParams and implicitParams + heldGenParams == neededGenParams:
if heldGenParams != neededGenParams and
implicitParams + heldGenParams == neededGenParams:
# This is an implicit + explicit generic procedure without all args passed,
# kicking back the sem'd symbol fixes #17212
# Uncertain the hackiness of this solution.
Expand Down
10 changes: 7 additions & 3 deletions compiler/sem/semtempl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,18 @@ type
spNone, spGenSym, spInject

proc symBinding(n: PNode): TSymBinding =
for i in 0..<n.len:
let it = n[i]
result = spNone
for it in n:
let key = if it.kind == nkExprColonExpr: it[0] else: it
if key.kind == nkIdent:

case key.kind
of nkIdent:
case whichKeyword(key.ident)
of wGensym: return spGenSym
of wInject: return spInject
else: discard
else:
discard

type
TSymChoiceRule = enum
Expand Down
2 changes: 1 addition & 1 deletion compiler/sem/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym,
c.magic = c.calleeSym.magic
if binding != nil and callee.kind in routineKinds:
var typeParams = callee.ast[genericParamsPos]
for i in 1..min(typeParams.len, binding.len-1):
for i in 1..min(typeParams.safeLen, binding.safeLen-1):
var formalTypeParam = typeParams[i-1].typ
var bound = binding[i].typ
if bound != nil:
Expand Down
2 changes: 1 addition & 1 deletion compiler/vm/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3626,7 +3626,7 @@ proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstC

# put macro generic parameters into registers
let gp = sym.ast[genericParamsPos]
for i in 0..<gp.len:
for i in 0..<gp.safeLen:
let idx = sym.typ.len + i
if idx < n.len:
setupMacroParam(tos.slots[idx], c[], n[idx], gp[i].sym.typ)
Expand Down

0 comments on commit e40ddb4

Please sign in to comment.