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
060f157d
Commit
060f157d
authored
Oct 17, 2008
by
Rob Pike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
type string parser; now handles all types
R=rsc DELTA=253 (153 added, 81 deleted, 19 changed) OCL=17331 CL=17331
parent
7cb6b678
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
166 additions
and
94 deletions
+166
-94
main.go
usr/r/reflect/main.go
+12
-23
tostring.go
usr/r/reflect/tostring.go
+7
-8
type.go
usr/r/reflect/type.go
+147
-63
No files found.
usr/r/reflect/main.go
View file @
060f157d
...
...
@@ -10,29 +10,6 @@ import (
func
main
()
{
var
s
string
;
if
false
{
s
=
reflect
.
ToString
(
reflect
.
Int8
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Int16
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Int32
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Int64
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Uint8
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Uint16
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Uint32
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Uint64
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Float32
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Float64
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Float80
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
String
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
PtrInt8
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
PtrPtrInt8
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
ArrayFloat32
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
MapStringInt16
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
ChanArray
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Structure
);
print
(
s
,
"
\n
"
);
s
=
reflect
.
ToString
(
reflect
.
Function
);
print
(
s
,
"
\n
"
);
}
var
t
reflect
.
Type
;
t
=
reflect
.
ParseTypeString
(
"int8"
);
...
...
@@ -52,4 +29,16 @@ func main() {
t
=
reflect
.
ParseTypeString
(
"map[string]int32"
);
s
=
reflect
.
ToString
(
t
);
print
(
s
,
"
\n
"
);
t
=
reflect
.
ParseTypeString
(
"*chan<-string"
);
s
=
reflect
.
ToString
(
t
);
print
(
s
,
"
\n
"
);
t
=
reflect
.
ParseTypeString
(
"struct {c *chan *int32; d float32}"
);
s
=
reflect
.
ToString
(
t
);
print
(
s
,
"
\n
"
);
t
=
reflect
.
ParseTypeString
(
"*(a int8, b int32)"
);
s
=
reflect
.
ToString
(
t
);
print
(
s
,
"
\n
"
);
t
=
reflect
.
ParseTypeString
(
"struct {c *(? *chan *int32, ? *int8)}"
);
s
=
reflect
.
ToString
(
t
);
print
(
s
,
"
\n
"
);
}
usr/r/reflect/tostring.go
View file @
060f157d
...
...
@@ -14,14 +14,14 @@ import (
export
func
ToString
(
typ
Type
)
string
func
FieldsToString
(
t
Type
)
string
{
func
FieldsToString
(
t
Type
,
sep
string
)
string
{
s
:=
t
.
(
StructType
);
var
str
string
;
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
str1
,
t
:=
s
.
Field
(
i
);
str1
+=
" "
+
ToString
(
t
);
if
i
<
s
.
Len
()
-
1
{
str1
+=
";
"
;
str1
+=
sep
+
"
"
;
}
str
+=
str1
;
}
...
...
@@ -86,16 +86,15 @@ func ToString(typ Type) string {
}
return
str
+
ToString
(
c
.
Elem
());
case
StructKind
:
return
"struct{"
+
FieldsToString
(
typ
)
+
"}"
;
return
"struct{"
+
FieldsToString
(
typ
,
";"
)
+
"}"
;
case
InterfaceKind
:
return
"interface{"
+
FieldsToString
(
typ
,
";"
)
+
"}"
;
case
FuncKind
:
f
:=
typ
.
(
FuncType
);
str
=
"func"
;
if
f
.
Receiver
()
!=
nil
{
str
+=
"("
+
FieldsToString
(
f
.
Receiver
())
+
")"
;
}
str
+=
"("
+
FieldsToString
(
f
.
In
())
+
")"
;
str
+=
"("
+
FieldsToString
(
f
.
In
(),
","
)
+
")"
;
if
f
.
Out
()
!=
nil
{
str
+=
"("
+
FieldsToString
(
f
.
Out
())
+
")"
;
str
+=
"("
+
FieldsToString
(
f
.
Out
()
,
","
)
+
")"
;
}
return
str
;
default
:
...
...
usr/r/reflect/type.go
View file @
060f157d
...
...
@@ -25,6 +25,7 @@ export const (
Int32Kind
;
Int64Kind
;
Int8Kind
;
InterfaceKind
;
MapKind
;
PtrKind
;
StringKind
;
...
...
@@ -241,26 +242,45 @@ func (t *StructTypeStruct) Len() int {
return
len
(
t
.
field
)
}
func
Struct
(
field
*
[]
Field
)
*
StructTypeStruct
{
func
NewStructType
Struct
(
field
*
[]
Field
)
*
StructTypeStruct
{
t
:=
new
(
StructTypeStruct
);
t
.
field
=
field
;
return
t
;
}
func
NewStructTypeStruct
(
field
*
[]
Field
)
*
StructTypeStruct
{
t
:=
new
(
StructTypeStruct
);
export
type
InterfaceType
interface
{
Field
(
int
)
(
name
string
,
typ
Type
);
Len
()
int
;
}
type
InterfaceTypeStruct
struct
{
field
*
[]
Field
;
}
func
(
t
*
InterfaceTypeStruct
)
Field
(
i
int
)
(
name
string
,
typ
Type
)
{
return
t
.
field
[
i
]
.
name
,
t
.
field
[
i
]
.
typ
.
Get
()
}
func
(
t
*
InterfaceTypeStruct
)
Len
()
int
{
return
len
(
t
.
field
)
}
func
NewInterfaceTypeStruct
(
field
*
[]
Field
)
*
InterfaceTypeStruct
{
t
:=
new
(
InterfaceTypeStruct
);
t
.
field
=
field
;
return
t
;
}
func
(
t
*
InterfaceTypeStruct
)
Kind
()
int
{
return
InterfaceKind
}
export
type
FuncType
interface
{
Receiver
()
StructType
;
In
()
StructType
;
Out
()
StructType
;
}
type
FuncTypeStruct
struct
{
receiver
*
StructTypeStruct
;
in
*
StructTypeStruct
;
out
*
StructTypeStruct
;
}
...
...
@@ -269,45 +289,24 @@ func (t *FuncTypeStruct) Kind() int {
return
FuncKind
}
func
(
t
*
FuncTypeStruct
)
Receiver
()
StructType
{
return
t
.
receiver
}
func
(
t
*
FuncTypeStruct
)
In
()
StructType
{
return
t
.
in
}
func
(
t
*
FuncTypeStruct
)
Out
()
StructType
{
if
t
.
out
==
nil
{
// nil.(StructType) != nil so make sure caller sees real nil
return
nil
}
return
t
.
out
}
func
NewFuncTypeStruct
(
receiver
,
in
,
out
*
StructTypeStruct
)
*
FuncTypeStruct
{
func
NewFuncTypeStruct
(
in
,
out
*
StructTypeStruct
)
*
FuncTypeStruct
{
t
:=
new
(
FuncTypeStruct
);
t
.
receiver
=
receiver
;
t
.
in
=
in
;
t
.
out
=
out
;
return
t
;
}
////////////////////////
//helpers for early bootstrap and debugging
func
Stub
(
n
string
,
t
Type
)
*
StubType
{
s
:=
new
(
StubType
);
s
.
name
=
n
;
s
.
typ
=
t
;
return
s
;
}
export
var
PtrInt8
Type
=
NewPtrTypeStruct
(
Stub
(
"i"
,
Int8
));
export
var
PtrPtrInt8
Type
=
NewPtrTypeStruct
(
Stub
(
"i"
,
PtrInt8
));
export
var
ArrayFloat32
Type
=
NewArrayTypeStruct
(
100
,
Stub
(
"f"
,
Float32
));
export
var
MapStringInt16
Type
=
NewMapTypeStruct
(
Stub
(
"s"
,
String
),
Stub
(
"i"
,
Int16
));
export
var
ChanArray
Type
=
NewChanTypeStruct
(
RecvDir
,
Stub
(
"a"
,
ArrayFloat32
));
var
F1
=
Field
{
"i"
,
Stub
(
"i"
,
Int64
)};
var
Fields
=
[]
Field
{
F1
};
export
var
Structure
=
NewStructTypeStruct
(
&
Fields
);
export
var
Function
Type
=
NewFuncTypeStruct
(
Structure
,
Structure
,
Structure
);
////////////////////////
// Cache of expanded types keyed by type name.
var
types
*
map
[
string
]
*
Type
// BUG TODO: should be Type not *Type
// List of typename, typestring pairs
...
...
@@ -380,7 +379,7 @@ func init() {
typename =
name '.' name
fieldlist =
[ field {
','
field } ]
[ field {
[ ',' | ';' ]
field } ]
field =
identifier stubtype
arraytype =
...
...
@@ -402,12 +401,13 @@ func init() {
*/
// Helper functions for token scanning
func
isdigit
(
c
uint8
)
bool
{
return
'0'
<=
c
&&
c
<=
'9'
}
func
special
(
c
uint8
)
bool
{
s
:=
"*[](){}<"
;
// Note: '.' is not in this list. "P.T" is an identifer, as is "?".
s
:=
"*[](){}<
;,
"
;
// Note: '.' is not in this list. "P.T" is an identifer, as is "?".
for
i
:=
0
;
i
<
len
(
s
);
i
++
{
if
c
==
s
[
i
]
{
return
true
...
...
@@ -416,12 +416,14 @@ func special(c uint8) bool {
return
false
;
}
// Simple parser for type strings
type
Parser
struct
{
str
string
;
index
int
;
token
string
;
str
string
;
// string being parsed
token
string
;
// the token being parsed now
index
int
;
// next character position in str
}
// Load next token into p.token
func
(
p
*
Parser
)
Next
()
{
token
:=
""
;
for
;
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
]
==
' '
;
p
.
index
++
{
...
...
@@ -434,28 +436,15 @@ func (p *Parser) Next() {
c
,
w
:=
sys
.
stringtorune
(
p
.
str
,
p
.
index
);
p
.
index
+=
w
;
switch
{
case
c
==
'*'
:
p
.
token
=
"*"
;
return
;
case
c
==
'['
:
p
.
token
=
"["
;
return
;
case
c
==
']'
:
p
.
token
=
"]"
;
return
;
case
c
==
'('
:
p
.
token
=
"("
;
return
;
case
c
==
')'
:
p
.
token
=
")"
;
return
;
case
c
==
'<'
:
if
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
+
1
]
==
'-'
{
if
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
]
==
'-'
{
p
.
index
++
;
p
.
token
=
"<-"
;
return
;
}
p
.
token
=
"<"
;
// shouldn't happen but let the parser figure it out
fallthrough
;
// shouldn't happen but let the parser figure it out
case
special
(
uint8
(
c
))
:
p
.
token
=
string
(
c
);
return
;
case
isdigit
(
uint8
(
c
))
:
for
p
.
index
<
len
(
p
.
str
)
&&
isdigit
(
p
.
str
[
p
.
index
])
{
...
...
@@ -464,7 +453,7 @@ func (p *Parser) Next() {
p
.
token
=
p
.
str
[
start
:
p
.
index
];
return
;
}
for
p
.
index
<
len
(
p
.
str
)
&&
!
special
(
p
.
str
[
p
.
index
])
{
for
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
]
!=
' '
&&
!
special
(
p
.
str
[
p
.
index
])
{
p
.
index
++
}
p
.
token
=
p
.
str
[
start
:
p
.
index
];
...
...
@@ -507,27 +496,127 @@ func (p *Parser) Map() *StubType {
return
NewStubType
(
NewMapTypeStruct
(
keytype
,
elemtype
));
}
func
(
p
*
Parser
)
Simple
()
*
StubType
{
func
(
p
*
Parser
)
Chan
(
dir
int
)
*
StubType
{
if
p
.
token
==
"<-"
{
if
dir
!=
BothDir
{
return
MissingStub
}
p
.
Next
();
dir
=
SendDir
;
}
elemtype
:=
p
.
Type
();
return
NewStubType
(
NewChanTypeStruct
(
dir
,
elemtype
));
}
// Parse array of fields for struct, interface, and func arguments
func
(
p
*
Parser
)
Fields
(
sep
string
)
*
[]
Field
{
a
:=
new
([]
Field
,
10
);
nf
:=
0
;
for
p
.
token
!=
""
&&
!
special
(
p
.
token
[
0
])
{
if
nf
==
len
(
a
)
{
a1
:=
new
([]
Field
,
2
*
nf
);
for
i
:=
0
;
i
<
nf
;
i
++
{
a1
[
i
]
=
a
[
i
];
}
a
=
a1
;
}
a
[
nf
]
.
name
=
p
.
token
;
p
.
Next
();
a
[
nf
]
.
typ
=
p
.
Type
();
nf
++
;
if
p
.
token
!=
sep
{
break
;
}
p
.
Next
();
// skip separator
}
return
a
[
0
:
nf
];
}
func
(
p
*
Parser
)
Struct
()
*
StubType
{
f
:=
p
.
Fields
(
";"
);
if
p
.
token
!=
"}"
{
return
MissingStub
;
}
p
.
Next
();
return
NewStubType
(
NewStructTypeStruct
(
f
));
}
func
(
p
*
Parser
)
Interface
()
*
StubType
{
f
:=
p
.
Fields
(
";"
);
if
p
.
token
!=
"}"
{
return
MissingStub
;
}
p
.
Next
();
return
NewStubType
(
NewInterfaceTypeStruct
(
f
));
}
func
(
p
*
Parser
)
Func
()
*
StubType
{
// may be 1 or 2 parenthesized lists
f1
:=
NewStructTypeStruct
(
p
.
Fields
(
","
));
if
p
.
token
!=
")"
{
return
MissingStub
;
}
p
.
Next
();
if
p
.
token
!=
"("
{
// 1 list: the in parameters only
return
NewStubType
(
NewFuncTypeStruct
(
f1
,
nil
));
}
p
.
Next
();
f2
:=
NewStructTypeStruct
(
p
.
Fields
(
","
));
if
p
.
token
!=
")"
{
return
MissingStub
;
}
p
.
Next
();
// 2 lists: the in and out parameters are present
return
NewStubType
(
NewFuncTypeStruct
(
f1
,
f2
));
}
func
(
p
*
Parser
)
Type
()
*
StubType
{
dir
:=
BothDir
;
switch
{
case
p
.
token
==
""
:
return
nil
;
case
p
.
token
==
"*"
:
p
.
Next
();
return
NewStubType
(
NewPtrTypeStruct
(
p
.
Simpl
e
()));
return
NewStubType
(
NewPtrTypeStruct
(
p
.
Typ
e
()));
case
p
.
token
==
"["
:
p
.
Next
();
return
p
.
Array
();
case
p
.
token
==
"map"
:
p
.
Next
();
return
p
.
Map
();
case
p
.
token
==
"<-"
:
p
.
Next
();
dir
=
RecvDir
;
if
p
.
token
!=
"chan"
{
return
MissingStub
;
}
fallthrough
;
case
p
.
token
==
"chan"
:
p
.
Next
();
return
p
.
Chan
(
dir
);
case
p
.
token
==
"struct"
:
p
.
Next
();
if
p
.
token
!=
"{"
{
return
MissingStub
}
p
.
Next
();
return
p
.
Struct
();
case
p
.
token
==
"interface"
:
p
.
Next
();
if
p
.
token
!=
"{"
{
return
MissingStub
}
p
.
Next
();
return
p
.
Interface
();
case
p
.
token
==
"("
:
p
.
Next
();
return
p
.
Func
();
case
isdigit
(
p
.
token
[
0
])
:
p
.
Next
();
print
(
"reflect.Simple: number encountered
\n
"
);
// TODO: remove
return
MissingStub
;
case
special
(
p
.
token
[
0
])
:
// TODO: get chans right
p
.
Next
();
print
(
"reflect.Simple: special character encountered
\n
"
);
// TODO: remove
return
MissingStub
;
}
// must be an identifier. is it basic? if so, we have a stub
...
...
@@ -543,7 +632,6 @@ func (p *Parser) Simple() *StubType {
}
}
if
ndot
!=
1
{
print
(
"reflect.Simple: illegal identifier "
,
p
.
token
,
"
\n
"
);
// TODO: remove
p
.
Next
();
return
MissingStub
;
}
...
...
@@ -553,10 +641,6 @@ func (p *Parser) Simple() *StubType {
return
s
;
}
func
(
p
*
Parser
)
Type
()
*
StubType
{
return
p
.
Simple
();
}
export
func
ParseTypeString
(
str
string
)
Type
{
p
:=
new
(
Parser
);
p
.
str
=
str
;
...
...
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