MODULE*IMPORT M3AST_AS_F;*M3CPragma EXPORTSM3CPragma ,M3CPragmaF ; IMPORT Text, TextExtras, ASCII; IMPORT M3AST_AS; IMPORT M3CSrcPos;
PROCEDURENewStore (): Store RAISES {}= BEGIN RETURN NEW(Store); END NewStore; PROCEDUREAddToStore ( body: Text.T; pos: M3CSrcPos.T; precedingNode: M3AST_AS.SRC_NODE; VAR store: Store) : T RAISES {}= VAR new := NEW(Iter, pos := pos, body := body, precedingNode := precedingNode); BEGIN WITH last = store.last DO IF last = NIL THEN store.first := new; ELSE last.next := new; new.prev := last; END; last := new; END; RETURN new; END AddToStore; PROCEDUREAddFollowingNode ( followingNode: M3AST_AS.SRC_NODE; store: Store) RAISES {}= VAR t := store.last; precedingNode := t.precedingNode; BEGIN REPEAT t.followingNode := followingNode; t := t.prev; UNTIL t = NIL OR t.precedingNode # precedingNode; END AddFollowingNode; PROCEDUREAddPrecedingStmOrDecl ( stmOrDecl: M3AST_AS.SRC_NODE; store: Store) RAISES {}= VAR t := store.last; precedingNode := t.precedingNode; BEGIN WHILE t # NIL AND t.precedingNode = precedingNode AND t.precedingStmOrDecl = NIL DO t.precedingStmOrDecl := stmOrDecl; t := t.prev; END; END AddPrecedingStmOrDecl; PROCEDURENewIter (ps: Store; after := M3CSrcPos.Null): Iter RAISES {}= BEGIN IF ps = NIL THEN RETURN NIL END; IF after = M3CSrcPos.Null OR ps.first = NIL OR M3CSrcPos.Compare(ps.first.pos, after) > 0 THEN RETURN ps.first; ELSE VAR t := ps.last; BEGIN LOOP IF M3CSrcPos.Compare(t.pos, after) <= 0 THEN RETURN t.next; ELSE t := t.prev; END; END; END; END; END NewIter; PROCEDURENext (VAR iter: Iter; VAR t: T): BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; t := iter; iter := iter.next; RETURN TRUE; END Next; PROCEDUREPosition (t: T): M3CSrcPos.T RAISES {}= BEGIN RETURN t.pos; END Position; PROCEDUREBody (t: T): Text.T RAISES {}= BEGIN RETURN t.body; END Body; PROCEDUREMatch (t: T; keyword: Text.T; VAR args: Text.T): BOOLEAN RAISES {}= VAR body := t.body; pos: CARDINAL := 2; length := Text.Length(keyword); startOfClosingBracket := Text.Length(body) - 2; BEGIN IF TextExtras.FindCharSet(body, ASCII.All - ASCII.Spaces, pos) THEN IF pos + length > startOfClosingBracket THEN RETURN FALSE END; FOR i := 0 TO length - 1 DO IF Text.GetChar(keyword, i) # Text.GetChar(body, pos + i) THEN RETURN FALSE; END; END; INC(pos, length); IF pos = startOfClosingBracket THEN args := NIL; RETURN TRUE; ELSIF NOT Text.GetChar(body, pos) IN ASCII.Spaces THEN RETURN FALSE ELSE INC(pos); IF TextExtras.FindCharSet(body, ASCII.All - ASCII.Spaces, pos) THEN IF pos >= startOfClosingBracket THEN args := NIL; ELSE VAR end := startOfClosingBracket - 1; BEGIN WHILE Text.GetChar(body, end) IN ASCII.Spaces DO DEC(end); END; args := TextExtras.Extract(body, pos, end + 1); END; END; (* if *) END; RETURN TRUE; END; (* if *) ELSE RETURN FALSE; END; (* if *) END Match; PROCEDUREHook (t: T): REFANY RAISES {}= BEGIN RETURN t.hook; END Hook; PROCEDURESetHook (t: T; hook: REFANY) RAISES {}= BEGIN t.hook := hook; END SetHook; PROCEDUREAfterNode ( store: Store; node: M3AST_AS.SRC_NODE) : Iter RAISES {}= BEGIN IF store = NIL THEN RETURN NIL END; VAR search := store.first; BEGIN WHILE search # NIL DO IF search.precedingNode = node THEN RETURN search END; search := search.next; END; RETURN NIL; END; END AfterNode; PROCEDUREBeforeNode ( store: Store; node: M3AST_AS.SRC_NODE) : Iter RAISES {}= BEGIN IF store = NIL THEN RETURN NIL END; VAR search := store.first; BEGIN WHILE search # NIL DO IF search.followingNode = node THEN RETURN search END; search := search.next; END; RETURN NIL; END; END BeforeNode; PROCEDUREAfterStmOrDecl ( store: Store; stmOrDecl: M3AST_AS.SRC_NODE) : Iter RAISES {}= BEGIN IF store = NIL THEN RETURN NIL END; VAR search := store.first; BEGIN WHILE search # NIL DO IF search.precedingStmOrDecl = stmOrDecl THEN RETURN search END; search := search.next; END; RETURN NIL; END; END AfterStmOrDecl; PROCEDUREPrecedingNode (t: T): M3AST_AS.SRC_NODE RAISES {}= BEGIN RETURN t.precedingNode; END PrecedingNode; PROCEDUREFollowingNode (t: T): M3AST_AS.SRC_NODE RAISES {}= BEGIN RETURN t.followingNode; END FollowingNode; PROCEDUREPrecedingStmOrDecl (t: T): M3AST_AS.SRC_NODE RAISES {}= BEGIN RETURN t.precedingStmOrDecl; END PrecedingStmOrDecl; BEGIN END M3CPragma.