Commit c13c03c2 authored by Robert Griesemer's avatar Robert Griesemer

- first cut at building and printing AST

R=r
OCL=15675
CL=15675
parent 4d12c0e1
...@@ -9,16 +9,16 @@ pretty: pretty.6 ...@@ -9,16 +9,16 @@ pretty: pretty.6
$(L) -o pretty pretty.6 $(L) -o pretty pretty.6
test: pretty test: pretty
pretty *.go pretty -s *.go
pretty ../gosrc/*.go pretty -s ../gosrc/*.go
pretty $(GOROOT)/test/sieve.go pretty -s $(GOROOT)/test/sieve.go
pretty $(GOROOT)/src/pkg/*.go pretty -s $(GOROOT)/src/pkg/*.go
pretty $(GOROOT)/src/lib/flag.go pretty -s $(GOROOT)/src/lib/flag.go
pretty $(GOROOT)/src/lib/fmt.go pretty -s $(GOROOT)/src/lib/fmt.go
pretty $(GOROOT)/src/lib/rand.go pretty -s $(GOROOT)/src/lib/rand.go
pretty $(GOROOT)/src/lib/math/*.go pretty -s $(GOROOT)/src/lib/math/*.go
pretty $(GOROOT)/src/lib/container/*.go pretty -s $(GOROOT)/src/lib/container/*.go
pretty $(GOROOT)/src/syscall/*.go pretty -s $(GOROOT)/src/syscall/*.go
echo "DONE" echo "DONE"
install: pretty install: pretty
...@@ -29,7 +29,7 @@ clean: ...@@ -29,7 +29,7 @@ clean:
pretty.6: parser.6 printer.6 platform.6 scanner.6 pretty.6: parser.6 printer.6 platform.6 scanner.6
parser.6: ast.6 scanner.6 utils.6 parser.6: ast.6 scanner.6 utils.6 printer.6
scanner.6: utils.6 platform.6 scanner.6: utils.6 platform.6
......
...@@ -4,36 +4,114 @@ ...@@ -4,36 +4,114 @@
package AST; package AST;
// ----------------------------------------------------------------------------
// Lists
export type Element interface {}
export type List struct {
a *[] Element
}
func (p *List) len() int {
return len(p.a);
}
func (p *List) at(i int) Element {
return p.a[i];
}
func (p *List) Add (x Element) {
a := p.a;
n := len(a);
if n == cap(a) {
b := new([] interface {}, 2*n);
for i := 0; i < n; i++ {
b[i] = a[i];
}
a = b;
}
a = a[0 : n + 1];
a[n] = x;
p.a = a;
}
export func NewList() *List {
p := new(List);
p.a = new([] interface {}, 10);
return p;
}
// ----------------------------------------------------------------------------
// Expressions
export type Expr interface { export type Expr interface {
pos() int;
print();
} }
export type Stat interface { export type Selector struct {
pos() int; pos int;
print(); x Expr;
field string;
} }
// --------------------------------------------------------------------- export type Index struct {
// Concrete nodes pos int;
x Expr;
index Expr;
}
export type Ident struct { export type Pair struct {
pos_ int; pos int;
val_ string; x, y Expr;
} }
func (p *Ident) pos() int { export type Binary struct {
return p.pos_; pos int;
tok int;
x, y Expr;
} }
func (p *Ident) print() { export type Unary struct {
print("x"); // TODO fix this pos int;
tok int;
x Expr;
}
export type Literal struct {
pos int;
tok int;
val string;
}
// ----------------------------------------------------------------------------
// Statements
// ----------------------------------------------------------------------------
// Visitor
export type Visitor interface {
DoBinary(x *Binary);
//DoUnary(x *Unary);
//DoLiteral(x *Literal);
} }
// TODO: complete this func (x *Binary) Visit(v Visitor) { v.DoBinary(x); }
//func (x *Unary) Visit(v Visitor) { v.DoUnary(x); }
//func (x *Literal) Visit(v Visitor) { v.DoLiteral(x); }
...@@ -6,8 +6,11 @@ package Parser ...@@ -6,8 +6,11 @@ package Parser
import Scanner "scanner" import Scanner "scanner"
import AST "ast" import AST "ast"
import Printer "printer"
export type Parser struct { export type Parser struct {
silent bool;
verbose bool; verbose bool;
indent uint; indent uint;
scanner *Scanner.Scanner; scanner *Scanner.Scanner;
...@@ -65,8 +68,9 @@ func (P *Parser) Next() { ...@@ -65,8 +68,9 @@ func (P *Parser) Next() {
} }
func (P *Parser) Open(verbose bool, scanner *Scanner.Scanner, tokchan *<-chan *Scanner.Token) { func (P *Parser) Open(silent, verbose bool, scanner *Scanner.Scanner, tokchan *<-chan *Scanner.Token) {
P.verbose = verbose; P.silent = silent;
P.verbose = verbose;
P.indent = 0; P.indent = 0;
P.scanner = scanner; P.scanner = scanner;
P.tokchan = tokchan; P.tokchan = tokchan;
...@@ -115,16 +119,16 @@ func (P *Parser) TryStatement() bool; ...@@ -115,16 +119,16 @@ func (P *Parser) TryStatement() bool;
func (P *Parser) ParseDeclaration(); func (P *Parser) ParseDeclaration();
func (P *Parser) ParseIdent() *AST.Ident { func (P *Parser) ParseIdent() *AST.Literal {
P.Trace("Ident"); P.Trace("Ident");
ident := new(AST.Ident); ident := new(AST.Literal);
ident.pos_, ident.val_ = P.pos, ""; ident.pos, ident.tok, ident.val = P.pos, Scanner.IDENT, "";
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
ident.val_ = P.val; ident.val = P.val;
if P.verbose { if P.verbose {
P.PrintIndent(); P.PrintIndent();
print("Ident = \"", ident.val_, "\"\n"); print("Ident = \"", ident.val, "\"\n");
} }
P.Next(); P.Next();
} else { } else {
...@@ -152,19 +156,26 @@ func (P *Parser) ParseIdentList() int { ...@@ -152,19 +156,26 @@ func (P *Parser) ParseIdentList() int {
} }
func (P *Parser) ParseQualifiedIdent(ident *AST.Ident) AST.Expr { func (P *Parser) ParseQualifiedIdent(ident *AST.Literal) AST.Expr {
P.Trace("QualifiedIdent"); P.Trace("QualifiedIdent");
if ident == nil { if ident == nil {
ident = P.ParseIdent(); ident = P.ParseIdent();
} }
var x AST.Expr = ident;
if P.tok == Scanner.PERIOD { if P.tok == Scanner.PERIOD {
P.Next(); P.Next();
ident = P.ParseIdent(); ident2 := P.ParseIdent();
z := new(AST.Selector);
z.pos, z.x, z.field = ident.pos, ident, ident2.val;
x = z;
} }
P.Ecart(); P.Ecart();
return ident; return x;
} }
...@@ -471,16 +482,18 @@ func (P *Parser) ParseBlock() { ...@@ -471,16 +482,18 @@ func (P *Parser) ParseBlock() {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Expressions // Expressions
func (P *Parser) ParseExpressionList() { func (P *Parser) ParseExpressionList() *AST.List {
P.Trace("ExpressionList"); P.Trace("ExpressionList");
P.ParseExpression(); p := AST.NewList();
p.Add(P.ParseExpression());
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.Next(); P.Next();
P.ParseExpression(); p.Add(P.ParseExpression());
} }
P.Ecart(); P.Ecart();
return p;
} }
...@@ -497,26 +510,33 @@ func (P *Parser) ParseFunctionLit() AST.Expr { ...@@ -497,26 +510,33 @@ func (P *Parser) ParseFunctionLit() AST.Expr {
} }
func (P *Parser) ParseExpressionPair() { func (P *Parser) ParseExpressionPair() AST.Expr {
P.Trace("ExpressionPair"); P.Trace("ExpressionPair");
P.ParseExpression(); x := P.ParseExpression();
pos := P.pos;
P.Expect(Scanner.COLON); P.Expect(Scanner.COLON);
P.ParseExpression(); y := P.ParseExpression();
z := new(AST.Pair);
z.pos, z.x, z.y = pos, x, y;
P.Ecart(); P.Ecart();
return z;
} }
func (P *Parser) ParseExpressionPairList() { func (P *Parser) ParseExpressionPairList() *AST.List {
P.Trace("ExpressionPairList"); P.Trace("ExpressionPairList");
P.ParseExpressionPair(); p := AST.NewList();
p.Add(P.ParseExpressionPair());
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.ParseExpressionPair(); p.Add(P.ParseExpressionPair());
} }
P.Ecart(); P.Ecart();
return p;
} }
...@@ -546,12 +566,11 @@ func (P *Parser) ParseCompositeLit() AST.Expr { ...@@ -546,12 +566,11 @@ func (P *Parser) ParseCompositeLit() AST.Expr {
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
var x AST.Expr; return nil;
return x;
} }
func (P *Parser) ParseOperand(ident *AST.Ident) AST.Expr { func (P *Parser) ParseOperand(ident *AST.Literal) AST.Expr {
P.Trace("Operand"); P.Trace("Operand");
if ident == nil && P.tok == Scanner.IDENT { if ident == nil && P.tok == Scanner.IDENT {
...@@ -559,39 +578,37 @@ func (P *Parser) ParseOperand(ident *AST.Ident) AST.Expr { ...@@ -559,39 +578,37 @@ func (P *Parser) ParseOperand(ident *AST.Ident) AST.Expr {
ident = P.ParseIdent(); ident = P.ParseIdent();
} }
var x AST.Expr; var z AST.Expr;
if ident != nil { if ident != nil {
// we have an identifier z = ident;
} else { } else {
switch P.tok { switch P.tok {
case Scanner.LPAREN: case Scanner.LPAREN:
P.Next(); P.Next();
x = P.ParseExpression(); z = P.ParseExpression();
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
case Scanner.INT:
P.Next();
case Scanner.FLOAT:
P.Next();
case Scanner.STRING: case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x := new(AST.Literal);
x.pos, x.tok, x.val = P.pos, P.tok, P.val;
z = x;
P.Next(); P.Next();
case Scanner.FUNC: case Scanner.FUNC:
P.ParseFunctionLit(); z = P.ParseFunctionLit();
case Scanner.HASH: case Scanner.HASH:
P.Next(); P.Next();
P.ParseType(); P.ParseType();
P.ParseCompositeLit(); P.ParseCompositeLit();
z = nil;
default: default:
if P.tok != Scanner.IDENT && P.TryType() { if P.tok != Scanner.IDENT && P.TryType() {
P.ParseCompositeLit(); z = P.ParseCompositeLit();
} else { } else {
P.Error(P.pos, "operand expected"); P.Error(P.pos, "operand expected");
P.Next(); // make progress P.Next(); // make progress
...@@ -601,18 +618,23 @@ func (P *Parser) ParseOperand(ident *AST.Ident) AST.Expr { ...@@ -601,18 +618,23 @@ func (P *Parser) ParseOperand(ident *AST.Ident) AST.Expr {
} }
P.Ecart(); P.Ecart();
return x; return z;
} }
func (P *Parser) ParseSelectorOrTypeGuard(x AST.Expr) AST.Expr { func (P *Parser) ParseSelectorOrTypeGuard(x AST.Expr) AST.Expr {
P.Trace("SelectorOrTypeGuard"); P.Trace("SelectorOrTypeGuard");
P.Expect(Scanner.PERIOD);
pos := P.pos; pos := P.pos;
P.Expect(Scanner.PERIOD);
if P.tok >= Scanner.IDENT { if P.tok == Scanner.IDENT {
P.ParseIdent(); ident := P.ParseIdent();
z := new(AST.Selector);
z.pos, z.x, z.field = pos, x, ident.val;
x = z;
} else { } else {
P.Expect(Scanner.LPAREN); P.Expect(Scanner.LPAREN);
P.ParseType(); P.ParseType();
...@@ -627,16 +649,21 @@ func (P *Parser) ParseSelectorOrTypeGuard(x AST.Expr) AST.Expr { ...@@ -627,16 +649,21 @@ func (P *Parser) ParseSelectorOrTypeGuard(x AST.Expr) AST.Expr {
func (P *Parser) ParseIndexOrSlice(x AST.Expr) AST.Expr { func (P *Parser) ParseIndexOrSlice(x AST.Expr) AST.Expr {
P.Trace("IndexOrSlice"); P.Trace("IndexOrSlice");
pos := P.pos;
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
i := P.ParseExpression(); i := P.ParseExpression();
if P.tok == Scanner.COLON { if P.tok == Scanner.COLON {
P.Next(); P.Next();
j := P.ParseExpression(); j := P.ParseExpression();
// TODO: handle this case
} }
P.Expect(Scanner.RBRACK); P.Expect(Scanner.RBRACK);
z := new(AST.Index);
z.pos, z.x, z.index = pos, x, i;
P.Ecart(); P.Ecart();
return x; return z;
} }
...@@ -668,20 +695,19 @@ func (P *Parser) ParseCall(x AST.Expr) AST.Expr { ...@@ -668,20 +695,19 @@ func (P *Parser) ParseCall(x AST.Expr) AST.Expr {
} }
func (P *Parser) ParsePrimaryExpr(ident *AST.Ident) AST.Expr { func (P *Parser) ParsePrimaryExpr(ident *AST.Literal) AST.Expr {
P.Trace("PrimaryExpr"); P.Trace("PrimaryExpr");
x := P.ParseOperand(ident); x := P.ParseOperand(ident);
for { L: for {
switch P.tok { switch P.tok {
case Scanner.PERIOD: x = P.ParseSelectorOrTypeGuard(x); case Scanner.PERIOD: x = P.ParseSelectorOrTypeGuard(x);
case Scanner.LBRACK: x = P.ParseIndexOrSlice(x); case Scanner.LBRACK: x = P.ParseIndexOrSlice(x);
case Scanner.LPAREN: x = P.ParseCall(x); case Scanner.LPAREN: x = P.ParseCall(x);
default: goto exit; default: break L;
} }
} }
exit:
P.Ecart(); P.Ecart();
return x; return x;
} }
...@@ -690,23 +716,26 @@ exit: ...@@ -690,23 +716,26 @@ exit:
func (P *Parser) ParseUnaryExpr() AST.Expr { func (P *Parser) ParseUnaryExpr() AST.Expr {
P.Trace("UnaryExpr"); P.Trace("UnaryExpr");
var x AST.Expr;
switch P.tok { switch P.tok {
case Scanner.ADD: fallthrough; case
case Scanner.SUB: fallthrough; Scanner.ADD, Scanner.SUB,
case Scanner.NOT: fallthrough; Scanner.NOT, Scanner.XOR,
case Scanner.XOR: fallthrough; Scanner.MUL, Scanner.ARROW,
case Scanner.MUL: fallthrough; Scanner.AND:
case Scanner.ARROW: fallthrough; pos, tok := P.pos, P.tok;
case Scanner.AND: P.Next();
P.Next(); y := P.ParseUnaryExpr();
x := P.ParseUnaryExpr();
P.Ecart(); x := new(AST.Unary);
return x; // TODO fix this x.pos, x.tok, x.x = pos, tok, y;
default:
x = P.ParsePrimaryExpr(nil);
} }
x := P.ParsePrimaryExpr(nil);
P.Ecart(); P.Ecart();
return x; // TODO fix this return x;
} }
...@@ -730,7 +759,7 @@ func Precedence(tok int) int { ...@@ -730,7 +759,7 @@ func Precedence(tok int) int {
} }
func (P *Parser) ParseBinaryExpr(ident *AST.Ident, prec1 int) AST.Expr { func (P *Parser) ParseBinaryExpr(ident *AST.Literal, prec1 int) AST.Expr {
P.Trace("BinaryExpr"); P.Trace("BinaryExpr");
var x AST.Expr; var x AST.Expr;
...@@ -742,8 +771,13 @@ func (P *Parser) ParseBinaryExpr(ident *AST.Ident, prec1 int) AST.Expr { ...@@ -742,8 +771,13 @@ func (P *Parser) ParseBinaryExpr(ident *AST.Ident, prec1 int) AST.Expr {
for prec := Precedence(P.tok); prec >= prec1; prec-- { for prec := Precedence(P.tok); prec >= prec1; prec-- {
for Precedence(P.tok) == prec { for Precedence(P.tok) == prec {
pos, tok := P.pos, P.tok;
P.Next(); P.Next();
y := P.ParseBinaryExpr(nil, prec + 1); y := P.ParseBinaryExpr(nil, prec + 1);
z := new(AST.Binary);
z.pos, z.tok, z.x, z.y = pos, tok, x, y;
x = z;
} }
} }
...@@ -753,7 +787,7 @@ func (P *Parser) ParseBinaryExpr(ident *AST.Ident, prec1 int) AST.Expr { ...@@ -753,7 +787,7 @@ func (P *Parser) ParseBinaryExpr(ident *AST.Ident, prec1 int) AST.Expr {
// Expressions where the first token may be an identifier which has already been consumed. // Expressions where the first token may be an identifier which has already been consumed.
func (P *Parser) ParseIdentExpression(ident *AST.Ident) AST.Expr { func (P *Parser) ParseIdentExpression(ident *AST.Literal) AST.Expr {
P.Trace("IdentExpression"); P.Trace("IdentExpression");
indent := P.indent; indent := P.indent;
...@@ -772,6 +806,10 @@ func (P *Parser) ParseExpression() AST.Expr { ...@@ -772,6 +806,10 @@ func (P *Parser) ParseExpression() AST.Expr {
P.Trace("Expression"); P.Trace("Expression");
x := P.ParseIdentExpression(nil); x := P.ParseIdentExpression(nil);
if !P.silent {
Printer.Print(x);
}
P.Ecart(); P.Ecart();
return x; return x;
......
...@@ -13,7 +13,8 @@ import Printer "printer" ...@@ -13,7 +13,8 @@ import Printer "printer"
var ( var (
verbose = Flag.Bool("v", false, nil, "verbose mode"); silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output");
verbose = Flag.Bool("v", false, nil, "verbose mode: trace parsing");
sixg = Flag.Bool("6g", false, nil, "6g compatibility mode"); sixg = Flag.Bool("6g", false, nil, "6g compatibility mode");
tokenchan = Flag.Bool("token_chan", false, nil, "use token channel for scanner-parser connection"); tokenchan = Flag.Bool("token_chan", false, nil, "use token channel for scanner-parser connection");
) )
...@@ -53,7 +54,7 @@ func main() { ...@@ -53,7 +54,7 @@ func main() {
} }
parser := new(Parser.Parser); parser := new(Parser.Parser);
parser.Open(verbose.BVal(), scanner, tstream); parser.Open(silent.BVal(), verbose.BVal(), scanner, tstream);
parser.ParseProgram(); parser.ParseProgram();
} }
......
...@@ -2,7 +2,64 @@ ...@@ -2,7 +2,64 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package Printer; package Printer
import Scanner "scanner"
import AST "ast"
// TODO Fill in the code to print the AST
type Printer struct {
}
func (P *Printer) Print(s string) {
print(s);
}
func (P *Printer) PrintExpr(x AST.Expr) {
/*
if x == nil {
P.Print("<nil>");
return;
}
switch x.tok {
case Scanner.IDENT:
P.Print(x.val);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
P.Print(x.val);
case Scanner.PERIOD:
P.PrintExpr(x.x);
P.Print(Scanner.TokenName(x.tok));
P.PrintExpr(x.y);
case Scanner.LBRACK:
P.PrintExpr(x.x);
P.Print("[");
P.PrintExpr(x.y);
P.Print("]");
default:
// unary or binary expression
print("(");
if x.x != nil {
P.PrintExpr(x.x);
}
P.Print(" " + Scanner.TokenName(x.tok) + " ");
P.PrintExpr(x.y);
print(")");
}
*/
}
export func Print(x AST.Expr) {
var P Printer;
print("expr = ");
(&P).PrintExpr(x);
print("\n");
}
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