Commit 82fbbdfc authored by Robert Griesemer's avatar Robert Griesemer

snapshot

- fixed expression and statement printing
- missing: declarations, comments

R=r
OCL=17207
CL=17207
parent 84523402
......@@ -11,7 +11,22 @@ pretty: pretty.6
test: pretty
pretty -s *.go
pretty -s ../gosrc/*.go
pretty -s $(GOROOT)/test/*.go
#pretty -s $(GOROOT)/test/*.go # contains incorrect programs
pretty -s $(GOROOT)/test/235.go
pretty -s $(GOROOT)/test/args.go
pretty -s $(GOROOT)/test/bufiolib.go
pretty -s $(GOROOT)/test/char_lit.go
pretty -s $(GOROOT)/test/complit.go
pretty -s $(GOROOT)/test/const.go
pretty -s $(GOROOT)/test/dialgoogle.go
pretty -s $(GOROOT)/test/empty.go
pretty -s $(GOROOT)/test/env.go
pretty -s $(GOROOT)/test/float_lit.go
pretty -s $(GOROOT)/test/fmt_test.go
pretty -s $(GOROOT)/test/for.go
pretty -s $(GOROOT)/test/func.go
pretty -s $(GOROOT)/test/func1.go
pretty -s $(GOROOT)/test/func2.go
pretty -s $(GOROOT)/src/pkg/*.go
pretty -s $(GOROOT)/src/lib/*.go
pretty -s $(GOROOT)/src/lib/*/*.go
......
......@@ -6,9 +6,9 @@ package Node
import Scanner "scanner"
type Node interface {}
type (
Node interface {};
Type struct;
Expr struct;
Stat struct;
......@@ -56,20 +56,6 @@ func (p *List) Add (x Node) {
}
/*
func (p *List) Print() {
print("(");
for i, n := 0, p.len(); i < n; i++ {
if i > 0 {
print(", ");
}
p.at(i).Print();
}
print(")");
}
*/
export func NewList() *List {
p := new(List);
p.a = new([] Node, 10) [0 : 0];
......@@ -110,19 +96,11 @@ export func NewType(pos, tok int) *Type {
// Expression pairs are represented as binary expressions with operator ":"
// Expression lists are represented as binary expressions with operator ","
export type Val struct {
i int;
f float;
s string;
t *Type;
}
export type Expr struct {
pos, tok int;
x, y *Expr; // binary (x, y) and unary (y) expressions
ident string; // identifiers
val *Val; // literals
s string; // identifiers and literals
t *Type; // declarations and composite literals
}
......@@ -138,28 +116,6 @@ func (x *Expr) len() int {
}
/*
func (x *Expr) Print() {
switch {
case x == nil:
print("nil");
case x.val != nil:
print(x.val.s);
default:
if x.x == nil {
print(Scanner.TokenName(x.tok));
} else {
x.x.Print();
print(" ");
print(Scanner.TokenName(x.tok));
print(" ");
}
x.y.Print();
}
}
*/
export func NewExpr(pos, tok int, x, y *Expr) *Expr {
e := new(Expr);
e.pos, e.tok, e.x, e.y = pos, tok, x, y;
......@@ -167,16 +123,9 @@ export func NewExpr(pos, tok int, x, y *Expr) *Expr {
}
export func NewIdent(pos int, ident string) *Expr {
e := new(Expr);
e.pos, e.tok, e.ident = pos, Scanner.IDENT, ident;
return e;
}
export func NewVal(pos, tok int, val *Val) *Expr {
export func NewLit(pos, tok int, s string) *Expr {
e := new(Expr);
e.pos, e.tok, e.val = pos, tok, val;
e.pos, e.tok, e.s = pos, tok, s;
return e;
}
......@@ -186,9 +135,8 @@ export func NewVal(pos, tok int, val *Val) *Expr {
export type Stat struct {
pos, tok int;
init *Stat;
expr *Expr;
post *Stat;
init, post *Stat;
lhs, expr *Expr;
block *List;
decl *Decl;
}
......@@ -204,14 +152,6 @@ export func NewStat(pos, tok int) *Stat {
// ----------------------------------------------------------------------------
// Declarations
export type VarDeclList struct {
}
func (d *VarDeclList) Print() {
}
export type Decl struct {
pos, tok int;
exported bool;
......
......@@ -66,7 +66,7 @@ func (P *Parser) Next() {
P.opt_semi = false;
if P.verbose {
P.PrintIndent();
print("[", P.pos, "] ", Scanner.TokenName(P.tok), "\n");
print("[", P.pos, "] ", Scanner.TokenString(P.tok), "\n");
}
}
......@@ -89,7 +89,7 @@ func (P *Parser) Error(pos int, msg string) {
func (P *Parser) Expect(tok int) {
if P.tok != tok {
P.Error(P.pos, "expected '" + Scanner.TokenName(tok) + "', found '" + Scanner.TokenName(P.tok) + "'");
P.Error(P.pos, "expected '" + Scanner.TokenString(tok) + "', found '" + Scanner.TokenString(P.tok) + "'");
}
P.Next(); // make progress in any case
}
......@@ -116,10 +116,10 @@ func (P *Parser) ParseIdent() *Node.Expr {
var x *Node.Expr;
if P.tok == Scanner.IDENT {
x = Node.NewIdent(P.pos, P.val);
x = Node.NewLit(P.pos, Scanner.IDENT, P.val);
if P.verbose {
P.PrintIndent();
print("Ident = \"", x.val, "\"\n");
print("Ident = \"", x.s, "\"\n");
}
P.Next();
} else {
......@@ -238,24 +238,35 @@ func (P *Parser) ParseChannelType() *Node.Type {
}
func (P *Parser) ParseVarDeclList() *Node.VarDeclList {
func (P *Parser) ParseVarDeclList() {
P.Trace("VarDeclList");
list := new(Node.VarDeclList);
P.ParseType();
list := Node.NewList();
list.Add(P.ParseType());
for P.tok == Scanner.COMMA {
P.Next();
P.ParseType();
list.Add(P.ParseType());
}
typ := P.TryType();
if typ == nil {
// we must have a list of types
if typ != nil {
// all list entries must be identifiers;
// convert the list into an expression list of identifiers
for i, n := 0, list.len(); i < n; i++ {
t := list.at(i).(*Node.Type);
if t.tok == Scanner.IDENT && t.expr.tok == Scanner.IDENT {
x := t.expr;
} else {
P.Error(t.pos, "identifier expected");
}
}
} else {
// all list entries are types
}
P.Ecart();
return list;
}
......@@ -263,10 +274,10 @@ func (P *Parser) ParseParameterList() *Node.List {
P.Trace("ParameterList");
list := Node.NewList();
list.Add(P.ParseVarDeclList());
P.ParseVarDeclList();
for P.tok == Scanner.COMMA {
P.Next();
list.Add(P.ParseVarDeclList());
P.ParseVarDeclList();
}
P.Ecart();
......@@ -394,7 +405,7 @@ func (P *Parser) ParseStructType() *Node.Type {
P.Next();
t.list = Node.NewList();
for P.tok == Scanner.IDENT {
t.list.Add(P.ParseVarDeclList());
P.ParseVarDeclList();
if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON);
}
......@@ -529,18 +540,13 @@ func (P *Parser) ParseOperand() *Node.Expr {
P.expr_lev--;
P.Expect(Scanner.RPAREN);
case Scanner.INT, Scanner.FLOAT:
val := new(Node.Val);
val.s = P.val;
x = Node.NewVal(P.pos, P.tok, val);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x = Node.NewLit(P.pos, P.tok, P.val);
P.Next();
case Scanner.STRING:
val := new(Node.Val);
val.s = P.val;
x = Node.NewVal(P.pos, Scanner.STRING, val);
for P.Next(); P.tok == Scanner.STRING; P.Next() {
val.s += P.val;
if x.tok == Scanner.STRING {
for ; P.tok == Scanner.STRING; P.Next() {
x.s += P.val;
}
}
case Scanner.FUNC:
......@@ -744,12 +750,12 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
P.Trace("SimpleStat");
var s *Node.Stat;
list := P.ParseExpressionList();
x := P.ParseExpressionList();
switch P.tok {
case Scanner.COLON:
// label declaration
if list.len() == 1 {
if x.len() == 1 {
} else {
P.Error(P.pos, "illegal label declaration");
}
......@@ -763,21 +769,22 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN:
s = Node.NewStat(P.pos, P.tok);
P.Next();
s.lhs = x;
s.expr = P.ParseExpressionList();
default:
if P.tok == Scanner.INC || P.tok == Scanner.DEC {
s = Node.NewStat(P.pos, P.tok);
if list.len() == 1 {
s.expr = list;
if x.len() == 1 {
s.expr = x;
} else {
P.Error(P.pos, "more then one operand");
}
P.Next();
} else {
s = Node.NewStat(P.pos, 0); // TODO give this a token value
if list.len() == 1 {
s.expr = list;
if x.len() == 1 {
s.expr = x;
} else {
P.Error(P.pos, "syntax error");
}
......@@ -830,7 +837,7 @@ func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat {
func (P *Parser) ParseControlClause(keyword int) *Node.Stat {
P.Trace("StatHeader");
P.Trace("ControlClause");
s := Node.NewStat(P.pos, keyword);
P.Expect(keyword);
......@@ -872,9 +879,9 @@ func (P *Parser) ParseIfStat() *Node.Stat {
if P.tok == Scanner.ELSE {
P.Next();
if P.tok == Scanner.IF {
P.ParseIfStat();
s.post = P.ParseIfStat();
} else {
P.ParseStatement();
s.post = P.ParseStatement();
}
}
......@@ -1005,12 +1012,6 @@ func (P *Parser) ParseFallthroughStat() *Node.Stat {
}
func (P *Parser) ParseEmptyStat() {
P.Trace("EmptyStat");
P.Ecart();
}
func (P *Parser) ParseRangeStat() *Node.Stat {
P.Trace("RangeStat");
......@@ -1026,6 +1027,12 @@ func (P *Parser) ParseRangeStat() *Node.Stat {
}
func (P *Parser) ParseEmptyStat() {
P.Trace("EmptyStat");
P.Ecart();
}
func (P *Parser) ParseStatement() *Node.Stat {
P.Trace("Statement");
indent := P.indent;
......
......@@ -13,7 +13,6 @@ export type Printer struct {
indent int; // indentation level
semi bool; // pending ";"
newl bool; // pending "\n"
prec int; // operator precedence
}
......@@ -32,6 +31,11 @@ func (P *Printer) String(s string) {
}
func (P *Printer) Token(tok int) {
P.String(Scanner.TokenString(tok));
}
func (P *Printer) NewLine() { // explicit "\n"
print("\n");
P.semi, P.newl = false, true;
......@@ -139,106 +143,68 @@ func (P *Printer) Type(t *Node.Type) {
// ----------------------------------------------------------------------------
// Expressions
func (P *Printer) Val(tok int, val *Node.Val) {
P.String(val.s); // for now
}
func (P *Printer) Expr(x *Node.Expr) {
func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
if x == nil {
return; // empty expression list
}
switch x.tok {
case Scanner.IDENT:
P.String(x.ident);
case Scanner.INT, Scanner.STRING, Scanner.FLOAT:
P.Val(x.tok, x.val);
case Scanner.LPAREN:
// calls
P.Expr(x.x);
P.String("(");
P.Expr(x.y);
P.String(")");
case Scanner.IDENT, Scanner.INT, Scanner.STRING, Scanner.FLOAT:
P.String(x.s);
case Scanner.COMMA:
P.Expr1(x.x, 0);
P.String(", ");
P.Expr1(x.y, 0);
case Scanner.PERIOD:
P.Expr1(x.x, 8);
P.String(".");
P.Expr1(x.y, 8);
case Scanner.LBRACK:
P.Expr(x.x);
P.Expr1(x.x, 8);
P.String("[");
P.Expr(x.y);
P.Expr1(x.y, 0);
P.String("]");
case Scanner.LPAREN:
P.Expr1(x.x, 8);
P.String("(");
P.Expr1(x.y, 0);
P.String(")");
default:
if x.x == nil {
// unary expression
P.String(Scanner.TokenName(x.tok));
P.Expr(x.y);
P.Token(x.tok);
P.Expr1(x.y, 7);
} else {
// binary expression: print ()'s if necessary
// TODO: pass precedence as parameter instead
outer := P.prec;
P.prec = Scanner.Precedence(x.tok);
if P.prec < outer {
prec := Scanner.Precedence(x.tok);
if prec < prec1 {
print("(");
}
P.Expr(x.x);
if x.tok != Scanner.PERIOD && x.tok != Scanner.COMMA {
P.String(" ");
}
P.String(Scanner.TokenName(x.tok));
if x.tok != Scanner.PERIOD {
P.String(" ");
}
P.Expr(x.y);
if P.prec < outer {
P.Expr1(x.x, prec);
P.String(" ");
P.Token(x.tok);
P.String(" ");
P.Expr1(x.y, prec);
if prec < prec1 {
print(")");
}
P.prec = outer;
}
}
}
// ----------------------------------------------------------------------------
// Statements
/*
func (P *Printer) DoLabel(x *AST.Label) {
P.indent--;
P.newl = true;
P.Print(x.ident);
P.String(":");
P.indent++;
}
func (P *Printer) DoExprStat(x *AST.ExprStat) {
P.Print(x.expr);
P.semi = true;
}
func (P *Printer) DoAssignment(x *AST.Assignment) {
P.PrintList(x.lhs);
P.String(" " + Scanner.TokenName(x.tok) + " ");
P.PrintList(x.rhs);
P.semi = true;
func (P *Printer) Expr(x *Node.Expr) {
P.Expr1(x, 0);
}
func (P *Printer) DoIfStat(x *AST.IfStat) {
P.String("if");
P.PrintControlClause(x.ctrl);
P.DoBlock(x.then);
if x.has_else {
P.newl = false;
P.String(" else ");
P.Print(x.else_);
}
}
*/
// ----------------------------------------------------------------------------
// Statements
func (P *Printer) Stat(s *Node.Stat)
......@@ -250,9 +216,15 @@ func (P *Printer) StatementList(list *Node.List) {
}
func (P *Printer) Block(list *Node.List) {
func (P *Printer) Block(list *Node.List, indent bool) {
P.OpenScope("{");
if !indent {
P.indent--;
}
P.StatementList(list);
if !indent {
P.indent++;
}
P.CloseScope("}");
}
......@@ -269,7 +241,7 @@ func (P *Printer) ControlClause(s *Node.Stat) {
P.Expr(s.expr);
P.semi = false;
}
if s.post != nil {
if s.tok == Scanner.FOR && s.post != nil {
P.semi = true;
P.String(" ");
P.Stat(s.post);
......@@ -286,6 +258,7 @@ func (P *Printer) Stat(s *Node.Stat) {
P.String("<nil stat>");
return;
}
switch s.tok {
case 0: // TODO use a real token const
P.Expr(s.expr);
......@@ -298,23 +271,43 @@ func (P *Printer) Stat(s *Node.Stat) {
Scanner.SUB_ASSIGN, Scanner.MUL_ASSIGN, Scanner.QUO_ASSIGN,
Scanner.REM_ASSIGN, Scanner.AND_ASSIGN, Scanner.OR_ASSIGN,
Scanner.XOR_ASSIGN, Scanner.SHL_ASSIGN, Scanner.SHR_ASSIGN:
P.String(Scanner.TokenName(s.tok));
P.Expr(s.lhs);
P.String(" ");
P.Token(s.tok);
P.String(" ");
P.Expr(s.expr);
P.semi = true;
case Scanner.INC, Scanner.DEC:
P.Expr(s.expr);
P.String(Scanner.TokenName(s.tok));
P.Token(s.tok);
P.semi = true;
case Scanner.IF, Scanner.FOR, Scanner.SWITCH, Scanner.SELECT:
P.String(Scanner.TokenName(s.tok));
case Scanner.LBRACE:
P.Block(s.block, true);
case Scanner.IF:
P.String("if");
P.ControlClause(s);
P.Block(s.block);
P.Block(s.block, true);
if s.post != nil {
P.newl = false;
P.String(" else ");
P.Stat(s.post);
}
case Scanner.FOR:
P.String("for");
P.ControlClause(s);
P.Block(s.block, true);
case Scanner.SWITCH, Scanner.SELECT:
P.Token(s.tok);
P.ControlClause(s);
P.Block(s.block, false);
case Scanner.CASE, Scanner.DEFAULT:
P.String(Scanner.TokenName(s.tok));
P.Token(s.tok);
if s.expr != nil {
P.String(" ");
P.Expr(s.expr);
......@@ -323,9 +316,10 @@ func (P *Printer) Stat(s *Node.Stat) {
P.OpenScope("");
P.StatementList(s.block);
P.CloseScope("");
case Scanner.GO, Scanner.RETURN, Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO:
P.String("go ");
P.Token(s.tok);
P.String(" ");
P.Expr(s.expr);
P.semi = true;
......@@ -341,15 +335,6 @@ func (P *Printer) Stat(s *Node.Stat) {
/*
func (P *Printer) DoImportDecl(x *AST.ImportDecl) {
if x.ident != nil {
P.Print(x.ident);
P.String(" ");
}
P.String(x.file);
}
func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
P.String("func ");
if x.typ.recv != nil {
......@@ -383,7 +368,7 @@ func (P *Printer) Declaration(d *Node.Decl) {
if d.exported {
P.String("export ");
}
P.String(Scanner.TokenName(d.tok));
P.Token(d.tok);
P.String(" ");
}
......@@ -417,10 +402,11 @@ func (P *Printer) Declaration(d *Node.Decl) {
panic("must be a func declaration");
}
P.String(" ");
P.Block(d.list);
P.Block(d.list, true);
}
}
// extra newline at the top level
if P.level == 0 {
P.NewLine();
}
......
......@@ -106,7 +106,7 @@ export const (
)
export func TokenName(tok int) string {
export func TokenString(tok int) string {
switch (tok) {
case ILLEGAL: return "ILLEGAL";
......@@ -233,7 +233,7 @@ func init() {
Keywords = new(map [string] int);
for i := KEYWORDS_BEG + 1; i < KEYWORDS_END; i++ {
Keywords[TokenName(i)] = i;
Keywords[TokenString(i)] = i;
}
// Provide column information in error messages for gri only...
......
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