Commit 84152806 authored by Robert Griesemer's avatar Robert Griesemer

- more missing constructs added

- removed excessive ";"'s
- no ()'s around expressions where not needed
- parser.go now reproduced and parseable again

R=r
OCL=15881
CL=15881
parent b70d42f3
...@@ -23,11 +23,13 @@ export type Visitor interface { ...@@ -23,11 +23,13 @@ export type Visitor interface {
DoPointerType(x *PointerType); DoPointerType(x *PointerType);
// Declarations // Declarations
DoImportDecl(x *ImportDecl);
DoConstDecl(x *ConstDecl); DoConstDecl(x *ConstDecl);
DoTypeDecl(x *TypeDecl); DoTypeDecl(x *TypeDecl);
DoVarDecl(x *VarDecl); DoVarDecl(x *VarDecl);
DoVarDeclList(x *VarDeclList); DoVarDeclList(x *VarDeclList);
DoFuncDecl(x *FuncDecl); DoFuncDecl(x *FuncDecl);
DoMethodDecl(x *MethodDecl);
DoDeclaration(x *Declaration); DoDeclaration(x *Declaration);
// Expressions // Expressions
...@@ -40,6 +42,7 @@ export type Visitor interface { ...@@ -40,6 +42,7 @@ export type Visitor interface {
DoSelector(x *Selector); DoSelector(x *Selector);
// Statements // Statements
DoLabel(x *Label);
DoBlock(x *Block); DoBlock(x *Block);
DoExprStat(x *ExprStat); DoExprStat(x *ExprStat);
DoAssignment(x *Assignment); DoAssignment(x *Assignment);
...@@ -50,6 +53,7 @@ export type Visitor interface { ...@@ -50,6 +53,7 @@ export type Visitor interface {
DoReturnStat(x *ReturnStat); DoReturnStat(x *ReturnStat);
DoIncDecStat(x *IncDecStat); DoIncDecStat(x *IncDecStat);
DoControlFlowStat(x *ControlFlowStat); DoControlFlowStat(x *ControlFlowStat);
DoGoStat(x *GoStat);
// Program // Program
DoProgram(x *Program); DoProgram(x *Program);
...@@ -71,7 +75,7 @@ export type Node interface { ...@@ -71,7 +75,7 @@ export type Node interface {
// Thus, empty lists can be represented by nil. // Thus, empty lists can be represented by nil.
export type List struct { export type List struct {
a *[] Node a *[] Node;
} }
...@@ -176,6 +180,8 @@ export type PointerType struct { ...@@ -176,6 +180,8 @@ export type PointerType struct {
export type InterfaceType struct { export type InterfaceType struct {
pos int; // position of "interface"
methods *List; // list of *MethodDecl
} }
...@@ -210,6 +216,12 @@ export type VarDeclList struct { ...@@ -210,6 +216,12 @@ export type VarDeclList struct {
} }
export type ImportDecl struct {
ident *Ident;
file string;
}
export type ConstDecl struct { export type ConstDecl struct {
ident *Ident; ident *Ident;
typ Type; typ Type;
...@@ -245,11 +257,19 @@ export type FuncDecl struct { ...@@ -245,11 +257,19 @@ export type FuncDecl struct {
} }
export type MethodDecl struct {
ident *Ident;
typ *FunctionType;
}
func (x *VarDeclList) Visit(v Visitor) { v.DoVarDeclList(x); } func (x *VarDeclList) Visit(v Visitor) { v.DoVarDeclList(x); }
func (x *ImportDecl) Visit(v Visitor) { v.DoImportDecl(x); }
func (x *ConstDecl) Visit(v Visitor) { v.DoConstDecl(x); } func (x *ConstDecl) Visit(v Visitor) { v.DoConstDecl(x); }
func (x *TypeDecl) Visit(v Visitor) { v.DoTypeDecl(x); } func (x *TypeDecl) Visit(v Visitor) { v.DoTypeDecl(x); }
func (x *VarDecl) Visit(v Visitor) { v.DoVarDecl(x); } func (x *VarDecl) Visit(v Visitor) { v.DoVarDecl(x); }
func (x *FuncDecl) Visit(v Visitor) { v.DoFuncDecl(x); } func (x *FuncDecl) Visit(v Visitor) { v.DoFuncDecl(x); }
func (x *MethodDecl) Visit(v Visitor) { v.DoMethodDecl(x); }
func (x *Declaration) Visit(v Visitor) { v.DoDeclaration(x); } func (x *Declaration) Visit(v Visitor) { v.DoDeclaration(x); }
...@@ -321,6 +341,12 @@ export type Stat interface { ...@@ -321,6 +341,12 @@ export type Stat interface {
} }
export type Label struct {
pos int; // position of ":"
ident Expr; // should be ident
}
export type Block struct { export type Block struct {
pos int; // position of "{" pos int; // position of "{"
stats *List; stats *List;
...@@ -398,7 +424,14 @@ export type ControlFlowStat struct { ...@@ -398,7 +424,14 @@ export type ControlFlowStat struct {
} }
export type GoStat struct {
pos int; // position of "go"
expr Expr;
}
func (x *Block) Visit(v Visitor) { v.DoBlock(x); } func (x *Block) Visit(v Visitor) { v.DoBlock(x); }
func (x *Label) Visit(v Visitor) { v.DoLabel(x); }
func (x *ExprStat) Visit(v Visitor) { v.DoExprStat(x); } func (x *ExprStat) Visit(v Visitor) { v.DoExprStat(x); }
func (x *Assignment) Visit(v Visitor) { v.DoAssignment(x); } func (x *Assignment) Visit(v Visitor) { v.DoAssignment(x); }
func (x *IfStat) Visit(v Visitor) { v.DoIfStat(x); } func (x *IfStat) Visit(v Visitor) { v.DoIfStat(x); }
...@@ -408,6 +441,8 @@ func (x *SwitchStat) Visit(v Visitor) { v.DoSwitchStat(x); } ...@@ -408,6 +441,8 @@ func (x *SwitchStat) Visit(v Visitor) { v.DoSwitchStat(x); }
func (x *ReturnStat) Visit(v Visitor) { v.DoReturnStat(x); } func (x *ReturnStat) Visit(v Visitor) { v.DoReturnStat(x); }
func (x *IncDecStat) Visit(v Visitor) { v.DoIncDecStat(x); } func (x *IncDecStat) Visit(v Visitor) { v.DoIncDecStat(x); }
func (x *ControlFlowStat) Visit(v Visitor) { v.DoControlFlowStat(x); } func (x *ControlFlowStat) Visit(v Visitor) { v.DoControlFlowStat(x); }
func (x *GoStat) Visit(v Visitor) { v.DoGoStat(x); }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Program // Program
......
...@@ -251,12 +251,12 @@ func (P *Parser) ParseChannelType() *AST.ChannelType { ...@@ -251,12 +251,12 @@ func (P *Parser) ParseChannelType() *AST.ChannelType {
func (P *Parser) ParseVarDeclList() *AST.VarDeclList { func (P *Parser) ParseVarDeclList() *AST.VarDeclList {
P.Trace("VarDeclList"); P.Trace("VarDeclList");
res := new(AST.VarDeclList); vars := new(AST.VarDeclList);
res.idents = P.ParseIdentList(); vars.idents = P.ParseIdentList();
res.typ = P.ParseVarType(); vars.typ = P.ParseVarType();
P.Ecart(); P.Ecart();
return res; return vars;
} }
...@@ -355,33 +355,39 @@ func (P *Parser) ParseFunctionType() *AST.FunctionType { ...@@ -355,33 +355,39 @@ func (P *Parser) ParseFunctionType() *AST.FunctionType {
} }
func (P *Parser) ParseMethodDecl() { func (P *Parser) ParseMethodDecl() *AST.MethodDecl {
P.Trace("MethodDecl"); P.Trace("MethodDecl");
ident := P.ParseIdent(); decl := new(AST.MethodDecl);
P.ParseFunctionType(); decl.ident = P.ParseIdent();
decl.typ = P.ParseFunctionType();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
P.Ecart(); P.Ecart();
return decl;
} }
func (P *Parser) ParseInterfaceType() *AST.InterfaceType { func (P *Parser) ParseInterfaceType() *AST.InterfaceType {
P.Trace("InterfaceType"); P.Trace("InterfaceType");
typ := new(AST.InterfaceType);
typ.pos = P.pos;
typ.methods = AST.NewList();
P.Expect(Scanner.INTERFACE); P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope(); P.OpenScope();
P.level--; P.level--;
for P.tok >= Scanner.IDENT { for P.tok == Scanner.IDENT {
P.ParseMethodDecl(); typ.methods.Add(P.ParseMethodDecl());
} }
P.level++; P.level++;
P.CloseScope(); P.CloseScope();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
return nil; return typ;
} }
...@@ -413,7 +419,7 @@ func (P *Parser) ParseStructType() *AST.StructType { ...@@ -413,7 +419,7 @@ func (P *Parser) ParseStructType() *AST.StructType {
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope(); P.OpenScope();
P.level--; P.level--;
for P.tok >= Scanner.IDENT { for P.tok == Scanner.IDENT {
typ.fields.Add(P.ParseVarDeclList()); typ.fields.Add(P.ParseVarDeclList());
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON); P.Expect(Scanner.SEMICOLON);
...@@ -505,23 +511,21 @@ func (P *Parser) ParseStatementList() *AST.List { ...@@ -505,23 +511,21 @@ func (P *Parser) ParseStatementList() *AST.List {
func (P *Parser) ParseBlock() *AST.Block { func (P *Parser) ParseBlock() *AST.Block {
P.Trace("Block"); P.Trace("Block");
pos := P.pos; block := new(AST.Block);
block.pos = P.pos;
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope(); P.OpenScope();
var stats *AST.List;
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON { if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
stats = P.ParseStatementList(); block.stats = P.ParseStatementList();
} }
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
P.CloseScope(); P.CloseScope();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
return block;
x := new(AST.Block);
x.pos, x.stats = pos, stats;
return x;
} }
...@@ -619,36 +623,37 @@ func (P *Parser) ParseCompositeLit() AST.Expr { ...@@ -619,36 +623,37 @@ func (P *Parser) ParseCompositeLit() AST.Expr {
func (P *Parser) ParseOperand() AST.Expr { func (P *Parser) ParseOperand() AST.Expr {
P.Trace("Operand"); P.Trace("Operand");
var z AST.Expr; var op AST.Expr;
switch P.tok { switch P.tok {
case Scanner.IDENT: case Scanner.IDENT:
z = P.ParseIdent(); op = P.ParseIdent();
case Scanner.LPAREN: case Scanner.LPAREN:
P.Next(); P.Next();
z = P.ParseExpression(); op = P.ParseExpression();
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING: case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x := new(AST.Literal); lit := new(AST.Literal);
x.pos, x.tok, x.val = P.pos, P.tok, P.val; lit.pos, lit.tok, lit.val = P.pos, P.tok, P.val;
z = x; op = lit;
P.Next(); P.Next();
case Scanner.FUNC: case Scanner.FUNC:
z = P.ParseFunctionLit(); op = P.ParseFunctionLit();
case Scanner.HASH: case Scanner.HASH:
P.Next(); P.Next();
P.ParseType(); P.ParseType();
P.ParseCompositeLit(); P.ParseCompositeLit();
z = nil; op = AST.NIL;
default: default:
if P.tok != Scanner.IDENT { if P.tok != Scanner.IDENT {
typ, ok := P.TryType(); typ, ok := P.TryType();
if ok { if ok {
z = P.ParseCompositeLit(); op = P.ParseCompositeLit();
break; break;
} }
} }
...@@ -658,7 +663,7 @@ func (P *Parser) ParseOperand() AST.Expr { ...@@ -658,7 +663,7 @@ func (P *Parser) ParseOperand() AST.Expr {
} }
P.Ecart(); P.Ecart();
return z; return op;
} }
...@@ -789,32 +794,12 @@ func (P *Parser) ParseUnaryExpr() AST.Expr { ...@@ -789,32 +794,12 @@ func (P *Parser) ParseUnaryExpr() AST.Expr {
} }
func Precedence(tok int) int {
// TODO should use a map or array here for lookup
switch tok {
case Scanner.LOR:
return 1;
case Scanner.LAND:
return 2;
case Scanner.ARROW:
return 3;
case Scanner.EQL, Scanner.NEQ, Scanner.LSS, Scanner.LEQ, Scanner.GTR, Scanner.GEQ:
return 4;
case Scanner.ADD, Scanner.SUB, Scanner.OR, Scanner.XOR:
return 5;
case Scanner.MUL, Scanner.QUO, Scanner.REM, Scanner.SHL, Scanner.SHR, Scanner.AND:
return 6;
}
return 0;
}
func (P *Parser) ParseBinaryExpr(prec1 int) AST.Expr { func (P *Parser) ParseBinaryExpr(prec1 int) AST.Expr {
P.Trace("BinaryExpr"); P.Trace("BinaryExpr");
x := P.ParseUnaryExpr(); x := P.ParseUnaryExpr();
for prec := Precedence(P.tok); prec >= prec1; prec-- { for prec := Scanner.Precedence(P.tok); prec >= prec1; prec-- {
for Precedence(P.tok) == prec { for Scanner.Precedence(P.tok) == prec {
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.Next(); P.Next();
y := P.ParseBinaryExpr(prec + 1); y := P.ParseBinaryExpr(prec + 1);
...@@ -857,7 +842,16 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -857,7 +842,16 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
switch P.tok { switch P.tok {
case Scanner.COLON: case Scanner.COLON:
// label declaration // label declaration
l := new(AST.Label);
l.pos = P.pos;
if x.len() == 1 {
l.ident = x.at(0);
} else {
P.Error(P.pos, "illegal label declaration");
l.ident = AST.NIL;
}
P.Next(); // consume ":" P.Next(); // consume ":"
stat = l;
case case
Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN, Scanner.DEFINE, Scanner.ASSIGN, Scanner.ADD_ASSIGN,
...@@ -867,9 +861,9 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -867,9 +861,9 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.Next(); P.Next();
y := P.ParseExpressionList(); y := P.ParseExpressionList();
asgn := new(AST.Assignment); a := new(AST.Assignment);
asgn.pos, asgn.tok, asgn.lhs, asgn.rhs = pos, tok, x, y; a.pos, a.tok, a.lhs, a.rhs = pos, tok, x, y;
stat = asgn; stat = a;
default: default:
if P.tok == Scanner.INC || P.tok == Scanner.DEC { if P.tok == Scanner.INC || P.tok == Scanner.DEC {
...@@ -883,14 +877,14 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -883,14 +877,14 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
P.Next(); P.Next();
stat = s; stat = s;
} else { } else {
xstat := new(AST.ExprStat); s := new(AST.ExprStat);
if x != nil && x.len() > 0 { if x != nil && x.len() > 0 {
xstat.expr = x.at(0); s.expr = x.at(0);
} else { } else {
// this is a syntax error // this is a syntax error
xstat.expr = AST.NIL; s.expr = AST.NIL;
} }
stat = xstat; stat = s;
} }
} }
...@@ -899,13 +893,17 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -899,13 +893,17 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
} }
func (P *Parser) ParseGoStat() { func (P *Parser) ParseGoStat() *AST.GoStat {
P.Trace("GoStat"); P.Trace("GoStat");
stat := new(AST.GoStat);
stat.pos = P.pos;
P.Expect(Scanner.GO); P.Expect(Scanner.GO);
P.ParseExpression(); stat.expr = P.ParseExpression();
P.Ecart(); P.Ecart();
return stat;
} }
...@@ -1155,7 +1153,7 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) { ...@@ -1155,7 +1153,7 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) {
case Scanner.MUL, Scanner.ARROW, Scanner.IDENT, Scanner.LPAREN: case Scanner.MUL, Scanner.ARROW, Scanner.IDENT, Scanner.LPAREN:
stat = P.ParseSimpleStat(); stat = P.ParseSimpleStat();
case Scanner.GO: case Scanner.GO:
P.ParseGoStat(); stat = P.ParseGoStat();
case Scanner.RETURN: case Scanner.RETURN:
stat = P.ParseReturnStat(); stat = P.ParseReturnStat();
case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO: case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO:
...@@ -1188,24 +1186,28 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) { ...@@ -1188,24 +1186,28 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Declarations // Declarations
func (P *Parser) ParseImportSpec() { func (P *Parser) ParseImportSpec() *AST.ImportDecl {
P.Trace("ImportSpec"); P.Trace("ImportSpec");
decl := new(AST.ImportDecl);
if P.tok == Scanner.PERIOD { if P.tok == Scanner.PERIOD {
P.Error(P.pos, `"import ." not yet handled properly`); P.Error(P.pos, `"import ." not yet handled properly`);
P.Next(); P.Next();
} else if P.tok == Scanner.IDENT { } else if P.tok == Scanner.IDENT {
P.ParseIdent(); decl.ident = P.ParseIdent();
} }
if P.tok == Scanner.STRING { if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes // TODO eventually the scanner should strip the quotes
decl.file = P.val;
P.Next(); P.Next();
} else { } else {
P.Expect(Scanner.STRING); // use Expect() error handling P.Expect(Scanner.STRING); // use Expect() error handling
} }
P.Ecart(); P.Ecart();
return decl;
} }
...@@ -1262,15 +1264,14 @@ func (P *Parser) ParseVarSpec(exported bool) *AST.VarDecl { ...@@ -1262,15 +1264,14 @@ func (P *Parser) ParseVarSpec(exported bool) *AST.VarDecl {
// TODO Replace this by using function pointers derived from methods. // TODO Replace this by using function pointers derived from methods.
func (P *Parser) ParseSpec(exported bool, keyword int) AST.Decl { func (P *Parser) ParseSpec(exported bool, keyword int) AST.Decl {
var decl AST.Decl = AST.NIL;
switch keyword { switch keyword {
case Scanner.IMPORT: P.ParseImportSpec(); case Scanner.IMPORT: return P.ParseImportSpec();
case Scanner.CONST: decl = P.ParseConstSpec(exported); case Scanner.CONST: return P.ParseConstSpec(exported);
case Scanner.TYPE: decl = P.ParseTypeSpec(exported); case Scanner.TYPE: return P.ParseTypeSpec(exported);
case Scanner.VAR: decl = P.ParseVarSpec(exported); case Scanner.VAR: return P.ParseVarSpec(exported);
default: panic("UNREACHABLE");
} }
return decl; panic("UNREACHABLE");
return AST.NIL;
} }
...@@ -1440,7 +1441,7 @@ func (P *Parser) ParseProgram() *AST.Program { ...@@ -1440,7 +1441,7 @@ func (P *Parser) ParseProgram() *AST.Program {
} }
for P.tok == Scanner.IMPORT { for P.tok == Scanner.IMPORT {
P.ParseDecl(false, Scanner.IMPORT); decls.Add(P.ParseDecl(false, Scanner.IMPORT));
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
} }
......
...@@ -41,10 +41,13 @@ func main() { ...@@ -41,10 +41,13 @@ func main() {
src, ok := Platform.ReadSourceFile(src_file); src, ok := Platform.ReadSourceFile(src_file);
if !ok { if !ok {
print("cannot open ", src_file, "\n"); print("cannot open ", src_file, "\n");
return; sys.exit(1);
} }
if silent.BVal() {
print("- ", src_file, "\n"); print("- ", src_file, "\n");
}
scanner := new(Scanner.Scanner); scanner := new(Scanner.Scanner);
scanner.Open(src_file, src); scanner.Open(src_file, src);
...@@ -57,6 +60,11 @@ func main() { ...@@ -57,6 +60,11 @@ func main() {
parser.Open(verbose.BVal(), scanner, tstream); parser.Open(verbose.BVal(), scanner, tstream);
prog := parser.ParseProgram(); prog := parser.ParseProgram();
if scanner.nerrors > 0 {
sys.exit(1);
}
if !silent.BVal() { if !silent.BVal() {
Printer.Print(prog); Printer.Print(prog);
} }
......
...@@ -11,6 +11,7 @@ import AST "ast" ...@@ -11,6 +11,7 @@ import AST "ast"
// Printer implements AST.Visitor // Printer implements AST.Visitor
type Printer struct { type Printer struct {
indent int; indent int;
prec int; // operator precedence
} }
...@@ -32,7 +33,10 @@ func (P *Printer) String(s string) { ...@@ -32,7 +33,10 @@ func (P *Printer) String(s string) {
func (P *Printer) Print(x AST.Node) { func (P *Printer) Print(x AST.Node) {
outer := P.prec;
P.prec = 0;
x.Visit(P); x.Visit(P);
P.prec = outer;
} }
...@@ -63,14 +67,9 @@ func (P *Printer) DoIdent(x *AST.Ident) { ...@@ -63,14 +67,9 @@ func (P *Printer) DoIdent(x *AST.Ident) {
// Types // Types
func (P *Printer) DoFunctionType(x *AST.FunctionType) { func (P *Printer) DoFunctionType(x *AST.FunctionType) {
/*
if x.recv != nil {
P.DoVarDeclList(x.recv);
}
*/
P.String("("); P.String("(");
P.PrintList(x.params); P.PrintList(x.params);
P.String(") "); P.String(")");
} }
...@@ -100,6 +99,10 @@ func (P *Printer) DoStructType(x *AST.StructType) { ...@@ -100,6 +99,10 @@ func (P *Printer) DoStructType(x *AST.StructType) {
func (P *Printer) DoMapType(x *AST.MapType) { func (P *Printer) DoMapType(x *AST.MapType) {
P.String("[");
P.Print(x.key);
P.String("] ");
P.Print(x.val);
} }
...@@ -110,6 +113,19 @@ func (P *Printer) DoChannelType(x *AST.ChannelType) { ...@@ -110,6 +113,19 @@ func (P *Printer) DoChannelType(x *AST.ChannelType) {
func (P *Printer) DoInterfaceType(x *AST.InterfaceType) { func (P *Printer) DoInterfaceType(x *AST.InterfaceType) {
P.String("interface {");
if x.methods.len() > 0 {
P.NewLine(1);
for i := 0; i < x.methods.len(); i++ {
if i > 0 {
P.NewLine(0);
}
P.Print(x.methods.at(i));
P.String(";");
}
P.NewLine(-1);
}
P.String("}");
} }
...@@ -125,6 +141,15 @@ func (P *Printer) DoPointerType(x *AST.PointerType) { ...@@ -125,6 +141,15 @@ func (P *Printer) DoPointerType(x *AST.PointerType) {
func (P *Printer) DoBlock(x *AST.Block); func (P *Printer) DoBlock(x *AST.Block);
func (P *Printer) DoImportDecl(x *AST.ImportDecl) {
if x.ident != nil {
P.Print(x.ident);
P.String(" ");
}
P.String(x.file);
}
func (P *Printer) DoConstDecl(x *AST.ConstDecl) { func (P *Printer) DoConstDecl(x *AST.ConstDecl) {
P.Print(x.ident); P.Print(x.ident);
P.String(" "); P.String(" ");
...@@ -168,6 +193,7 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) { ...@@ -168,6 +193,7 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
} }
P.DoIdent(x.ident); P.DoIdent(x.ident);
P.DoFunctionType(x.typ); P.DoFunctionType(x.typ);
P.String(" ");
if x.body != nil { if x.body != nil {
P.DoBlock(x.body); P.DoBlock(x.body);
} else { } else {
...@@ -179,6 +205,12 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) { ...@@ -179,6 +205,12 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
} }
func (P *Printer) DoMethodDecl(x *AST.MethodDecl) {
P.DoIdent(x.ident);
P.DoFunctionType(x.typ);
}
func (P *Printer) DoDeclaration(x *AST.Declaration) { func (P *Printer) DoDeclaration(x *AST.Declaration) {
P.String(Scanner.TokenName(x.tok)); P.String(Scanner.TokenName(x.tok));
P.String(" "); P.String(" ");
...@@ -208,11 +240,22 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) { ...@@ -208,11 +240,22 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) {
// Expressions // Expressions
func (P *Printer) DoBinary(x *AST.Binary) { func (P *Printer) DoBinary(x *AST.Binary) {
outer := P.prec;
P.prec = Scanner.Precedence(x.tok);
if P.prec < outer {
print("("); print("(");
}
P.Print(x.x); P.Print(x.x);
P.String(" " + Scanner.TokenName(x.tok) + " "); P.String(" " + Scanner.TokenName(x.tok) + " ");
P.Print(x.y); P.Print(x.y);
if P.prec < outer {
print(")"); print(")");
}
P.prec = outer;
} }
...@@ -261,12 +304,8 @@ func (P *Printer) DoSelector(x *AST.Selector) { ...@@ -261,12 +304,8 @@ func (P *Printer) DoSelector(x *AST.Selector) {
// Statements // Statements
func (P *Printer) DoBlock(x *AST.Block) { func (P *Printer) DoBlock(x *AST.Block) {
if x == nil || x.stats == nil {
P.NewLine(0);
return;
}
P.String("{"); P.String("{");
if x.stats != nil {
P.NewLine(1); P.NewLine(1);
for i := 0; i < x.stats.len(); i++ { for i := 0; i < x.stats.len(); i++ {
if i > 0 { if i > 0 {
...@@ -275,13 +314,20 @@ func (P *Printer) DoBlock(x *AST.Block) { ...@@ -275,13 +314,20 @@ func (P *Printer) DoBlock(x *AST.Block) {
P.Print(x.stats.at(i)); P.Print(x.stats.at(i));
} }
P.NewLine(-1); P.NewLine(-1);
}
P.String("}"); P.String("}");
} }
func (P *Printer) DoLabel(x *AST.Label) {
P.Print(x.ident);
P.String(":");
}
func (P *Printer) DoExprStat(x *AST.ExprStat) { func (P *Printer) DoExprStat(x *AST.ExprStat) {
P.Print(x.expr); P.Print(x.expr);
P.String(";"); //P.String(";");
} }
...@@ -289,7 +335,7 @@ func (P *Printer) DoAssignment(x *AST.Assignment) { ...@@ -289,7 +335,7 @@ func (P *Printer) DoAssignment(x *AST.Assignment) {
P.PrintList(x.lhs); P.PrintList(x.lhs);
P.String(" " + Scanner.TokenName(x.tok) + " "); P.String(" " + Scanner.TokenName(x.tok) + " ");
P.PrintList(x.rhs); P.PrintList(x.rhs);
P.String(";"); //P.String(";");
} }
...@@ -401,7 +447,7 @@ func (P *Printer) DoReturnStat(x *AST.ReturnStat) { ...@@ -401,7 +447,7 @@ func (P *Printer) DoReturnStat(x *AST.ReturnStat) {
func (P *Printer) DoIncDecStat(x *AST.IncDecStat) { func (P *Printer) DoIncDecStat(x *AST.IncDecStat) {
P.Print(x.expr); P.Print(x.expr);
P.String(Scanner.TokenName(x.tok)); P.String(Scanner.TokenName(x.tok));
P.String(";"); //P.String(";");
} }
...@@ -415,6 +461,13 @@ func (P *Printer) DoControlFlowStat(x *AST.ControlFlowStat) { ...@@ -415,6 +461,13 @@ func (P *Printer) DoControlFlowStat(x *AST.ControlFlowStat) {
} }
func (P *Printer) DoGoStat(x *AST.GoStat) {
P.String("go ");
P.Print(x.expr);
P.String(";");
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Program // Program
......
...@@ -11,6 +11,7 @@ import Utils "utils" ...@@ -11,6 +11,7 @@ import Utils "utils"
export const ( export const (
ILLEGAL = iota; ILLEGAL = iota;
EOF; EOF;
IDENT;
INT; INT;
FLOAT; FLOAT;
STRING; STRING;
...@@ -73,9 +74,6 @@ export const ( ...@@ -73,9 +74,6 @@ export const (
LAND; LAND;
LOR; LOR;
// IDENT must be immediately before keywords
IDENT;
// keywords // keywords
KEYWORDS_BEG; KEYWORDS_BEG;
BREAK; BREAK;
...@@ -115,6 +113,7 @@ export func TokenName(tok int) string { ...@@ -115,6 +113,7 @@ export func TokenName(tok int) string {
switch (tok) { switch (tok) {
case ILLEGAL: return "illegal"; case ILLEGAL: return "illegal";
case EOF: return "eof"; case EOF: return "eof";
case IDENT: return "ident";
case INT: return "int"; case INT: return "int";
case FLOAT: return "float"; case FLOAT: return "float";
case STRING: return "string"; case STRING: return "string";
...@@ -177,8 +176,6 @@ export func TokenName(tok int) string { ...@@ -177,8 +176,6 @@ export func TokenName(tok int) string {
case LAND: return "&&"; case LAND: return "&&";
case LOR: return "||"; case LOR: return "||";
case IDENT: return "ident";
case BREAK: return "break"; case BREAK: return "break";
case CASE: return "case"; case CASE: return "case";
case CHAN: return "chan"; case CHAN: return "chan";
...@@ -210,6 +207,26 @@ export func TokenName(tok int) string { ...@@ -210,6 +207,26 @@ export func TokenName(tok int) string {
} }
export func Precedence(tok int) int {
// TODO should use a map or array here for lookup
switch tok {
case LOR:
return 1;
case LAND:
return 2;
case ARROW:
return 3;
case EQL, NEQ, LSS, LEQ, GTR, GEQ:
return 4;
case ADD, SUB, OR, XOR:
return 5;
case MUL, QUO, REM, SHL, SHR, AND:
return 6;
}
return 0;
}
func init() { func init() {
Keywords = new(map [string] int); Keywords = new(map [string] int);
......
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