Interpret runs the program and outputs a generated resource graph. It requires an AST, and the table of values required to populate that AST. Type unification, and earlier steps should obviously be run first so that you can actually get a useful resource graph out of this instead of an error! XXX: a
(ast interfaces.Stmt, table interfaces.Table)
| 75 | // actually get a useful resource graph out of this instead of an error! |
| 76 | // XXX: add a ctx? |
| 77 | func (obj *Interpreter) Interpret(ast interfaces.Stmt, table interfaces.Table) (*pgraph.Graph, error) { |
| 78 | obj.Logf("interpreting...") |
| 79 | |
| 80 | // build the kind,name -> res mapping |
| 81 | obj.lookup = make(map[engine.ResPtrUID]engine.Res) |
| 82 | obj.lookupHidden = make(map[engine.ResPtrUID][]engine.Res) |
| 83 | // build the send/recv mapping |
| 84 | obj.receive = make(map[engine.ResPtrUID]map[string]*engine.Send) |
| 85 | // build the exports |
| 86 | obj.export = make(map[engine.ResDelete]engine.Res) |
| 87 | |
| 88 | // Remember that if a resource is "Hidden", then make sure it is NOT |
| 89 | // sending to anyone, since it would never produce a value. It can |
| 90 | // receive values, since those might be used during export. |
| 91 | // |
| 92 | // Remember that if a resource is "Hidden", then it may exist alongside |
| 93 | // another resource with the same kind+name without triggering the |
| 94 | // "inequivalent duplicate resource" style of errors. Of course multiple |
| 95 | // hidden resources with the same kind+name may also exist |
| 96 | // simultaneously, just keep in mind that it means that an edge pointing |
| 97 | // to a particular kind+name now actually may point to more than one! |
| 98 | // |
| 99 | // This is needed because of two reasons: (1) because a regular resource |
| 100 | // will likely never be compatible with a "Hidden" and "Exported" |
| 101 | // resource because one resource might have the Meta:hidden and |
| 102 | // Meta:export params and one might not; (2) because you may wish to |
| 103 | // have two different hidden resources of different params which export |
| 104 | // to different hosts, which means they would likely not be compatible. |
| 105 | // |
| 106 | // Since we can have more than one "Hidden" and "Exported" resource with |
| 107 | // the same name and kind, it's important that we don't export that data |
| 108 | // to the same (kind, name, host) location since we'd have multiple |
| 109 | // writers to the same key in our World store. We could consider |
| 110 | // checking for compatibility, but that's more difficult to achieve. The |
| 111 | // "any" host is treated as a special key, which punts this duplicate |
| 112 | // problem to being a collection problem. (Which could happen with two |
| 113 | // different hosts each exporting a different value to a single host.) |
| 114 | // |
| 115 | // Remember that the resource graph that this function returns, may now |
| 116 | // contain two or more identically named kind+name resources, if at |
| 117 | // least one of them is "Hidden". If they are entirely identical, then |
| 118 | // it's acceptable to merge them. They may _not_ be merged with the |
| 119 | // CompatibleRes API, since on resource "collection" a param may be |
| 120 | // changed which could conceivably be incompatible with how we ran the |
| 121 | // AdaptCmp API when we merged them. |
| 122 | |
| 123 | output, err := ast.Output(table) // contains resList, edgeList, etc... |
| 124 | if err != nil { |
| 125 | return nil, err |
| 126 | } |
| 127 | |
| 128 | graph, err := pgraph.NewGraph("interpret") // give graph a default name |
| 129 | if err != nil { |
| 130 | return nil, errwrap.Wrapf(err, "could not create new graph") |
| 131 | } |
| 132 | |
| 133 | for _, res := range output.Resources { |
| 134 | kind := res.Kind() |