Commit 3548350d authored by Robert Griesemer's avatar Robert Griesemer

Snapshot.

Added support for function literals, composite literals.
Bug fixes.

R=r
OCL=15911
CL=15911
parent d4edee3d
...@@ -40,6 +40,8 @@ export type Visitor interface { ...@@ -40,6 +40,8 @@ export type Visitor interface {
DoIndex(x *Index); DoIndex(x *Index);
DoCall(x *Call); DoCall(x *Call);
DoSelector(x *Selector); DoSelector(x *Selector);
DoCompositeLit(x *CompositeLit);
DoFunctionLit(x *FunctionLit);
// Statements // Statements
DoLabel(x *Label); DoLabel(x *Label);
...@@ -167,9 +169,16 @@ export type MapType struct { ...@@ -167,9 +169,16 @@ export type MapType struct {
} }
export const /* chan mode */ (
FULL = iota;
RECV;
SEND;
)
export type ChannelType struct { export type ChannelType struct {
pos int; // position of "chan" or "<-" (if before "chan") pos int; // position of "chan" or "<-" (if before "chan")
elt Type; elt Type;
mode int;
} }
...@@ -324,6 +333,20 @@ export type Literal struct { ...@@ -324,6 +333,20 @@ export type Literal struct {
} }
export type CompositeLit struct {
pos int; // position of "{"
typ Type;
vals *List // list of Expr
}
export type FunctionLit struct {
pos int; // position of "func"
typ *FunctionType;
body *Block;
}
func (x *Binary) Visit(v Visitor) { v.DoBinary(x); } func (x *Binary) Visit(v Visitor) { v.DoBinary(x); }
func (x *Unary) Visit(v Visitor) { v.DoUnary(x); } func (x *Unary) Visit(v Visitor) { v.DoUnary(x); }
func (x *Literal) Visit(v Visitor) { v.DoLiteral(x); } func (x *Literal) Visit(v Visitor) { v.DoLiteral(x); }
...@@ -331,6 +354,8 @@ func (x *Pair) Visit(v Visitor) { v.DoPair(x); } ...@@ -331,6 +354,8 @@ func (x *Pair) Visit(v Visitor) { v.DoPair(x); }
func (x *Index) Visit(v Visitor) { v.DoIndex(x); } func (x *Index) Visit(v Visitor) { v.DoIndex(x); }
func (x *Call) Visit(v Visitor) { v.DoCall(x); } func (x *Call) Visit(v Visitor) { v.DoCall(x); }
func (x *Selector) Visit(v Visitor) { v.DoSelector(x); } func (x *Selector) Visit(v Visitor) { v.DoSelector(x); }
func (x *CompositeLit) Visit(v Visitor) { v.DoCompositeLit(x); }
func (x *FunctionLit) Visit(v Visitor) { v.DoFunctionLit(x); }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
......
...@@ -212,6 +212,7 @@ func (P *Parser) ParseArrayType() *AST.ArrayType { ...@@ -212,6 +212,7 @@ func (P *Parser) ParseArrayType() *AST.ArrayType {
typ := new(AST.ArrayType); typ := new(AST.ArrayType);
typ.pos = P.pos; typ.pos = P.pos;
typ.len_ = AST.NIL;
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
if P.tok != Scanner.RBRACK { if P.tok != Scanner.RBRACK {
...@@ -231,15 +232,18 @@ func (P *Parser) ParseChannelType() *AST.ChannelType { ...@@ -231,15 +232,18 @@ func (P *Parser) ParseChannelType() *AST.ChannelType {
typ := new(AST.ChannelType); typ := new(AST.ChannelType);
typ.pos = P.pos; typ.pos = P.pos;
typ.mode = AST.FULL;
if P.tok == Scanner.CHAN { if P.tok == Scanner.CHAN {
P.Next(); P.Next();
if P.tok == Scanner.ARROW { if P.tok == Scanner.ARROW {
P.Next(); P.Next();
typ.mode = AST.SEND;
} }
} else { } else {
P.Expect(Scanner.ARROW); P.Expect(Scanner.ARROW);
P.Expect(Scanner.CHAN); P.Expect(Scanner.CHAN);
typ.mode = AST.RECV;
} }
typ.elt = P.ParseVarType(); typ.elt = P.ParseVarType();
...@@ -532,91 +536,106 @@ func (P *Parser) ParseBlock() *AST.Block { ...@@ -532,91 +536,106 @@ func (P *Parser) ParseBlock() *AST.Block {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Expressions // Expressions
func (P *Parser) ParseExpressionList() *AST.List { func (P *Parser) ParseExpressionList(list *AST.List) {
P.Trace("ExpressionList"); P.Trace("ExpressionList");
p := AST.NewList(); list.Add(P.ParseExpression());
p.Add(P.ParseExpression());
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.Next(); P.Next();
p.Add(P.ParseExpression()); list.Add(P.ParseExpression());
} }
P.Ecart(); P.Ecart();
return p;
} }
func (P *Parser) ParseFunctionLit() AST.Expr { func (P *Parser) ParseNewExpressionList() *AST.List {
list := AST.NewList();
P.ParseExpressionList(list);
return list;
}
func (P *Parser) ParseFunctionLit() *AST.FunctionLit {
P.Trace("FunctionLit"); P.Trace("FunctionLit");
fun := new(AST.FunctionLit);
fun.pos = P.pos;
P.Expect(Scanner.FUNC); P.Expect(Scanner.FUNC);
P.ParseFunctionType(); fun.typ = P.ParseFunctionType();
P.ParseBlock(); fun.body = P.ParseBlock();
P.Ecart(); P.Ecart();
var x AST.Expr; return fun;
return x;
} }
func (P *Parser) ParseExpressionPair() AST.Expr { func (P *Parser) ParseExpressionPair() AST.Expr {
P.Trace("ExpressionPair"); P.Trace("ExpressionPair");
x := P.ParseExpression(); p := new(AST.Pair);
pos := P.pos; p.x = P.ParseExpression();
p.pos = P.pos;
P.Expect(Scanner.COLON); P.Expect(Scanner.COLON);
y := P.ParseExpression(); p.y = P.ParseExpression();
z := new(AST.Pair);
z.pos, z.x, z.y = pos, x, y;
P.Ecart(); P.Ecart();
return z; return p;
} }
func (P *Parser) ParseExpressionPairList() *AST.List { func (P *Parser) ParseExpressionPairList(list *AST.List) {
P.Trace("ExpressionPairList"); P.Trace("ExpressionPairList");
p := AST.NewList(); list.Add(P.ParseExpressionPair());
p.Add(P.ParseExpressionPair());
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
p.Add(P.ParseExpressionPair()); list.Add(P.ParseExpressionPair());
} }
P.Ecart(); P.Ecart();
return p;
} }
func (P *Parser) ParseCompositeLit() AST.Expr { func (P *Parser) ParseCompositeLit(typ AST.Type) AST.Expr {
P.Trace("CompositeLit"); P.Trace("CompositeLit");
lit := new(AST.CompositeLit);
lit.pos = P.pos;
lit.typ = typ;
lit.vals = AST.NewList();
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
// TODO: should allow trailing ',' // TODO: should allow trailing ','
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
P.ParseExpression(); x := P.ParseExpression();
if P.tok == Scanner.COMMA { if P.tok == Scanner.COMMA {
P.Next(); P.Next();
lit.vals.Add(x);
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
P.ParseExpressionList(); P.ParseExpressionList(lit.vals);
} }
} else if P.tok == Scanner.COLON { } else if P.tok == Scanner.COLON {
p := new(AST.Pair);
p.pos = P.pos;
p.x = x;
P.Next(); P.Next();
P.ParseExpression(); p.y = P.ParseExpression();
lit.vals.Add(p);
if P.tok == Scanner.COMMA { if P.tok == Scanner.COMMA {
P.Next(); P.Next();
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
P.ParseExpressionPairList(); P.ParseExpressionPairList(lit.vals);
} }
} }
} else {
lit.vals.Add(x);
} }
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
return nil; return lit;
} }
...@@ -645,15 +664,15 @@ func (P *Parser) ParseOperand() AST.Expr { ...@@ -645,15 +664,15 @@ func (P *Parser) ParseOperand() AST.Expr {
case Scanner.HASH: case Scanner.HASH:
P.Next(); P.Next();
P.ParseType(); typ := P.ParseType();
P.ParseCompositeLit(); P.ParseCompositeLit(typ);
op = AST.NIL; op = AST.NIL;
default: default:
if P.tok != Scanner.IDENT { if P.tok != Scanner.IDENT {
typ, ok := P.TryType(); typ, ok := P.TryType();
if ok { if ok {
op = P.ParseCompositeLit(); op = P.ParseCompositeLit(typ);
break; break;
} }
} }
...@@ -712,11 +731,14 @@ func (P *Parser) ParseIndexOrSlice(x AST.Expr) AST.Expr { ...@@ -712,11 +731,14 @@ func (P *Parser) ParseIndexOrSlice(x AST.Expr) AST.Expr {
} }
func (P *Parser) ParseCall(x AST.Expr) AST.Expr { func (P *Parser) ParseCall(x AST.Expr) *AST.Call {
P.Trace("Call"); P.Trace("Call");
pos := P.pos; call := new(AST.Call);
var args *AST.List = nil; call.pos = P.pos;
call.fun = x;
call.args = nil;
P.Expect(Scanner.LPAREN); P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
// first arguments could be a type if the call is to "new" // first arguments could be a type if the call is to "new"
...@@ -727,24 +749,24 @@ func (P *Parser) ParseCall(x AST.Expr) AST.Expr { ...@@ -727,24 +749,24 @@ func (P *Parser) ParseCall(x AST.Expr) AST.Expr {
if P.tok != Scanner.IDENT && P.tok != Scanner.LPAREN { if P.tok != Scanner.IDENT && P.tok != Scanner.LPAREN {
typ, ok := P.TryType(); typ, ok := P.TryType();
if ok { if ok {
call.args = AST.NewList();
call.args.Add(typ);
if P.tok == Scanner.COMMA { if P.tok == Scanner.COMMA {
P.Next(); P.Next();
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
args = P.ParseExpressionList(); P.ParseExpressionList(call.args);
} }
} }
} else { } else {
args = P.ParseExpressionList(); call.args = P.ParseNewExpressionList();
} }
} else { } else {
args = P.ParseExpressionList(); call.args = P.ParseNewExpressionList();
} }
} }
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
P.Ecart(); P.Ecart();
call := new(AST.Call);
call.pos, call.fun, call.args = pos, x, args;
return call; return call;
} }
...@@ -837,7 +859,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -837,7 +859,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
P.Trace("SimpleStat"); P.Trace("SimpleStat");
var stat AST.Stat = AST.NIL; var stat AST.Stat = AST.NIL;
x := P.ParseExpressionList(); x := P.ParseNewExpressionList();
switch P.tok { switch P.tok {
case Scanner.COLON: case Scanner.COLON:
...@@ -860,7 +882,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -860,7 +882,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN: Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN:
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.Next(); P.Next();
y := P.ParseExpressionList(); y := P.ParseNewExpressionList();
a := new(AST.Assignment); a := new(AST.Assignment);
a.pos, a.tok, a.lhs, a.rhs = pos, tok, x, y; a.pos, a.tok, a.lhs, a.rhs = pos, tok, x, y;
stat = a; stat = a;
...@@ -915,7 +937,7 @@ func (P *Parser) ParseReturnStat() *AST.ReturnStat { ...@@ -915,7 +937,7 @@ func (P *Parser) ParseReturnStat() *AST.ReturnStat {
P.Expect(Scanner.RETURN); P.Expect(Scanner.RETURN);
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE { if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
stat.res = P.ParseExpressionList(); stat.res = P.ParseNewExpressionList();
} }
P.Ecart(); P.Ecart();
...@@ -1020,7 +1042,7 @@ func (P *Parser) ParseCase() *AST.CaseClause { ...@@ -1020,7 +1042,7 @@ func (P *Parser) ParseCase() *AST.CaseClause {
if P.tok == Scanner.CASE { if P.tok == Scanner.CASE {
P.Next(); P.Next();
clause.exprs = P.ParseExpressionList(); clause.exprs = P.ParseNewExpressionList();
} else { } else {
P.Expect(Scanner.DEFAULT); P.Expect(Scanner.DEFAULT);
} }
...@@ -1218,6 +1240,7 @@ func (P *Parser) ParseConstSpec(exported bool) *AST.ConstDecl { ...@@ -1218,6 +1240,7 @@ func (P *Parser) ParseConstSpec(exported bool) *AST.ConstDecl {
decl.ident = P.ParseIdent(); decl.ident = P.ParseIdent();
var ok bool; var ok bool;
decl.typ, ok = P.TryType(); decl.typ, ok = P.TryType();
decl.val = AST.NIL;
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.Next(); P.Next();
...@@ -1248,12 +1271,13 @@ func (P *Parser) ParseVarSpec(exported bool) *AST.VarDecl { ...@@ -1248,12 +1271,13 @@ func (P *Parser) ParseVarSpec(exported bool) *AST.VarDecl {
decl.idents = P.ParseIdentList(); decl.idents = P.ParseIdentList();
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.Next(); P.Next();
decl.vals = P.ParseExpressionList(); decl.typ = AST.NIL;
decl.vals = P.ParseNewExpressionList();
} else { } else {
decl.typ = P.ParseVarType(); decl.typ = P.ParseVarType();
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.Next(); P.Next();
decl.vals = P.ParseExpressionList(); decl.vals = P.ParseNewExpressionList();
} }
} }
......
...@@ -107,7 +107,11 @@ func (P *Printer) DoMapType(x *AST.MapType) { ...@@ -107,7 +107,11 @@ func (P *Printer) DoMapType(x *AST.MapType) {
func (P *Printer) DoChannelType(x *AST.ChannelType) { func (P *Printer) DoChannelType(x *AST.ChannelType) {
P.String("chan "); switch x.mode {
case AST.FULL: P.String("chan ");
case AST.RECV: P.String("<-chan ");
case AST.SEND: P.String("chan <- ");
}
P.Print(x.elt); P.Print(x.elt);
} }
...@@ -226,8 +230,8 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) { ...@@ -226,8 +230,8 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) {
if i > 0 { if i > 0 {
P.NewLine(0); P.NewLine(0);
} }
//print("*** i = ", i, "\n");
P.Print(x.decls.at(i)); P.Print(x.decls.at(i));
P.String(";");
} }
P.NewLine(-1); P.NewLine(-1);
P.String(")"); P.String(")");
...@@ -300,6 +304,22 @@ func (P *Printer) DoSelector(x *AST.Selector) { ...@@ -300,6 +304,22 @@ func (P *Printer) DoSelector(x *AST.Selector) {
} }
func (P *Printer) DoCompositeLit(x *AST.CompositeLit) {
P.Print(x.typ);
P.String("{");
P.PrintList(x.vals);
P.String("}");
}
func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
P.String("func ");
P.Print(x.typ);
P.String(" ");
P.Print(x.body);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Statements // Statements
...@@ -320,8 +340,10 @@ func (P *Printer) DoBlock(x *AST.Block) { ...@@ -320,8 +340,10 @@ func (P *Printer) DoBlock(x *AST.Block) {
func (P *Printer) DoLabel(x *AST.Label) { func (P *Printer) DoLabel(x *AST.Label) {
P.NewLine(-1);
P.Print(x.ident); P.Print(x.ident);
P.String(":"); P.String(":");
P.indent++;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment