# HG changeset patch # User Adam Chlipala # Date 1261690509 18000 # Node ID e7707995330858ad49fde4dbccee2fb77ba3b635 # Parent f1647f16097d9393a2cbed9def95dedb9dc43c80 Module roots diff -r f1647f16097d -r e77079953308 src/compiler.sig --- a/src/compiler.sig Thu Dec 24 15:49:52 2009 -0500 +++ b/src/compiler.sig Thu Dec 24 16:35:09 2009 -0500 @@ -157,5 +157,6 @@ val debug : bool ref val addPath : string * string -> unit + val addModuleRoot : string * string -> unit end diff -r f1647f16097d -r e77079953308 src/compiler.sml --- a/src/compiler.sml Thu Dec 24 15:49:52 2009 -0500 +++ b/src/compiler.sml Thu Dec 24 16:35:09 2009 -0500 @@ -643,9 +643,24 @@ fun capitalize "" = "" | capitalize s = str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE) +structure SM = BinaryMapFn(struct + type ord_key = string + val compare = String.compare + end) + +val moduleRoots = ref ([] : (string * string) list) +fun addModuleRoot (k, v) = moduleRoots := (k, v) :: !moduleRoots + +structure SS = BinarySetFn(struct + type ord_key = string + val compare = String.compare + end) + val parse = { func = fn {database, sources = fnames, ffi, ...} : job => let + val mrs = !moduleRoots + val anyErrors = ref false fun checkErrors () = anyErrors := (!anyErrors orelse ErrorMsg.anyErrors ()) fun nameOf fname = capitalize (OS.Path.file fname) @@ -665,6 +680,8 @@ (Source.DFfiStr (mname, sgn), loc) end + val defed = ref SS.empty + fun parseOne fname = let val mname = nameOf fname @@ -686,13 +703,51 @@ last = ErrorMsg.dummyPos} val ds = #func parseUr ur + val d = (Source.DStr (mname, sgnO, (Source.StrConst ds, loc)), loc) + + val d = case List.find (fn (root, name) => + String.isPrefix (root ^ "/") fname) mrs of + NONE => d + | SOME (root, name) => + let + val fname = String.extract (fname, size root + 1, NONE) + val pieces = name :: String.tokens (fn ch => ch = #"/") fname + val pieces = List.filter (fn s => size s > 0 + andalso Char.isAlpha (String.sub (s, 0))) + pieces + val pieces = map capitalize pieces + + fun makeD prefix pieces = + case pieces of + [] => (ErrorMsg.error "Empty module path"; + (Source.DStyle "Boo", loc)) + | [_] => d + | piece :: pieces => + let + val this = prefix ^ "." ^ piece + val old = SS.member (!defed, this) + in + defed := SS.add (!defed, this); + (Source.DStr (piece, NONE, + (Source.StrConst (if old then + [(Source.DOpen (piece, []), + loc), + makeD prefix pieces] + else + [makeD prefix pieces]), loc)), + loc) + end + in + makeD "" pieces + end in checkErrors (); - (Source.DStr (mname, sgnO, (Source.StrConst ds, loc)), loc) + d end val dsFfi = map parseFfi ffi val ds = map parseOne fnames + val loc = ErrorMsg.dummySpan in if !anyErrors then ErrorMsg.error "Parse failure" @@ -703,11 +758,13 @@ val final = nameOf (List.last fnames) val ds = dsFfi @ ds - @ [(Source.DExport (Source.StrVar final, ErrorMsg.dummySpan), ErrorMsg.dummySpan)] + @ [(Source.DExport (Source.StrVar final, loc), loc)] + + val ds = case database of + NONE => ds + | SOME s => (Source.DDatabase s, loc) :: ds in - case database of - NONE => ds - | SOME s => (Source.DDatabase s, ErrorMsg.dummySpan) :: ds + ds end handle Empty => ds end, print = SourcePrint.p_file