Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Expression.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -375,6 +375,6 @@
 }
 
-
-UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function ) {}
+UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) :
+		Expression( _aname ), function(_function), args(_args) {}
 
 UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
@@ -382,7 +382,4 @@
 	cloneAll( other.args, args );
 }
-
-UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) :
-		Expression( _aname ), function(_function), args(_args) {}
 
 UntypedExpr::~UntypedExpr() {
@@ -568,4 +565,22 @@
 }
 
+StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
+	assert( statements );
+	std::list< Statement * > & body = statements->get_kids();
+	if ( ! body.empty() ) {
+		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
+			cloneAll( exprStmt->get_expr()->get_results(), get_results() );
+		}
+	}
+}
+StmtExpr::StmtExpr( const StmtExpr &other ) : statements( other.statements->clone() ) {}
+StmtExpr::~StmtExpr() {
+	delete statements;
+}
+void StmtExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Statement Expression: " << std::endl;
+	statements->print( os, indent+2 );
+}
+
 std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
 	expr->print( out );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Expression.h	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -98,7 +98,6 @@
 class UntypedExpr : public Expression {
   public:
-	UntypedExpr( Expression *function, Expression *_aname = nullptr );
+	UntypedExpr( Expression *function, const std::list<Expression *> &args = std::list< Expression * >(), Expression *_aname = nullptr );
 	UntypedExpr( const UntypedExpr &other );
-	UntypedExpr( Expression *function, std::list<Expression *> &args, Expression *_aname = nullptr );
 	virtual ~UntypedExpr();
 
@@ -483,40 +482,4 @@
 };
 
