Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
28547615
Commit
28547615
authored
Aug 05, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- fixed another export bug
- more self-verification code R=r OCL=13894 CL=13894
parent
f7f6329e
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
187 additions
and
115 deletions
+187
-115
export.go
usr/gri/gosrc/export.go
+8
-13
globals.go
usr/gri/gosrc/globals.go
+1
-1
import.go
usr/gri/gosrc/import.go
+16
-19
parser.go
usr/gri/gosrc/parser.go
+88
-67
printer.go
usr/gri/gosrc/printer.go
+10
-4
d.go
usr/gri/gosrc/test/d.go
+5
-0
universe.go
usr/gri/gosrc/universe.go
+1
-0
verifier.go
usr/gri/gosrc/verifier.go
+58
-11
No files found.
usr/gri/gosrc/export.go
View file @
28547615
...
...
@@ -124,7 +124,9 @@ func (E *Exporter) WriteScope(scope *Globals.Scope) {
}
for
p
:=
scope
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
E
.
WriteObject
(
p
.
obj
);
if
p
.
obj
.
exported
{
E
.
WriteObject
(
p
.
obj
);
}
}
E
.
WriteObject
(
nil
);
...
...
@@ -158,7 +160,8 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
if
!
typ
.
obj
.
exported
{
// the type is invisible (it's identifier is not exported)
// prepend "." to the identifier to make it an illegal
// identifier and thus invisible in Go source code
// identifier for importing packages and thus inaccessible
// from those package's source code
ident
=
"."
+
ident
;
}
}
...
...
@@ -170,17 +173,14 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
}
switch
typ
.
form
{
case
Type
.
ALIAS
:
case
Type
.
ALIAS
,
Type
.
MAP
:
E
.
WriteType
(
typ
.
aux
);
E
.
WriteType
(
typ
.
elt
);
case
Type
.
ARRAY
:
E
.
WriteInt
(
typ
.
len_
);
E
.
WriteType
(
typ
.
elt
);
case
Type
.
MAP
:
E
.
WriteType
(
typ
.
key
);
E
.
WriteType
(
typ
.
elt
);
case
Type
.
CHANNEL
:
E
.
WriteInt
(
typ
.
flags
);
E
.
WriteType
(
typ
.
elt
);
...
...
@@ -262,12 +262,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
// export package 0
pkg
:=
comp
.
pkg_list
[
0
];
E
.
WritePackage
(
pkg
);
for
p
:=
pkg
.
scope
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
if
p
.
obj
.
exported
{
E
.
WriteObject
(
p
.
obj
);
}
}
E
.
WriteObject
(
nil
);
E
.
WriteScope
(
pkg
.
scope
);
if
E
.
debug
{
print
"
\n
("
,
E
.
buf_pos
,
" bytes)
\n
"
;
...
...
usr/gri/gosrc/globals.go
View file @
28547615
...
...
@@ -30,7 +30,7 @@ export type Type struct {
size
int
;
// in bytes
len_
int
;
// array length, no. of parameters (w/o recv)
obj
*
Object
;
// primary type object or NULL
key
*
Type
;
// maps
aux
*
Type
;
// alias base type or map key
elt
*
Type
;
// aliases, arrays, maps, channels, pointers
scope
*
Scope
;
// structs, interfaces, functions
}
...
...
usr/gri/gosrc/import.go
View file @
28547615
...
...
@@ -140,23 +140,26 @@ func (I *Importer) ReadPackage() *Globals.Package {
}
func
(
I
*
Importer
)
ReadScope
(
)
*
Globals
.
Scope
{
func
(
I
*
Importer
)
ReadScope
(
scope
*
Globals
.
Scope
,
allow_multiples
bool
)
{
if
I
.
debug
{
print
" {"
;
}
scope
:=
Globals
.
NewScope
(
nil
);
obj
:=
I
.
ReadObject
();
for
obj
!=
nil
{
scope
.
Insert
(
obj
);
// allow_multiples is for debugging only - we should never
// have multiple imports where we don't expect them
if
allow_multiples
{
scope
.
InsertImport
(
obj
);
}
else
{
scope
.
Insert
(
obj
);
}
obj
=
I
.
ReadObject
();
}
if
I
.
debug
{
print
" }"
;
}
return
scope
;
}
...
...
@@ -191,27 +194,26 @@ func (I *Importer) ReadType() *Globals.Type {
I
.
type_ref
++
;
switch
(
typ
.
form
)
{
case
Type
.
ALIAS
:
case
Type
.
ALIAS
,
Type
.
MAP
:
typ
.
aux
=
I
.
ReadType
();
typ
.
elt
=
I
.
ReadType
();
case
Type
.
ARRAY
:
typ
.
len_
=
I
.
ReadInt
();
typ
.
elt
=
I
.
ReadType
();
case
Type
.
MAP
:
typ
.
key
=
I
.
ReadType
();
typ
.
elt
=
I
.
ReadType
();
case
Type
.
CHANNEL
:
typ
.
flags
=
I
.
ReadInt
();
typ
.
elt
=
I
.
ReadType
();
case
Type
.
FUNCTION
:
typ
.
flags
=
I
.
ReadInt
();
typ
.
scope
=
I
.
ReadScope
();
typ
.
scope
=
Globals
.
NewScope
(
nil
);
I
.
ReadScope
(
typ
.
scope
,
false
);
case
Type
.
STRUCT
,
Type
.
INTERFACE
:
typ
.
scope
=
I
.
ReadScope
();
typ
.
scope
=
Globals
.
NewScope
(
nil
);
I
.
ReadScope
(
typ
.
scope
,
false
);
case
Type
.
POINTER
,
Type
.
REFERENCE
:
typ
.
elt
=
I
.
ReadType
();
...
...
@@ -241,6 +243,7 @@ func (I *Importer) ReadObject() *Globals.Object {
ident
:=
I
.
ReadString
();
obj
:=
Globals
.
NewObject
(
0
,
tag
,
ident
);
obj
.
exported
=
true
;
obj
.
typ
=
I
.
ReadType
();
switch
(
tag
)
{
...
...
@@ -290,13 +293,7 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.
// import package
pkg
:=
I
.
ReadPackage
();
{
obj
:=
I
.
ReadObject
();
for
obj
!=
nil
{
obj
.
pnolev
=
pkg
.
obj
.
pnolev
;
pkg
.
scope
.
InsertImport
(
obj
);
obj
=
I
.
ReadObject
();
}
}
I
.
ReadScope
(
pkg
.
scope
,
true
);
if
I
.
debug
{
print
"
\n
("
,
I
.
buf_pos
,
" bytes)
\n
"
;
...
...
usr/gri/gosrc/parser.go
View file @
28547615
...
...
@@ -147,74 +147,82 @@ func (P *Parser) Declare(obj *Globals.Object) {
func
MakeFunctionType
(
sig
*
Globals
.
Scope
,
p0
,
r0
int
,
check_recv
bool
)
*
Globals
.
Type
{
// Determine if we have a receiver or not.
// TODO do we still need this?
if
p0
>
0
&&
check_recv
{
// method
if
p0
!=
1
{
panic
"p0 != 1"
;
// Determine if we have a receiver or not.
// TODO do we still need this?
if
p0
>
0
&&
check_recv
{
// method
if
p0
!=
1
{
panic
"p0 != 1"
;
}
}
}
typ
:=
Globals
.
NewType
(
Type
.
FUNCTION
);
if
p0
==
0
{
typ
.
flags
=
0
;
}
else
{
typ
.
flags
=
Type
.
RECV
;
}
typ
.
len_
=
r0
-
p0
;
typ
.
scope
=
sig
;
return
typ
;
typ
:=
Globals
.
NewType
(
Type
.
FUNCTION
);
if
p0
==
0
{
typ
.
flags
=
0
;
}
else
{
typ
.
flags
=
Type
.
RECV
;
}
typ
.
len_
=
r0
-
p0
;
typ
.
scope
=
sig
;
// parameters are always exported (they can't be accessed w/o the function
// or function type being exported)
for
p
:=
sig
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
p
.
obj
.
exported
=
true
;
}
return
typ
;
}
func
(
P
*
Parser
)
DeclareFunc
(
ident
string
,
typ
*
Globals
.
Type
)
*
Globals
.
Object
{
// determine scope
scope
:=
P
.
top_scope
;
if
typ
.
flags
&
Type
.
RECV
!=
0
{
// method - declare in corresponding struct
if
typ
.
scope
.
entries
.
len_
<
1
{
panic
"no recv in signature?"
;
}
recv_typ
:=
typ
.
scope
.
entries
.
first
.
obj
.
typ
;
if
recv_typ
.
form
==
Type
.
POINTER
{
recv_typ
=
recv_typ
.
elt
;
}
scope
=
recv_typ
.
scope
;
}
// declare the function
obj
:=
scope
.
Lookup
(
ident
);
if
obj
==
nil
{
obj
=
Globals
.
NewObject
(
-
1
,
Object
.
FUNC
,
ident
);
obj
.
typ
=
typ
;
// TODO do we need to set the primary type? probably...
P
.
DeclareInScope
(
scope
,
obj
);
return
obj
;
}
// obj != NULL: possibly a forward declaration.
if
(
obj
.
kind
!=
Object
.
FUNC
)
{
P
.
Error
(
-
1
,
`"`
+
ident
+
`" is declared already`
);
// Continue but do not insert this function into the scope.
obj
=
Globals
.
NewObject
(
-
1
,
Object
.
FUNC
,
ident
);
obj
.
typ
=
typ
;
// TODO do we need to set the pry
mary type? probably...
return
obj
;
}
// We have a function with the same name.
/*
if (!EqualTypes(type, obj->type()
)) {
this->Error("type of \"%s\" does not match its forward declaration", name.cstr());
// Continue but do not insert this function into the scope.
NewObject(Object::FUNC, name);
obj->set_type(type);
return obj;
}
*/
// We have a matching forward declaration. Use it.
return
obj
;
// determine scope
scope
:=
P
.
top_scope
;
if
typ
.
flags
&
Type
.
RECV
!=
0
{
// method - declare in corresponding struct
if
typ
.
scope
.
entries
.
len_
<
1
{
panic
"no recv in signature?"
;
}
recv_typ
:=
typ
.
scope
.
entries
.
first
.
obj
.
typ
;
if
recv_typ
.
form
==
Type
.
POINTER
{
recv_typ
=
recv_typ
.
elt
;
}
scope
=
recv_typ
.
scope
;
}
// declare the function
obj
:=
scope
.
Lookup
(
ident
);
if
obj
==
nil
{
obj
=
Globals
.
NewObject
(
-
1
,
Object
.
FUNC
,
ident
);
obj
.
typ
=
typ
;
// TODO do we need to set the primary type? probably...
P
.
DeclareInScope
(
scope
,
obj
);
return
obj
;
}
// obj != NULL: possibly a forward declaration.
if
obj
.
kind
!=
Object
.
FUNC
{
P
.
Error
(
-
1
,
`"`
+
ident
+
`" is declared already`
);
// Continue but do not insert this function into the scope.
obj
=
Globals
.
NewObject
(
-
1
,
Object
.
FUNC
,
ident
);
obj
.
typ
=
typ
;
// TODO do we need to set the pri
mary type? probably...
return
obj
;
}
// We have a function with the same name.
/*
if !EqualTypes(type, obj->type(
)) {
this->Error("type of \"%s\" does not match its forward declaration", name.cstr());
// Continue but do not insert this function into the scope.
NewObject(Object::FUNC, name);
obj->set_type(type);
return obj;
}
*/
// We have a matching forward declaration. Use it.
return
obj
;
}
...
...
@@ -521,7 +529,7 @@ func (P *Parser) ParseAnonymousSignature() *Globals.Type {
if
P
.
tok
==
Scanner
.
PERIOD
{
p0
=
sig
.
entries
.
len_
;
if
(
P
.
semantic_checks
&&
p0
!=
1
)
{
if
P
.
semantic_checks
&&
p0
!=
1
{
P
.
Error
(
recv_pos
,
"must have exactly one receiver"
)
panic
"UNIMPLEMENTED (ParseAnonymousSignature)"
;
// TODO do something useful here
...
...
@@ -561,7 +569,7 @@ func (P *Parser) ParseNamedSignature() (name string, typ *Globals.Type) {
recv_pos
:=
P
.
pos
;
P
.
ParseParameters
();
p0
=
sig
.
entries
.
len_
;
if
(
P
.
semantic_checks
&&
p0
!=
1
)
{
if
P
.
semantic_checks
&&
p0
!=
1
{
print
"p0 = "
,
p0
,
"
\n
"
;
P
.
Error
(
recv_pos
,
"must have exactly one receiver"
)
panic
"UNIMPLEMENTED (ParseNamedSignature)"
;
...
...
@@ -651,7 +659,7 @@ func (P *Parser) ParseMapType() *Globals.Type {
P
.
Expect
(
Scanner
.
MAP
);
P
.
Expect
(
Scanner
.
LBRACK
);
typ
:=
Globals
.
NewType
(
Type
.
MAP
);
typ
.
key
=
P
.
ParseVarType
();
typ
.
aux
=
P
.
ParseVarType
();
P
.
Expect
(
Scanner
.
RBRACK
);
typ
.
elt
=
P
.
ParseVarType
();
P
.
Ecart
();
...
...
@@ -1617,7 +1625,7 @@ func (P *Parser) ParseImportSpec() {
obj
=
P
.
ParseIdentDecl
(
Object
.
PACKAGE
);
}
if
(
P
.
semantic_checks
&&
P
.
tok
==
Scanner
.
STRING
)
{
if
P
.
semantic_checks
&&
P
.
tok
==
Scanner
.
STRING
{
// TODO eventually the scanner should strip the quotes
pkg_name
:=
P
.
val
[
1
:
len
(
P
.
val
)
-
1
];
// strip quotes
pkg
:=
Import
.
Import
(
P
.
comp
,
pkg_name
);
...
...
@@ -1699,6 +1707,11 @@ func (P *Parser) ParseTypeSpec(exported bool) {
if
typ
!=
nil
{
if
make_alias
{
alias
:=
Globals
.
NewType
(
Type
.
ALIAS
);
if
typ
.
form
==
Type
.
ALIAS
{
alias
.
aux
=
typ
.
aux
;
// the base type
}
else
{
alias
.
aux
=
typ
;
}
alias
.
elt
=
typ
;
typ
=
alias
;
}
...
...
@@ -1706,6 +1719,14 @@ func (P *Parser) ParseTypeSpec(exported bool) {
if
typ
.
obj
==
nil
{
typ
.
obj
=
obj
;
// primary type object
}
// if the type is exported, for now we export all fields
// of structs and interfaces by default
// TODO this needs to change eventually
if
exported
&&
(
typ
.
form
==
Type
.
STRUCT
||
typ
.
form
==
Type
.
INTERFACE
)
{
for
p
:=
typ
.
scope
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
p
.
obj
.
exported
=
true
;
}
}
}
P
.
Ecart
();
...
...
usr/gri/gosrc/printer.go
View file @
28547615
...
...
@@ -109,7 +109,7 @@ func (P *Printer) PrintScope(scope *Globals.Scope, delta int) {
}
else
{
n
=
0
;
for
p
:=
scope
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
if
p
.
obj
.
exported
{
if
p
.
obj
.
exported
&&
!
IsAnonymous
(
p
.
obj
.
ident
)
{
n
++
;
}
}
...
...
@@ -120,7 +120,7 @@ func (P *Printer) PrintScope(scope *Globals.Scope, delta int) {
if
n
>
0
{
P
.
level
+=
delta
;
for
p
:=
scope
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
if
P
.
print_all
||
p
.
obj
.
exported
{
if
P
.
print_all
||
p
.
obj
.
exported
&&
!
IsAnonymous
(
p
.
obj
.
ident
)
{
P
.
PrintIndent
();
P
.
PrintObjectStruct
(
p
.
obj
);
}
...
...
@@ -200,7 +200,12 @@ func (P *Printer) PrintTypeStruct(typ *Globals.Type) {
case
Type
.
ALIAS
:
P
.
PrintType
(
typ
.
elt
);
if
typ
.
aux
!=
typ
.
elt
{
print
" /* "
;
P
.
PrintType
(
typ
.
aux
);
print
" */"
;
}
case
Type
.
ARRAY
:
print
"[]"
;
P
.
PrintType
(
typ
.
elt
);
...
...
@@ -217,7 +222,7 @@ func (P *Printer) PrintTypeStruct(typ *Globals.Type) {
case
Type
.
MAP
:
print
"map ["
;
P
.
PrintType
(
typ
.
key
);
P
.
PrintType
(
typ
.
aux
);
print
"] "
;
P
.
PrintType
(
typ
.
elt
);
...
...
@@ -263,4 +268,5 @@ export func PrintObject(comp *Globals.Compilation, obj *Globals.Object, print_al
var
P
Printer
;
(
&
P
)
.
Init
(
comp
,
print_all
);
(
&
P
)
.
PrintObjectStruct
(
obj
);
print
"
\n
"
;
}
usr/gri/gosrc/test/d.go
View file @
28547615
...
...
@@ -13,3 +13,7 @@ export type T2 struct {
export
func
(
obj
*
T2
)
M1
(
u
,
v
float
)
{
}
export
func
F0
(
a
int
,
b
T0
)
int
{
return
a
+
b
;
}
\ No newline at end of file
usr/gri/gosrc/universe.go
View file @
28547615
...
...
@@ -71,6 +71,7 @@ func DeclType(form int, ident string, size int) *Globals.Type {
func
DeclAlias
(
ident
string
,
typ
*
Globals
.
Type
)
*
Globals
.
Type
{
alias
:=
Globals
.
NewType
(
Type
.
ALIAS
);
alias
.
aux
=
typ
;
alias
.
elt
=
typ
;
return
DeclObj
(
Object
.
TYPE
,
ident
,
alias
)
.
typ
;
}
...
...
usr/gri/gosrc/verifier.go
View file @
28547615
...
...
@@ -21,12 +21,27 @@ func Error(msg string) {
}
func
VerifyObject
(
obj
*
Globals
.
Object
,
pnolev
int
);
type
Verifier
struct
{
comp
*
Globals
.
Compilation
;
// various sets for marking the graph (and thus avoid cycles)
objs
*
map
[
*
Globals
.
Object
]
bool
;
typs
*
map
[
*
Globals
.
Type
]
bool
;
pkgs
*
map
[
*
Globals
.
Package
]
bool
;
}
func
(
V
*
Verifier
)
VerifyObject
(
obj
*
Globals
.
Object
,
pnolev
int
);
func
VerifyType
(
typ
*
Globals
.
Type
)
{
func
(
V
*
Verifier
)
VerifyType
(
typ
*
Globals
.
Type
)
{
if
V
.
typs
[
typ
]
{
return
;
// already verified
}
V
.
typs
[
typ
]
=
true
;
if
typ
.
obj
!=
nil
{
VerifyObject
(
typ
.
obj
,
0
);
V
.
V
erifyObject
(
typ
.
obj
,
0
);
}
switch
typ
.
form
{
...
...
@@ -70,8 +85,14 @@ func VerifyType(typ *Globals.Type) {
}
func
VerifyObject
(
obj
*
Globals
.
Object
,
pnolev
int
)
{
VerifyType
(
obj
.
typ
);
func
(
V
*
Verifier
)
VerifyObject
(
obj
*
Globals
.
Object
,
pnolev
int
)
{
if
V
.
objs
[
obj
]
{
return
;
// already verified
}
V
.
objs
[
obj
]
=
true
;
// all objects have a non-nil type
V
.
VerifyType
(
obj
.
typ
);
switch
obj
.
kind
{
case
Object
.
CONST
:
...
...
@@ -92,20 +113,46 @@ func VerifyObject(obj *Globals.Object, pnolev int) {
}
func
VerifyScope
(
scope
*
Globals
.
Scope
)
{
func
(
V
*
Verifier
)
VerifyScope
(
scope
*
Globals
.
Scope
)
{
for
p
:=
scope
.
entries
.
first
;
p
!=
nil
;
p
=
p
.
next
{
VerifyObject
(
p
.
obj
,
0
);
V
.
V
erifyObject
(
p
.
obj
,
0
);
}
}
func
VerifyPackage
(
pkg
*
Globals
.
Package
,
pno
int
)
{
VerifyObject
(
pkg
.
obj
,
0
);
func
(
V
*
Verifier
)
VerifyPackage
(
pkg
*
Globals
.
Package
,
pno
int
)
{
if
V
.
pkgs
[
pkg
]
{
return
;
// already verified
}
V
.
pkgs
[
pkg
]
=
true
;
V
.
VerifyObject
(
pkg
.
obj
,
pno
);
V
.
VerifyScope
(
pkg
.
scope
);
}
export
func
Verify
(
comp
*
Globals
.
Compilation
)
{
func
(
V
*
Verifier
)
Verify
(
comp
*
Globals
.
Compilation
)
{
// initialize Verifier
V
.
comp
=
comp
;
V
.
objs
=
new
(
map
[
*
Globals
.
Object
]
bool
);
V
.
typs
=
new
(
map
[
*
Globals
.
Type
]
bool
);
V
.
pkgs
=
new
(
map
[
*
Globals
.
Package
]
bool
);
// verify all packages
filenames
:=
new
(
map
[
string
]
bool
);
for
i
:=
0
;
i
<
comp
.
pkg_ref
;
i
++
{
VerifyPackage
(
comp
.
pkg_list
[
i
],
i
);
pkg
:=
comp
.
pkg_list
[
i
];
// each pkg filename must appear only once
if
filenames
[
pkg
.
file_name
]
{
Error
(
"package filename present more then once"
);
}
filenames
[
pkg
.
file_name
]
=
true
;
V
.
VerifyPackage
(
pkg
,
i
);
}
}
export
func
Verify
(
comp
*
Globals
.
Compilation
)
{
V
:=
new
(
Verifier
);
V
.
Verify
(
comp
);
}
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