// Portions adapted from google/go-jsonnet v0.21.0 (Apache-2.0).
// https://github.com/google/go-jsonnet/tree/67968688d9952f50662e979fab1bef889d0d3e57
// Source: internal/program/desugarer.go
// Copyright 2016 Google Inc. All rights reserved.
// Modifications: Implemented analysis-only lowering on MoonBit ASTs with resource checks.
// License and retained attribution: LICENSE and NOTICE at the module root.
// Analysis-only lowering follows pinned go-jsonnet internal/program/desugarer.go.
// Copyright Google Inc.; Apache-2.0; see NOTICE.
///|
fn lint_std_call(name : String, args : Array[Expr], loc : Location) -> Expr {
let std : Expr = { kind: Var("$std"), loc, end: None, }
let key : Expr = { kind: Literal(Json::string(name)), loc, end: None, }
let target : Expr = { kind: Index(std, key), loc, end: None, }
{ kind: Call(target, args.map(e => (None, e)), false), loc, end: None, }
}
///|
fn lint_comp(body : Expr, clauses : Array[Clause], loc : Location) -> Expr {
let mut inside : Expr = { kind: Arr([body]), loc, end: None, }
let conditions = []
for i = clauses.length() - 1; i >= 0; i = i - 1 {
match clauses[i] {
When(e) => conditions.push(e)
For(name, source) => {
if conditions.pop() is Some(first) {
let mut condition = first
while conditions.pop() is Some(next) {
condition = { kind: Binary("&&", condition, next), loc, end: None, }
}
inside = {
kind: If(condition, inside, { kind: Arr([]), loc, end: None, }),
loc,
end: None,
}
}
let function : Expr = {
kind: Func([{ name, default_value: None, range: None, }], inside),
loc,
end: None,
}
inside = lint_std_call("$flatMapArray", [function, source], loc)
}
}
}
inside
}