-/// TupleExpr represents a tuple expression ( [a, b, c] )
-class TupleExpr : public Expression {
-  public:
-	TupleExpr( Expression *_aname = nullptr );
-	TupleExpr( const TupleExpr &other );
-	virtual ~TupleExpr();
-
-	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
-	std::list<Expression*>& get_exprs() { return exprs; }
-
-	virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	std::list<Expression*> exprs;
-};
-
-/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
-class SolvedTupleExpr : public Expression {
-  public:
-	SolvedTupleExpr( Expression *_aname = nullptr ) : Expression( _aname ) {}
-	SolvedTupleExpr( std::list<Expression *> &, Expression *_aname = nullptr );
-	SolvedTupleExpr( const SolvedTupleExpr &other );
-	virtual ~SolvedTupleExpr() {}
-
-	std::list<Expression*> &get_exprs() { return exprs; }
-
-	virtual SolvedTupleExpr *clone() const { return new SolvedTupleExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	std::list<Expression*> exprs;
-};
-
 /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
 class TypeExpr : public Expression {
@@ -672,4 +635,22 @@
 };
 
+/// TupleExpr represents a tuple expression ( [a, b, c] )
+class TupleExpr : public Expression {
+  public:
+	TupleExpr( Expression *_aname = nullptr );
+	TupleExpr( const TupleExpr &other );
+	virtual ~TupleExpr();
+
+	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
+	std::list<Expression*>& get_exprs() { return exprs; }
+
+	virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list<Expression*> exprs;
+};
+
 /// TupleIndexExpr represents an element selection operation on a tuple value, e.g. t.3 after processing by the expression analyzer
 class TupleIndexExpr : public Expression {
@@ -714,44 +695,39 @@
 };
 
-/// MultipleAssignExpr represents a multiple assignment operation, where both sides of the assignment have tuple type, e.g. [a, b, c] = [d, e, f];
-class MultipleAssignExpr : public Expression {
-  public:
-	MultipleAssignExpr( Expression * lhs, Expression * rhs );
-	MultipleAssignExpr( const MultipleAssignExpr &other );
-	virtual ~MultipleAssignExpr();
-
-	Expression * get_lhs() const { return lhs; }
-	Expression * get_rhs() const { return rhs; }
-	MultipleAssignExpr * set_lhs( Expression *newValue ) { lhs = newValue; return this; }
-	MultipleAssignExpr * set_rhs( Expression *newValue ) { rhs = newValue; return this; }
-
-	virtual MultipleAssignExpr *clone() const { return new MultipleAssignExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	Expression * lhs;
-	Expression * rhs;
-};
-
-/// MassAssignExpr represents a mass assignment operations, where the left hand side has tuple type and the right hand side does not, e.g. [a, b, c] = 5.0;
-class MassAssignExpr : public Expression {
-  public:
-	MassAssignExpr( Expression * tuple, int field );
-	MassAssignExpr( const MassAssignExpr &other );
-	virtual ~MassAssignExpr();
-
-	Expression * get_lhs() const { return lhs; }
-	Expression * get_rhs() const { return rhs; }
-	MassAssignExpr * set_lhs( Expression *newValue ) { lhs = newValue; return this; }
-	MassAssignExpr * set_rhs( Expression *newValue ) { rhs = newValue; return this; }
-
-	virtual MassAssignExpr *clone() const { return new MassAssignExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	Expression * lhs; // multiple exprs
-	Expression * rhs; // single expr
+/// TupleAssignExpr represents a multiple assignment operation, where both sides of the assignment have tuple type, e.g. [a, b, c] = [d, e, f];, or a mass assignment operation, where the left hand side has tuple type and the right hand side does not, e.g. [a, b, c] = 5.0;
+class TupleAssignExpr : public Expression {
+  public:
+	TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr );
+	TupleAssignExpr( const TupleAssignExpr &other );
+	virtual ~TupleAssignExpr();
+
+	std::list< Expression * > & get_assigns() { return assigns; }
+	std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
+
+	virtual TupleAssignExpr *clone() const { return new TupleAssignExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list< Expression * > assigns; // assignment expressions that use tempDecls
+	std::list< ObjectDecl * > tempDecls; // temporaries for address of lhs exprs
+};
+
+/// StmtExpr represents a GCC 'statement expression', e.g. ({ int x = 5; x; })
+class StmtExpr : public Expression {
+public:
+	StmtExpr( CompoundStmt *statements );
+	StmtExpr( const StmtExpr & other );
+	virtual ~StmtExpr();
+
+	CompoundStmt * get_statements() const { return statements; }
+	StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
+
+	virtual StmtExpr *clone() const { return new StmtExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+private:
+	CompoundStmt * statements;
 };
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Mutator.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -308,16 +308,4 @@
 }
 
-Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
-	mutateAll( tupleExpr->get_exprs(), *this );
-	return tupleExpr;
-}
-
-Expression *Mutator::mutate( SolvedTupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
-	mutateAll( tupleExpr->get_exprs(), *this );
-	return tupleExpr;
-}
-
 Expression *Mutator::mutate( TypeExpr *typeExpr ) {
 	mutateAll( typeExpr->get_results(), *this );
@@ -364,4 +352,10 @@
 }
 
+Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
+	mutateAll( tupleExpr->get_results(), *this );
+	mutateAll( tupleExpr->get_exprs(), *this );
+	return tupleExpr;
+}
+
 Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
 	mutateAll( tupleExpr->get_results(), *this );
@@ -377,16 +371,15 @@
 }
 
-Expression *Mutator::mutate( MultipleAssignExpr *assignExpr ) {
+Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
 	mutateAll( assignExpr->get_results(), *this );
-	assignExpr->set_lhs( maybeMutate( assignExpr->get_lhs(), *this ) );
-	assignExpr->set_rhs( maybeMutate( assignExpr->get_rhs(), *this ) );
+	mutateAll( assignExpr->get_tempDecls(), *this );
+	mutateAll( assignExpr->get_assigns(), *this );
 	return assignExpr;
 }
 
-Expression *Mutator::mutate( MassAssignExpr *assignExpr ) {
-	mutateAll( assignExpr->get_results(), *this );
-	assignExpr->set_lhs( maybeMutate( assignExpr->get_lhs(), *this ) );
-	assignExpr->set_rhs( maybeMutate( assignExpr->get_rhs(), *this ) );
-	return assignExpr;
+Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
+	mutateAll( stmtExpr->get_results(), *this );
+	stmtExpr->set_statements( maybeMutate( stmtExpr->get_statements(), *this ) );
+	return stmtExpr;
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Mutator.h	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -71,6 +71,4 @@
 	virtual Expression* mutate( ConditionalExpr *conditionalExpr );
 	virtual Expression* mutate( CommaExpr *commaExpr );
-	virtual Expression* mutate( TupleExpr *tupleExpr );
-	virtual Expression* mutate( SolvedTupleExpr *tupleExpr );
 	virtual Expression* mutate( TypeExpr *typeExpr );
 	virtual Expression* mutate( AsmExpr *asmExpr );
@@ -80,8 +78,9 @@
 	virtual Expression* mutate( UntypedValofExpr *valofExpr );
 	virtual Expression* mutate( RangeExpr *rangeExpr );
+	virtual Expression* mutate( TupleExpr *tupleExpr );
 	virtual Expression* mutate( TupleIndexExpr *tupleExpr );
 	virtual Expression* mutate( MemberTupleExpr *tupleExpr );
-	virtual Expression* mutate( MultipleAssignExpr *assignExpr );
-	virtual Expression* mutate( MassAssignExpr *assignExpr );
+	virtual Expression* mutate( TupleAssignExpr *assignExpr );
+	virtual Expression* mutate( StmtExpr * stmtExpr );
 
 	virtual Type* mutate( VoidType *basicType );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/SynTree.h	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -76,6 +76,4 @@
 class ConditionalExpr;
 class CommaExpr;
-class TupleExpr;
-class SolvedTupleExpr;
 class TypeExpr;
 class AsmExpr;
@@ -85,8 +83,9 @@
 class UntypedValofExpr;
 class RangeExpr;
+class TupleExpr;
 class TupleIndexExpr;
 class MemberTupleExpr;
-class MultipleAssignExpr;
-class MassAssignExpr;
+class TupleAssignExpr;
+class StmtExpr;
 
 class Type;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/TupleExpr.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -17,4 +17,5 @@
 #include "Common/utility.h"
 #include "Type.h"
+#include "Declaration.h"
 
 TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) {
@@ -31,18 +32,4 @@
 void TupleExpr::print( std::ostream &os, int indent ) const {
 	os << std::string( indent, ' ' ) << "Tuple:" << std::endl;
-	printAll( exprs, os, indent+2 );
-	Expression::print( os, indent );
-}
-
-SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname ) : Expression( _aname ) {
-	std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs));
-}
-
-SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other ) : Expression( other ) {
-	cloneAll( other.exprs, exprs );
-}
-
-void SolvedTupleExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Solved Tuple:" << std::endl;
 	printAll( exprs, os, indent+2 );
 	Expression::print( os, indent );
