-- MixMasterMXCode.mesa
DIRECTORY Ascii, Atom, EditSpan, FS, IO, PFS, RefText, Rope, Scheme, TextEdit, TextNode, TiogaIO;
MixMasterMXCode: CEDAR PROGRAM
IMPORTS Ascii, Atom, EditSpan, FS, IO, PFS, RefText, Rope, Scheme, TextEdit, TextNode, TiogaIO
= BEGIN OPEN Scheme;
  SymbolFromRope: PROC [rope: Rope.ROPE] RETURNS [Symbol] ~ {RETURN[Atom.MakeAtom[rope]]};
  RopeFromSymbol: PROC [Symbol] RETURNS [Rope.ROPE] ~ Atom.GetPName;
  TheSymbol: PROC [a: Any] RETURNS [Scheme.Symbol] = {
    WITH a SELECT FROM
      a: Scheme.Symbol => RETURN [a];
      ENDCASE => Complain[a, "not a Scheme.Symbol"];
    };
  TheRefTextNode: PROC [a: Any] RETURNS [TextEdit.RefTextNode] = {
    WITH a SELECT FROM
      a: TextEdit.RefTextNode => RETURN [a];
      ENDCASE => Complain[a, "not a TextEdit.RefTextNode"];
    };
  MixMasterPrim: PROC [SELF: Primitive, ARG1,ARG2,ARG3: Any, REST: ProperList] RETURNS [result: Any ← unspecified] = {
INNER: PROC = {
    POP: PROC RETURNS [a: Any ← undefined] = {
      IF REST#NIL THEN {a ← REST.car; REST ← NARROW[REST.cdr]}};
    DATA: Pair ~ NARROW[SELF.data];
    env: Environment ~ NARROW[DATA.cdr];
    SELECT NAT[NARROW[DATA.car, REF INT]↑] FROM
      20 => {
        symbol: Any ← ARG1;
        text: REF TEXT ← RefText.ObtainScratch[100];
        j: NAT ← 0;
        changed: BOOL ← FALSE;
        text ← RefText.AppendRope[text, Atom.GetPName[TheSymbol[symbol]]];
        FOR i: NAT IN [0..text.length) DO
        SELECT text[i] FROM
        '? => {text[j] ← 'P; changed ← TRUE; j ← j+1 };
        IN ['a..'z], IN ['A..'Z], IN ['0..'9] => { text[j] ← text[i]; j ← j+1 };
        ENDCASE => {
        changed ← TRUE;
        IF i+1 < text.length THEN text[i+1] ← Ascii.Upper[text[i+1]];
        };
        ENDLOOP;
        text.length ← j;
        IF changed
        THEN {result ← StringFromRope[Atom.GetPName[Atom.MakeAtomFromRefText[rt: text]]]}
        ELSE result ← symbol;
        RefText.ReleaseScratch[text];
        };
      19 => {
        tiogaNode: Any ← ARG1;
        result ← MakeFixnum[TextNode.Level[TheRefTextNode[tiogaNode]]];
        };
      18 => {
        tiogaNode: Any ← ARG1;
        result ← IF TheRefTextNode[tiogaNode].comment THEN true ELSE false;
        };
      17 => {
        tiogaNode: Any ← ARG1;
        result ← TheRefTextNode[tiogaNode].format;
        IF result = NIL THEN result ← $default;
        };
      16 => {
        tiogaNode: Any ← ARG1;
        result ← StringFromRope[TheRefTextNode[tiogaNode].rope];
        };
      15 => {
        destNode: Any ← ARG1;
        string: Any ← ARG2;
        format: Any ← ARG3;
        dstNode: TextNode.Ref = TheRefTextNode[destNode];
        srcNode: TextNode.Ref = TextEdit.FromRope[RopeFromString[TheString[string]]];
        srcRoot: TextNode.Ref = TextEdit.DocFromNode[srcNode];
        copy: TextNode.Span = EditSpan.Copy[destRoot: TextNode.Root[dstNode], sourceRoot: srcRoot, dest: TextNode.MakeNodeLoc[dstNode], source: TextNode.MakeNodeSpan[first: srcNode, last: srcNode], where: sibling, nesting: 0];
        IF format # undefined THEN copy.start.node.format ← TheSymbol[format];
        result ← copy.start.node;
        };
      14 => {
        destNode: Any ← ARG1;
        string: Any ← ARG2;
        format: Any ← ARG3;
        dstNode: TextNode.Ref = TheRefTextNode[destNode];
        srcNode: TextNode.Ref = TextEdit.FromRope[RopeFromString[TheString[string]]];
        srcRoot: TextNode.Ref = TextEdit.DocFromNode[srcNode];
        copy: TextNode.Span = EditSpan.Copy[destRoot: TextNode.Root[dstNode], sourceRoot: srcRoot, dest: TextNode.MakeNodeLoc[dstNode], source: TextNode.MakeNodeSpan[first: srcNode, last: srcNode], where: child, nesting: 1];
        IF format # undefined THEN copy.start.node.format ← TheSymbol[format];
        result ← copy.start.node;
        };
      13 => {
        destNode: Any ← ARG1;
        sourceNode: Any ← ARG2;
        dstNode: TextNode.Ref = TheRefTextNode[destNode];
        srcNode: TextNode.Ref = TheRefTextNode[sourceNode];
        src: TextNode.Span = TextNode.MakeNodeSpan[first: srcNode, last: srcNode];
        copy: TextNode.Span = EditSpan.Copy[destRoot: TextNode.Root[dstNode], sourceRoot: TextNode.Root[srcNode], dest: TextNode.MakeNodeLoc[dstNode], source: src, where: sibling, nesting: 0];
        result ← copy.start.node;
        };
      12 => {
        destNode: Any ← ARG1;
        sourceNode: Any ← ARG2;
        dstNode: TextNode.Ref = TheRefTextNode[destNode];
        srcNode: TextNode.Ref = TheRefTextNode[sourceNode];
        src: TextNode.Span = TextNode.MakeNodeSpan[first: srcNode, last: TextNode.LastWithin[srcNode]];
        copy: TextNode.Span = EditSpan.Copy[destRoot: TextNode.Root[dstNode], sourceRoot: TextNode.Root[srcNode], dest: TextNode.MakeNodeLoc[dstNode], source: src, where: sibling, nesting: 0];
        result ← copy.start.node;
        };
      11 => {
        patternRootNode: Any ← ARG1;
        content: TextNode.Ref ← TextEdit.FromRope[""];
        new: TextNode.Ref ← TextEdit.DocFromNode[content];
        IF patternRootNode # undefined THEN EditSpan.Inherit[old: TheRefTextNode[patternRootNode], new: new, allprops: TRUE];
        result ← content;
        };
      10 => {
        tiogaNode: Any ← ARG1;
        result ← TextNode.Root[TheRefTextNode[tiogaNode]];
        };
      9 => {
        tiogaNode: Any ← ARG1;
        child: TextNode.Ref = TextNode.FirstChild[TheRefTextNode[tiogaNode]];
        result ← IF child = NIL THEN false ELSE child;
        };
      8 => {
        tiogaNode: Any ← ARG1;
        next: TextNode.Ref = TextNode.Next[TheRefTextNode[tiogaNode]];
        result ← IF next = NIL THEN false ELSE next;
        };
      7 => {
        tiogaNode: Any ← ARG1;
        next: TextNode.Ref = TextNode.StepForward[node: TheRefTextNode[tiogaNode]];
        result ← IF next = NIL THEN false ELSE next;
        };
      6 => {
        tiogaRoot: Any ← ARG1;
        s: IO.STREAM ~ IO.ROS[];
        TiogaIO.PutDoc[s, IO.noWhereStream, IO.noWhereStream, TextNode.Root[TheRefTextNode[tiogaRoot]]];
        result ← StringFromRope[IO.RopeFromROS[s]];
        };
      5 => {
        filenameString: Any ← ARG1;
        tiogaNode: Any ← ARG2;
        result ← MakeFixnum[TiogaIO.ToFile[fileName: ThePath[filenameString], root: TextNode.Root[TheRefTextNode[tiogaNode]]].dataLen];
        };
      4 => {
        filenameString: Any ← ARG1;
        result ← TiogaIO.FromFile[fileName: ThePath[filenameString]].root;
        };
      3 => {
        filenameString: Any ← ARG1;
        fullFName: ROPE;
        cp: FS.ComponentPositions;
        dirOmitted: BOOL;
        [fullFName: fullFName, cp: cp, dirOmitted: dirOmitted] ← FS.ExpandName[RopeFromString[TheString[filenameString]]];
        result ← IF cp.ext.length = 0 AND cp.ext.start = cp.base.start+cp.base.length THEN false ELSE StringFromRope[Rope.Substr[fullFName, cp.ext.start, cp.ext.length]];
        };
      2 => {
        filenameString: Any ← ARG1;
        fullFName: ROPE;
        cp: FS.ComponentPositions;
        dirOmitted: BOOL;
        [fullFName: fullFName, cp: cp, dirOmitted: dirOmitted] ← FS.ExpandName[RopeFromString[TheString[filenameString]]];
        result ← StringFromRope[Rope.Substr[fullFName, cp.base.start, cp.base.length]];
        };
      1 => {
        filenameString: Any ← ARG1;
        FS.Delete[name: RopeFromString[TheString[filenameString]]];
        };
      0 => {
        patternString: Any ← ARG1;
        head: Pair ~ Cons[NIL, NIL];
        last: Pair ← head;
        EachName: FS.NameProc = {
        new: Pair ~ Cons[StringFromRope[fullFName], NIL];
        last.cdr ← new;
        last ← new;
        RETURN [TRUE]
        };
        FS.EnumerateForNames[pattern: RopeFromString[TheString[patternString]], proc: EachName, wDir: NIL];
        result ← head.cdr;
        head.cdr ← NIL;
        last ← NIL;
        };
      ENDCASE => ERROR
    }; INNER[!
        PFS.Error => {
        IF error.group = user THEN Complain[error.code, error.explanation];
        };
    ];
    };
    
  MixMasterInit: PROC [env: Environment] = {
    DefinePrimitive[name: "cedarfy-symbol", nArgs: 1, proc: MixMasterPrim, doc: "(symbol) Translates dash-containing symbol into nonDashContaining symbol or string", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[20], env]];
    DefinePrimitive[name: "tioga-level", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) returns the level of the node", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[19], env]];
    DefinePrimitive[name: "tioga-comment?", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) says whether tioga-node is a comment", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[18], env]];
    DefinePrimitive[name: "tioga-format", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) returns the format symbol of Tioga node", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[17], env]];
    DefinePrimitive[name: "tioga-text", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) returns the text contents of the node", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[16], env]];
    DefinePrimitive[name: "tioga-insert-text-as-sibling!", nArgs: 3, proc: MixMasterPrim, doc: "(dest-node string format) insert a new node as a sibling", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[15], env]];
    DefinePrimitive[name: "tioga-insert-text-as-child!", nArgs: 3, proc: MixMasterPrim, doc: "(dest-node string format) insert a new Tioga node as a child", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[14], env]];
    DefinePrimitive[name: "tioga-copy-node!", nArgs: 2, proc: MixMasterPrim, doc: "(dest-node source-node) copy a node to a new place (returns copied node)", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[13], env]];
    DefinePrimitive[name: "tioga-copy-branch!", nArgs: 2, proc: MixMasterPrim, doc: "(dest-node source-node) copy a branch to a new place (returns copied branch)", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[12], env]];
    DefinePrimitive[name: "tioga-create-doc", nArgs: 1, proc: MixMasterPrim, doc: "([ pattern-root-node ]) Make a new Tioga document", env: env, optional: 1, dotted: FALSE, data: Cons[MakeFixnum[11], env]];
    DefinePrimitive[name: "tioga-root", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) Return the root node of a Tioga document", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[10], env]];
    DefinePrimitive[name: "tioga-child", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) Return the first child node or #f", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[9], env]];
    DefinePrimitive[name: "tioga-sibling", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) Return the next sibling node or #f", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[8], env]];
    DefinePrimitive[name: "tioga-forward", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-node) Return the next Tioga node in the document, or #f", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[7], env]];
    DefinePrimitive[name: "tioga->string", nArgs: 1, proc: MixMasterPrim, doc: "(tioga-root) Makes a string of the content portion of a Tioga document", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[6], env]];
    DefinePrimitive[name: "tioga-file-write", nArgs: 2, proc: MixMasterPrim, doc: "(filename-string tioga-node) Write a Tioga document", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[5], env]];
    DefinePrimitive[name: "tioga-file-read", nArgs: 1, proc: MixMasterPrim, doc: "(filename-string) Read a Tioga document", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[4], env]];
    DefinePrimitive[name: "filename-ext", nArgs: 1, proc: MixMasterPrim, doc: "(filename-string) return the extension of the filename, or #f if not present", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[3], env]];
    DefinePrimitive[name: "filename-base", nArgs: 1, proc: MixMasterPrim, doc: "(filename-string) return the base of the filename", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[2], env]];
    DefinePrimitive[name: "file-delete", nArgs: 1, proc: MixMasterPrim, doc: "(filename-string) delete a file", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[1], env]];
    DefinePrimitive[name: "file-list", nArgs: 1, proc: MixMasterPrim, doc: "(pattern-string) return a list of file name strings matching pattern-string", env: env, optional: 0, dotted: FALSE, data: Cons[MakeFixnum[0], env]];
    };
    
  ROPE: TYPE ~ Rope.ROPE;
  ThePath: PROC [any: Any] RETURNS [PFS.PATH] ~ {RETURN[PFS.PathFromRope[RopeFromString[TheString[any]]]]};
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  RegisterInit[MixMasterInit];
END.