File: spec.sml

package info (click to toggle)
mlton 20100608-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 34,980 kB
  • ctags: 69,089
  • sloc: ansic: 18,421; lisp: 2,879; makefile: 1,570; sh: 1,325; pascal: 256; asm: 97
file content (114 lines) | stat: -rw-r--r-- 3,141 bytes parent folder | download | duplicates (7)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
(* spec.sml
 * 2005 Matthew Fluet (mfluet@acm.org)
 *  Adapted for MLton.
 *)

(*
 * spec.sml - A data structure describing the export interface of a
 *            C program.
 *
 *  (C) 2001, Lucent Technologies, Bell Labs
 *
 * author: Matthias Blume (blume@research.bell-labs.com)
 *)
structure Spec = struct

    datatype constness = RO | RW
    type tag = string

    datatype basic_ctype =
        SCHAR | UCHAR 
      | SSHORT | USHORT 
      | SINT | UINT 
      | SLONG | ULONG
      | SLONGLONG | ULONGLONG
      | FLOAT | DOUBLE

    datatype ctype =
        BASIC of basic_ctype
      | VOIDPTR
      | STRUCT of tag
      | UNION of tag
      | ENUM of tag * bool
      | FPTR of cft
      | PTR of cobj
      | ARR of { t: ctype, d: int, esz: int }
      | UNIMPLEMENTED of string

    withtype cft = { args: ctype list, res: ctype option }

    and cobj = constness * ctype

    datatype fieldspec =
        OFIELD of { offset: int, spec: cobj, synthetic: bool }
      | SBF of { offset: int, constness: constness, bits: word, shift: word }
      | UBF of { offset: int, constness: constness, bits: word, shift: word }

    type field = { name: string, spec: fieldspec }

    type s =
         { src: string,
           tag: tag, 
           anon: bool, 
           size: word, 
           fields: field list,
           exclude: bool }
    type u =
         { src: string,
           tag: tag, 
           anon: bool, 
           size: word, 
           all: field list,
           exclude: bool }

    type gty = { src: string, name: string, spec: ctype }

    type gvar = { src: string, name: string, spec: cobj }

    type gfun = { src: string,
                  name: string, 
                  spec: cft, 
                  argnames: string list option }

    type enumval = { name: string, spec: LargeInt.int }

    type enum = { src: string,
                  tag: tag, 
                  anon: bool, 
                  descr: string, 
                  spec: enumval list,
                  exclude: bool }

    type spec = { structs: s list,
                  unions: u list,
                  gtys: gty list,
                  gvars: gvar list,
                  gfuns: gfun list,
                  enums: enum list }

    fun join (x: spec, y: spec) = let
        fun uniq sel = let
            fun loop ([], a) = rev a
              | loop (h :: t, a) =
                loop (t, if List.exists
                                (fn x => (sel x : string) = sel h) a then a
                         else h :: a)
        in
            loop
        end
    in
        { structs = uniq #tag (#structs x, #structs y),
          unions = uniq #tag (#unions x, #unions y),
          gtys = uniq #name (#gtys x, #gtys y),
          gvars = uniq #name (#gvars x, #gvars y),
          gfuns = uniq #name (#gfuns x, #gfuns y),
          enums = uniq #tag (#enums x, #enums y) } : spec
    end

    val empty : spec = { structs = [], 
                         unions = [], 
                         gtys = [], 
                         gvars = [],
                         gfuns = [], 
                         enums = [] }
end