summaryrefslogtreecommitdiff
path: root/symtab.fun
blob: 7518640536f522d86f66bc1608994c364c6fa67c (plain)
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
91
92
functor Symtab(H: HASHTABLE): SYMTAB = struct

  type 'token t =
    ((string * 'token option * 'token option) option Array.array
        * int H.t) ref

  type 'token auxInfo = 'token option * 'token option

  exception UnknownId

  fun init () =
  let
    val log = 20
    val h = H.createLog log
  in
    ref $ (Array.array (H.size h, NONE), h)
  end

  fun insert symtab idStr cl =
  let
    val (array, table) = !symtab

    val id = H.taken table
    val prev = H.insertIfNew table idStr id

    fun update id cl arg =
    let
      val (ppc, kw) = cl arg
    in
      Array.update (array, id, SOME (idStr, ppc, kw))
    end
  in
    case prev of
      NONE => (update id cl (NONE, NONE); id)
    | SOME id =>
        case Array.sub (array, id) of
          NONE => raise Unreachable
        | SOME (_, ppc, kw) => (update id cl (ppc, kw); id)
  end

  fun getId symtab idStr =
  let
    val (array, table) = !symtab
    val id = H.taken table
    val prev = H.insertIfNew table idStr id
  in
    case prev of
      NONE => (Array.update (array, id, SOME (idStr, NONE, NONE)); id)
    | SOME id => id
  end

  fun getAuxInfo symtab id =
  let
    val (array, _) = !symtab
  in
    case Array.sub (array, id) of
      NONE => raise UnknownId
    | SOME (_, ppc, kw) => (ppc, kw)
  end

  fun getStr symtab id =
  let
    val (array, _) = !symtab
  in
    case Array.sub (array, id) of
      NONE => raise UnknownId
    | SOME (str, _, _) => str
  end

  fun isPpcDir symtab id =
    case getAuxInfo symtab id of
      (SOME ppc, _) => SOME ppc
    | _ => NONE

  fun isKw symtab id =
    case getAuxInfo symtab id of
      (_, SOME kw) => SOME kw
    | _ => NONE

  fun print symtab =
  let
    val (array, _) = !symtab
    fun print idx =
      case Array.sub (array, idx) of
        NONE => printf `"\n" %
      | SOME (str, _, _) =>
          (printf I idx `": " `str `"\n" %; print (idx + 1))
  in
    printf `"Symbol table:\n" %;
    print 0
  end
end