Commit c5a29a6d authored by Robert Griesemer's avatar Robert Griesemer

- more ast buidling and printing

- almost complete language reproduced

R=r
OCL=15801
CL=15801
parent afd04fdb
......@@ -15,10 +15,20 @@ export type Visitor interface {
// Types
DoFunctionType(x *FunctionType);
DoArrayType(x *ArrayType);
DoStructType(x *StructType);
DoMapType(x *MapType);
DoChannelType(x *ChannelType);
DoInterfaceType(x *InterfaceType);
DoPointerType(x *PointerType);
// Declarations
//DoVarDeclList(x *VarDeclList);
DoConstDecl(x *ConstDecl);
DoTypeDecl(x *TypeDecl);
DoVarDecl(x *VarDecl);
DoVarDeclList(x *VarDeclList);
DoFuncDecl(x *FuncDecl);
DoDeclaration(x *Declaration);
// Expressions
DoBinary(x *Binary);
......@@ -35,8 +45,10 @@ export type Visitor interface {
DoAssignment(x *Assignment);
DoIfStat(x *IfStat);
DoForStat(x *ForStat);
DoSwitch(x *Switch);
DoReturn(x *Return);
DoCaseClause(x *CaseClause);
DoSwitchStat(x *SwitchStat);
DoReturnStat(x *ReturnStat);
DoIncDecStat(x *IncDecStat);
// Program
DoProgram(x *Program);
......@@ -60,6 +72,7 @@ export type List struct {
func (p *List) len() int {
if p == nil { return 0; }
return len(p.a);
}
......@@ -122,14 +135,61 @@ export type Type interface {
}
export type Expr interface {
Visit(x Visitor);
}
export type ArrayType struct {
pos int; // position of "["
len_ Expr;
elt Type;
}
export type StructType struct {
pos int; // position of "struct"
fields *List; // list of *VarDeclList
}
export type MapType struct {
pos int; // position of "map"
key, val Type;
}
export type ChannelType struct {
pos int; // position of "chan" or "<-" (if before "chan")
elt Type;
}
export type PointerType struct {
pos int; // position of "*"
base Type;
}
export type InterfaceType struct {
}
export type FunctionType struct {
pos int; // position of "("
recv *VarDeclList;
params *List;
result *List;
params *List; // list of *VarDeclList
result *List; // list of *VarDeclList
}
func (x *FunctionType) Visit(v Visitor) { v.DoFunctionType(x); }
func (x *FunctionType) Visit(v Visitor) { v.DoFunctionType(x); }
func (x *ArrayType) Visit(v Visitor) { v.DoArrayType(x); }
func (x *StructType) Visit(v Visitor) { v.DoStructType(x); }
func (x *MapType) Visit(v Visitor) { v.DoMapType(x); }
func (x *ChannelType) Visit(v Visitor) { v.DoChannelType(x); }
func (x *PointerType) Visit(v Visitor) { v.DoPointerType(x); }
func (x *InterfaceType) Visit(v Visitor) { v.DoInterfaceType(x); }
// ----------------------------------------------------------------------------
......@@ -142,73 +202,99 @@ export type Decl interface {
export type VarDeclList struct {
idents *List;
typ *Node;
typ Type;
}
export type ConstDecl struct {
ident *Ident;
typ Type;
val Expr;
}
export type TypeDecl struct {
ident *Ident;
typ Type;
}
export type VarDecl struct {
idents *List;
typ Type;
vals *List;
}
export type Declaration struct {
pos int; // position of token
tok int;
decls *List;
}
export type FuncDecl struct {
pos int;
pos int; // position of "func"
ident *Ident;
typ *FunctionType;
body *Block;
}
func (x *VarDeclList) Visit(v Visitor) { /*v.DoVarDeclList(x);*/ }
func (x *FuncDecl) Visit(v Visitor) { v.DoFuncDecl(x); }
func (x *VarDeclList) Visit(v Visitor) { v.DoVarDeclList(x); }
func (x *ConstDecl) Visit(v Visitor) { v.DoConstDecl(x); }
func (x *TypeDecl) Visit(v Visitor) { v.DoTypeDecl(x); }
func (x *VarDecl) Visit(v Visitor) { v.DoVarDecl(x); }
func (x *FuncDecl) Visit(v Visitor) { v.DoFuncDecl(x); }
func (x *Declaration) Visit(v Visitor) { v.DoDeclaration(x); }
// ----------------------------------------------------------------------------
// Expressions
export type Expr interface {
Visit(x Visitor);
}
export type Selector struct {
pos int;
pos int; // position of "."
x Expr;
field string;
}
export type Index struct {
pos int;
pos int; // position of "["
x Expr;
index Expr;
}
export type Call struct {
pos int;
pos int; // position of "("
fun Expr;
args *List;
}
export type Pair struct {
pos int;
pos int; // position of ":"
x, y Expr;
}
export type Binary struct {
pos int;
pos int; // position of operator tok
tok int;
x, y Expr;
}
export type Unary struct {
pos int;
pos int; // position of operator tok
tok int;
x Expr;
}
export type Literal struct {
pos int;
pos int; // position of literal
tok int;
val string;
}
......@@ -232,7 +318,7 @@ export type Stat interface {
export type Block struct {
pos int;
pos int; // position of "{"
stats *List;
}
......@@ -243,14 +329,14 @@ export type ExprStat struct {
export type Assignment struct {
pos int;
pos int; // position of assignment token
tok int;
lhs, rhs *List;
}
export type IfStat struct {
pos int;
pos int; // position of "if"
init Stat;
cond Expr;
then, else_ *Block;
......@@ -258,28 +344,52 @@ export type IfStat struct {
export type ForStat struct {
pos int;
pos int; // position of "for"
init Stat;
cond Expr;
post Stat;
body *Block;
}
export type Switch struct {
export type CaseClause struct {
pos int; // position of "case" or "default"
exprs *List; // nil if default case
stats *List; // list of Stat
falls bool;
}
export type Return struct {
pos int;
export type SwitchStat struct {
pos int; // position of "switch"
init Stat;
tag Expr;
cases *List; // list of *CaseClause
}
export type ReturnStat struct {
pos int; // position of "return"
res *List;
}
export type IncDecStat struct {
pos int; // position of token
tok int;
expr Expr;
}
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 *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); }
func (x *CaseClause) Visit(v Visitor) { v.DoCaseClause(x); }
func (x *SwitchStat) Visit(v Visitor) { v.DoSwitchStat(x); }
func (x *ReturnStat) Visit(v Visitor) { v.DoReturnStat(x); }
func (x *IncDecStat) Visit(v Visitor) { v.DoIncDecStat(x); }
// ----------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -36,13 +36,11 @@ func (P *Printer) Print(x AST.Node) {
func (P *Printer) PrintList(p *AST.List) {
if p != nil {
for i := 0; i < p.len(); i++ {
if i > 0 {
P.String(", ");
}
P.Print(p.at(i));
for i := 0; i < p.len(); i++ {
if i > 0 {
P.String(", ");
}
P.Print(p.at(i));
}
}
......@@ -52,7 +50,6 @@ func (P *Printer) PrintList(p *AST.List) {
func (P *Printer) DoNil(x *AST.Nil) {
P.String("?");
P.NewLine(0);
}
......@@ -76,14 +73,89 @@ func (P *Printer) DoFunctionType(x *AST.FunctionType) {
}
func (P *Printer) DoArrayType(x *AST.ArrayType) {
P.String("[");
P.Print(x.len_);
P.String("] ");
P.Print(x.elt);
}
func (P *Printer) DoStructType(x *AST.StructType) {
P.String("struct {");
if x.fields.len() > 0 {
P.NewLine(1);
for i := 0; i < x.fields.len(); i++ {
if i > 0 {
P.NewLine(0);
}
P.Print(x.fields.at(i));
P.String(";");
}
P.NewLine(-1);
}
P.String("}");
}
func (P *Printer) DoMapType(x *AST.MapType) {
}
func (P *Printer) DoChannelType(x *AST.ChannelType) {
P.String("chan ");
P.Print(x.elt);
}
func (P *Printer) DoInterfaceType(x *AST.InterfaceType) {
}
func (P *Printer) DoPointerType(x *AST.PointerType) {
P.String("*");
P.Print(x.base);
}
// ----------------------------------------------------------------------------
// Declarations
func (P *Printer) DoBlock(x *AST.Block);
//func (P *Printer) DoVarDeclList(x *VarDeclList) {
//}
func (P *Printer) DoConstDecl(x *AST.ConstDecl) {
P.Print(x.ident);
P.String(" ");
P.Print(x.typ);
P.String(" = ");
P.Print(x.val);
}
func (P *Printer) DoTypeDecl(x *AST.TypeDecl) {
P.Print(x.ident);
P.String(" ");
P.Print(x.typ);
}
func (P *Printer) DoVarDecl(x *AST.VarDecl) {
P.PrintList(x.idents);
P.String(" ");
P.Print(x.typ);
if x.vals != nil {
P.String(" = ");
P.PrintList(x.vals);
}
}
func (P *Printer) DoVarDeclList(x *AST.VarDeclList) {
P.PrintList(x.idents);
P.String(" ");
P.Print(x.typ);
}
func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
......@@ -106,6 +178,30 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
}
func (P *Printer) DoDeclaration(x *AST.Declaration) {
P.String(Scanner.TokenName(x.tok));
P.String(" ");
switch x.decls.len() {
case 0:
P.String("()");
case 1:
P.Print(x.decls.at(0));
default:
P.String("(");
P.NewLine(1);
for i := 0; i < x.decls.len(); i++ {
if i > 0 {
P.NewLine(0);
}
P.Print(x.decls.at(i));
}
P.NewLine(-1);
P.String(")");
}
P.NewLine(0);
}
// ----------------------------------------------------------------------------
// Expressions
......@@ -214,18 +310,81 @@ func (P *Printer) DoForStat(x *AST.ForStat) {
}
func (P *Printer) DoSwitch(x *AST.Switch) {
/*
func AnalyzeCase(x *AST.SwitchStat) bool {
for i := 0; i < x.cases.len(); i++ {
clause := x.cases.at(i).(AST.CaseClause);
if clause.stats.len() > 1 {
return false;
}
}
return true;
}
*/
func (P *Printer) DoCaseClause(x *AST.CaseClause) {
if x.exprs != nil {
P.String("case ");
P.PrintList(x.exprs);
P.String(":");
} else {
P.String("default:");
}
n := x.stats.len();
m := n;
if x.falls {
m++;
}
if m == 0 {
P.NewLine(0);
} else {
P.NewLine(1);
for i := 0; i < n; i++ {
if i > 0 {
P.NewLine(0);
}
P.Print(x.stats.at(i));
}
if x.falls {
if n > 0 {
P.NewLine(0);
}
P.String("fallthrough;");
}
P.NewLine(-1);
}
}
func (P *Printer) DoSwitchStat(x *AST.SwitchStat) {
P.String("switch ");
P.String("{");
P.NewLine(0);
for i := 0; i < x.cases.len(); i++ {
P.Print(x.cases.at(i));
}
P.NewLine(0);
P.String("}");
}
func (P *Printer) DoReturn(x *AST.Return) {
func (P *Printer) DoReturnStat(x *AST.ReturnStat) {
P.String("return ");
P.PrintList(x.res);
P.String(";");
}
func (P *Printer) DoIncDecStat(x *AST.IncDecStat) {
P.Print(x.expr);
P.String(Scanner.TokenName(x.tok));
P.String(";");
}
// ----------------------------------------------------------------------------
// Program
......
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