Commit 9e3b0f44 authored by Robert Griesemer's avatar Robert Griesemer

snapshot before making more changes:

- fine-tuning of ast
- more accurate block pos info (improved printing in some cases)
- collecting local variables and fields
- more work on type checking
- lots of minor tweaks

R=r
OCL=23375
CL=23375
parent f4279f58
......@@ -16,12 +16,23 @@ type (
Object struct;
Type struct;
Block struct;
Expr struct;
Stat struct;
Decl struct;
)
// ----------------------------------------------------------------------------
// Support
func assert(pred bool) {
if !pred {
panic("assertion failed");
}
}
// ----------------------------------------------------------------------------
// Objects
......@@ -63,7 +74,7 @@ type Object struct {
Pnolev int; // >= 0: package no., <= 0: function nesting level, 0: global level
// attached values
Block *array.Array; End int; // stats for function literals; end of block pos
Body *Block; // function body
}
......@@ -174,16 +185,41 @@ type Node struct {
}
// ----------------------------------------------------------------------------
// Blocks
//
// Syntactic constructs of the form:
//
// "{" StatementList "}"
// ":" StatementList
type Block struct {
Node;
List *array.Array;
End int; // position of closing "}" if present
}
func NewBlock(pos, tok int) *Block {
assert(tok == Scanner.LBRACE || tok == Scanner.COLON);
b := new(Block);
b.Pos, b.Tok, b.List = pos, tok, array.New(0);
return b;
}
// ----------------------------------------------------------------------------
// Expressions
type Expr struct {
Node;
X, Y *Expr; // binary (X, Y) and unary (Y) expressions
Obj *Object;
Obj *Object; // identifiers, literals
Typ *Type;
}
// Length of a comma-separated expression list.
func (x *Expr) Len() int {
if x == nil {
return 0;
......@@ -196,6 +232,19 @@ func (x *Expr) Len() int {
}
// The i'th expression in a comma-separated expression list.
func (x *Expr) At(i int) *Expr {
for j := 0; j < i; j++ {
assert(x.Tok == Scanner.COMMA);
x = x.Y;
}
if x.Tok == Scanner.COMMA {
x = x.X;
}
return x;
}
func NewExpr(pos, tok int, x, y *Expr) *Expr {
if x != nil && x.Tok == Scanner.TYPE || y != nil && y.Tok == Scanner.TYPE {
panic("no type expression allowed");
......@@ -302,7 +351,7 @@ type Type struct {
Form int; // type form
Size int; // size in bytes
Obj *Object; // primary type object or NULL
Scope *Scope; // forwards, structs, interfaces, functions
Scope *Scope; // locals, fields & methods
// syntactic components
Pos int; // source position (< 0 if unknown position)
......@@ -311,7 +360,6 @@ type Type struct {
Key *Type; // receiver type or map key
Elt *Type; // array, map, channel or pointer element type, function result type
List *array.Array; End int; // struct fields, interface methods, function parameters
Scope *Scope; // struct fields, methods
}
......@@ -351,9 +399,9 @@ func (t *Type) Nfields() int {
// requires complete Type.Pos access
func NewTypeExpr(typ *Type) *Expr {
obj := NewObject(typ.Pos, TYPE, "");
obj.Typ = typ;
return NewLit(Scanner.TYPE, obj);
e := new(Expr);
e.Pos, e.Tok, e.Typ = typ.Pos, Scanner.TYPE, typ;
return e;
}
......@@ -367,7 +415,7 @@ type Stat struct {
Node;
Init, Post *Stat;
Expr *Expr;
Block *array.Array; End int; // block end position
Body *Block; // composite statement body
Decl *Decl;
}
......@@ -391,7 +439,6 @@ type Decl struct {
Typ *Type;
Val *Expr;
// list of *Decl for ()-style declarations
// list of *Stat for func declarations (or nil for forward decl)
List *array.Array; End int;
}
......
This diff is collapsed.
......@@ -537,7 +537,7 @@ func (P *Printer) Type(t *AST.Type) int {
// ----------------------------------------------------------------------------
// Expressions
func (P *Printer) Block(pos int, list *array.Array, end int, indent bool);
func (P *Printer) Block(b *AST.Block, indent bool);
func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
if x == nil {
......@@ -547,7 +547,7 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
switch x.Tok {
case Scanner.TYPE:
// type expr
P.Type(x.Obj.Typ);
P.Type(x.Typ);
case Scanner.IDENT:
P.HtmlIdentifier(x);
......@@ -560,7 +560,7 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
// function literal
P.String(x.Pos, "func");
P.Type(x.Obj.Typ);
P.Block(0, x.Obj.Block, x.Obj.End, true);
P.Block(x.Obj.Body, true);
P.newlines = 0;
case Scanner.COMMA:
......@@ -646,24 +646,22 @@ func (P *Printer) Expr(x *AST.Expr) {
func (P *Printer) Stat(s *AST.Stat)
func (P *Printer) StatementList(list *array.Array) {
if list != nil {
for i, n := 0, list.Len(); i < n; i++ {
P.newlines = 1; // for first entry
P.Stat(list.At(i).(*AST.Stat));
P.newlines = 1;
for i, n := 0, list.Len(); i < n; i++ {
P.Stat(list.At(i).(*AST.Stat));
P.newlines = 1;
P.state = inside_list;
}
P.state = inside_list;
}
}
func (P *Printer) Block(pos int, list *array.Array, end int, indent bool) {
func (P *Printer) Block(b *AST.Block, indent bool) {
P.state = opening_scope;
P.String(pos, "{");
P.Token(b.Pos, b.Tok);
if !indent {
P.indentation--;
}
P.StatementList(list);
P.StatementList(b.List);
if !indent {
P.indentation++;
}
......@@ -671,7 +669,11 @@ func (P *Printer) Block(pos int, list *array.Array, end int, indent bool) {
P.separator = none;
}
P.state = closing_scope;
P.String(end, "}");
if b.Tok == Scanner.LBRACE {
P.String(b.End, "}");
} else {
P.String(0, ""); // process closing_scope state transition!
}
}
......@@ -737,12 +739,12 @@ func (P *Printer) Stat(s *AST.Stat) {
case Scanner.LBRACE:
// block
P.Block(s.Pos, s.Block, s.End, true);
P.Block(s.Body, true);
case Scanner.IF:
P.String(s.Pos, "if");
P.ControlClause(s);
P.Block(0, s.Block, s.End, true);
P.Block(s.Body, true);
if s.Post != nil {
P.separator = blank;
P.String(0, "else");
......@@ -753,12 +755,12 @@ func (P *Printer) Stat(s *AST.Stat) {
case Scanner.FOR:
P.String(s.Pos, "for");
P.ControlClause(s);
P.Block(0, s.Block, s.End, true);
P.Block(s.Body, true);
case Scanner.SWITCH, Scanner.SELECT:
P.Token(s.Pos, s.Tok);
P.ControlClause(s);
P.Block(0, s.Block, s.End, false);
P.Block(s.Body, false);
case Scanner.CASE, Scanner.DEFAULT:
P.Token(s.Pos, s.Tok);
......@@ -766,9 +768,11 @@ func (P *Printer) Stat(s *AST.Stat) {
P.separator = blank;
P.Expr(s.Expr);
}
P.String(0, ":");
// TODO: try to use P.Block instead
// P.Block(s.Body, true);
P.String(s.Body.Pos, ":");
P.indentation++;
P.StatementList(s.Block);
P.StatementList(s.Body.List);
P.indentation--;
P.newlines = 1;
......@@ -850,9 +854,9 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
}
P.Expr(d.Ident);
P.separator = P.Type(d.Typ);
if d.List != nil {
if d.Val != nil {
P.separator = blank;
P.Block(0, d.List, d.End, true);
P.Block(d.Val.Obj.Body, true);
}
default:
......
......@@ -170,8 +170,8 @@ func TokenString(tok int) string {
case RPAREN: return ")";
case LBRACK: return "[";
case RBRACK: return "]";
case LBRACE: return "LBRACE";
case RBRACE: return "RBRACE";
case LBRACE: return "{";
case RBRACE: return "}";
case COMMA: return ",";
case SEMICOLON: return ";";
......
......@@ -24,9 +24,10 @@ apply1() {
#echo $1 $2
case `basename $F` in
# files with errors (skip them)
# the following have semantic errors: bug039.go | bug040.go
method1.go | selftest1.go | func3.go | \
bug014.go | bug025.go | bug029.go | bug032.go | bug050.go | bug068.go | \
bug088.go | bug083.go | bug106.go | bug125.go | bug126.go ) ;;
bug014.go | bug025.go | bug029.go | bug032.go | bug039.go | bug040.go | bug050.go | bug068.go | \
bug088.go | bug083.go | bug106.go | bug125.go | bug126.go | bug132.go ) ;;
* ) $1 $2; count $F;;
esac
}
......
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