Skip to content

Commit

Permalink
Adding support for StmtExpr
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotchance committed Sep 18, 2017
1 parent 8dc4d7f commit a7d1140
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 3 deletions.
2 changes: 2 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func Parse(line string) Node {
return parseReturnStmt(line)
case "ReturnsTwiceAttr":
return parseReturnsTwiceAttr(line)
case "StmtExpr":
return parseStmtExpr(line)
case "StringLiteral":
return parseStringLiteral(line)
case "SwitchStmt":
Expand Down
2 changes: 2 additions & 0 deletions ast/position.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ func setPosition(node Node, position Position) {
n.Pos = position
case *ReturnsTwiceAttr:
n.Pos = position
case *StmtExpr:
n.Pos = position
case *StringLiteral:
n.Pos = position
case *SwitchStmt:
Expand Down
45 changes: 45 additions & 0 deletions ast/stmt_expr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ast

type StmtExpr struct {
Addr Address
Pos Position
Type string
ChildNodes []Node
}

func parseStmtExpr(line string) *StmtExpr {
groups := groupsFromRegex(
"<(?P<position>.*)> '(?P<type>.*)'",
line,
)

return &StmtExpr{
Addr: ParseAddress(groups["address"]),
Pos: NewPositionFromString(groups["position"]),
Type: groups["type"],
ChildNodes: []Node{},
}
}

// AddChild adds a new child node. Child nodes can then be accessed with the
// Children attribute.
func (n *StmtExpr) AddChild(node Node) {
n.ChildNodes = append(n.ChildNodes, node)
}

// Address returns the numeric address of the node. See the documentation for
// the Address type for more information.
func (n *StmtExpr) Address() Address {
return n.Addr
}

// Children returns the child nodes. If this node does not have any children or
// this node does not support children it will always return an empty slice.
func (n *StmtExpr) Children() []Node {
return n.ChildNodes
}

// Position returns the position in the original source code.
func (n *StmtExpr) Position() Position {
return n.Pos
}
18 changes: 18 additions & 0 deletions ast/stmt_expr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ast

import (
"testing"
)

func TestStmtExpr(t *testing.T) {
nodes := map[string]Node{
`0x7ff4f9100d28 <col:11, col:18> 'int'`: &StmtExpr{
Addr: 0x7ff4f9100d28,
Pos: NewPositionFromString("col:11, col:18"),
Type: "int",
ChildNodes: []Node{},
},
}

runNodeTests(t, nodes)
}
7 changes: 6 additions & 1 deletion tests/operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

int main()
{
plan(33);
plan(35);

int i = 10;
signed char j = 1;
Expand Down Expand Up @@ -115,5 +115,10 @@ int main()
is_eq(wF, expectedW);
is_eq(eF, expectedE);

diag("Statement expressions")
int s1 = ({ 2; });
is_eq(s1, 2);
is_eq(({ int foo = s1 * 3; foo + 1; }), 7);

done_testing();
}
2 changes: 0 additions & 2 deletions transpiler/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ func transpileCompoundStmt(n *ast.CompoundStmt, p *program.Program) (
return nil, nil, nil, err
}

// preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)

if result != nil {
stmts = append(stmts, result...)
}
Expand Down
3 changes: 3 additions & 0 deletions transpiler/transpiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ func transpileToExpr(node ast.Node, p *program.Program, exprIsStmt bool) (
case *ast.UnaryExprOrTypeTraitExpr:
return transpileUnaryExprOrTypeTraitExpr(n, p)

case *ast.StmtExpr:
return transpileStmtExpr(n, p)

default:
p.AddMessage(p.GenerateWarningMessage(errors.New("cannot transpile to expr"), node))
expr = util.NewNil()
Expand Down
22 changes: 22 additions & 0 deletions transpiler/unary.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,25 @@ func transpileUnaryExprOrTypeTraitExpr(n *ast.UnaryExprOrTypeTraitExpr, p *progr

return util.NewIntLit(sizeInBytes), n.Type1, nil, nil, nil
}

func transpileStmtExpr(n *ast.StmtExpr, p *program.Program) (
*goast.CallExpr, string, []goast.Stmt, []goast.Stmt, error) {
returnType, err := types.ResolveType(p, n.Type)
if err != nil {
return nil, "", nil, nil, err
}

body, pre, post, err := transpileCompoundStmt(n.Children()[0].(*ast.CompoundStmt), p)
if err != nil {
return nil, "", pre, post, err
}

// The body of the StmtExpr is always a CompoundStmt. However, the last
// statement needs to be transformed into an explicit return statement.
lastStmt := body.List[len(body.List)-1]
body.List[len(body.List)-1] = &goast.ReturnStmt{
Results: []goast.Expr{lastStmt.(*goast.ExprStmt).X},
}

return util.NewFuncClosure(returnType, body.List...), n.Type, pre, post, nil
}

0 comments on commit a7d1140

Please sign in to comment.