@@ -90,4 +77,30 @@
 
 
+TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ), assigns( assigns ), tempDecls( tempDecls ) {
+	for ( Expression * expr : assigns ) {
+		cloneAll( expr->get_results(), get_results() );
+	}
+}
+
+TupleAssignExpr::TupleAssignExpr( const TupleAssignExpr &other ) : Expression( other ), tempDecls( other.tempDecls ) /* temporary */ {
+	cloneAll( other.assigns, assigns );
+	// xxx - clone needs to go into assigns and replace tempDecls
+}
+
+TupleAssignExpr::~TupleAssignExpr() {
+	deleteAll( assigns );
+	// deleteAll( tempDecls );
+}
+
+void TupleAssignExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Tuple Assignment Expression, with temporaries:" << std::endl;
+	printAll( tempDecls, os, indent+4 );
+	os << std::string( indent+2, ' ' ) << "with assignments: " << std::endl;
+	printAll( assigns, os, indent+4 );
+	Expression::print( os, indent );
+}
+
+
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/TupleType.cc
===================================================================
--- src/SynTree/TupleType.cc	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/TupleType.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleType.cc -- 
+// TupleType.cc --
 //
 // Author           : Richard C. Bilson
@@ -17,5 +17,5 @@
 #include "Common/utility.h"
 
