Skip to content
This repository has been archived by the owner on Mar 18, 2020. It is now read-only.

Commit

Permalink
Use std::tuple<T1, T2> in the Rhs of assign/declare expressions
Browse files Browse the repository at this point in the history
This allows writing code such as:

      func gcd(x, y int) int {
              for y != 0 {
                      x, y = y, x%y
              }
              return x
      }

Which gets compiled to:

      int gcd(int x, int y) {
        {
          for (; y != 0;) {
            std::tie(x, y) = std::tuple<int, int>(y, x % y);
          }
        }
        return x;
      }
  • Loading branch information
lpereira committed Apr 4, 2017
1 parent 7432ac1 commit 6bf8e5e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
35 changes: 31 additions & 4 deletions compiler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ func (c *Compiler) genAssignStmt(gen *nodeGen, a *ast.AssignStmt) (err error) {
fmt.Fprint(gen.out, ")")
}

var tupleOk bool
switch a.Tok {
case token.ADD_ASSIGN:
fmt.Fprint(gen.out, " += ")
Expand All @@ -872,21 +873,47 @@ func (c *Compiler) genAssignStmt(gen *nodeGen, a *ast.AssignStmt) (err error) {
fmt.Fprint(gen.out, " >>= ")
case token.AND_NOT_ASSIGN:
fmt.Fprint(gen.out, " &= ~(")
defer fmt.Fprint(gen.out, ")")
case token.ASSIGN, token.DEFINE:
fmt.Fprint(gen.out, " = ")
tupleOk = true
default:
return fmt.Errorf("Unknown assignment token")
}

if len(a.Rhs) == 1 {
return c.walk(gen, a.Rhs[0])
}

if !tupleOk {
return fmt.Errorf("Rhs incompatible with Lhs")
}

var types []string
for _, e := range a.Rhs {
if err = c.walk(gen, e); err != nil {
return err
typ, ok := c.inf.Types[e]
if !ok {
return fmt.Errorf("Couldn't determine type of expression")
}

ctyp, err := c.toTypeSig(typ.Type)
if err != nil {
return fmt.Errorf("Couldn't get type signature: %s", err)
}

types = append(types, ctyp)
}

if a.Tok == token.AND_NOT_ASSIGN {
fmt.Fprint(gen.out, ")")
fmt.Fprintf(gen.out, "std::tuple<%s>(", strings.Join(types, ", "))
for i, e := range a.Rhs {
if err = c.walk(gen, e); err != nil {
return err
}
if i < len(a.Rhs)-1 {
fmt.Fprint(gen.out, ", ")
}
}
fmt.Fprint(gen.out, ")")

return nil
}
Expand Down
8 changes: 8 additions & 0 deletions samples/swap/swap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package main

func gcd(x, y int) int {
for y != 0 {
x, y = y, x%y
}
return x
}

0 comments on commit 6bf8e5e

Please sign in to comment.