; ---------- SORTS -------------------------------------------- TYPE FSystem = Id -> X; X = File | Dir; File :: F: STR-list; Id = STR; Dir :: D: FSystem; Path = X-list; Paths = Path-list; ENDTYPE ; ---------- STATE ------------------------------------------- ; FS : FSystem; ; ---------- FUNCTIONS --------------------------------------- FUNC ls(fs:FSystem):Ids RETURNS dom(fs); FUNC allId(fs:FSystem):Ids RETURNS UNION({let(x=fs[i]) in if ( is-File(x) -> {i}, is-Dir(x) -> {i} U allId(D(x)) ) | i<-dom(fs)}); FUNC mkdir(fs:FSystem,i:Id,p:Path):FSystem RETURNS if p in dirs(fs) then (fs + (if p == <> then [i->Dir([])] else let(j=head(p), q=tail(p), sfs=D(fs[j])) in [j->Dir(mkdir(sfs,i,q))])) else fs; FUNC create(fs:FSystem,i:Id,f:File,p:Path):FSystem RETURNS if p in dirs(fs) then (fs + (if p == <> then [i->File(f)] else let(j=head(p), q=tail(p), sfs=D(fs[j])) in [j->Dir(create(sfs,i,f,q))])) else fs; FUNC files(fs:FSystem):Paths RETURNS UNION({let (x=fs[i]) in if ( is-File(x) -> {}, is-Dir(x) -> { | p <- files(D(x))} ) | i<-dom(fs)}); FUNC dirs(fs:FSystem):Paths RETURNS {<>} U UNION({let (x=fs[i]) in if ( is-File(x) -> {}, is-Dir(x) -> { | p <- dirs(D(x))} ) | i<-dom(fs)}); FUNC applypath(fs:FSystem,p:Path):X RETURNS if p == <> then fs else let(j=head(p), q=tail(p), sfs=D(fs[j])) in applypath(sfs,q); ; ---------- EVENTS -------------------------------------------- FUNC FORMAT(): STATE fs <- []; FUNC VI(i:Id,f:File,p:Path): PRE p in dirs(fs) STATE fs <- create(fs,i,f,p); FUNC LS():Ids RETURNS ls(fs); FUNC CAT(p:Path):File PRE p in files(fs) RETURNS let (sfs =D(applypath(fs,tail(p)))) in F(sfs[head(p)]); FUNC MKDIR(i:Id,p:Path): PRE p in dirs(fs) STATE fs <- mkdir(fs,i,p);