commit 07bc628
shrub
·
2026-10-15 18:02:46 +0000 UTC
parent 8cb90de
use string buffer instead of allocating per character
+10,
-2
1@@ -1,5 +1,7 @@
2 #include "share/atspre_staload.hats"
3-staload IO = "libats/libc/SATS/stdio.sats"
4+staload "libats/libc/SATS/stdio.sats"
5+staload "libats/SATS/stringbuf.sats"
6+staload "libats/DATS/stringbuf.dats"
7 staload "scan.sats"
8 staload "parse.sats"
9
10@@ -9,12 +11,18 @@ let
11 (* initialize the scanner *)
12 var s: scanner = @{
13 file = manifest,
14- cur = $IO.fgetc0(manifest),
15+ buf = stringbuf_make_nil(i2sz(64)),
16+ cur = fgetc0(manifest),
17 line = 1,
18 col = 1 }
19 val result = parse(s, nil_vt(), nil_vt(), nil_vt())
20 in
21 printrule(result.rules);
22 manifest_free(result);
23+ let
24+ val @{file = _, buf = buf, cur = _, line = _, col = _} = s
25+ in
26+ stringbuf_free(buf)
27+ end;
28 fileref_close(manifest)
29 end
+39,
-60
1@@ -1,21 +1,30 @@
2 #include "share/atspre_staload.hats"
3 #define ATS_DYNLOADFLAG 0
4-staload IO = "libats/libc/SATS/stdio.sats"
5+staload "libats/libc/SATS/stdio.sats"
6+staload "libats/SATS/stringbuf.sats"
7+staload "libats/DATS/stringbuf.dats"
8 staload "scan.sats"
9
10 exception ScanErr of ()
11
12 (*get one character from a file and return the corresponding int*)
13 fun char (manifest: FILEref): int =
14- $IO.fgetc0(manifest)
15+ fgetc0(manifest)
16
17-(* stuff ninja allows *)
18 fun isnamec(c: int): bool =
19 isalnum(c) ||
20 (c = char2int0('_')) ||
21 (c = char2int0('-')) ||
22 (c = char2int0('.'))
23
24+fun isvaluec(c: int): bool =
25+ (c != char2int0('\n'))
26+
27+fun ispathc(c: int): bool =
28+ (c != char2int0('\n')) &&
29+ (c != char2int0 (' ')) &&
30+ (c != char2int0 (':'))
31+
32 implement next(s) (*void*) =
33 ((if s.cur = char2int0('\n') then (
34 s.line := s.line + 1;
35@@ -23,34 +32,31 @@ implement next(s) (*void*) =
36 else s.col := s.col +1);
37 s.cur := char(s.file))
38
39-fun name(s: &scanner, chars: List0_vt(charNZ)): List0_vt(charNZ) =
40- if (s.cur >= 0) && isnamec(s.cur) then
41+fun read(s: &scanner, allowed: (int) -<fun1> bool): void =
42+ if (s.cur >= 0) && allowed(s.cur) then
43 let
44- val c = g1ofg0_char(int2char0(s.cur))
45+ val c = g1ofg0_char(int2char0(s.cur))
46 in
47 if c != '\000' then
48 let
49- val more = cons_vt(c, chars);
50+ val inserted = stringbuf_insert_char(s.buf, c);
51 in
52- next(s);
53- name(s, more)
54- end
55- else list_vt_reverse(chars)
56+ if inserted = 1 then (
57+ next(s);
58+ read(s, allowed) )
59+ else $raise ScanErr
60+ end
61+ else ()
62 end
63- else list_vt_reverse(chars)
64+ else ()
65
66-(* list of chars to string pointer *)
67-fun c2s(chars: List0_vt(charNZ)): Strptr1 =
68-let
69- val text = string_make_list_vt(chars)
70- prval () = lemma_strnptr_param(text)
71-in
72- strnptr2strptr(text)
73-end
74
75-(* do name with the initialized scanner and a fresh list *)
76 implement scanname(s) (*Strptr1*)=
77- c2s(name(s, nil_vt()))
78+let
79+ val () = read(s, isnamec)
80+in
81+ stringbuf_takeout_all(s.buf)
82+end
83
84 implement skipspace(s) (*void*) =
85 if (s.cur = char2int0(' ')) then (
86@@ -106,43 +112,16 @@ implement scankeyword(s) =
87 else (prerrln!("expected name at ",s.line, ":", s.col);
88 $raise ScanErr())
89
90-fun value(s: &scanner, chars: List0_vt(charNZ)): List0_vt(charNZ) =
91- if (s.cur >=0) && (s.cur != char2int0('\n')) then (
92- let
93- val c = g1ofg0_char(int2char0(s.cur))
94- in
95- if c != '\000' then
96- let
97- val more = cons_vt(c, chars);
98- in
99- next (s);
100- value(s, more)
101- end
102- else list_vt_reverse(chars)
103- end
104- ) else list_vt_reverse(chars)
105-
106-implement scanvalue(s) =
107- c2s(value(s, nil_vt()))
108-
109-fun path(s: &scanner, chars: List0_vt(charNZ)): List0_vt(charNZ) =
110- if (s.cur >= 0) &&
111- (s.cur != char2int0 ('\n')) &&
112- (s.cur != char2int0 (':')) &&
113- (s.cur != char2int0 (' ')) then (
114- let val c = g1ofg0_char(int2char0(s.cur))
115- in
116- if c != '\000' then
117- let
118- val more = cons_vt(c, chars)
119- in
120- next(s);
121- path(s, more)
122- end
123- else list_vt_reverse(chars)
124- end
125- ) else list_vt_reverse(chars)
126+implement scanvalue(s) (*Strptr1*) =
127+let
128+ val () = read(s, isvaluec)
129+in
130+ stringbuf_takeout_all(s.buf)
131+end
132
133 implement scanpath(s) =
134- c2s(path(s, nil_vt()))
135-
136+let
137+ val () = read(s, ispathc)
138+in
139+ stringbuf_takeout_all(s.buf)
140+end
+4,
-1
1@@ -1,5 +1,8 @@
2-typedef scanner = @{
3+staload "libats/SATS/stringbuf.sats"
4+
5+vtypedef scanner = @{
6 file = FILEref,
7+ buf = stringbuf,
8 cur = int,
9 line = int,
10 col = int