engine, lang: Modern exported resources
I've been waiting to write this patch for a long time. I firmly believe that the idea of "exported resources" was truly a brilliant one, but which was never even properly understood by its original inventors! This patch set aims to show how it should have been done. The main differences are: * Real-time modelling, since "once per run" makes no sense. * Filter with code/functions not language syntax. * Directed exporting to limit the intended recipients. The next step is to add more "World" reading and filtering functions to make it easy and expressive to make your selection of resources to collect!
This commit is contained in:
@@ -261,6 +261,11 @@
|
||||
lval.str = yylex.Text()
|
||||
return PANIC_IDENTIFIER
|
||||
}
|
||||
/collect/ {
|
||||
yylex.pos(lval) // our pos
|
||||
lval.str = yylex.Text()
|
||||
return COLLECT_IDENTIFIER
|
||||
}
|
||||
/"(\\.|[^"])*"/
|
||||
{ // This matches any number of the bracketed patterns
|
||||
// that are surrounded by the two quotes on each side.
|
||||
|
||||
@@ -104,6 +104,7 @@ func init() {
|
||||
%token CLASS_IDENTIFIER INCLUDE_IDENTIFIER
|
||||
%token IMPORT_IDENTIFIER AS_IDENTIFIER
|
||||
%token COMMENT ERROR
|
||||
%token COLLECT_IDENTIFIER
|
||||
%token PANIC_IDENTIFIER
|
||||
|
||||
// precedence table
|
||||
@@ -188,6 +189,11 @@ stmt:
|
||||
$$.stmt = $1.stmt
|
||||
locate(yylex, $1, yyDollar[len(yyDollar)-1], $$.stmt)
|
||||
}
|
||||
| collect
|
||||
{
|
||||
$$.stmt = $1.stmt
|
||||
locate(yylex, $1, yyDollar[len(yyDollar)-1], $$.stmt)
|
||||
}
|
||||
| resource
|
||||
{
|
||||
$$.stmt = $1.stmt
|
||||
@@ -1026,6 +1032,46 @@ panic:
|
||||
locate(yylex, $1, yyDollar[len(yyDollar)-1], $$.stmt)
|
||||
}
|
||||
;
|
||||
collect:
|
||||
// `collect file "/tmp/hello" { ... }`
|
||||
// `collect file ["/tmp/hello", ...,] { ... }`
|
||||
// `collect file [struct{name => "/tmp/hello", host => "foo",}, ...,] { ... }`
|
||||
COLLECT_IDENTIFIER resource
|
||||
{
|
||||
// A "collect" stmt is exactly a regular "res" statement, except
|
||||
// it has the boolean "Collect" field set to true, and it also
|
||||
// has a special "resource body" entry which accepts the special
|
||||
// collected data from the function graph.
|
||||
$$.stmt = $2.stmt // it's us now
|
||||
kind := $2.stmt.(*ast.StmtRes).Kind
|
||||
res := $$.stmt.(*ast.StmtRes)
|
||||
res.Collect = true
|
||||
// We are secretly adding a special field to the res contents,
|
||||
// which receives all of the exported data so that we have it
|
||||
// arrive in our function graph in the standard way. We'd need
|
||||
// to have this data to be able to build the resources we want!
|
||||
call := &ast.ExprCall{
|
||||
// function name to lookup special values from that kind
|
||||
Name: funcs.CollectFuncName,
|
||||
Args: []interfaces.Expr{
|
||||
&ast.ExprStr{ // magic operator first
|
||||
V: kind, // tell it what we're reading
|
||||
},
|
||||
// names to collect
|
||||
// XXX: Can we copy the same AST nodes to here?
|
||||
// XXX: Do I need to run .Copy() on them ?
|
||||
// str, []str, or []struct{name str; host str}
|
||||
res.Name, // expr (hopefully one of those types)
|
||||
},
|
||||
}
|
||||
collect := &ast.StmtResCollect{ // special field
|
||||
Kind: kind, // might as well tell it directly
|
||||
Value: call,
|
||||
}
|
||||
res.Contents = append(res.Contents, collect)
|
||||
locate(yylex, $1, yyDollar[len(yyDollar)-1], $$.stmt)
|
||||
}
|
||||
;
|
||||
/* TODO: do we want to include this?
|
||||
// resource bind
|
||||
rbind:
|
||||
|
||||
Reference in New Issue
Block a user