aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob L. Kreuze2023-05-04 13:32:55 -0400
committerJakob L. Kreuze2023-05-04 13:32:55 -0400
commit1f8bc0ab2b66bb950e09a05bf804376f5bdd1def (patch)
tree09403904f8b4ab5f04760aeb13ee71729850cb40
parentfe4f9ad29958626bdf7fb472f64b8ae2a5f5db3b (diff)
Document (and fix) scope "breadcrumb" format
-rw-r--r--compiler/types.scm29
1 files changed, 26 insertions, 3 deletions
diff --git a/compiler/types.scm b/compiler/types.scm
index 2e25d78..07e9550 100644
--- a/compiler/types.scm
+++ b/compiler/types.scm
@@ -85,10 +85,34 @@
(map (match-lambda
((group-head rules ...)
`(,group-head
- ,@(map (compose (cut tree-map <> f (scope policy) '())) rules))))
+ ,@(map (lambda (rule i)
+ (let ((breadcrumb `(,(name (head rule)) ,i)))
+ (tree-map rule f (scope policy) breadcrumb)))
+ rules
+ (iota (length rules))))))
rule-groups))
policy))
+;; `f' is called with `scope' and `breadcrumb' as auxiliary arguments.
+;;
+;; `scope' is a `<scope>', which gives opaque access to the variables that have
+;; been defined in the policy, and any constraints we've mined thus far in the
+;; compilation process. (In general, it's devoid of helpful information until
+;; the `extract-identifiers' pass runs.)
+;;
+;; `breadcrumb' is a marker that specifies where the `form' argument exists in
+;; the policy. Rego is lexically scoped, so this information is important for
+;; determining which identifiers are in-scope for a particular place in the
+;; program. The breadcrumb is always a list that begins with (1.) the name of
+;; the current rule group and (2.) the index of the head being observed.
+;; Following that is a sequence of list indices corresponding to this particular
+;; path in the tree. For example:
+;;
+;; ("q" 0 0)
+;;
+;; Corresponds to the first clause in the conjunction of the first rule that
+;; defines `q'.
+
(define-method (tree-map form f scope breadcrumb)
form)
@@ -238,8 +262,7 @@ and `identifier' is a <reference>"
(match form
(($ <rule> default head body)
;; A rule body introduces a new scope.
- (let* ((breadcrumb (add-to-end breadcrumb (name head)))
- (inner (with-modified-slot form 'head
+ (let* ((inner (with-modified-slot form 'head
(tree-map head f scope breadcrumb)))
(inner (with-modified-slot inner 'body
(tree-map body f scope breadcrumb))))

© 2015 - 2026 Jakob L. Kreuze