summary refs log tree commit diff stats
path: root/compiler/ic/to_packed_ast.nim
blob: 85fec908194b11b778b17709b090dbeab01cab66 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#
#
#           The Nim Compiler
#        (c) Copyright 2020 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

import std / [hashes, tables]
import packed_ast, bitabs
import ".." / [ast, idents, lineinfos, options, pathutils, msgs]

type
  Context = object
    thisModule: int32
    lastFile: FileIndex # remember the last lookup entry.
    lastLit: LitId
    filenames: Table[FileIndex, LitId]

proc toLitId(x: FileIndex; ir: var PackedTree; c: var Context): LitId =
  if x == c.lastFile:
    result = c.lastLit
  else:
    result = c.filenames.getOrDefault(x)
    if result == LitId(0):
      let p = msgs.toFullPath(ir.sh.config, x)
      result = getOrIncl(ir.sh.strings, p)
      c.filenames[x] = result
    c.lastFile = x
    c.lastLit = result

proc toPackedInfo(x: TLineInfo; ir: var PackedTree; c: var Context): PackedLineInfo =
  PackedLineInfo(line: x.line, col: x.col, file: toLitId(x.fileIndex, ir, c))

proc toPackedType(t: PType; ir: var PackedTree; c: var Context): TypeId =
  result = TypeId(0)

proc toPackedSym(s: PSym; ir: var PackedTree; c: var Context): SymId =
  result = SymId(0)

proc toPackedSymNode(n: PNode; ir: var PackedTree; c: var Context) =
  assert n.kind == nkSym
  let t = toPackedType(n.typ, ir, c)

  if n.sym.itemId.module == c.thisModule:
    # it is a symbol that belongs to the module we're currently
    # packing:
    let sid = toPackedSym(n.sym, ir, c)
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: int32(sid),
      typeId: t, info: toPackedInfo(n.info, ir, c))
  else:
    # store it as an external module reference:
    #  nkModuleRef
    discard


proc toPackedNode*(n: PNode; ir: var PackedTree; c: var Context) =
  template toP(x: TLineInfo): PackedLineInfo = toPackedInfo(x, ir, c)

  case n.kind
  of nkNone, nkEmpty, nkNilLit:
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: 0,
      typeId: toPackedType(n.typ, ir, c), info: toP n.info)
  of nkIdent:
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: int32 getOrIncl(ir.sh.strings, n.ident.s),
      typeId: toPackedType(n.typ, ir, c), info: toP n.info)
  of nkSym:
    toPackedSymNode(n, ir, c)
  of directIntLit:
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: int32(n.intVal),
      typeId: toPackedType(n.typ, ir, c), info: toP n.info)
  of externIntLit:
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: int32 getOrIncl(ir.sh.integers, n.intVal),
      typeId: toPackedType(n.typ, ir, c), info: toP n.info)
  of nkStrLit..nkTripleStrLit:
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: int32 getOrIncl(ir.sh.strings, n.strVal),
      typeId: toPackedType(n.typ, ir, c), info: toP n.info)
  of nkFloatLit..nkFloat128Lit:
    ir.nodes.add Node(kind: n.kind, flags: n.flags, operand: int32 getOrIncl(ir.sh.floats, n.floatVal),
      typeId: toPackedType(n.typ, ir, c), info: toP n.info)
  else:
    let patchPos = ir.prepare(n.kind, n.flags, toPackedType(n.typ, ir, c), toP n.info)
    for i in 0..<n.len:
      toPackedNode(n[i], ir, c)
    ir.patch patchPos

proc moduleToIr*(n: PNode; ir: var PackedTree; module: PSym) =
  var c = Context(thisModule: module.itemId.module)
  toPackedNode(n, ir, c)