Commit 3cfd91f8 authored by Robert Griesemer's avatar Robert Griesemer

daily snapshot:

- use explicit expression lists instead of binary trees to represent lists of the form a, b, c
(per discussion w/ Russ)
- use explicit nodes for various language constructs for better readability
- various adjustments in parsing and printing

next steps:
- clean up AST fully so it can be checked in as library

R=r
OCL=26371
CL=26371
parent dea4394a
......@@ -273,37 +273,6 @@ func (x *MapType) Visit(v ExprVisitor) { v.DoMapType(x); }
func (x *ChannelType) Visit(v ExprVisitor) { v.DoChannelType(x); }
// Length of a comma-separated expression list.
func ExprLen(x Expr) int {
if x == nil {
return 0;
}
n := 1;
for {
if p, ok := x.(*BinaryExpr); ok && p.Tok == token.COMMA {
n++;
x = p.Y;
} else {
break;
}
}
return n;
}
func ExprAt(x Expr, i int) Expr {
for j := 0; j < i; j++ {
assert(x.(*BinaryExpr).Tok == token.COMMA);
x = x.(*BinaryExpr).Y;
}
if t, is_binary := x.(*BinaryExpr); is_binary && t.Tok == token.COMMA {
x = t.X;
}
return x;
}
// ----------------------------------------------------------------------------
// Blocks
//
......@@ -357,6 +326,24 @@ type (
Expr Expr;
};
AssignmentStat struct {
Loc scanner.Location; // location of Tok
Tok int; // assignment token
Lhs, Rhs Expr;
};
TupleAssignStat struct {
Loc scanner.Location; // location of Tok
Tok int; // assignment token
Lhs, Rhs []Expr;
};
IncDecStat struct {
Loc scanner.Location; // location of '++' or '--'
Tok int; // token.INC or token.DEC
Expr Expr;
};
CompositeStat struct {
Body *Block;
};
......@@ -369,6 +356,13 @@ type (
Else Stat;
};
RangeClause struct { // appears only as Init stat in a ForStat
Loc scanner.Location; // location of "=" or ":="
Tok int; // token.ASSIGN or token.DEFINE
Lhs []Expr;
Rhs Expr;
};
ForStat struct {
Loc scanner.Location; // location of "for"
Init Stat;
......@@ -377,9 +371,15 @@ type (
Body *Block;
};
TypeSwitchClause struct { // appears only as Init stat in a SwitchStat
Loc scanner.Location; // location of ":="
Lhs *Ident;
Rhs Expr;
};
CaseClause struct {
Loc scanner.Location; // position for "case" or "default"
Expr Expr; // nil means default case
Loc scanner.Location; // location of "case" or "default"
Values []Expr; // nil means default case
Body *Block;
};
......@@ -389,7 +389,14 @@ type (
Tag Expr;
Body *Block;
};
CommClause struct {
Loc scanner.Location; // location of "case" or "default"
Tok int; // token.ASSIGN, token.DEFINE (valid only if Lhs != nil)
Lhs, Rhs Expr; // Rhs == nil means default case
Body *Block;
};
SelectStat struct {
Loc scanner.Location; // location of "select"
Body *Block;
......@@ -401,6 +408,11 @@ type (
Label *Ident; // if any, or nil
};
ReturnStat struct {
Loc scanner.Location; // location of "return"
Results []Expr;
};
EmptyStat struct {
Loc scanner.Location; // location of ";"
};
......@@ -412,13 +424,20 @@ type StatVisitor interface {
DoLabeledStat(s *LabeledStat);
DoDeclarationStat(s *DeclarationStat);
DoExpressionStat(s *ExpressionStat);
DoAssignmentStat(s *AssignmentStat);
DoTupleAssignStat(s *TupleAssignStat);
DoIncDecStat(s *IncDecStat);
DoCompositeStat(s *CompositeStat);
DoIfStat(s *IfStat);
DoRangeClause(s *RangeClause);
DoForStat(s *ForStat);
DoTypeSwitchClause(s *TypeSwitchClause);
DoCaseClause(s *CaseClause);
DoSwitchStat(s *SwitchStat);
DoCommClause(s *CommClause);
DoSelectStat(s *SelectStat);
DoControlFlowStat(s *ControlFlowStat);
DoReturnStat(s *ReturnStat);
DoEmptyStat(s *EmptyStat);
}
......@@ -427,13 +446,20 @@ func (s *BadStat) Visit(v StatVisitor) { v.DoBadStat(s); }
func (s *LabeledStat) Visit(v StatVisitor) { v.DoLabeledStat(s); }
func (s *DeclarationStat) Visit(v StatVisitor) { v.DoDeclarationStat(s); }
func (s *ExpressionStat) Visit(v StatVisitor) { v.DoExpressionStat(s); }
func (s *AssignmentStat) Visit(v StatVisitor) { v.DoAssignmentStat(s); }
func (s *TupleAssignStat) Visit(v StatVisitor) { v.DoTupleAssignStat(s); }
func (s *IncDecStat) Visit(v StatVisitor) { v.DoIncDecStat(s); }
func (s *CompositeStat) Visit(v StatVisitor) { v.DoCompositeStat(s); }
func (s *IfStat) Visit(v StatVisitor) { v.DoIfStat(s); }
func (s *RangeClause) Visit(v StatVisitor) { v.DoRangeClause(s); }
func (s *ForStat) Visit(v StatVisitor) { v.DoForStat(s); }
func (s *TypeSwitchClause) Visit(v StatVisitor) { v.DoTypeSwitchClause(s); }
func (s *CaseClause) Visit(v StatVisitor) { v.DoCaseClause(s); }
func (s *SwitchStat) Visit(v StatVisitor) { v.DoSwitchStat(s); }
func (s *CommClause) Visit(v StatVisitor) { v.DoCommClause(s); }
func (s *SelectStat) Visit(v StatVisitor) { v.DoSelectStat(s); }
func (s *ControlFlowStat) Visit(v StatVisitor) { v.DoControlFlowStat(s); }
func (s *ReturnStat) Visit(v StatVisitor) { v.DoReturnStat(s); }
func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); }
......@@ -461,7 +487,7 @@ type (
Loc scanner.Location; // if > 0: position of "const"
Names []*Ident;
Typ Expr;
Vals Expr;
Values []Expr;
Comment CommentGroup;
};
......@@ -476,7 +502,7 @@ type (
Loc scanner.Location; // if > 0: position of "var"
Names []*Ident;
Typ Expr;
Vals Expr;
Values []Expr;
Comment CommentGroup;
};
......
This diff is collapsed.
......@@ -463,6 +463,18 @@ func (P *Printer) Idents(list []*ast.Ident, full bool) int {
}
func (P *Printer) Exprs(list []ast.Expr) {
for i, x := range list {
if i > 0 {
P.Token(noloc, token.COMMA);
P.separator = blank;
P.state = inside_list;
}
P.Expr(x);
}
}
func (P *Printer) Parameters(list []*ast.Field) {
P.Token(noloc, token.LPAREN);
if len(list) > 0 {
......@@ -856,6 +868,30 @@ func (P *Printer) DoExpressionStat(s *ast.ExpressionStat) {
}
func (P *Printer) DoAssignmentStat(s *ast.AssignmentStat) {
P.Expr(s.Lhs);
P.separator = blank;
P.Token(s.Loc, s.Tok);
P.separator = blank;
P.Expr(s.Rhs);
}
func (P *Printer) DoTupleAssignStat(s *ast.TupleAssignStat) {
P.Exprs(s.Lhs);
P.separator = blank;
P.Token(s.Loc, s.Tok);
P.separator = blank;
P.Exprs(s.Rhs);
}
func (P *Printer) DoIncDecStat(s *ast.IncDecStat) {
P.Expr(s.Expr);
P.Token(s.Loc, s.Tok);
}
func (P *Printer) DoCompositeStat(s *ast.CompositeStat) {
P.Block(s.Body, true);
}
......@@ -868,6 +904,12 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
if expr != nil {
P.Expr(expr);
}
} else if range_clause, ok := init.(*ast.RangeClause); ok {
// range clause
P.Stat(range_clause);
} else if typeswitch_clause, ok := init.(*ast.TypeSwitchClause); ok {
// type switch clause
P.Stat(typeswitch_clause);
} else {
// all semicolons required
// (they are not separators, print them explicitly)
......@@ -906,6 +948,17 @@ func (P *Printer) DoIfStat(s *ast.IfStat) {
}
func (P *Printer) DoRangeClause(s *ast.RangeClause) {
P.Exprs(s.Lhs);
P.separator = blank;
P.Token(s.Loc, s.Tok);
P.separator = blank;
P.Token(noloc, token.RANGE);
P.separator = blank;
P.Expr(s.Rhs);
}
func (P *Printer) DoForStat(s *ast.ForStat) {
P.Token(s.Loc, token.FOR);
P.ControlClause(true, s.Init, s.Cond, s.Post);
......@@ -913,11 +966,24 @@ func (P *Printer) DoForStat(s *ast.ForStat) {
}
func (P *Printer) DoTypeSwitchClause(s *ast.TypeSwitchClause) {
P.Expr(s.Lhs);
P.separator = blank;
P.Token(s.Loc, token.DEFINE);
P.separator = blank;
P.Expr(s.Rhs);
P.Token(s.Loc, token.PERIOD);
P.Token(s.Loc, token.LPAREN);
P.Token(s.Loc, token.TYPE);
P.Token(s.Loc, token.RPAREN);
}
func (P *Printer) DoCaseClause(s *ast.CaseClause) {
if s.Expr != nil {
if s.Values != nil {
P.Token(s.Loc, token.CASE);
P.separator = blank;
P.Expr(s.Expr);
P.Exprs(s.Values);
} else {
P.Token(s.Loc, token.DEFAULT);
}
......@@ -938,6 +1004,37 @@ func (P *Printer) DoSwitchStat(s *ast.SwitchStat) {
}
func (P *Printer) DoTypeSwitchStat(s *ast.SwitchStat) {
P.Token(s.Loc, token.SWITCH);
P.ControlClause(false, s.Init, s.Tag, nil);
P.Block(s.Body, false);
}
func (P *Printer) DoCommClause(s *ast.CommClause) {
if s.Rhs != nil {
P.Token(s.Loc, token.CASE);
P.separator = blank;
if s.Lhs != nil {
P.Expr(s.Lhs);
P.separator = blank;
P.Token(noloc, s.Tok);
P.separator = blank;
}
P.Expr(s.Rhs);
} else {
P.Token(s.Loc, token.DEFAULT);
}
// TODO: try to use P.Block instead
// P.Block(s.Body, true);
P.Token(s.Body.Loc, token.COLON);
P.indentation++;
P.StatementList(s.Body.List);
P.indentation--;
P.newlines = 1;
}
func (P *Printer) DoSelectStat(s *ast.SelectStat) {
P.Token(s.Loc, token.SELECT);
P.separator = blank;
......@@ -954,6 +1051,13 @@ func (P *Printer) DoControlFlowStat(s *ast.ControlFlowStat) {
}
func (P *Printer) DoReturnStat(s *ast.ReturnStat) {
P.Token(s.Loc, token.RETURN);
P.separator = blank;
P.Exprs(s.Results);
}
func (P *Printer) DoEmptyStat(s *ast.EmptyStat) {
P.String(s.Loc, "");
}
......@@ -999,11 +1103,11 @@ func (P *Printer) DoConstDecl(d *ast.ConstDecl) {
P.separator = blank; // TODO switch to tab? (indentation problem with structs)
P.Expr(d.Typ);
}
if d.Vals != nil {
if d.Values != nil {
P.separator = tab;
P.Token(noloc, token.ASSIGN);
P.separator = blank;
P.Expr(d.Vals);
P.Exprs(d.Values);
}
P.newlines = 2;
}
......@@ -1032,11 +1136,11 @@ func (P *Printer) DoVarDecl(d *ast.VarDecl) {
P.Expr(d.Typ);
//P.separator = P.Type(d.Typ);
}
if d.Vals != nil {
if d.Values != nil {
P.separator = tab;
P.Token(noloc, token.ASSIGN);
P.separator = blank;
P.Expr(d.Vals);
P.Exprs(d.Values);
}
P.newlines = 2;
}
......
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