Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
c5a29a6d
Commit
c5a29a6d
authored
Sep 24, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- more ast buidling and printing
- almost complete language reproduced R=r OCL=15801 CL=15801
parent
afd04fdb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
517 additions
and
187 deletions
+517
-187
usr/gri/pretty/ast.go
usr/gri/pretty/ast.go
+141
-31
usr/gri/pretty/parser.go
usr/gri/pretty/parser.go
+206
-145
usr/gri/pretty/printer.go
usr/gri/pretty/printer.go
+170
-11
No files found.
usr/gri/pretty/ast.go
View file @
c5a29a6d
...
@@ -15,10 +15,20 @@ export type Visitor interface {
...
@@ -15,10 +15,20 @@ export type Visitor interface {
// Types
// Types
DoFunctionType
(
x
*
FunctionType
);
DoFunctionType
(
x
*
FunctionType
);
DoArrayType
(
x
*
ArrayType
);
DoStructType
(
x
*
StructType
);
DoMapType
(
x
*
MapType
);
DoChannelType
(
x
*
ChannelType
);
DoInterfaceType
(
x
*
InterfaceType
);
DoPointerType
(
x
*
PointerType
);
// Declarations
// Declarations
//DoVarDeclList(x *VarDeclList);
DoConstDecl
(
x
*
ConstDecl
);
DoTypeDecl
(
x
*
TypeDecl
);
DoVarDecl
(
x
*
VarDecl
);
DoVarDeclList
(
x
*
VarDeclList
);
DoFuncDecl
(
x
*
FuncDecl
);
DoFuncDecl
(
x
*
FuncDecl
);
DoDeclaration
(
x
*
Declaration
);
// Expressions
// Expressions
DoBinary
(
x
*
Binary
);
DoBinary
(
x
*
Binary
);
...
@@ -35,8 +45,10 @@ export type Visitor interface {
...
@@ -35,8 +45,10 @@ export type Visitor interface {
DoAssignment
(
x
*
Assignment
);
DoAssignment
(
x
*
Assignment
);
DoIfStat
(
x
*
IfStat
);
DoIfStat
(
x
*
IfStat
);
DoForStat
(
x
*
ForStat
);
DoForStat
(
x
*
ForStat
);
DoSwitch
(
x
*
Switch
);
DoCaseClause
(
x
*
CaseClause
);
DoReturn
(
x
*
Return
);
DoSwitchStat
(
x
*
SwitchStat
);
DoReturnStat
(
x
*
ReturnStat
);
DoIncDecStat
(
x
*
IncDecStat
);
// Program
// Program
DoProgram
(
x
*
Program
);
DoProgram
(
x
*
Program
);
...
@@ -60,6 +72,7 @@ export type List struct {
...
@@ -60,6 +72,7 @@ export type List struct {
func
(
p
*
List
)
len
()
int
{
func
(
p
*
List
)
len
()
int
{
if
p
==
nil
{
return
0
;
}
return
len
(
p
.
a
);
return
len
(
p
.
a
);
}
}
...
@@ -122,14 +135,61 @@ export type Type interface {
...
@@ -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
{
export
type
FunctionType
struct
{
pos
int
;
// position of "("
recv
*
VarDeclList
;
recv
*
VarDeclList
;
params
*
List
;
params
*
List
;
// list of *VarDeclList
result
*
List
;
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 {
...
@@ -142,73 +202,99 @@ export type Decl interface {
export
type
VarDeclList
struct
{
export
type
VarDeclList
struct
{
idents
*
List
;
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
{
export
type
FuncDecl
struct
{
pos
int
;
pos
int
;
// position of "func"
ident
*
Ident
;
ident
*
Ident
;
typ
*
FunctionType
;
typ
*
FunctionType
;
body
*
Block
;
body
*
Block
;
}
}
func
(
x
*
VarDeclList
)
Visit
(
v
Visitor
)
{
/*v.DoVarDeclList(x);*/
}
func
(
x
*
VarDeclList
)
Visit
(
v
Visitor
)
{
v
.
DoVarDeclList
(
x
);
}
func
(
x
*
FuncDecl
)
Visit
(
v
Visitor
)
{
v
.
DoFuncDecl
(
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
// Expressions
export
type
Expr
interface
{
Visit
(
x
Visitor
);
}
export
type
Selector
struct
{
export
type
Selector
struct
{
pos
int
;
pos
int
;
// position of "."
x
Expr
;
x
Expr
;
field
string
;
field
string
;
}
}
export
type
Index
struct
{
export
type
Index
struct
{
pos
int
;
pos
int
;
// position of "["
x
Expr
;
x
Expr
;
index
Expr
;
index
Expr
;
}
}
export
type
Call
struct
{
export
type
Call
struct
{
pos
int
;
pos
int
;
// position of "("
fun
Expr
;
fun
Expr
;
args
*
List
;
args
*
List
;
}
}
export
type
Pair
struct
{
export
type
Pair
struct
{
pos
int
;
pos
int
;
// position of ":"
x
,
y
Expr
;
x
,
y
Expr
;
}
}
export
type
Binary
struct
{
export
type
Binary
struct
{
pos
int
;
pos
int
;
// position of operator tok
tok
int
;
tok
int
;
x
,
y
Expr
;
x
,
y
Expr
;
}
}
export
type
Unary
struct
{
export
type
Unary
struct
{
pos
int
;
pos
int
;
// position of operator tok
tok
int
;
tok
int
;
x
Expr
;
x
Expr
;
}
}
export
type
Literal
struct
{
export
type
Literal
struct
{
pos
int
;
pos
int
;
// position of literal
tok
int
;
tok
int
;
val
string
;
val
string
;
}
}
...
@@ -232,7 +318,7 @@ export type Stat interface {
...
@@ -232,7 +318,7 @@ export type Stat interface {
export
type
Block
struct
{
export
type
Block
struct
{
pos
int
;
pos
int
;
// position of "{"
stats
*
List
;
stats
*
List
;
}
}
...
@@ -243,14 +329,14 @@ export type ExprStat struct {
...
@@ -243,14 +329,14 @@ export type ExprStat struct {
export
type
Assignment
struct
{
export
type
Assignment
struct
{
pos
int
;
pos
int
;
// position of assignment token
tok
int
;
tok
int
;
lhs
,
rhs
*
List
;
lhs
,
rhs
*
List
;
}
}
export
type
IfStat
struct
{
export
type
IfStat
struct
{
pos
int
;
pos
int
;
// position of "if"
init
Stat
;
init
Stat
;
cond
Expr
;
cond
Expr
;
then
,
else_
*
Block
;
then
,
else_
*
Block
;
...
@@ -258,28 +344,52 @@ export type IfStat struct {
...
@@ -258,28 +344,52 @@ export type IfStat struct {
export
type
ForStat
struct
{
export
type
ForStat
struct
{
pos
int
;
pos
int
;
// position of "for"
init
Stat
;
cond
Expr
;
post
Stat
;
body
*
Block
;
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
{
export
type
SwitchStat
struct
{
pos
int
;
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
;
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
*
Block
)
Visit
(
v
Visitor
)
{
v
.
DoBlock
(
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
);
}
func
(
x
*
ForStat
)
Visit
(
v
Visitor
)
{
v
.
DoForStat
(
x
);
}
func
(
x
*
ForStat
)
Visit
(
v
Visitor
)
{
v
.
DoForStat
(
x
);
}
func
(
x
*
Switch
)
Visit
(
v
Visitor
)
{
v
.
DoSwitch
(
x
);
}
func
(
x
*
CaseClause
)
Visit
(
v
Visitor
)
{
v
.
DoCaseClause
(
x
);
}
func
(
x
*
Return
)
Visit
(
v
Visitor
)
{
v
.
DoReturn
(
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
);
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
...
...
usr/gri/pretty/parser.go
View file @
c5a29a6d
...
@@ -110,10 +110,10 @@ func (P *Parser) CloseScope() {
...
@@ -110,10 +110,10 @@ func (P *Parser) CloseScope() {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Common productions
// Common productions
func
(
P
*
Parser
)
TryType
()
bool
;
func
(
P
*
Parser
)
TryType
()
(
AST
.
Type
,
bool
)
;
func
(
P
*
Parser
)
ParseExpression
()
AST
.
Expr
;
func
(
P
*
Parser
)
ParseExpression
()
AST
.
Expr
;
func
(
P
*
Parser
)
TryStatement
()
(
AST
.
Stat
,
bool
);
func
(
P
*
Parser
)
TryStatement
()
(
AST
.
Stat
,
bool
);
func
(
P
*
Parser
)
ParseDeclaration
()
AST
.
Decl
;
func
(
P
*
Parser
)
ParseDeclaration
()
AST
.
Node
;
func
(
P
*
Parser
)
ParseIdent
()
*
AST
.
Ident
{
func
(
P
*
Parser
)
ParseIdent
()
*
AST
.
Ident
{
...
@@ -152,22 +152,18 @@ func (P *Parser) ParseIdentList() *AST.List {
...
@@ -152,22 +152,18 @@ func (P *Parser) ParseIdentList() *AST.List {
}
}
func
(
P
*
Parser
)
ParseQualifiedIdent
(
ident
*
AST
.
Ident
)
AST
.
Expr
{
func
(
P
*
Parser
)
ParseQualifiedIdent
()
AST
.
Expr
{
P
.
Trace
(
"QualifiedIdent"
);
P
.
Trace
(
"QualifiedIdent"
);
if
ident
==
nil
{
var
x
AST
.
Expr
=
P
.
ParseIdent
();
ident
=
P
.
ParseIdent
();
}
var
x
AST
.
Expr
=
ident
;
if
P
.
tok
==
Scanner
.
PERIOD
{
if
P
.
tok
==
Scanner
.
PERIOD
{
P
.
Next
();
pos
:=
P
.
pos
;
ident2
:=
P
.
ParseIdent
();
P
.
Next
();
y
:=
P
.
ParseIdent
();
z
:=
new
(
AST
.
Selector
);
z
.
pos
,
z
.
x
,
z
.
field
=
ident
.
pos
,
ident
,
ident2
.
val
;
z
:=
new
(
AST
.
Selector
);
x
=
z
;
z
.
pos
,
z
.
x
,
z
.
field
=
pos
,
x
,
y
.
val
;
x
=
z
;
}
}
P
.
Ecart
();
P
.
Ecart
();
...
@@ -178,55 +174,64 @@ func (P *Parser) ParseQualifiedIdent(ident *AST.Ident) AST.Expr {
...
@@ -178,55 +174,64 @@ func (P *Parser) ParseQualifiedIdent(ident *AST.Ident) AST.Expr {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Types
// Types
func
(
P
*
Parser
)
ParseType
()
{
func
(
P
*
Parser
)
ParseType
()
AST
.
Type
{
P
.
Trace
(
"Type"
);
P
.
Trace
(
"Type"
);
typ
:=
P
.
TryType
();
typ
,
ok
:=
P
.
TryType
();
if
!
typ
{
if
!
ok
{
P
.
Error
(
P
.
pos
,
"type expected"
);
P
.
Error
(
P
.
pos
,
"type expected"
);
}
}
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
func
(
P
*
Parser
)
ParseVarType
()
{
func
(
P
*
Parser
)
ParseVarType
()
AST
.
Type
{
P
.
Trace
(
"VarType"
);
P
.
Trace
(
"VarType"
);
P
.
ParseType
();
typ
:=
P
.
ParseType
();
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
func
(
P
*
Parser
)
ParseTypeName
()
AST
.
Expr
{
func
(
P
*
Parser
)
ParseTypeName
()
AST
.
Type
{
P
.
Trace
(
"TypeName"
);
P
.
Trace
(
"TypeName"
);
x
:=
P
.
ParseQualifiedIdent
(
nil
);
typ
:=
P
.
ParseQualifiedIdent
(
);
P
.
Ecart
();
P
.
Ecart
();
return
x
;
return
typ
;
}
}
func
(
P
*
Parser
)
ParseArrayType
()
{
func
(
P
*
Parser
)
ParseArrayType
()
*
AST
.
ArrayType
{
P
.
Trace
(
"ArrayType"
);
P
.
Trace
(
"ArrayType"
);
typ
:=
new
(
AST
.
ArrayType
);
typ
.
pos
=
P
.
pos
;
P
.
Expect
(
Scanner
.
LBRACK
);
P
.
Expect
(
Scanner
.
LBRACK
);
if
P
.
tok
!=
Scanner
.
RBRACK
{
if
P
.
tok
!=
Scanner
.
RBRACK
{
// TODO set typ.len
// TODO set typ.len
P
.
ParseExpression
();
typ
.
len_
=
P
.
ParseExpression
();
}
}
P
.
Expect
(
Scanner
.
RBRACK
);
P
.
Expect
(
Scanner
.
RBRACK
);
P
.
ParseType
();
typ
.
elt
=
P
.
ParseType
();
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
func
(
P
*
Parser
)
ParseChannelType
()
{
func
(
P
*
Parser
)
ParseChannelType
()
*
AST
.
ChannelType
{
P
.
Trace
(
"ChannelType"
);
P
.
Trace
(
"ChannelType"
);
typ
:=
new
(
AST
.
ChannelType
);
typ
.
pos
=
P
.
pos
;
if
P
.
tok
==
Scanner
.
CHAN
{
if
P
.
tok
==
Scanner
.
CHAN
{
P
.
Next
();
P
.
Next
();
if
P
.
tok
==
Scanner
.
ARROW
{
if
P
.
tok
==
Scanner
.
ARROW
{
...
@@ -236,9 +241,10 @@ func (P *Parser) ParseChannelType() {
...
@@ -236,9 +241,10 @@ func (P *Parser) ParseChannelType() {
P
.
Expect
(
Scanner
.
ARROW
);
P
.
Expect
(
Scanner
.
ARROW
);
P
.
Expect
(
Scanner
.
CHAN
);
P
.
Expect
(
Scanner
.
CHAN
);
}
}
P
.
ParseVarType
();
typ
.
elt
=
P
.
ParseVarType
();
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
...
@@ -247,7 +253,7 @@ func (P *Parser) ParseVarDeclList() *AST.VarDeclList {
...
@@ -247,7 +253,7 @@ func (P *Parser) ParseVarDeclList() *AST.VarDeclList {
res
:=
new
(
AST
.
VarDeclList
);
res
:=
new
(
AST
.
VarDeclList
);
res
.
idents
=
P
.
ParseIdentList
();
res
.
idents
=
P
.
ParseIdentList
();
P
.
ParseVarType
();
res
.
typ
=
P
.
ParseVarType
();
P
.
Ecart
();
P
.
Ecart
();
return
res
;
return
res
;
...
@@ -337,6 +343,7 @@ func (P *Parser) ParseFunctionType() *AST.FunctionType {
...
@@ -337,6 +343,7 @@ func (P *Parser) ParseFunctionType() *AST.FunctionType {
P
.
level
--
;
P
.
level
--
;
typ
:=
new
(
AST
.
FunctionType
);
typ
:=
new
(
AST
.
FunctionType
);
typ
.
pos
=
P
.
pos
;
typ
.
params
=
P
.
ParseParameters
();
typ
.
params
=
P
.
ParseParameters
();
typ
.
result
=
P
.
ParseResult
();
typ
.
result
=
P
.
ParseResult
();
...
@@ -359,7 +366,7 @@ func (P *Parser) ParseMethodDecl() {
...
@@ -359,7 +366,7 @@ func (P *Parser) ParseMethodDecl() {
}
}
func
(
P
*
Parser
)
ParseInterfaceType
()
{
func
(
P
*
Parser
)
ParseInterfaceType
()
*
AST
.
InterfaceType
{
P
.
Trace
(
"InterfaceType"
);
P
.
Trace
(
"InterfaceType"
);
P
.
Expect
(
Scanner
.
INTERFACE
);
P
.
Expect
(
Scanner
.
INTERFACE
);
...
@@ -374,31 +381,40 @@ func (P *Parser) ParseInterfaceType() {
...
@@ -374,31 +381,40 @@ func (P *Parser) ParseInterfaceType() {
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
Ecart
();
P
.
Ecart
();
return
nil
;
}
}
func
(
P
*
Parser
)
ParseMapType
()
{
func
(
P
*
Parser
)
ParseMapType
()
*
AST
.
MapType
{
P
.
Trace
(
"MapType"
);
P
.
Trace
(
"MapType"
);
typ
:=
new
(
AST
.
MapType
);
typ
.
pos
=
P
.
pos
;
P
.
Expect
(
Scanner
.
MAP
);
P
.
Expect
(
Scanner
.
MAP
);
P
.
Expect
(
Scanner
.
LBRACK
);
P
.
Expect
(
Scanner
.
LBRACK
);
P
.
ParseVarType
();
typ
.
key
=
P
.
ParseVarType
();
P
.
Expect
(
Scanner
.
RBRACK
);
P
.
Expect
(
Scanner
.
RBRACK
);
P
.
ParseVarType
();
typ
.
val
=
P
.
ParseVarType
();
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
func
(
P
*
Parser
)
ParseStructType
()
{
func
(
P
*
Parser
)
ParseStructType
()
*
AST
.
StructType
{
P
.
Trace
(
"StructType"
);
P
.
Trace
(
"StructType"
);
typ
:=
new
(
AST
.
StructType
);
typ
.
pos
=
P
.
pos
;
typ
.
fields
=
AST
.
NewList
();
P
.
Expect
(
Scanner
.
STRUCT
);
P
.
Expect
(
Scanner
.
STRUCT
);
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
.
ParseVarDeclList
(
);
typ
.
fields
.
Add
(
P
.
ParseVarDeclList
()
);
if
P
.
tok
!=
Scanner
.
RBRACE
{
if
P
.
tok
!=
Scanner
.
RBRACE
{
P
.
Expect
(
Scanner
.
SEMICOLON
);
P
.
Expect
(
Scanner
.
SEMICOLON
);
}
}
...
@@ -409,38 +425,44 @@ func (P *Parser) ParseStructType() {
...
@@ -409,38 +425,44 @@ func (P *Parser) ParseStructType() {
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
func
(
P
*
Parser
)
ParsePointerType
()
{
func
(
P
*
Parser
)
ParsePointerType
()
*
AST
.
PointerType
{
P
.
Trace
(
"PointerType"
);
P
.
Trace
(
"PointerType"
);
typ
:=
new
(
AST
.
PointerType
);
typ
.
pos
=
P
.
pos
;
P
.
Expect
(
Scanner
.
MUL
);
P
.
Expect
(
Scanner
.
MUL
);
P
.
ParseType
();
typ
.
base
=
P
.
ParseType
();
P
.
Ecart
();
P
.
Ecart
();
return
typ
;
}
}
// Returns false if no type was found.
// Returns false if no type was found.
func
(
P
*
Parser
)
TryType
()
bool
{
func
(
P
*
Parser
)
TryType
()
(
AST
.
Type
,
bool
)
{
P
.
Trace
(
"Type (try)"
);
P
.
Trace
(
"Type (try)"
);
var
typ
AST
.
Type
=
AST
.
NIL
;
found
:=
true
;
found
:=
true
;
switch
P
.
tok
{
switch
P
.
tok
{
case
Scanner
.
IDENT
:
P
.
ParseTypeName
();
case
Scanner
.
IDENT
:
typ
=
P
.
ParseTypeName
();
case
Scanner
.
LBRACK
:
P
.
ParseArrayType
();
case
Scanner
.
LBRACK
:
typ
=
P
.
ParseArrayType
();
case
Scanner
.
CHAN
,
Scanner
.
ARROW
:
P
.
ParseChannelType
();
case
Scanner
.
CHAN
,
Scanner
.
ARROW
:
typ
=
P
.
ParseChannelType
();
case
Scanner
.
INTERFACE
:
P
.
ParseInterfaceType
();
case
Scanner
.
INTERFACE
:
typ
=
P
.
ParseInterfaceType
();
case
Scanner
.
LPAREN
:
P
.
ParseFunctionType
();
case
Scanner
.
LPAREN
:
typ
=
P
.
ParseFunctionType
();
case
Scanner
.
MAP
:
P
.
ParseMapType
();
case
Scanner
.
MAP
:
typ
=
P
.
ParseMapType
();
case
Scanner
.
STRUCT
:
P
.
ParseStructType
();
case
Scanner
.
STRUCT
:
typ
=
P
.
ParseStructType
();
case
Scanner
.
MUL
:
P
.
ParsePointerType
();
case
Scanner
.
MUL
:
typ
=
P
.
ParsePointerType
();
default
:
found
=
false
;
default
:
found
=
false
;
}
}
P
.
Ecart
();
P
.
Ecart
();
return
found
;
return
typ
,
found
;
}
}
...
@@ -623,12 +645,16 @@ func (P *Parser) ParseOperand() AST.Expr {
...
@@ -623,12 +645,16 @@ func (P *Parser) ParseOperand() AST.Expr {
z
=
nil
;
z
=
nil
;
default
:
default
:
if
P
.
tok
!=
Scanner
.
IDENT
&&
P
.
TryType
()
{
if
P
.
tok
!=
Scanner
.
IDENT
{
z
=
P
.
ParseCompositeLit
();
typ
,
ok
:=
P
.
TryType
();
}
else
{
if
ok
{
P
.
Error
(
P
.
pos
,
"operand expected"
);
z
=
P
.
ParseCompositeLit
();
P
.
Next
();
// make progress
break
;
}
}
}
P
.
Error
(
P
.
pos
,
"operand expected"
);
P
.
Next
();
// make progress
}
}
P
.
Ecart
();
P
.
Ecart
();
...
@@ -693,12 +719,17 @@ func (P *Parser) ParseCall(x AST.Expr) AST.Expr {
...
@@ -693,12 +719,17 @@ func (P *Parser) ParseCall(x AST.Expr) AST.Expr {
// - exclude "("'s because function types are not allowed and they indicate an expression
// - exclude "("'s because function types are not allowed and they indicate an expression
// - still a problem for "new(*T)" (the "*")
// - still a problem for "new(*T)" (the "*")
// - possibility: make "new" a keyword again (or disallow "*" types in new)
// - possibility: make "new" a keyword again (or disallow "*" types in new)
if
P
.
tok
!=
Scanner
.
IDENT
&&
P
.
tok
!=
Scanner
.
LPAREN
&&
P
.
TryType
()
{
if
P
.
tok
!=
Scanner
.
IDENT
&&
P
.
tok
!=
Scanner
.
LPAREN
{
if
P
.
tok
==
Scanner
.
COMMA
{
typ
,
ok
:=
P
.
TryType
();
P
.
Next
();
if
ok
{
if
P
.
tok
!=
Scanner
.
RPAREN
{
if
P
.
tok
==
Scanner
.
COMMA
{
args
=
P
.
ParseExpressionList
();
P
.
Next
();
if
P
.
tok
!=
Scanner
.
RPAREN
{
args
=
P
.
ParseExpressionList
();
}
}
}
}
else
{
args
=
P
.
ParseExpressionList
();
}
}
}
else
{
}
else
{
args
=
P
.
ParseExpressionList
();
args
=
P
.
ParseExpressionList
();
...
@@ -842,7 +873,15 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
...
@@ -842,7 +873,15 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
default
:
default
:
if
P
.
tok
==
Scanner
.
INC
||
P
.
tok
==
Scanner
.
DEC
{
if
P
.
tok
==
Scanner
.
INC
||
P
.
tok
==
Scanner
.
DEC
{
s
:=
new
(
AST
.
IncDecStat
);
s
.
pos
,
s
.
tok
=
P
.
pos
,
P
.
tok
;
if
x
.
len
()
==
1
{
s
.
expr
=
x
.
at
(
0
);
}
else
{
P
.
Error
(
P
.
pos
,
"more then one operand"
);
}
P
.
Next
();
P
.
Next
();
stat
=
s
;
}
else
{
}
else
{
xstat
:=
new
(
AST
.
ExprStat
);
xstat
:=
new
(
AST
.
ExprStat
);
if
x
!=
nil
&&
x
.
len
()
>
0
{
if
x
!=
nil
&&
x
.
len
()
>
0
{
...
@@ -870,10 +909,10 @@ func (P *Parser) ParseGoStat() {
...
@@ -870,10 +909,10 @@ func (P *Parser) ParseGoStat() {
}
}
func
(
P
*
Parser
)
ParseReturnStat
()
*
AST
.
Return
{
func
(
P
*
Parser
)
ParseReturnStat
()
*
AST
.
Return
Stat
{
P
.
Trace
(
"ReturnStat"
);
P
.
Trace
(
"ReturnStat"
);
ret
:=
new
(
AST
.
Return
);
ret
:=
new
(
AST
.
Return
Stat
);
ret
.
pos
=
P
.
pos
;
ret
.
pos
=
P
.
pos
;
P
.
Expect
(
Scanner
.
RETURN
);
P
.
Expect
(
Scanner
.
RETURN
);
...
@@ -898,30 +937,57 @@ func (P *Parser) ParseControlFlowStat(tok int) {
...
@@ -898,30 +937,57 @@ func (P *Parser) ParseControlFlowStat(tok int) {
}
}
func
(
P
*
Parser
)
ParseIfStat
()
*
AST
.
IfStat
{
func
(
P
*
Parser
)
ParseStatHeader
(
keyword
int
)
(
AST
.
Stat
,
AST
.
Expr
,
AST
.
Stat
)
{
P
.
Trace
(
"IfStat"
);
P
.
Trace
(
"StatHeader"
);
x
:=
new
(
AST
.
IfStat
);
x
.
pos
,
x
.
cond
=
P
.
pos
,
AST
.
NIL
;
var
init
,
cond
AST
.
Node
=
AST
.
NIL
,
AST
.
NIL
;
var
(
P
.
Expect
(
Scanner
.
IF
);
init
AST
.
Stat
=
AST
.
NIL
;
P
.
OpenScope
();
expr
AST
.
Expr
=
AST
.
NIL
;
post
AST
.
Stat
=
AST
.
NIL
;
)
has_init
,
has_expr
,
has_post
:=
false
,
false
,
false
;
P
.
Expect
(
keyword
);
if
P
.
tok
!=
Scanner
.
LBRACE
{
if
P
.
tok
!=
Scanner
.
LBRACE
{
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
init
=
P
.
ParseSimpleStat
();
init
=
P
.
ParseSimpleStat
();
has_init
=
true
;
}
}
if
P
.
tok
==
Scanner
.
SEMICOLON
{
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
P
.
Next
();
if
P
.
tok
!=
Scanner
.
LBRACE
{
if
keyword
==
Scanner
.
FOR
{
cond
=
P
.
ParseExpression
();
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
expr
=
P
.
ParseExpression
();
has_expr
=
true
;
}
P
.
Expect
(
Scanner
.
SEMICOLON
);
if
P
.
tok
!=
Scanner
.
LBRACE
{
post
=
P
.
ParseSimpleStat
();
has_post
=
true
;
}
}
else
{
}
else
{
cond
=
init
;
if
P
.
tok
!=
Scanner
.
LBRACE
{
init
=
AST
.
NIL
;
expr
=
P
.
ParseExpression
();
has_expr
=
true
;
}
}
}
}
}
}
}
x
.
init
,
x
.
cond
=
init
,
cond
;
P
.
Ecart
();
return
init
,
expr
,
post
;
}
func
(
P
*
Parser
)
ParseIfStat
()
*
AST
.
IfStat
{
P
.
Trace
(
"IfStat"
);
x
:=
new
(
AST
.
IfStat
);
x
.
pos
=
P
.
pos
;
var
dummy
AST
.
Stat
;
x
.
init
,
x
.
cond
,
dummy
=
P
.
ParseStatHeader
(
Scanner
.
IF
);
x
.
then
=
P
.
ParseBlock
();
x
.
then
=
P
.
ParseBlock
();
if
P
.
tok
==
Scanner
.
ELSE
{
if
P
.
tok
==
Scanner
.
ELSE
{
...
@@ -936,7 +1002,6 @@ func (P *Parser) ParseIfStat() *AST.IfStat {
...
@@ -936,7 +1002,6 @@ func (P *Parser) ParseIfStat() *AST.IfStat {
}
}
x
.
else_
=
b
;
x
.
else_
=
b
;
}
}
P
.
CloseScope
();
P
.
Ecart
();
P
.
Ecart
();
return
x
;
return
x
;
...
@@ -949,87 +1014,70 @@ func (P *Parser) ParseForStat() *AST.ForStat {
...
@@ -949,87 +1014,70 @@ func (P *Parser) ParseForStat() *AST.ForStat {
stat
:=
new
(
AST
.
ForStat
);
stat
:=
new
(
AST
.
ForStat
);
stat
.
pos
=
P
.
pos
;
stat
.
pos
=
P
.
pos
;
P
.
Expect
(
Scanner
.
FOR
);
P
.
ParseStatHeader
(
Scanner
.
FOR
);
P
.
OpenScope
();
if
P
.
tok
!=
Scanner
.
LBRACE
{
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
P
.
ParseSimpleStat
();
}
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
P
.
ParseExpression
();
}
P
.
Expect
(
Scanner
.
SEMICOLON
);
if
P
.
tok
!=
Scanner
.
LBRACE
{
P
.
ParseSimpleStat
();
}
}
}
stat
.
body
=
P
.
ParseBlock
();
stat
.
body
=
P
.
ParseBlock
();
P
.
CloseScope
();
P
.
Ecart
();
P
.
Ecart
();
return
stat
;
return
stat
;
}
}
func
(
P
*
Parser
)
ParseCase
()
{
func
(
P
*
Parser
)
ParseCase
()
*
AST
.
CaseClause
{
P
.
Trace
(
"Case"
);
P
.
Trace
(
"Case"
);
clause
:=
new
(
AST
.
CaseClause
);
clause
.
pos
=
P
.
pos
;
if
P
.
tok
==
Scanner
.
CASE
{
if
P
.
tok
==
Scanner
.
CASE
{
P
.
Next
();
P
.
Next
();
P
.
ParseExpressionList
();
clause
.
exprs
=
P
.
ParseExpressionList
();
}
else
{
}
else
{
P
.
Expect
(
Scanner
.
DEFAULT
);
P
.
Expect
(
Scanner
.
DEFAULT
);
}
}
P
.
Expect
(
Scanner
.
COLON
);
P
.
Expect
(
Scanner
.
COLON
);
P
.
Ecart
();
P
.
Ecart
();
return
clause
;
}
}
func
(
P
*
Parser
)
ParseCaseClause
()
{
func
(
P
*
Parser
)
ParseCaseClause
()
*
AST
.
CaseClause
{
P
.
Trace
(
"CaseClause"
);
P
.
Trace
(
"CaseClause"
);
P
.
ParseCase
();
clause
:=
P
.
ParseCase
();
if
P
.
tok
!=
Scanner
.
FALLTHROUGH
&&
P
.
tok
!=
Scanner
.
RBRACE
{
if
P
.
tok
!=
Scanner
.
FALLTHROUGH
&&
P
.
tok
!=
Scanner
.
RBRACE
{
P
.
ParseStatementList
();
clause
.
stats
=
P
.
ParseStatementList
();
P
.
Optional
(
Scanner
.
SEMICOLON
);
P
.
Optional
(
Scanner
.
SEMICOLON
);
}
}
if
P
.
tok
==
Scanner
.
FALLTHROUGH
{
if
P
.
tok
==
Scanner
.
FALLTHROUGH
{
P
.
Next
();
P
.
Next
();
clause
.
falls
=
true
;
P
.
Optional
(
Scanner
.
SEMICOLON
);
P
.
Optional
(
Scanner
.
SEMICOLON
);
}
}
P
.
Ecart
();
P
.
Ecart
();
return
clause
;
}
}
func
(
P
*
Parser
)
ParseSwitchStat
()
{
func
(
P
*
Parser
)
ParseSwitchStat
()
*
AST
.
SwitchStat
{
P
.
Trace
(
"SwitchStat"
);
P
.
Trace
(
"SwitchStat"
);
P
.
Expect
(
Scanner
.
SWITCH
);
stat
:=
new
(
AST
.
SwitchStat
);
P
.
OpenScope
();
stat
.
pos
=
P
.
pos
;
if
P
.
tok
!=
Scanner
.
LBRACE
{
stat
.
init
=
AST
.
NIL
;
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
stat
.
cases
=
AST
.
NewList
();
P
.
ParseSimpleStat
();
}
P
.
ParseStatHeader
(
Scanner
.
SWITCH
);
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
if
P
.
tok
!=
Scanner
.
LBRACE
{
P
.
ParseExpression
();
}
}
}
P
.
Expect
(
Scanner
.
LBRACE
);
P
.
Expect
(
Scanner
.
LBRACE
);
for
P
.
tok
==
Scanner
.
CASE
||
P
.
tok
==
Scanner
.
DEFAULT
{
for
P
.
tok
==
Scanner
.
CASE
||
P
.
tok
==
Scanner
.
DEFAULT
{
P
.
ParseCaseClause
(
);
stat
.
cases
.
Add
(
P
.
ParseCaseClause
()
);
}
}
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
CloseScope
();
P
.
Ecart
();
P
.
Ecart
();
return
stat
;
}
}
...
@@ -1109,10 +1157,8 @@ func (P *Parser) TryStatement() (AST.Stat, bool) {
...
@@ -1109,10 +1157,8 @@ func (P *Parser) TryStatement() (AST.Stat, bool) {
var
stat
AST
.
Stat
=
AST
.
NIL
;
var
stat
AST
.
Stat
=
AST
.
NIL
;
res
:=
true
;
res
:=
true
;
switch
P
.
tok
{
switch
P
.
tok
{
case
Scanner
.
CONST
:
fallthrough
;
case
Scanner
.
CONST
,
Scanner
.
TYPE
,
Scanner
.
VAR
:
case
Scanner
.
TYPE
:
fallthrough
;
stat
=
P
.
ParseDeclaration
();
case
Scanner
.
VAR
:
P
.
ParseDeclaration
();
case
Scanner
.
FUNC
:
case
Scanner
.
FUNC
:
// for now we do not allow local function declarations
// for now we do not allow local function declarations
fallthrough
;
fallthrough
;
...
@@ -1131,7 +1177,7 @@ func (P *Parser) TryStatement() (AST.Stat, bool) {
...
@@ -1131,7 +1177,7 @@ func (P *Parser) TryStatement() (AST.Stat, bool) {
case
Scanner
.
FOR
:
case
Scanner
.
FOR
:
stat
=
P
.
ParseForStat
();
stat
=
P
.
ParseForStat
();
case
Scanner
.
SWITCH
:
case
Scanner
.
SWITCH
:
P
.
ParseSwitchStat
();
stat
=
P
.
ParseSwitchStat
();
case
Scanner
.
RANGE
:
case
Scanner
.
RANGE
:
P
.
ParseRangeStat
();
P
.
ParseRangeStat
();
case
Scanner
.
SELECT
:
case
Scanner
.
SELECT
:
...
@@ -1173,70 +1219,83 @@ func (P *Parser) ParseImportSpec() {
...
@@ -1173,70 +1219,83 @@ func (P *Parser) ParseImportSpec() {
}
}
func
(
P
*
Parser
)
ParseConstSpec
(
exported
bool
)
{
func
(
P
*
Parser
)
ParseConstSpec
(
exported
bool
)
AST
.
Decl
{
P
.
Trace
(
"ConstSpec"
);
P
.
Trace
(
"ConstSpec"
);
list
:=
P
.
ParseIdent
();
decl
:=
new
(
AST
.
ConstDecl
);
P
.
TryType
();
decl
.
ident
=
P
.
ParseIdent
();
var
ok
bool
;
decl
.
typ
,
ok
=
P
.
TryType
();
if
P
.
tok
==
Scanner
.
ASSIGN
{
if
P
.
tok
==
Scanner
.
ASSIGN
{
P
.
Next
();
P
.
Next
();
P
.
ParseExpressionList
();
decl
.
val
=
P
.
ParseExpression
();
}
}
P
.
Ecart
();
P
.
Ecart
();
return
decl
;
}
}
func
(
P
*
Parser
)
ParseTypeSpec
(
exported
bool
)
{
func
(
P
*
Parser
)
ParseTypeSpec
(
exported
bool
)
AST
.
Decl
{
P
.
Trace
(
"TypeSpec"
);
P
.
Trace
(
"TypeSpec"
);
ident
:=
P
.
ParseIdent
();
decl
:=
new
(
AST
.
TypeDecl
);
P
.
ParseType
();
decl
.
ident
=
P
.
ParseIdent
();
decl
.
typ
=
P
.
ParseType
();
P
.
Ecart
();
P
.
Ecart
();
return
decl
;
}
}
func
(
P
*
Parser
)
ParseVarSpec
(
exported
bool
)
{
func
(
P
*
Parser
)
ParseVarSpec
(
exported
bool
)
AST
.
Decl
{
P
.
Trace
(
"VarSpec"
);
P
.
Trace
(
"VarSpec"
);
P
.
ParseIdentList
();
decl
:=
new
(
AST
.
VarDecl
);
decl
.
idents
=
P
.
ParseIdentList
();
if
P
.
tok
==
Scanner
.
ASSIGN
{
if
P
.
tok
==
Scanner
.
ASSIGN
{
P
.
Next
();
P
.
Next
();
P
.
ParseExpressionList
();
decl
.
vals
=
P
.
ParseExpressionList
();
}
else
{
}
else
{
P
.
ParseVarType
();
decl
.
typ
=
P
.
ParseVarType
();
if
P
.
tok
==
Scanner
.
ASSIGN
{
if
P
.
tok
==
Scanner
.
ASSIGN
{
P
.
Next
();
P
.
Next
();
P
.
ParseExpressionList
();
decl
.
vals
=
P
.
ParseExpressionList
();
}
}
}
}
P
.
Ecart
();
P
.
Ecart
();
return
decl
;
}
}
// TODO With method variables, we wouldn't need this dispatch function.
// TODO With method variables, we wouldn't need this dispatch function.
func
(
P
*
Parser
)
ParseSpec
(
exported
bool
,
keyword
int
)
{
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
:
P
.
ParseImportSpec
();
case
Scanner
.
CONST
:
P
.
ParseConstSpec
(
exported
);
case
Scanner
.
CONST
:
decl
=
P
.
ParseConstSpec
(
exported
);
case
Scanner
.
TYPE
:
P
.
ParseTypeSpec
(
exported
);
case
Scanner
.
TYPE
:
decl
=
P
.
ParseTypeSpec
(
exported
);
case
Scanner
.
VAR
:
P
.
ParseVarSpec
(
exported
);
case
Scanner
.
VAR
:
decl
=
P
.
ParseVarSpec
(
exported
);
default
:
panic
(
"UNREACHABLE"
);
default
:
panic
(
"UNREACHABLE"
);
}
}
return
decl
;
}
}
func
(
P
*
Parser
)
ParseDecl
(
exported
bool
,
keyword
int
)
{
func
(
P
*
Parser
)
ParseDecl
(
exported
bool
,
keyword
int
)
*
AST
.
Declaration
{
P
.
Trace
(
"Decl"
);
P
.
Trace
(
"Decl"
);
decl
:=
new
(
AST
.
Declaration
);
decl
.
decls
=
AST
.
NewList
();
decl
.
pos
,
decl
.
tok
=
P
.
pos
,
P
.
tok
;
P
.
Expect
(
keyword
);
P
.
Expect
(
keyword
);
if
P
.
tok
==
Scanner
.
LPAREN
{
if
P
.
tok
==
Scanner
.
LPAREN
{
P
.
Next
();
P
.
Next
();
for
P
.
tok
!=
Scanner
.
RPAREN
{
for
P
.
tok
!=
Scanner
.
RPAREN
{
P
.
ParseSpec
(
exported
,
keyword
);
decl
.
decls
.
Add
(
P
.
ParseSpec
(
exported
,
keyword
)
);
if
P
.
tok
!=
Scanner
.
RPAREN
{
if
P
.
tok
!=
Scanner
.
RPAREN
{
// P.Expect(Scanner.SEMICOLON);
// P.Expect(Scanner.SEMICOLON);
P
.
Optional
(
Scanner
.
SEMICOLON
);
// TODO this seems wrong! (needed for math.go)
P
.
Optional
(
Scanner
.
SEMICOLON
);
// TODO this seems wrong! (needed for math.go)
...
@@ -1244,10 +1303,11 @@ func (P *Parser) ParseDecl(exported bool, keyword int) {
...
@@ -1244,10 +1303,11 @@ func (P *Parser) ParseDecl(exported bool, keyword int) {
}
}
P
.
Next
();
// consume ")"
P
.
Next
();
// consume ")"
}
else
{
}
else
{
P
.
ParseSpec
(
exported
,
keyword
);
decl
.
decls
.
Add
(
P
.
ParseSpec
(
exported
,
keyword
)
);
}
}
P
.
Ecart
();
P
.
Ecart
();
return
decl
;
}
}
...
@@ -1326,10 +1386,12 @@ func (P *Parser) ParseExportDecl() {
...
@@ -1326,10 +1386,12 @@ func (P *Parser) ParseExportDecl() {
}
}
func
(
P
*
Parser
)
ParseDeclaration
()
AST
.
Decl
{
func
(
P
*
Parser
)
ParseDeclaration
()
AST
.
Node
{
P
.
Trace
(
"Declaration"
);
P
.
Trace
(
"Declaration"
);
indent
:=
P
.
indent
;
indent
:=
P
.
indent
;
var
node
AST
.
Node
;
exported
:=
false
;
exported
:=
false
;
if
P
.
tok
==
Scanner
.
EXPORT
{
if
P
.
tok
==
Scanner
.
EXPORT
{
if
P
.
level
==
0
{
if
P
.
level
==
0
{
...
@@ -1340,12 +1402,11 @@ func (P *Parser) ParseDeclaration() AST.Decl {
...
@@ -1340,12 +1402,11 @@ func (P *Parser) ParseDeclaration() AST.Decl {
P
.
Next
();
P
.
Next
();
}
}
var
x
AST
.
Decl
=
AST
.
NIL
;
switch
P
.
tok
{
switch
P
.
tok
{
case
Scanner
.
CONST
,
Scanner
.
TYPE
,
Scanner
.
VAR
:
case
Scanner
.
CONST
,
Scanner
.
TYPE
,
Scanner
.
VAR
:
P
.
ParseDecl
(
exported
,
P
.
tok
);
node
=
P
.
ParseDecl
(
exported
,
P
.
tok
);
case
Scanner
.
FUNC
:
case
Scanner
.
FUNC
:
x
=
P
.
ParseFuncDecl
(
exported
);
node
=
P
.
ParseFuncDecl
(
exported
);
case
Scanner
.
EXPORT
:
case
Scanner
.
EXPORT
:
if
exported
{
if
exported
{
P
.
Error
(
P
.
pos
,
"cannot mark export declaration for export"
);
P
.
Error
(
P
.
pos
,
"cannot mark export declaration for export"
);
...
@@ -1365,7 +1426,7 @@ func (P *Parser) ParseDeclaration() AST.Decl {
...
@@ -1365,7 +1426,7 @@ func (P *Parser) ParseDeclaration() AST.Decl {
panic
(
"imbalanced tracing code (Declaration)"
);
panic
(
"imbalanced tracing code (Declaration)"
);
}
}
P
.
Ecart
();
P
.
Ecart
();
return
x
;
return
node
;
}
}
...
...
usr/gri/pretty/printer.go
View file @
c5a29a6d
...
@@ -36,13 +36,11 @@ func (P *Printer) Print(x AST.Node) {
...
@@ -36,13 +36,11 @@ func (P *Printer) Print(x AST.Node) {
func
(
P
*
Printer
)
PrintList
(
p
*
AST
.
List
)
{
func
(
P
*
Printer
)
PrintList
(
p
*
AST
.
List
)
{
if
p
!=
nil
{
for
i
:=
0
;
i
<
p
.
len
();
i
++
{
for
i
:=
0
;
i
<
p
.
len
();
i
++
{
if
i
>
0
{
if
i
>
0
{
P
.
String
(
", "
);
P
.
String
(
", "
);
}
P
.
Print
(
p
.
at
(
i
));
}
}
P
.
Print
(
p
.
at
(
i
));
}
}
}
}
...
@@ -52,7 +50,6 @@ func (P *Printer) PrintList(p *AST.List) {
...
@@ -52,7 +50,6 @@ func (P *Printer) PrintList(p *AST.List) {
func
(
P
*
Printer
)
DoNil
(
x
*
AST
.
Nil
)
{
func
(
P
*
Printer
)
DoNil
(
x
*
AST
.
Nil
)
{
P
.
String
(
"?"
);
P
.
String
(
"?"
);
P
.
NewLine
(
0
);
}
}
...
@@ -76,14 +73,89 @@ func (P *Printer) DoFunctionType(x *AST.FunctionType) {
...
@@ -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
// Declarations
func
(
P
*
Printer
)
DoBlock
(
x
*
AST
.
Block
);
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
)
{
func
(
P
*
Printer
)
DoFuncDecl
(
x
*
AST
.
FuncDecl
)
{
...
@@ -106,6 +178,30 @@ 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
// Expressions
...
@@ -214,18 +310,81 @@ func (P *Printer) DoForStat(x *AST.ForStat) {
...
@@ -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
(
"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
)
DoReturn
Stat
(
x
*
AST
.
ReturnStat
)
{
P
.
String
(
"return "
);
P
.
String
(
"return "
);
P
.
PrintList
(
x
.
res
);
P
.
PrintList
(
x
.
res
);
P
.
String
(
";"
);
P
.
String
(
";"
);
}
}
func
(
P
*
Printer
)
DoIncDecStat
(
x
*
AST
.
IncDecStat
)
{
P
.
Print
(
x
.
expr
);
P
.
String
(
Scanner
.
TokenName
(
x
.
tok
));
P
.
String
(
";"
);
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Program
// Program
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment