summaryrefslogtreecommitdiff
path: root/symtab.fun
diff options
context:
space:
mode:
authorVladimir Azarov <avm@intermediate-node.net>2025-05-26 14:42:35 +0200
committerVladimir Azarov <avm@intermediate-node.net>2025-05-26 14:42:35 +0200
commit6f3fa80b37ca5f8d992f5d6f66aee77ead303bf4 (patch)
tree1d3099280e63fac03d906b24bc6b877840348eab /symtab.fun
parentc6b6203f8420f76a47433717eab8026d524ec5c1 (diff)
Symbol table
Diffstat (limited to 'symtab.fun')
-rw-r--r--symtab.fun92
1 files changed, 92 insertions, 0 deletions
diff --git a/symtab.fun b/symtab.fun
new file mode 100644
index 0000000..7518640
--- /dev/null
+++ b/symtab.fun
@@ -0,0 +1,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