diff options
| author | Jakob L. Kreuze | 2023-05-04 13:32:55 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze | 2023-05-04 13:32:55 -0400 |
| commit | 1f8bc0ab2b66bb950e09a05bf804376f5bdd1def (patch) | |
| tree | 09403904f8b4ab5f04760aeb13ee71729850cb40 | |
| parent | fe4f9ad29958626bdf7fb472f64b8ae2a5f5db3b (diff) | |
Document (and fix) scope "breadcrumb" format
| -rw-r--r-- | compiler/types.scm | 29 |
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)))) |