mirror of
https://github.com/golang/go
synced 2024-11-22 21:40:03 -07:00
- added initial formatting: indentation
- more AST nodes built and printed R=r OCL=15735 CL=15735
This commit is contained in:
parent
09bed25621
commit
83267dce11
@ -13,7 +13,11 @@ export type Visitor interface {
|
||||
DoNil(x *Nil);
|
||||
DoIdent(x *Ident);
|
||||
|
||||
// Types
|
||||
DoFunctionType(x *FunctionType);
|
||||
|
||||
// Declarations
|
||||
//DoVarDeclList(x *VarDeclList);
|
||||
DoFuncDecl(x *FuncDecl);
|
||||
|
||||
// Expressions
|
||||
@ -29,8 +33,8 @@ export type Visitor interface {
|
||||
DoBlock(x *Block);
|
||||
DoExprStat(x *ExprStat);
|
||||
DoAssignment(x *Assignment);
|
||||
DoIf(x *If);
|
||||
DoFor(x *For);
|
||||
DoIfStat(x *IfStat);
|
||||
DoForStat(x *ForStat);
|
||||
DoSwitch(x *Switch);
|
||||
DoReturn(x *Return);
|
||||
|
||||
@ -110,6 +114,24 @@ func (x *Nil) Visit(v Visitor) { v.DoNil(x); }
|
||||
func (x *Ident) Visit(v Visitor) { v.DoIdent(x); }
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
export type Type interface {
|
||||
Visit(x Visitor);
|
||||
}
|
||||
|
||||
|
||||
export type FunctionType struct {
|
||||
recv *VarDeclList;
|
||||
params *List;
|
||||
result *List;
|
||||
}
|
||||
|
||||
|
||||
func (x *FunctionType) Visit(v Visitor) { v.DoFunctionType(x); }
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Declarations
|
||||
|
||||
@ -118,13 +140,21 @@ export type Decl interface {
|
||||
}
|
||||
|
||||
|
||||
export type VarDeclList struct {
|
||||
idents *List;
|
||||
typ *Node;
|
||||
}
|
||||
|
||||
|
||||
export type FuncDecl struct {
|
||||
pos int;
|
||||
ident *Ident;
|
||||
typ *FunctionType;
|
||||
body *Block;
|
||||
}
|
||||
|
||||
|
||||
func (x *VarDeclList) Visit(v Visitor) { /*v.DoVarDeclList(x);*/ }
|
||||
func (x *FuncDecl) Visit(v Visitor) { v.DoFuncDecl(x); }
|
||||
|
||||
|
||||
@ -219,14 +249,17 @@ export type Assignment struct {
|
||||
}
|
||||
|
||||
|
||||
export type If struct {
|
||||
export type IfStat struct {
|
||||
pos int;
|
||||
init Stat;
|
||||
cond Expr;
|
||||
then, else_ *Block;
|
||||
}
|
||||
|
||||
|
||||
export type For struct {
|
||||
export type ForStat struct {
|
||||
pos int;
|
||||
body *Block;
|
||||
}
|
||||
|
||||
|
||||
@ -243,8 +276,8 @@ export type Return struct {
|
||||
func (x *Block) Visit(v Visitor) { v.DoBlock(x); }
|
||||
func (x *ExprStat) Visit(v Visitor) { v.DoExprStat(x); }
|
||||
func (x *Assignment) Visit(v Visitor) { v.DoAssignment(x); }
|
||||
func (x *If) Visit(v Visitor) { v.DoIf(x); }
|
||||
func (x *For) Visit(v Visitor) { v.DoFor(x); }
|
||||
func (x *IfStat) Visit(v Visitor) { v.DoIfStat(x); }
|
||||
func (x *ForStat) Visit(v Visitor) { v.DoForStat(x); }
|
||||
func (x *Switch) Visit(v Visitor) { v.DoSwitch(x); }
|
||||
func (x *Return) Visit(v Visitor) { v.DoReturn(x); }
|
||||
|
||||
|
@ -137,19 +137,18 @@ func (P *Parser) ParseIdent() *AST.Ident {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseIdentList() int {
|
||||
func (P *Parser) ParseIdentList() *AST.List {
|
||||
P.Trace("IdentList");
|
||||
|
||||
P.ParseIdent();
|
||||
n := 1;
|
||||
list := AST.NewList();
|
||||
list.Add(P.ParseIdent());
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
P.ParseIdent();
|
||||
n++;
|
||||
list.Add(P.ParseIdent());
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
return n;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@ -243,43 +242,47 @@ func (P *Parser) ParseChannelType() {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseVarDeclList() int {
|
||||
func (P *Parser) ParseVarDeclList() *AST.VarDeclList {
|
||||
P.Trace("VarDeclList");
|
||||
|
||||
n := P.ParseIdentList();
|
||||
res := new(AST.VarDeclList);
|
||||
res.idents = P.ParseIdentList();
|
||||
P.ParseVarType();
|
||||
|
||||
P.Ecart();
|
||||
return n;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseParameterList() int {
|
||||
// Returns a list of AST.VarDeclList
|
||||
func (P *Parser) ParseParameterList() *AST.List {
|
||||
P.Trace("ParameterList");
|
||||
|
||||
n := P.ParseVarDeclList();
|
||||
list := AST.NewList();
|
||||
list.Add(P.ParseVarDeclList());
|
||||
for P.tok == Scanner.COMMA {
|
||||
P.Next();
|
||||
n += P.ParseVarDeclList();
|
||||
list.Add(P.ParseVarDeclList());
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
return n;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseParameters() int {
|
||||
// Returns a list of AST.VarDeclList
|
||||
func (P *Parser) ParseParameters() *AST.List {
|
||||
P.Trace("Parameters");
|
||||
|
||||
n := 0;
|
||||
var list *AST.List;
|
||||
P.Expect(Scanner.LPAREN);
|
||||
if P.tok != Scanner.RPAREN {
|
||||
n = P.ParseParameterList();
|
||||
list = P.ParseParameterList();
|
||||
}
|
||||
P.Expect(Scanner.RPAREN);
|
||||
|
||||
P.Ecart();
|
||||
return n;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@ -299,7 +302,7 @@ func (P *Parser) ParseResultList() {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseResult() {
|
||||
func (P *Parser) ParseResult() *AST.List {
|
||||
P.Trace("Result");
|
||||
|
||||
if P.tok == Scanner.LPAREN {
|
||||
@ -317,6 +320,7 @@ func (P *Parser) ParseResult() {
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -326,19 +330,21 @@ func (P *Parser) ParseResult() {
|
||||
// (params) type
|
||||
// (params) (results)
|
||||
|
||||
func (P *Parser) ParseFunctionType() {
|
||||
func (P *Parser) ParseFunctionType() *AST.FunctionType {
|
||||
P.Trace("FunctionType");
|
||||
|
||||
P.OpenScope();
|
||||
P.level--;
|
||||
|
||||
P.ParseParameters();
|
||||
P.ParseResult();
|
||||
typ := new(AST.FunctionType);
|
||||
typ.params = P.ParseParameters();
|
||||
typ.result = P.ParseResult();
|
||||
|
||||
P.level++;
|
||||
P.CloseScope();
|
||||
|
||||
P.Ecart();
|
||||
return typ;
|
||||
}
|
||||
|
||||
|
||||
@ -892,25 +898,31 @@ func (P *Parser) ParseControlFlowStat(tok int) {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseIfStat() *AST.If {
|
||||
func (P *Parser) ParseIfStat() *AST.IfStat {
|
||||
P.Trace("IfStat");
|
||||
|
||||
x := new(AST.If);
|
||||
x := new(AST.IfStat);
|
||||
x.pos, x.cond = P.pos, AST.NIL;
|
||||
|
||||
var init, cond AST.Node = AST.NIL, AST.NIL;
|
||||
P.Expect(Scanner.IF);
|
||||
P.OpenScope();
|
||||
if P.tok != Scanner.LBRACE {
|
||||
if P.tok != Scanner.SEMICOLON {
|
||||
P.ParseSimpleStat();
|
||||
init = P.ParseSimpleStat();
|
||||
}
|
||||
if P.tok == Scanner.SEMICOLON {
|
||||
P.Next();
|
||||
if P.tok != Scanner.LBRACE {
|
||||
x.cond = P.ParseExpression();
|
||||
cond = P.ParseExpression();
|
||||
} else {
|
||||
cond = init;
|
||||
init = AST.NIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
x.init, x.cond = init, cond;
|
||||
|
||||
x.then = P.ParseBlock();
|
||||
if P.tok == Scanner.ELSE {
|
||||
P.Next();
|
||||
@ -931,9 +943,12 @@ func (P *Parser) ParseIfStat() *AST.If {
|
||||
}
|
||||
|
||||
|
||||
func (P *Parser) ParseForStat() {
|
||||
func (P *Parser) ParseForStat() *AST.ForStat {
|
||||
P.Trace("ForStat");
|
||||
|
||||
stat := new(AST.ForStat);
|
||||
stat.pos = P.pos;
|
||||
|
||||
P.Expect(Scanner.FOR);
|
||||
P.OpenScope();
|
||||
if P.tok != Scanner.LBRACE {
|
||||
@ -951,10 +966,11 @@ func (P *Parser) ParseForStat() {
|
||||
}
|
||||
}
|
||||
}
|
||||
P.ParseBlock();
|
||||
stat.body = P.ParseBlock();
|
||||
P.CloseScope();
|
||||
|
||||
P.Ecart();
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
@ -1113,7 +1129,7 @@ func (P *Parser) TryStatement() (AST.Stat, bool) {
|
||||
case Scanner.IF:
|
||||
stat = P.ParseIfStat();
|
||||
case Scanner.FOR:
|
||||
P.ParseForStat();
|
||||
stat = P.ParseForStat();
|
||||
case Scanner.SWITCH:
|
||||
P.ParseSwitchStat();
|
||||
case Scanner.RANGE:
|
||||
@ -1247,40 +1263,42 @@ func (P *Parser) ParseDecl(exported bool, keyword int) {
|
||||
func (P *Parser) ParseFuncDecl(exported bool) *AST.FuncDecl {
|
||||
P.Trace("FuncDecl");
|
||||
|
||||
pos := P.pos;
|
||||
fun := new(AST.FuncDecl);
|
||||
fun.pos = P.pos;
|
||||
|
||||
P.Expect(Scanner.FUNC);
|
||||
|
||||
P.OpenScope();
|
||||
P.level--;
|
||||
|
||||
var recv *AST.VarDeclList;
|
||||
if P.tok == Scanner.LPAREN {
|
||||
recv_pos := P.pos;
|
||||
n := P.ParseParameters();
|
||||
recv := P.ParseParameters().at(0);
|
||||
/*
|
||||
if n != 1 {
|
||||
P.Error(recv_pos, "must have exactly one receiver");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
ident := P.ParseIdent();
|
||||
|
||||
P.ParseFunctionType();
|
||||
fun.ident = P.ParseIdent();
|
||||
fun.typ = P.ParseFunctionType();
|
||||
fun.typ.recv = recv;
|
||||
|
||||
P.level++;
|
||||
P.CloseScope();
|
||||
|
||||
var body *AST.Block;
|
||||
if P.tok == Scanner.SEMICOLON {
|
||||
// forward declaration
|
||||
P.Next();
|
||||
} else {
|
||||
body = P.ParseBlock();
|
||||
fun.body = P.ParseBlock();
|
||||
}
|
||||
|
||||
P.Ecart();
|
||||
|
||||
x := new(AST.FuncDecl);
|
||||
x.pos, x.ident, x.body = pos, ident, body;
|
||||
return x;
|
||||
return fun;
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,18 @@ type Printer /* implements AST.Visitor */ struct {
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) NewLine(delta int) {
|
||||
P.indent += delta;
|
||||
if P.indent < 0 {
|
||||
panic("negative indent");
|
||||
}
|
||||
print("\n");
|
||||
for i := P.indent; i > 0; i-- {
|
||||
print("\t");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) String(s string) {
|
||||
print(s);
|
||||
}
|
||||
@ -23,7 +35,7 @@ func (P *Printer) Print(x AST.Node) {
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) PrintExprList(p *AST.List) {
|
||||
func (P *Printer) PrintList(p *AST.List) {
|
||||
if p != nil {
|
||||
for i := 0; i < p.len(); i++ {
|
||||
if i > 0 {
|
||||
@ -39,7 +51,8 @@ func (P *Printer) PrintExprList(p *AST.List) {
|
||||
// Basics
|
||||
|
||||
func (P *Printer) DoNil(x *AST.Nil) {
|
||||
P.String("?\n");
|
||||
P.String("?");
|
||||
P.NewLine(0);
|
||||
}
|
||||
|
||||
|
||||
@ -48,20 +61,48 @@ func (P *Printer) DoIdent(x *AST.Ident) {
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
func (P *Printer) DoFunctionType(x *AST.FunctionType) {
|
||||
/*
|
||||
if x.recv != nil {
|
||||
P.DoVarDeclList(x.recv);
|
||||
}
|
||||
*/
|
||||
P.String("(");
|
||||
P.PrintList(x.params);
|
||||
P.String(") ");
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Declarations
|
||||
|
||||
func (P *Printer) DoBlock(x *AST.Block);
|
||||
|
||||
|
||||
//func (P *Printer) DoVarDeclList(x *VarDeclList) {
|
||||
//}
|
||||
|
||||
|
||||
func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
|
||||
P.String("func ");
|
||||
if x.typ.recv != nil {
|
||||
P.String("(");
|
||||
P.PrintList(x.typ.recv.idents);
|
||||
P.String(") ");
|
||||
}
|
||||
P.DoIdent(x.ident);
|
||||
P.String("(... something here ...) ");
|
||||
P.DoFunctionType(x.typ);
|
||||
if x.body != nil {
|
||||
P.DoBlock(x.body);
|
||||
} else {
|
||||
P.String(";\n");
|
||||
P.String(";");
|
||||
}
|
||||
P.NewLine(0);
|
||||
P.NewLine(0);
|
||||
P.NewLine(0);
|
||||
}
|
||||
|
||||
|
||||
@ -106,7 +147,7 @@ func (P *Printer) DoIndex(x *AST.Index) {
|
||||
func (P *Printer) DoCall(x *AST.Call) {
|
||||
P.Print(x.fun);
|
||||
P.String("(");
|
||||
P.PrintExprList(x.args);
|
||||
P.PrintList(x.args);
|
||||
P.String(")");
|
||||
}
|
||||
|
||||
@ -123,55 +164,65 @@ func (P *Printer) DoSelector(x *AST.Selector) {
|
||||
|
||||
func (P *Printer) DoBlock(x *AST.Block) {
|
||||
if x == nil || x.stats == nil {
|
||||
P.String("\n");
|
||||
P.NewLine(0);
|
||||
return;
|
||||
}
|
||||
|
||||
P.String("{\n");
|
||||
P.indent++;
|
||||
P.String("{");
|
||||
P.NewLine(1);
|
||||
for i := 0; i < x.stats.len(); i++ {
|
||||
P.Print(x.stats.at(i));
|
||||
P.String("\n");
|
||||
if i > 0 {
|
||||
P.NewLine(0);
|
||||
}
|
||||
P.indent--;
|
||||
P.String("}\n");
|
||||
P.Print(x.stats.at(i));
|
||||
}
|
||||
P.NewLine(-1);
|
||||
P.String("}");
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) DoExprStat(x *AST.ExprStat) {
|
||||
P.Print(x.expr);
|
||||
P.String(";");
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) DoAssignment(x *AST.Assignment) {
|
||||
P.PrintExprList(x.lhs);
|
||||
P.PrintList(x.lhs);
|
||||
P.String(" " + Scanner.TokenName(x.tok) + " ");
|
||||
P.PrintExprList(x.rhs);
|
||||
P.PrintList(x.rhs);
|
||||
P.String(";");
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) DoIf(x *AST.If) {
|
||||
func (P *Printer) DoIfStat(x *AST.IfStat) {
|
||||
P.String("if ");
|
||||
P.Print(x.init);
|
||||
P.String("; ");
|
||||
P.Print(x.cond);
|
||||
P.DoBlock(x.then);
|
||||
if x.else_ != nil {
|
||||
P.String("else ");
|
||||
P.String(" else ");
|
||||
P.DoBlock(x.else_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) DoFor(x *AST.For) {
|
||||
func (P *Printer) DoForStat(x *AST.ForStat) {
|
||||
P.String("for ");
|
||||
P.DoBlock(x.body);
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) DoSwitch(x *AST.Switch) {
|
||||
P.String("switch ");
|
||||
}
|
||||
|
||||
|
||||
func (P *Printer) DoReturn(x *AST.Return) {
|
||||
P.String("return ");
|
||||
P.PrintExprList(x.res);
|
||||
P.PrintList(x.res);
|
||||
P.String(";");
|
||||
}
|
||||
|
||||
|
||||
@ -181,7 +232,7 @@ func (P *Printer) DoReturn(x *AST.Return) {
|
||||
func (P *Printer) DoProgram(x *AST.Program) {
|
||||
P.String("package ");
|
||||
P.DoIdent(x.ident);
|
||||
P.String("\n");
|
||||
P.NewLine(0);
|
||||
for i := 0; i < x.decls.len(); i++ {
|
||||
P.Print(x.decls.at(i));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user