File: sourceMap.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (115 lines) | stat: -rw-r--r-- 4,120 bytes parent folder | download | duplicates (5)
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
115
structure SourceMapping :> SOURCE_MAPPING =
struct

  type charpos = int

  type region = charpos * charpos

  datatype location = LOC of {srcFile   : UniqueSymbol.symbol,
                              beginLine : int,
                              beginCol  : int,
                              endLine   : int,
                              endCol    : int
                             }
  datatype state = STATE of {lineNum : int,
                             file    : UniqueSymbol.symbol, 
                             charPos : charpos
                            }

  datatype sourcemap = SOURCEMAP of
          { linePos  : charpos list ref,
            filePos  : {linePos:charpos list, 
                        line   :int,
                        srcFile:UniqueSymbol.symbol} list ref,
            lineNum  : int ref
          }

  val dummyLoc = LOC{srcFile=UniqueSymbol.fromString "???", 
                     beginLine=1,beginCol=1,
                     endLine=1,endCol=1}
  fun newmap{srcFile} = SOURCEMAP
         { linePos = ref [0],
           filePos = ref [{linePos=[],line=1,
                           srcFile=UniqueSymbol.fromString srcFile}],
           lineNum = ref 1
         }

  fun newline (SOURCEMAP{linePos,lineNum,...}) pos =
      (linePos := pos :: !linePos; lineNum := 1 + !lineNum)

  fun state(SOURCEMAP{linePos,lineNum,filePos, ...}) =
      let val {srcFile, ...} = hd(! filePos)
          val charPos        = hd(! linePos)
          val lineNum        = ! lineNum
      in  STATE{file=srcFile, charPos=charPos, lineNum=lineNum} end

  fun resynch (SOURCEMAP{linePos,filePos,lineNum,...}) {pos,srcFile,line} =
      (filePos := {linePos= !linePos,
                   line= !lineNum,
                   srcFile=UniqueSymbol.fromString srcFile
                  } :: !filePos;
       linePos := [pos];
       lineNum := line
      )
  fun reset srcMap (STATE{file, lineNum, charPos}) =
     (print(UniqueSymbol.toString file^" "^Int.toString lineNum^"\n");
      resynch srcMap {pos=charPos,
                      srcFile=UniqueSymbol.toString file, line=lineNum} 
     )

  fun parseDirective sourceMap (pos,directive) =
      let fun sep #" "  = true
            | sep #"\"" = true
            | sep #"#"  = true
            | sep #"\n" = true
            | sep _     = false
      in  case String.tokens sep directive of
            line::srcFile::_ =>
             (case Int.fromString line of
                 SOME line => 
                    resynch sourceMap {pos=pos,srcFile=srcFile,line=line}
              |  _ => newline sourceMap pos
             )
         | _ => newline sourceMap pos
      end

  fun currPos(SOURCEMAP{linePos,...}) = hd (!linePos)

  fun location(SOURCEMAP{linePos,filePos,lineNum,...}) (x,y) =
  let fun findPos(p,currPos,currFile,pos::rest,filePos,line) =
           if p > pos then
              {srcFile=currFile,line=line,column=p - pos}
           else findPos(p,pos,currFile,rest,filePos,line-1)
        | findPos(p,currPos,currFile,[],{linePos,line,srcFile}::filePos,_) =
           findPos(p,currPos,srcFile,linePos,filePos,line)
        | findPos(p,currPos,currFile,[],[],line) = 
            {srcFile=currFile,line=line,column=0}

      val {srcFile=currFile,...} = hd(!filePos)
      val {srcFile,line=l1,column=c1} = 
             findPos(x,x,currFile,!linePos,!filePos,!lineNum)
      val {srcFile,line=l2,column=c2} = 
             findPos(y,y,currFile,!linePos,!filePos,!lineNum)
  in  LOC{srcFile   = srcFile,
          beginLine = l1,
          beginCol  = c1,
          endLine   = l2,
          endCol    = c2
         }
  end

  fun toString(LOC{srcFile,beginLine,beginCol,endLine,endCol}) =
  let val int = Int.toString
  in  UniqueSymbol.toString srcFile^":"^int beginLine^"."^int beginCol^
           (if beginLine = endLine andalso beginCol = endCol then ""
            else "-"^int endLine^"."^int endCol)
  end

  fun directive(LOC{srcFile,beginLine,beginCol,endLine,endCol}) =
  let val int = Int.toString
  in  "(*#line "^int beginLine^"."^int beginCol^" \""^
        UniqueSymbol.toString srcFile^"\"*)"
  end

end