-TupleType::TupleType( const Type::Qualifiers &tq ) : Type( tq ) {
+TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types ) : Type( tq ), types( types ) {
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Type.h	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -348,5 +348,5 @@
 class TupleType : public Type {
   public:
-	TupleType( const Type::Qualifiers &tq );
+	TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types = std::list< Type * >() );
 	TupleType( const TupleType& );
 	virtual ~TupleType();
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Visitor.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -261,14 +261,4 @@
 }
 
-void Visitor::visit( TupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
-	acceptAll( tupleExpr->get_exprs(), *this );
-}
-
-void Visitor::visit( SolvedTupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
-	acceptAll( tupleExpr->get_exprs(), *this );
-}
-
 void Visitor::visit( TypeExpr *typeExpr ) {
 	acceptAll( typeExpr->get_results(), *this );
@@ -309,4 +299,9 @@
 }
 
+void Visitor::visit( TupleExpr *tupleExpr ) {
+	acceptAll( tupleExpr->get_results(), *this );
+	acceptAll( tupleExpr->get_exprs(), *this );
+}
+
 void Visitor::visit( TupleIndexExpr *tupleExpr ) {
 	acceptAll( tupleExpr->get_results(), *this );
@@ -320,14 +315,13 @@
 }
 
-void Visitor::visit( MultipleAssignExpr *assignExpr ) {
+void Visitor::visit( TupleAssignExpr *assignExpr ) {
 	acceptAll( assignExpr->get_results(), *this );
-	maybeAccept( assignExpr->get_lhs(), *this );
-	maybeAccept( assignExpr->get_rhs(), *this );
-}
-
-void Visitor::visit( MassAssignExpr *assignExpr ) {
-	acceptAll( assignExpr->get_results(), *this );
-	maybeAccept( assignExpr->get_lhs(), *this );
-	maybeAccept( assignExpr->get_rhs(), *this );
+	acceptAll( assignExpr->get_tempDecls(), *this );
+	acceptAll( assignExpr->get_assigns(), *this );
+}
+
+void Visitor::visit( StmtExpr *stmtExpr ) {
+	acceptAll( stmtExpr->get_results(), *this );
+	maybeAccept( stmtExpr->get_statements(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision add7117c7fabc334eeb5508d12db94492b7fcdbc)
+++ src/SynTree/Visitor.h	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
@@ -71,6 +71,4 @@
 	virtual void visit( ConditionalExpr *conditionalExpr );
 	virtual void visit( CommaExpr *commaExpr );
-	virtual void visit( TupleExpr *tupleExpr );
-	virtual void visit( SolvedTupleExpr *tupleExpr );
 	virtual void visit( TypeExpr *typeExpr );
 	virtual void visit( AsmExpr *asmExpr );
@@ -80,8 +78,9 @@
 	virtual void visit( UntypedValofExpr *valofExpr );
 	virtual void visit( RangeExpr *rangeExpr );
+	virtual void visit( TupleExpr *tupleExpr );
 	virtual void visit( TupleIndexExpr *tupleExpr );
 	virtual void visit( MemberTupleExpr *tupleExpr );
-	virtual void visit( MultipleAssignExpr *assignExpr );
-	virtual void visit( MassAssignExpr *assignExpr );
+	virtual void visit( TupleAssignExpr *assignExpr );
+	virtual void visit( StmtExpr * stmtExpr );
 
 	virtual void visit( VoidType *basicType );
