commit 9d04fa7

shrub  ·  2026-10-14 18:15:06 +0000 UTC
parent 26fdb2f
check command binding, pretty print results
6 files changed,  +51, -9
+1, -1
1@@ -7,5 +7,5 @@ rule cc
2 rule shit
3   command = shit
4 
5-build poop: piss in
6+build poop: shit in
7 
+1, -0
1@@ -14,6 +14,7 @@ let
2         col  = 1 }
3     val result = parse(s, nil_vt(), nil_vt())
4 in
5+    printrule(result.rules);
6     manifest_free(result);
7     fileref_close(manifest)
8 end
+44, -7
 1@@ -90,16 +90,38 @@ fun rulebinding(s: &scanner,
 2     else(list_vt_reverse(b))
 3    
 4 
 5+(* does a list of bindings contain a "command" binding *)
 6+fun hascommand(bindings: !List0_vt(binding)): bool =
 7+    case+ bindings of 
 8+    | nil_vt() => false
 9+    | @cons_vt(entry, rest) =>
10+    let 
11+        val found = if strptr_length(entry.value) >0 && entry.key = "command" then true
12+        else hascommand(rest)
13+    in
14+        fold@(bindings);
15+        found
16+    end
17+ 
18 fun rule(s: &scanner): rule = 
19-let 
20+let
21         val ()       = skipspace(s)
22         val rulename = scanname (s)
23 in 
24     skipspace(s);
25     if s.cur = char2int0('\n') then (
26         next(s);
27-        let val bindings = rulebinding(s, nil_vt()) in
28-        @{name = rulename, bindings = bindings} end
29+        let 
30+            val bindings = rulebinding(s, nil_vt()) 
31+        in
32+            if hascommand(bindings) = true then
33+                @{name = rulename, bindings = bindings} 
34+            else (
35+                prerrln!("rule is missing 'command' binding");
36+                strptr_free(rulename);
37+                bindings_free(bindings);
38+                $raise ParseErr )
39+        end
40     ) else (
41         strptr_free(rulename);
42         prerrln!("expected newline after rule name at", s.line, ":", s.col);
43@@ -177,17 +199,32 @@ fun hasrule(rules: !List0_vt(rule), name: !Strptr1): bool =
44     in
45         (* close the list *)
46         fold@(rules);
47-
48         found
49     end
50-       
51+
52+fun printbindings(bindings: !List0_vt(binding)): void =
53+    case+ bindings of 
54+    | nil_vt() => ()
55+    | @cons_vt(entry, rest) => (
56+    println!("  binding: ", entry.key," = ",entry.value);
57+    printbindings(rest);
58+    fold@(bindings) )
59+ 
60+implement printrule(rules) =
61+     case+ rules of
62+     | nil_vt() => ()
63+     | @cons_vt(entry, rest) => (
64+     println!("rule: ", entry.name);
65+     printbindings(entry.bindings);
66+     printrule(rest);
67+     fold@(rules) )
68+
69 implement parse(s, rules, edges) (*manifest*) = 
70 let
71     val tok = scankeyword(s)
72 in
73     (case+ tok of
74-    | ~TOKrule (line,col)       => (println!("rule at: ", line,":", col);
75-                                    let 
76+    | ~TOKrule (line,col)       => (let 
77                                         val r    = rule(s);
78                                         val more = cons_vt(r, rules)
79                                     in
+1, -0
1@@ -22,5 +22,6 @@ vtypedef manifest = @{
2 }
3 
4 fun manifest_free(m: manifest): void 
5+fun printrule(rules: !List0_vt(rule)): void
6 fun parse(s: &scanner, rules: List0_vt(rule), edges: List0_vt(edge)): manifest
7 
+0, -1
1@@ -1,6 +1,5 @@
2 #include "share/atspre_staload.hats"
3 #define ATS_DYNLOADFLAG 0
4-staload STD = "libats/libc/SATS/stdlib.sats"
5 staload IO = "libats/libc/SATS/stdio.sats"
6 staload "scan.sats"
7 
+4, -0
 1@@ -12,6 +12,10 @@ datavtype tok =
 2     | TOKvar   of (Strptr1, int, int) 
 3     | TOKeof   of (int, int) 
 4 
 5+datavtype stringpart =
 6+    | Literal  of Strptr1
 7+    | Variable of Strptr1
 8+
 9 fun next       (s: &scanner): void 
10 fun scanname   (s: &scanner): Strptr1
11 fun skipspace  (s: &scanner): void