Commit 09bed256 authored by Robert Griesemer's avatar Robert Griesemer

- snapshot of pretty printer status

- parts of AST built and printed
- no formatting yet

R=r
OCL=15727
CL=15727
parent 7c48a394
......@@ -4,14 +4,54 @@
package AST
// ----------------------------------------------------------------------------
// Lists
// Visitor
export type Element interface {}
export type Visitor interface {
// Basics
DoNil(x *Nil);
DoIdent(x *Ident);
// Declarations
DoFuncDecl(x *FuncDecl);
// Expressions
DoBinary(x *Binary);
DoUnary(x *Unary);
DoLiteral(x *Literal);
DoPair(x *Pair);
DoIndex(x *Index);
DoCall(x *Call);
DoSelector(x *Selector);
// Statements
DoBlock(x *Block);
DoExprStat(x *ExprStat);
DoAssignment(x *Assignment);
DoIf(x *If);
DoFor(x *For);
DoSwitch(x *Switch);
DoReturn(x *Return);
// Program
DoProgram(x *Program);
}
// ----------------------------------------------------------------------------
// An AST Node
export type Node interface {
Visit(x Visitor);
}
// ----------------------------------------------------------------------------
// Lists
export type List struct {
a *[] Element
a *[] Node
}
......@@ -20,17 +60,17 @@ func (p *List) len() int {
}
func (p *List) at(i int) Element {
func (p *List) at(i int) Node {
return p.a[i];
}
func (p *List) Add (x Element) {
func (p *List) Add (x Node) {
a := p.a;
n := len(a);
if n == cap(a) {
b := new([] interface {}, 2*n);
b := new([] Node, 2*n);
for i := 0; i < n; i++ {
b[i] = a[i];
}
......@@ -45,15 +85,54 @@ func (p *List) Add (x Element) {
export func NewList() *List {
p := new(List);
p.a = new([] interface {}, 10);
p.a = new([] Node, 10) [0 : 0];
return p;
}
// ----------------------------------------------------------------------------
// Basics
export type Nil struct {
// The Node "nil" value
}
export var NIL *Nil = new(Nil);
export type Ident struct {
pos int;
val string;
}
func (x *Nil) Visit(v Visitor) { v.DoNil(x); }
func (x *Ident) Visit(v Visitor) { v.DoIdent(x); }
// ----------------------------------------------------------------------------
// Declarations
export type Decl interface {
Visit(x Visitor);
}
export type FuncDecl struct {
pos int;
ident *Ident;
body *Block;
}
func (x *FuncDecl) Visit(v Visitor) { v.DoFuncDecl(x); }
// ----------------------------------------------------------------------------
// Expressions
export type Expr interface {
Visit(x Visitor);
}
......@@ -71,6 +150,13 @@ export type Index struct {
}
export type Call struct {
pos int;
fun Expr;
args *List;
}
export type Pair struct {
pos int;
x, y Expr;
......@@ -98,20 +184,79 @@ export type Literal struct {
}
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); }
func (x *Pair) Visit(v Visitor) { v.DoPair(x); }
func (x *Index) Visit(v Visitor) { v.DoIndex(x); }
func (x *Call) Visit(v Visitor) { v.DoCall(x); }
func (x *Selector) Visit(v Visitor) { v.DoSelector(x); }
// ----------------------------------------------------------------------------
// Statements
export type Stat interface {
Visit(x Visitor);
}
export type Block struct {
pos int;
stats *List;
}
export type ExprStat struct {
expr Expr;
}
export type Assignment struct {
pos int;
tok int;
lhs, rhs *List;
}
export type If struct {
pos int;
cond Expr;
then, else_ *Block;
}
export type For struct {
}
export type Switch struct {
}
export type Return struct {
pos int;
res *List;
}
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 *Switch) Visit(v Visitor) { v.DoSwitch(x); }
func (x *Return) Visit(v Visitor) { v.DoReturn(x); }
// ----------------------------------------------------------------------------
// Visitor
// Program
export type Visitor interface {
DoBinary(x *Binary);
//DoUnary(x *Unary);
//DoLiteral(x *Literal);
export type Program struct {
pos int;
ident *Ident;
decls *List;
}
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); }
func (x *Program) Visit(v Visitor) { v.DoProgram(x); }
This diff is collapsed.
......@@ -54,8 +54,11 @@ func main() {
}
parser := new(Parser.Parser);
parser.Open(silent.BVal(), verbose.BVal(), scanner, tstream);
parser.Open(verbose.BVal(), scanner, tstream);
parser.ParseProgram();
prog := parser.ParseProgram();
if !silent.BVal() {
Printer.Print(prog);
}
}
}
......@@ -8,58 +8,192 @@ import Scanner "scanner"
import AST "ast"
type Printer struct {
type Printer /* implements AST.Visitor */ struct {
indent int;
}
func (P *Printer) Print(s string) {
func (P *Printer) String(s string) {
print(s);
}
func (P *Printer) PrintExpr(x AST.Expr) {
/*
if x == nil {
P.Print("<nil>");
return;
func (P *Printer) Print(x AST.Node) {
x.Visit(P);
}
func (P *Printer) PrintExprList(p *AST.List) {
if p != nil {
for i := 0; i < p.len(); i++ {
if i > 0 {
P.String(", ");
}
P.Print(p.at(i));
}
}
}
switch x.tok {
case Scanner.IDENT:
P.Print(x.val);
// ----------------------------------------------------------------------------
// Basics
case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
P.Print(x.val);
func (P *Printer) DoNil(x *AST.Nil) {
P.String("?\n");
}
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("]");
func (P *Printer) DoIdent(x *AST.Ident) {
P.String(x.val);
}
default:
// unary or binary expression
print("(");
if x.x != nil {
P.PrintExpr(x.x);
// ----------------------------------------------------------------------------
// Declarations
func (P *Printer) DoBlock(x *AST.Block);
func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
P.String("func ");
P.DoIdent(x.ident);
P.String("(... something here ...) ");
if x.body != nil {
P.DoBlock(x.body);
} else {
P.String(";\n");
}
P.Print(" " + Scanner.TokenName(x.tok) + " ");
P.PrintExpr(x.y);
}
// ----------------------------------------------------------------------------
// Expressions
func (P *Printer) DoBinary(x *AST.Binary) {
print("(");
P.Print(x.x);
P.String(" " + Scanner.TokenName(x.tok) + " ");
P.Print(x.y);
print(")");
}
func (P *Printer) DoUnary(x *AST.Unary) {
P.String(Scanner.TokenName(x.tok));
P.Print(x.x);
}
func (P *Printer) DoLiteral(x *AST.Literal) {
P.String(x.val);
}
func (P *Printer) DoPair(x *AST.Pair) {
P.Print(x.x);
P.String(" : ");
P.Print(x.y);
}
func (P *Printer) DoIndex(x *AST.Index) {
P.Print(x.x);
P.String("[");
P.Print(x.index);
P.String("]");
}
func (P *Printer) DoCall(x *AST.Call) {
P.Print(x.fun);
P.String("(");
P.PrintExprList(x.args);
P.String(")");
}
func (P *Printer) DoSelector(x *AST.Selector) {
P.Print(x.x);
P.String(".");
P.String(x.field);
}
// ----------------------------------------------------------------------------
// Statements
func (P *Printer) DoBlock(x *AST.Block) {
if x == nil || x.stats == nil {
P.String("\n");
return;
}
P.String("{\n");
P.indent++;
for i := 0; i < x.stats.len(); i++ {
P.Print(x.stats.at(i));
P.String("\n");
}
*/
P.indent--;
P.String("}\n");
}
export func Print(x AST.Expr) {
func (P *Printer) DoExprStat(x *AST.ExprStat) {
P.Print(x.expr);
}
func (P *Printer) DoAssignment(x *AST.Assignment) {
P.PrintExprList(x.lhs);
P.String(" " + Scanner.TokenName(x.tok) + " ");
P.PrintExprList(x.rhs);
}
func (P *Printer) DoIf(x *AST.If) {
P.String("if ");
P.Print(x.cond);
P.DoBlock(x.then);
if x.else_ != nil {
P.String("else ");
P.DoBlock(x.else_);
}
}
func (P *Printer) DoFor(x *AST.For) {
}
func (P *Printer) DoSwitch(x *AST.Switch) {
}
func (P *Printer) DoReturn(x *AST.Return) {
P.String("return ");
P.PrintExprList(x.res);
}
// ----------------------------------------------------------------------------
// Program
func (P *Printer) DoProgram(x *AST.Program) {
P.String("package ");
P.DoIdent(x.ident);
P.String("\n");
for i := 0; i < x.decls.len(); i++ {
P.Print(x.decls.at(i));
}
}
// ----------------------------------------------------------------------------
// Driver
export func Print(x AST.Node) {
var P Printer;
print("expr = ");
(&P).PrintExpr(x);
(&P).Print(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