From d326917432fdfe09b4bc4ac4ab25d3bed6f1966f Mon Sep 17 00:00:00 2001 From: James Shubin Date: Mon, 1 Jul 2024 14:38:14 -0400 Subject: [PATCH] lang: interfaces: Add some unification basics This includes the GenericCheck helper which we'll use everywhere, and the standard single invariant which we use throughout. --- lang/interfaces/unification.go | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lang/interfaces/unification.go b/lang/interfaces/unification.go index aa0db672..cab0a16d 100644 --- a/lang/interfaces/unification.go +++ b/lang/interfaces/unification.go @@ -37,6 +37,46 @@ import ( "github.com/purpleidea/mgmt/util/errwrap" ) +// UnificationInvariant is the only type of invariant that we currently support. +// It always lets you specify an `Expr` so that we know what we're referring to. +// It always lets you specify two types which must get unified for a successful +// solution. Those two types are symmetrical in that it doesn't matter which is +// used where, it only affects how we print out error messages. +type UnificationInvariant struct { // formerly the SamInvariant + // Expr is the expression we are determining the type for. This improves + // our error messages. + Expr Expr + + // Expect is one of the two types to unify. + Expect *types.Type + + // Actual is one of the two types to unify. + Actual *types.Type +} + +// GenericCheck is the generic implementation of the Check Expr interface call. +// It is checking that the input type is equal to the object that Check is +// running on. In doing so, it adds any invariants that are necessary. Check +// must always call Infer to produce the invariant. The implementation can be +// generic for all expressions. +func GenericCheck(obj Expr, typ *types.Type) ([]*UnificationInvariant, error) { + // Generic implementation of Check: + // This wants to be inferred, because it always knows its type. + actual, invariants, err := obj.Infer() + if err != nil { + return nil, err + } + + invar := &UnificationInvariant{ + Expr: obj, + Expect: typ, // sam says not backwards + Actual: actual, + } + invariants = append(invariants, invar) + + return invariants, nil +} + // Invariant represents a constraint that is described by the Expr's and Stmt's, // and which is passed into the unification solver to describe what is known by // the AST.