Skip to content

Commit

Permalink
Clarify and simplify AST (using a command Node and
Browse files Browse the repository at this point in the history
more generic expr Node)
  • Loading branch information
simcap committed Feb 17, 2017
1 parent f73af75 commit d535130
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 331 deletions.
10 changes: 5 additions & 5 deletions commands/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var runCmd = &cobra.Command{
func runTemplate(templ *template.Template, defaults map[string]interface{}) error {
resolved, err := templ.ResolveHoles(defaults)
exitOn(err)
logger.Infof("used default params: %s (list and set defaults with `awless config`)", sprintProcessedParams(resolved))
logger.Infof("used default params: %s", sprintProcessedParams(resolved))

fills := make(map[string]interface{})
if holes := templ.GetHolesValuesSet(); len(holes) > 0 {
Expand Down Expand Up @@ -106,11 +106,11 @@ func runTemplate(templ *template.Template, defaults map[string]interface{}) erro
)
awsDriver.SetLogger(logger.DefaultLogger)

for _, st := range templ.Statements {
if validators, ok := validation.ValidatorsPerActions[st.Action()]; ok {
graph := sync.LoadCurrentLocalGraph(awscloud.ServicePerResourceType[st.Entity()])
for _, cmd := range templ.CommandNodesIterator() {
if validators, ok := validation.ValidatorsPerActions[cmd.Action]; ok {
graph := sync.LoadCurrentLocalGraph(awscloud.ServicePerResourceType[cmd.Entity])
for _, v := range validators {
if err := v.Validate(graph, st.Params()); err != nil {
if err := v.Validate(graph, cmd.Params); err != nil {
return err
}
}
Expand Down
127 changes: 43 additions & 84 deletions template/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,60 +26,48 @@ type Node interface {
String() string
}

type AST struct {
Statements []*Statement

// state to build the AST
currentStatement *Statement
currentKey string
}

type Statement struct {
Node
Result interface{}
Line string
Err error
}

func (s *Statement) clone() *Statement {
newStat := &Statement{}
newStat.Node = s.Node.clone()
newStat.Result = s.Result
newStat.Err = s.Err

return newStat
type DeclarationNode struct {
Ident string
Expr ExpressionNode
}

func (s *Statement) Action() string {
switch n := s.Node.(type) {
case *ExpressionNode:
return n.Action
case *DeclarationNode:
return n.Right.Action
default:
panic(fmt.Sprintf("unknown type of node %T", s.Node))
}
type ExpressionNode interface {
Node
Result() interface{}
Err() error
}

func (s *Statement) Entity() string {
switch n := s.Node.(type) {
case *ExpressionNode:
return n.Entity
case *DeclarationNode:
return n.Right.Entity
default:
panic(fmt.Sprintf("unknown type of node %T", s.Node))
}
}
type CommandNode struct {
CmdResult interface{}
CmdErr error

func (s *Statement) Params() map[string]interface{} {
switch n := s.Node.(type) {
case *ExpressionNode:
return n.Params
case *DeclarationNode:
return n.Right.Params
default:
panic(fmt.Sprintf("unknown type of node %T", s.Node))
}
Action, Entity string
Refs map[string]string
Params map[string]interface{}
Aliases map[string]string
Holes map[string]string
}

type AST struct {
Statements []*Statement
func (n *CommandNode) Result() interface{} { return n.CmdResult }
func (n *CommandNode) Err() error { return n.CmdErr }

currentStatement *Statement
currentKey string
func (s *Statement) clone() *Statement {
newStat := &Statement{}
newStat.Node = s.Node.clone()

return newStat
}

func (a *AST) String() string {
Expand All @@ -90,48 +78,19 @@ func (a *AST) String() string {
return strings.Join(all, "\n")
}

type IdentifierNode struct {
Ident string
Val interface{}
}

func (n *IdentifierNode) String() string {
return fmt.Sprintf("%s", n.Ident)
}

func (n *IdentifierNode) clone() Node {
return &IdentifierNode{
Ident: n.Ident,
Val: n.Val,
}
}

type DeclarationNode struct {
Left *IdentifierNode
Right *ExpressionNode
}

func (n *DeclarationNode) clone() Node {
return &DeclarationNode{
Left: n.Left.clone().(*IdentifierNode),
Right: n.Right.clone().(*ExpressionNode),
Ident: n.Ident,
Expr: n.Expr.clone().(ExpressionNode),
}
}

func (n *DeclarationNode) String() string {
return fmt.Sprintf("%s = %s", n.Left, n.Right)
}

type ExpressionNode struct {
Action, Entity string
Refs map[string]string
Params map[string]interface{}
Aliases map[string]string
Holes map[string]string
return fmt.Sprintf("%s = %s", n.Ident, n.Expr)
}

func (n *ExpressionNode) clone() Node {
expr := &ExpressionNode{
func (n *CommandNode) clone() Node {
cmd := &CommandNode{
Action: n.Action, Entity: n.Entity,
Refs: make(map[string]string),
Params: make(map[string]interface{}),
Expand All @@ -140,22 +99,22 @@ func (n *ExpressionNode) clone() Node {
}

for k, v := range n.Refs {
expr.Refs[k] = v
cmd.Refs[k] = v
}
for k, v := range n.Params {
expr.Params[k] = v
cmd.Params[k] = v
}
for k, v := range n.Aliases {
expr.Aliases[k] = v
cmd.Aliases[k] = v
}
for k, v := range n.Holes {
expr.Holes[k] = v
cmd.Holes[k] = v
}

return expr
return cmd
}

func (n *ExpressionNode) String() string {
func (n *CommandNode) String() string {
var all []string
for k, v := range n.Refs {
all = append(all, fmt.Sprintf("%s=$%v", k, v))
Expand All @@ -172,7 +131,7 @@ func (n *ExpressionNode) String() string {
return fmt.Sprintf("%s %s %s", n.Action, n.Entity, strings.Join(all, " "))
}

func (n *ExpressionNode) ProcessHoles(fills map[string]interface{}) map[string]interface{} {
func (n *CommandNode) ProcessHoles(fills map[string]interface{}) map[string]interface{} {
processed := make(map[string]interface{})
if n.Params == nil {
n.Params = make(map[string]interface{})
Expand All @@ -187,7 +146,7 @@ func (n *ExpressionNode) ProcessHoles(fills map[string]interface{}) map[string]i
return processed
}

func (n *ExpressionNode) ProcessRefs(fills map[string]interface{}) {
func (n *CommandNode) ProcessRefs(fills map[string]interface{}) {
if n.Params == nil {
n.Params = make(map[string]interface{})
}
Expand Down
43 changes: 6 additions & 37 deletions template/ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@ func TestCloneAST(t *testing.T) {
tree := &AST{}

tree.Statements = append(tree.Statements, &Statement{Node: &DeclarationNode{
Left: &IdentifierNode{Ident: "myvar"},
Right: &ExpressionNode{
Ident: "myvar",
Expr: &CommandNode{
Action: "create", Entity: "vpc",
Refs: map[string]string{"myname": "name"},
Params: map[string]interface{}{"count": 1},
Aliases: map[string]string{"subnet": "my-subnet"},
Holes: make(map[string]string),
}}}, &Statement{Node: &DeclarationNode{
Left: &IdentifierNode{Ident: "myothervar"},
Right: &ExpressionNode{
Ident: "myothervar",
Expr: &CommandNode{
Action: "create", Entity: "subnet",
Refs: make(map[string]string),
Params: make(map[string]interface{}),
Aliases: make(map[string]string),
Holes: map[string]string{"vpc": "myvar"},
}}}, &Statement{Node: &ExpressionNode{
}}}, &Statement{Node: &CommandNode{
Action: "create", Entity: "instance",
Refs: make(map[string]string),
Params: make(map[string]interface{}),
Expand All @@ -55,40 +55,9 @@ func TestCloneAST(t *testing.T) {
t.Fatalf("\ngot %#v\n\nwant %#v", got, want)
}

clone.Statements[0].Node.(*DeclarationNode).Right.Params["new"] = "trump"
clone.Statements[0].Node.(*DeclarationNode).Expr.(*CommandNode).Params["new"] = "trump"

if got, want := clone.Statements, tree.Statements; reflect.DeepEqual(got, want) {
t.Fatalf("\ngot %s\n\nwant %s", got, want)
}
}

func TestGetStatementAttributes(t *testing.T) {
params := map[string]interface{}{"count": 1}
st := &Statement{Node: &DeclarationNode{
Left: &IdentifierNode{},
Right: &ExpressionNode{
Action: "create", Entity: "vpc", Params: params,
}}}
if got, want := st.Action(), "create"; got != want {
t.Fatalf("got %s, want %s", got, want)
}
if got, want := st.Entity(), "vpc"; got != want {
t.Fatalf("got %s, want %s", got, want)
}
if got, want := st.Params(), params; !reflect.DeepEqual(got, want) {
t.Fatalf("got %s, want %s", got, want)
}

st = &Statement{Node: &ExpressionNode{
Action: "delete", Entity: "subnet", Params: params,
}}
if got, want := st.Action(), "delete"; got != want {
t.Fatalf("got %s, want %s", got, want)
}
if got, want := st.Entity(), "subnet"; got != want {
t.Fatalf("got %s, want %s", got, want)
}
if got, want := st.Params(), params; !reflect.DeepEqual(got, want) {
t.Fatalf("got %s, want %s", got, want)
}
}
Loading

0 comments on commit d535130

Please sign in to comment.