Commit 1595a194 authored by Robert Griesemer's avatar Robert Griesemer

today's snapshot: steps towards using interfaces for statements in ast

R=r
OCL=24380
CL=24380
parent 6aabf31a
......@@ -18,7 +18,7 @@ type (
Block struct;
Expr interface;
Stat struct;
StatImpl struct;
Decl struct;
)
......@@ -350,11 +350,11 @@ func NewBlock(pos, tok int) *Block {
// Expressions
type (
Visitor interface;
ExprVisitor interface;
Expr interface {
Pos() int;
Visit(v Visitor);
Visit(v ExprVisitor);
};
BadExpr struct {
......@@ -421,7 +421,7 @@ type (
)
type Visitor interface {
type ExprVisitor interface {
DoBadExpr(x *BadExpr);
DoIdent(x *Ident);
DoBinaryExpr(x *BinaryExpr);
......@@ -451,18 +451,18 @@ func (x *Index) Pos() int { return x.Pos_; }
func (x *Call) Pos() int { return x.Pos_; }
func (x *BadExpr) Visit(v Visitor) { v.DoBadExpr(x); }
func (x *Ident) Visit(v Visitor) { v.DoIdent(x); }
func (x *BinaryExpr) Visit(v Visitor) { v.DoBinaryExpr(x); }
func (x *UnaryExpr) Visit(v Visitor) { v.DoUnaryExpr(x); }
func (x *BasicLit) Visit(v Visitor) { v.DoBasicLit(x); }
func (x *FunctionLit) Visit(v Visitor) { v.DoFunctionLit(x); }
func (x *CompositeLit) Visit(v Visitor) { v.DoCompositeLit(x); }
func (x *TypeLit) Visit(v Visitor) { v.DoTypeLit(x); }
func (x *Selector) Visit(v Visitor) { v.DoSelector(x); }
func (x *TypeGuard) Visit(v Visitor) { v.DoTypeGuard(x); }
func (x *Index) Visit(v Visitor) { v.DoIndex(x); }
func (x *Call) Visit(v Visitor) { v.DoCall(x); }
func (x *BadExpr) Visit(v ExprVisitor) { v.DoBadExpr(x); }
func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); }
func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
func (x *TypeLit) Visit(v ExprVisitor) { v.DoTypeLit(x); }
func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }
func (x *Index) Visit(v ExprVisitor) { v.DoIndex(x); }
func (x *Call) Visit(v ExprVisitor) { v.DoCall(x); }
......@@ -518,23 +518,112 @@ func (t *Type) Nfields() int {
// ----------------------------------------------------------------------------
// Statements
type Stat struct {
type (
StatVisitor interface;
Stat interface {
Visit(v StatVisitor);
};
BadStat struct {
Pos int;
};
LabelDecl struct {
Pos int; // position of ":"
Label *Ident;
};
DeclarationStat struct {
Decl *Decl;
};
ExpressionStat struct {
Pos int; // position of Tok
Tok int; // INC, DEC, RETURN, GO, DEFER
Expr Expr;
};
IfStat struct {
Pos int; // position of "if"
Init Stat;
Cond Expr;
Body *Block;
Else Stat;
};
ForStat struct {
Pos int; // position of "for"
Init Stat;
Cond Expr;
Post Stat;
Body *Block;
};
SwitchStat struct {
Pos int; // position of "switch"
Init Stat;
Tag Expr;
Body *Block;
};
SelectStat struct {
Pos int; // position of "select"
Body *Block;
};
ControlFlowStat struct {
Pos int; // position of Tok
Tok int; // BREAK, CONTINUE, GOTO, FALLTHROUGH
Label *Ident; // if any, or nil
};
)
type StatVisitor interface {
DoBadStat(s *BadStat);
DoLabelDecl(s *LabelDecl);
DoDeclarationStat(s *DeclarationStat);
DoExpressionStat(s *ExpressionStat);
DoIfStat(s *IfStat);
DoForStat(s *ForStat);
DoSwitchStat(s *SwitchStat);
DoSelectStat(s *SelectStat);
DoControlFlowStat(s *ControlFlowStat);
}
func (s *BadStat) Visit(v StatVisitor) { v.DoBadStat(s); }
func (s *LabelDecl) Visit(v StatVisitor) { v.DoLabelDecl(s); }
func (s *DeclarationStat) Visit(v StatVisitor) { v.DoDeclarationStat(s); }
func (s *ExpressionStat) Visit(v StatVisitor) { v.DoExpressionStat(s); }
func (s *IfStat) Visit(v StatVisitor) { v.DoIfStat(s); }
func (s *ForStat) Visit(v StatVisitor) { v.DoForStat(s); }
func (s *SwitchStat) Visit(v StatVisitor) { v.DoSwitchStat(s); }
func (s *SelectStat) Visit(v StatVisitor) { v.DoSelectStat(s); }
func (s *ControlFlowStat) Visit(v StatVisitor) { v.DoControlFlowStat(s); }
// ----------------------------------------------------------------------------
// Old style statements
type StatImpl struct {
Node;
Init, Post *Stat;
Init, Post *StatImpl;
Expr Expr;
Body *Block; // composite statement body
Decl *Decl; // declaration statement
}
func NewStat(pos, tok int) *Stat {
s := new(Stat);
func NewStat(pos, tok int) *StatImpl {
s := new(StatImpl);
s.Pos, s.Tok = pos, tok;
return s;
}
var BadStat = NewStat(0, Scanner.ILLEGAL);
var OldBadStat = NewStat(0, Scanner.ILLEGAL);
// ----------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -371,9 +371,8 @@ func (P *Printer) Token(pos int, tok int) {
func (P *Printer) Error(pos int, tok int, msg string) {
P.String(0, "<");
P.Token(pos, tok);
P.String(0, " " + msg + ">");
fmt.Printf("\ninternal printing error: pos = %d, tok = %s, %s\n", pos, Scanner.TokenString(tok), msg);
panic();
}
......@@ -723,12 +722,25 @@ func (P *Printer) Expr(x AST.Expr) {
// ----------------------------------------------------------------------------
// Statements
func (P *Printer) Stat(s *AST.Stat)
func (P *Printer) Stat(s AST.Stat) {
s.Visit(P);
}
func (P *Printer) StatImpl(s *AST.StatImpl)
func (P *Printer) StatementList(list *array.Array) {
for i, n := 0, list.Len(); i < n; i++ {
P.newlines = 1; // for first entry
P.Stat(list.At(i).(*AST.Stat));
if s, is_StatImpl := list.At(i).(*AST.StatImpl); is_StatImpl {
P.StatImpl(s);
} else if s, is_Stat := list.At(i).(AST.Stat); is_Stat {
s.Visit(P);
} else {
panic();
}
P.newlines = 1;
P.state = inside_list;
}
......@@ -757,7 +769,7 @@ func (P *Printer) Block(b *AST.Block, indent bool) {
}
func (P *Printer) ControlClause(s *AST.Stat) {
func (P *Printer) OldControlClause(s *AST.StatImpl) {
has_post := s.Tok == Scanner.FOR && s.Post != nil; // post also used by "if"
P.separator = blank;
......@@ -770,7 +782,7 @@ func (P *Printer) ControlClause(s *AST.Stat) {
// all semicolons required
// (they are not separators, print them explicitly)
if s.Init != nil {
P.Stat(s.Init);
P.StatImpl(s.Init);
P.separator = none;
}
P.String(0, ";");
......@@ -783,7 +795,7 @@ func (P *Printer) ControlClause(s *AST.Stat) {
P.String(0, ";");
P.separator = blank;
if has_post {
P.Stat(s.Post);
P.StatImpl(s.Post);
}
}
}
......@@ -793,7 +805,7 @@ func (P *Printer) ControlClause(s *AST.Stat) {
func (P *Printer) Declaration(d *AST.Decl, parenthesized bool);
func (P *Printer) Stat(s *AST.Stat) {
func (P *Printer) StatImpl(s *AST.StatImpl) {
switch s.Tok {
case Scanner.EXPRSTAT:
// expression statement
......@@ -823,23 +835,23 @@ func (P *Printer) Stat(s *AST.Stat) {
case Scanner.IF:
P.String(s.Pos, "if");
P.ControlClause(s);
P.OldControlClause(s);
P.Block(s.Body, true);
if s.Post != nil {
P.separator = blank;
P.String(0, "else");
P.separator = blank;
P.Stat(s.Post);
P.StatImpl(s.Post);
}
case Scanner.FOR:
P.String(s.Pos, "for");
P.ControlClause(s);
P.OldControlClause(s);
P.Block(s.Body, true);
case Scanner.SWITCH, Scanner.SELECT:
P.Token(s.Pos, s.Tok);
P.ControlClause(s);
P.OldControlClause(s);
P.Block(s.Body, false);
case Scanner.CASE, Scanner.DEFAULT:
......@@ -872,6 +884,116 @@ func (P *Printer) Stat(s *AST.Stat) {
}
func (P *Printer) DoBadStat(s *AST.BadStat) {
panic();
}
func (P *Printer) DoLabelDecl(s *AST.LabelDecl) {
panic();
}
func (P *Printer) DoDeclarationStat(s *AST.DeclarationStat) {
P.Declaration(s.Decl, false);
}
func (P *Printer) DoExpressionStat(s *AST.ExpressionStat) {
switch s.Tok {
case Scanner.ILLEGAL:
P.Expr(s.Expr);
case Scanner.INC, Scanner.DEC:
P.Expr(s.Expr);
P.Token(s.Pos, s.Tok);
case Scanner.RETURN, Scanner.GO, Scanner.DEFER:
P.Token(s.Pos, s.Tok);
if s.Expr != nil {
P.separator = blank;
P.Expr(s.Expr);
}
default:
P.Error(s.Pos, s.Tok, "DoExpressionStat");
unreachable();
}
P.separator = semicolon;
}
func (P *Printer) ControlClause(isForStat bool, init AST.Stat, expr AST.Expr, post AST.Stat) {
P.separator = blank;
if init == nil && post == nil {
// no semicolons required
if expr != nil {
P.Expr(expr);
}
} else {
// all semicolons required
// (they are not separators, print them explicitly)
if init != nil {
P.Stat(init);
P.separator = none;
}
P.String(0, ";");
P.separator = blank;
if expr != nil {
P.Expr(expr);
P.separator = none;
}
if isForStat {
P.String(0, ";");
P.separator = blank;
if post != nil {
P.Stat(post);
}
}
}
P.separator = blank;
}
func (P *Printer) DoIfStat(s *AST.IfStat) {
P.String(s.Pos, "if");
P.ControlClause(false, s.Init, s.Cond, nil);
P.Block(s.Body, true);
if s.Else != nil {
P.separator = blank;
P.String(0, "else");
P.separator = blank;
P.Stat(s.Else);
}
}
func (P *Printer) DoForStat(s *AST.ForStat) {
P.String(s.Pos, "for");
P.ControlClause(true, s.Init, s.Cond, s.Post);
P.Block(s.Body, true);
}
func (P *Printer) DoSwitchStat(s *AST.SwitchStat) {
P.String(s.Pos, "switch");
P.ControlClause(false, s.Init, s.Tag, nil);
P.Block(s.Body, false);
}
func (P *Printer) DoSelectStat(s *AST.SelectStat) {
panic();
}
func (P *Printer) DoControlFlowStat(s *AST.ControlFlowStat) {
P.Token(s.Pos, s.Tok);
if s.Label != nil {
P.separator = blank;
P.Expr(s.Label);
}
P.separator = semicolon;
}
// ----------------------------------------------------------------------------
// Declarations
......
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