-
Notifications
You must be signed in to change notification settings - Fork 2
/
String.m
138 lines (126 loc) · 2.9 KB
/
String.m
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
MODULE String;
IMPORT Std;
TYPE STRING* = POINTER TO StringRec;
StringRec*= RECORD (Std.ObjectRec)
str* : POINTER TO ARRAY OF CHAR;
len* : INTEGER;
END;
PROCEDURE String*(c: ARRAY OF CHAR) : STRING;
VAR i: INTEGER;
s: STRING;
BEGIN
NEW(s);
s.len := LEN(c);
NEW(s.str, s.len);
FOR i := 0 TO s.len - 1 DO
s.str^[i] := c[i];
END;
RETURN s;
END String;
PROCEDURE (this: STRING) CompareTo*(that: Std.OBJECT) : INTEGER;
BEGIN
IF this = that THEN
RETURN 0
ELSE
WITH
that : STRING DO
IF this.str^ = that.str^ THEN
RETURN 0
ELSIF this.str^ < that.str^ THEN
RETURN -1
ELSE
RETURN 1
END
ELSE
RETURN 1
END
END
END CompareTo;
PROCEDURE (s: STRING) Length*() : INTEGER;
BEGIN
RETURN s.len;
END Length;
PROCEDURE (s: STRING) Insert*(pos: INTEGER; c: STRING);
VAR str : POINTER TO ARRAY OF CHAR;
i, len : INTEGER;
BEGIN
len := s.len;
NEW(str, len);
FOR i := 0 TO len - 1 DO
str[i] := s.str[i];
END;
NEW(s.str, len + c.len - 1);
(* Head *)
FOR i := 0 TO pos - 1 DO
s.str[i] := str[i];
END;
(* Insert *)
FOR i := 0 TO c.len - 1 DO
s.str[i + pos] := c.str[i];
END;
(* Tail *)
FOR i := pos TO len - 1 DO
s.str[i + c.len - 1] := str[i];
END;
s.len := len + c.len - 1;
END Insert;
PROCEDURE (s: STRING) Append*(c: STRING);
BEGIN
s.Insert(s.len - 1, c);
END Append;
PROCEDURE (s: STRING) Delete*(start, length: INTEGER);
VAR str : POINTER TO ARRAY OF CHAR;
i, len : INTEGER;
BEGIN
len := s.len;
NEW(str, len);
FOR i := 0 TO len - 1 DO
str[i] := s.str[i];
END;
NEW(s.str, len - length);
(* Head *)
FOR i := 0 TO start - 1 DO
s.str[i] := str[i];
END;
(* Tail *)
FOR i := start + length TO len - 1 DO
s.str[i - length] := str[i];
END;
s.len := len - length;
END Delete;
PROCEDURE (s: STRING) Pos*(c: STRING) : INTEGER;
VAR i, j : INTEGER;
found: BOOLEAN;
BEGIN
FOR i := 0 TO s.len - c.len DO
IF s.str[i] = c.str[0] THEN
found := TRUE;
FOR j := 0 TO c.len - 2 DO
IF s.str[i + j] # c.str[j] THEN
found := FALSE;
END;
IF (j = c.len - 2) & found THEN
RETURN i;
END
END
END
END;
RETURN 0;
END Pos;
PROCEDURE (s: STRING) Clone*() : STRING;
VAR c : STRING;
i : INTEGER;
BEGIN
NEW(c);
c.len := s.len;
NEW(c.str, c.len);
FOR i := 0 TO s.len - 1 DO
c.str[i] := s.str[i]
END;
RETURN c
END Clone;
PROCEDURE (s: STRING) Substring*(start, length: INTEGER) : STRING;
BEGIN
RETURN s;
END Substring;
END String.