Sync go parser with fishman-ctags
New features include: * struct/interface detection * struct member parsing * function prototype parsing
This commit is contained in:
parent
b5702f03dc
commit
e433490672
@ -13,6 +13,7 @@
|
|||||||
/*
|
/*
|
||||||
* MACROS
|
* MACROS
|
||||||
*/
|
*/
|
||||||
|
#define MAX_SIGNATURE_LENGTH 512
|
||||||
#define isType(token,t) (boolean) ((token)->type == (t))
|
#define isType(token,t) (boolean) ((token)->type == (t))
|
||||||
#define isKeyword(token,k) (boolean) ((token)->keyword == (k))
|
#define isKeyword(token,k) (boolean) ((token)->keyword == (k))
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ typedef struct sTokenInfo {
|
|||||||
|
|
||||||
static int Lang_go;
|
static int Lang_go;
|
||||||
static vString *scope;
|
static vString *scope;
|
||||||
|
static vString *signature = NULL;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GOTAG_UNDEFINED = -1,
|
GOTAG_UNDEFINED = -1,
|
||||||
@ -85,6 +87,9 @@ typedef enum {
|
|||||||
GOTAG_CONST,
|
GOTAG_CONST,
|
||||||
GOTAG_TYPE,
|
GOTAG_TYPE,
|
||||||
GOTAG_VAR,
|
GOTAG_VAR,
|
||||||
|
GOTAG_STRUCT,
|
||||||
|
GOTAG_INTERFACE,
|
||||||
|
GOTAG_MEMBER
|
||||||
} goKind;
|
} goKind;
|
||||||
|
|
||||||
static kindOption GoKinds[] = {
|
static kindOption GoKinds[] = {
|
||||||
@ -92,7 +97,10 @@ static kindOption GoKinds[] = {
|
|||||||
{TRUE, 'f', "function", "functions"},
|
{TRUE, 'f', "function", "functions"},
|
||||||
{TRUE, 'c', "macro", "constants"},
|
{TRUE, 'c', "macro", "constants"},
|
||||||
{TRUE, 't', "typedef", "types"},
|
{TRUE, 't', "typedef", "types"},
|
||||||
{TRUE, 'v', "variable", "variables"}
|
{TRUE, 'v', "variable", "variables"},
|
||||||
|
{TRUE, 's', "struct", "structs"},
|
||||||
|
{TRUE, 'i', "interface", "interfaces"},
|
||||||
|
{TRUE, 'm', "member", "struct members"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static keywordDesc GoKeywordTable[] = {
|
static keywordDesc GoKeywordTable[] = {
|
||||||
@ -149,6 +157,17 @@ static tokenInfo *newToken (void)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tokenInfo *copyToken (tokenInfo *other)
|
||||||
|
{
|
||||||
|
tokenInfo *const token = xMalloc (1, tokenInfo);
|
||||||
|
token->type = other->type;
|
||||||
|
token->keyword = other->keyword;
|
||||||
|
token->string = vStringNewCopy (other->string);
|
||||||
|
token->lineNumber = other->lineNumber;
|
||||||
|
token->filePosition = other->filePosition;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
static void deleteToken (tokenInfo * const token)
|
static void deleteToken (tokenInfo * const token)
|
||||||
{
|
{
|
||||||
if (token != NULL)
|
if (token != NULL)
|
||||||
@ -201,6 +220,8 @@ static void readToken (tokenInfo *const token)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
static tokenType lastTokenType = TOKEN_NONE;
|
static tokenType lastTokenType = TOKEN_NONE;
|
||||||
|
boolean firstWhitespace = TRUE;
|
||||||
|
boolean whitespace;
|
||||||
|
|
||||||
token->type = TOKEN_NONE;
|
token->type = TOKEN_NONE;
|
||||||
token->keyword = KEYWORD_NONE;
|
token->keyword = KEYWORD_NONE;
|
||||||
@ -219,11 +240,16 @@ getNextChar:
|
|||||||
lastTokenType == TOKEN_CLOSE_CURLY ||
|
lastTokenType == TOKEN_CLOSE_CURLY ||
|
||||||
lastTokenType == TOKEN_CLOSE_SQUARE))
|
lastTokenType == TOKEN_CLOSE_SQUARE))
|
||||||
{
|
{
|
||||||
token->type = TOKEN_SEMICOLON;
|
c = ';'; // semicolon injection
|
||||||
goto done;
|
}
|
||||||
|
whitespace = c == '\t' || c == ' ' || c == '\r' || c == '\n';
|
||||||
|
if (signature && whitespace && firstWhitespace && vStringLength (signature) < MAX_SIGNATURE_LENGTH)
|
||||||
|
{
|
||||||
|
firstWhitespace = FALSE;
|
||||||
|
vStringPut(signature, ' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (c == '\t' || c == ' ' || c == '\r' || c == '\n');
|
while (whitespace);
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -354,71 +380,79 @@ getNextChar:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
if (signature && vStringLength (signature) < MAX_SIGNATURE_LENGTH)
|
||||||
|
{
|
||||||
|
if (token->type == TOKEN_LEFT_ARROW)
|
||||||
|
vStringCatS(signature, "<-");
|
||||||
|
else if (token->type == TOKEN_STRING)
|
||||||
|
{
|
||||||
|
// only struct member annotations can appear in function prototypes
|
||||||
|
// so only `` type strings are possible
|
||||||
|
vStringPut(signature, '`');
|
||||||
|
vStringCat(signature, token->string);
|
||||||
|
vStringPut(signature, '`');
|
||||||
|
}
|
||||||
|
else if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_KEYWORD)
|
||||||
|
vStringCat(signature, token->string);
|
||||||
|
else if (c != EOF)
|
||||||
|
vStringPut(signature, c);
|
||||||
|
}
|
||||||
|
|
||||||
lastTokenType = token->type;
|
lastTokenType = token->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void skipToMatched (tokenInfo *const token)
|
static boolean skipToMatchedNoRead (tokenInfo *const token)
|
||||||
{
|
{
|
||||||
int nest_level = 0;
|
int nest_level = 0;
|
||||||
tokenType open_token;
|
tokenType open_token = token->type;
|
||||||
tokenType close_token;
|
tokenType close_token;
|
||||||
|
|
||||||
switch (token->type)
|
switch (open_token)
|
||||||
{
|
{
|
||||||
case TOKEN_OPEN_PAREN:
|
case TOKEN_OPEN_PAREN:
|
||||||
open_token = TOKEN_OPEN_PAREN;
|
|
||||||
close_token = TOKEN_CLOSE_PAREN;
|
close_token = TOKEN_CLOSE_PAREN;
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPEN_CURLY:
|
case TOKEN_OPEN_CURLY:
|
||||||
open_token = TOKEN_OPEN_CURLY;
|
|
||||||
close_token = TOKEN_CLOSE_CURLY;
|
close_token = TOKEN_CLOSE_CURLY;
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPEN_SQUARE:
|
case TOKEN_OPEN_SQUARE:
|
||||||
open_token = TOKEN_OPEN_SQUARE;
|
|
||||||
close_token = TOKEN_CLOSE_SQUARE;
|
close_token = TOKEN_CLOSE_SQUARE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine will skip to a matching closing token.
|
* This routine will skip to a matching closing token.
|
||||||
* It will also handle nested tokens like the (, ) below.
|
* It will also handle nested tokens.
|
||||||
* ( name varchar(30), text binary(10) )
|
|
||||||
*/
|
*/
|
||||||
if (isType (token, open_token))
|
nest_level++;
|
||||||
|
while (nest_level > 0 && !isType (token, TOKEN_EOF))
|
||||||
{
|
{
|
||||||
nest_level++;
|
|
||||||
while (!(isType (token, close_token) && (nest_level == 0)) &&
|
|
||||||
!isType (token, TOKEN_EOF))
|
|
||||||
{
|
|
||||||
readToken (token);
|
|
||||||
if (isType (token, open_token))
|
|
||||||
{
|
|
||||||
nest_level++;
|
|
||||||
}
|
|
||||||
if (isType (token, close_token))
|
|
||||||
{
|
|
||||||
if (nest_level > 0)
|
|
||||||
{
|
|
||||||
nest_level--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readToken (token);
|
readToken (token);
|
||||||
|
if (isType (token, open_token))
|
||||||
|
nest_level++;
|
||||||
|
else if (isType (token, close_token))
|
||||||
|
nest_level--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void skipType (tokenInfo *const token)
|
static void skipToMatched (tokenInfo *const token)
|
||||||
|
{
|
||||||
|
if (skipToMatchedNoRead (token))
|
||||||
|
readToken (token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean skipType (tokenInfo *const token)
|
||||||
{
|
{
|
||||||
again:
|
|
||||||
// Type = TypeName | TypeLit | "(" Type ")" .
|
// Type = TypeName | TypeLit | "(" Type ")" .
|
||||||
// Skips also function multiple return values "(" Type {"," Type} ")"
|
// Skips also function multiple return values "(" Type {"," Type} ")"
|
||||||
if (isType (token, TOKEN_OPEN_PAREN))
|
if (isType (token, TOKEN_OPEN_PAREN))
|
||||||
{
|
{
|
||||||
skipToMatched (token);
|
skipToMatched (token);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeName = QualifiedIdent.
|
// TypeName = QualifiedIdent.
|
||||||
@ -433,7 +467,7 @@ again:
|
|||||||
if (isType (token, TOKEN_IDENTIFIER))
|
if (isType (token, TOKEN_IDENTIFIER))
|
||||||
readToken (token);
|
readToken (token);
|
||||||
}
|
}
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructType = "struct" "{" { FieldDecl ";" } "}"
|
// StructType = "struct" "{" { FieldDecl ";" } "}"
|
||||||
@ -443,7 +477,7 @@ again:
|
|||||||
readToken (token);
|
readToken (token);
|
||||||
// skip over "{}"
|
// skip over "{}"
|
||||||
skipToMatched (token);
|
skipToMatched (token);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayType = "[" ArrayLength "]" ElementType .
|
// ArrayType = "[" ArrayLength "]" ElementType .
|
||||||
@ -452,7 +486,7 @@ again:
|
|||||||
if (isType (token, TOKEN_OPEN_SQUARE))
|
if (isType (token, TOKEN_OPEN_SQUARE))
|
||||||
{
|
{
|
||||||
skipToMatched (token);
|
skipToMatched (token);
|
||||||
goto again;
|
return skipType (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PointerType = "*" BaseType .
|
// PointerType = "*" BaseType .
|
||||||
@ -461,7 +495,7 @@ again:
|
|||||||
if (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW))
|
if (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW))
|
||||||
{
|
{
|
||||||
readToken (token);
|
readToken (token);
|
||||||
goto again;
|
return skipType (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapType = "map" "[" KeyType "]" ElementType .
|
// MapType = "map" "[" KeyType "]" ElementType .
|
||||||
@ -471,7 +505,7 @@ again:
|
|||||||
readToken (token);
|
readToken (token);
|
||||||
// skip over "[]"
|
// skip over "[]"
|
||||||
skipToMatched (token);
|
skipToMatched (token);
|
||||||
goto again;
|
return skipType (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FunctionType = "func" Signature .
|
// FunctionType = "func" Signature .
|
||||||
@ -486,11 +520,15 @@ again:
|
|||||||
// Result is parameters or type or nothing. skipType treats anything
|
// Result is parameters or type or nothing. skipType treats anything
|
||||||
// surrounded by parentheses as a type, and does nothing if what
|
// surrounded by parentheses as a type, and does nothing if what
|
||||||
// follows is not a type.
|
// follows is not a type.
|
||||||
goto again;
|
return skipType (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void makeTag (tokenInfo *const token, const goKind kind)
|
static void makeTag (tokenInfo *const token, const goKind kind,
|
||||||
|
tokenInfo *const parent_token, const goKind parent_kind,
|
||||||
|
const char *argList)
|
||||||
{
|
{
|
||||||
const char *const name = vStringValue (token->string);
|
const char *const name = vStringValue (token->string);
|
||||||
|
|
||||||
@ -504,7 +542,14 @@ static void makeTag (tokenInfo *const token, const goKind kind)
|
|||||||
e.filePosition = token->filePosition;
|
e.filePosition = token->filePosition;
|
||||||
e.kindName = GoKinds [kind].name;
|
e.kindName = GoKinds [kind].name;
|
||||||
e.kind = GoKinds [kind].letter;
|
e.kind = GoKinds [kind].letter;
|
||||||
|
if (argList)
|
||||||
|
e.extensionFields.arglist = argList;
|
||||||
|
|
||||||
|
if (parent_kind != GOTAG_UNDEFINED && parent_token != NULL)
|
||||||
|
{
|
||||||
|
e.extensionFields.scope[0] = GoKinds[parent_kind].name;
|
||||||
|
e.extensionFields.scope[1] = vStringValue (parent_token->string);
|
||||||
|
}
|
||||||
makeTagEntry (&e);
|
makeTagEntry (&e);
|
||||||
|
|
||||||
if (scope && Option.include.qualifiedTags)
|
if (scope && Option.include.qualifiedTags)
|
||||||
@ -524,7 +569,7 @@ static void parsePackage (tokenInfo *const token)
|
|||||||
readToken (token);
|
readToken (token);
|
||||||
if (isType (token, TOKEN_IDENTIFIER))
|
if (isType (token, TOKEN_IDENTIFIER))
|
||||||
{
|
{
|
||||||
makeTag (token, GOTAG_PACKAGE);
|
makeTag (token, GOTAG_PACKAGE, NULL, GOTAG_UNDEFINED, NULL);
|
||||||
if (!scope && Option.include.qualifiedTags)
|
if (!scope && Option.include.qualifiedTags)
|
||||||
{
|
{
|
||||||
scope = vStringNew ();
|
scope = vStringNew ();
|
||||||
@ -549,11 +594,25 @@ static void parseFunctionOrMethod (tokenInfo *const token)
|
|||||||
|
|
||||||
if (isType (token, TOKEN_IDENTIFIER))
|
if (isType (token, TOKEN_IDENTIFIER))
|
||||||
{
|
{
|
||||||
makeTag (token, GOTAG_FUNCTION);
|
tokenInfo *functionToken = copyToken (token);
|
||||||
|
|
||||||
|
// Start recording signature
|
||||||
|
signature = vStringNew ();
|
||||||
|
|
||||||
// Skip over parameters.
|
// Skip over parameters.
|
||||||
readToken (token);
|
readToken (token);
|
||||||
skipToMatched (token);
|
skipToMatchedNoRead (token);
|
||||||
|
|
||||||
|
vStringStripLeading (signature);
|
||||||
|
vStringStripTrailing (signature);
|
||||||
|
makeTag (functionToken, GOTAG_FUNCTION, NULL, GOTAG_UNDEFINED, signature->buffer);
|
||||||
|
deleteToken (functionToken);
|
||||||
|
vStringDelete(signature);
|
||||||
|
|
||||||
|
// Stop recording signature
|
||||||
|
signature = NULL;
|
||||||
|
|
||||||
|
readToken (token);
|
||||||
|
|
||||||
// Skip over result.
|
// Skip over result.
|
||||||
skipType (token);
|
skipType (token);
|
||||||
@ -564,6 +623,75 @@ static void parseFunctionOrMethod (tokenInfo *const token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parseStructMembers (tokenInfo *const token, tokenInfo *const parent_token)
|
||||||
|
{
|
||||||
|
// StructType = "struct" "{" { FieldDecl ";" } "}" .
|
||||||
|
// FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] .
|
||||||
|
// AnonymousField = [ "*" ] TypeName .
|
||||||
|
// Tag = string_lit .
|
||||||
|
|
||||||
|
readToken (token);
|
||||||
|
if (!isType (token, TOKEN_OPEN_CURLY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
readToken (token);
|
||||||
|
while (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))
|
||||||
|
{
|
||||||
|
tokenInfo *memberCandidate = NULL;
|
||||||
|
boolean first = TRUE;
|
||||||
|
|
||||||
|
while (!isType (token, TOKEN_EOF))
|
||||||
|
{
|
||||||
|
if (isType (token, TOKEN_IDENTIFIER))
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
// could be anonymous field like in 'struct {int}' - we don't know yet
|
||||||
|
memberCandidate = copyToken (token);
|
||||||
|
first = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (memberCandidate)
|
||||||
|
{
|
||||||
|
// if we are here, there was a comma and memberCandidate isn't an anonymous field
|
||||||
|
makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL);
|
||||||
|
deleteToken (memberCandidate);
|
||||||
|
memberCandidate = NULL;
|
||||||
|
}
|
||||||
|
makeTag (token, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL);
|
||||||
|
}
|
||||||
|
readToken (token);
|
||||||
|
}
|
||||||
|
if (!isType (token, TOKEN_COMMA))
|
||||||
|
break;
|
||||||
|
readToken (token);
|
||||||
|
}
|
||||||
|
|
||||||
|
// in the case of an anonymous field, we already read part of the
|
||||||
|
// type into memberCandidate and skipType() should return FALSE so no tag should
|
||||||
|
// be generated in this case.
|
||||||
|
if (skipType (token) && memberCandidate)
|
||||||
|
makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL);
|
||||||
|
|
||||||
|
if (memberCandidate)
|
||||||
|
deleteToken (memberCandidate);
|
||||||
|
|
||||||
|
while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_CURLY)
|
||||||
|
&& !isType (token, TOKEN_EOF))
|
||||||
|
{
|
||||||
|
readToken (token);
|
||||||
|
skipToMatched (token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isType (token, TOKEN_CLOSE_CURLY))
|
||||||
|
{
|
||||||
|
// we are at TOKEN_SEMICOLON
|
||||||
|
readToken (token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
||||||
{
|
{
|
||||||
// ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
|
// ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
|
||||||
@ -586,11 +714,26 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
tokenInfo *typeToken = NULL;
|
||||||
|
|
||||||
while (!isType (token, TOKEN_EOF))
|
while (!isType (token, TOKEN_EOF))
|
||||||
{
|
{
|
||||||
if (isType (token, TOKEN_IDENTIFIER))
|
if (isType (token, TOKEN_IDENTIFIER))
|
||||||
{
|
{
|
||||||
makeTag (token, kind);
|
if (kind == GOTAG_TYPE)
|
||||||
|
{
|
||||||
|
typeToken = copyToken (token);
|
||||||
|
readToken (token);
|
||||||
|
if (isKeyword (token, KEYWORD_struct))
|
||||||
|
makeTag (typeToken, GOTAG_STRUCT, NULL, GOTAG_UNDEFINED, NULL);
|
||||||
|
else if (isKeyword (token, KEYWORD_interface))
|
||||||
|
makeTag (typeToken, GOTAG_INTERFACE, NULL, GOTAG_UNDEFINED, NULL);
|
||||||
|
else
|
||||||
|
makeTag (typeToken, kind, NULL, GOTAG_UNDEFINED, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
makeTag (token, kind, NULL, GOTAG_UNDEFINED, NULL);
|
||||||
readToken (token);
|
readToken (token);
|
||||||
}
|
}
|
||||||
if (!isType (token, TOKEN_COMMA))
|
if (!isType (token, TOKEN_COMMA))
|
||||||
@ -598,7 +741,17 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind)
|
|||||||
readToken (token);
|
readToken (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
skipType (token);
|
if (typeToken)
|
||||||
|
{
|
||||||
|
if (isKeyword (token, KEYWORD_struct))
|
||||||
|
parseStructMembers (token, typeToken);
|
||||||
|
else
|
||||||
|
skipType (token);
|
||||||
|
deleteToken (typeToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
skipType (token);
|
||||||
|
|
||||||
while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_PAREN)
|
while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_PAREN)
|
||||||
&& !isType (token, TOKEN_EOF))
|
&& !isType (token, TOKEN_EOF))
|
||||||
{
|
{
|
||||||
|
@ -15,8 +15,11 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type T6 struct {
|
type T6 struct {
|
||||||
a, b, c, d int
|
_a, _b, _c, _d int
|
||||||
e float32
|
int
|
||||||
|
T1 `annotation`
|
||||||
|
*T2
|
||||||
|
_e float32
|
||||||
//ignored int
|
//ignored int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,4 +47,4 @@ func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f
|
|||||||
func main() {
|
func main() {
|
||||||
go func (){}()
|
go func (){}()
|
||||||
fmt.Println("Hello, 世界")
|
fmt.Println("Hello, 世界")
|
||||||
}
|
}
|
@ -12,23 +12,28 @@ T1
|
|||||||
T2フ4096ヨ0
|
T2フ4096ヨ0
|
||||||
T3フ4096ヨ0
|
T3フ4096ヨ0
|
||||||
T4フ4096ヨ0
|
T4フ4096ヨ0
|
||||||
T5フ4096ヨ0
|
T5フ32ヨ0
|
||||||
T6フ4096ヨ0
|
T6フ2048ヨ0
|
||||||
T7フ4096ヨ0
|
T7フ4096ヨ0
|
||||||
T8フ4096ヨ0
|
T8フ4096ヨ0
|
||||||
T9フ4096ヨ0
|
T9フ4096ヨ0
|
||||||
|
_aフ64ホT6ヨ0
|
||||||
|
_bフ64ホT6ヨ0
|
||||||
|
_cフ64ホT6ヨ0
|
||||||
|
_dフ64ホT6ヨ0
|
||||||
|
_eフ64ホT6ヨ0
|
||||||
aフ16384ヨ0
|
aフ16384ヨ0
|
||||||
bフ16384ヨ0
|
bフ16384ヨ0
|
||||||
cフ16384ヨ0
|
cフ16384ヨ0
|
||||||
dフ16384ヨ0
|
dフ16384ヨ0
|
||||||
eフ16384ヨ0
|
eフ16384ヨ0
|
||||||
fフ16384ヨ0
|
fフ16384ヨ0
|
||||||
f1フ16ヨ0
|
f1フ16ヘ()ヨ0
|
||||||
f2フ16ヨ0
|
f2フ16ヘ()ヨ0
|
||||||
f3フ16ヨ0
|
f3フ16ヘ()ヨ0
|
||||||
f4フ16ヨ0
|
f4フ16ヘ(a func () func ())ヨ0
|
||||||
f5フ16ヨ0
|
f5フ16ヘ()ヨ0
|
||||||
gフ16384ヨ0
|
gフ16384ヨ0
|
||||||
hフ16384ヨ0
|
hフ16384ヨ0
|
||||||
mainフ16ヨ0
|
mainフ16ヘ()ヨ0
|
||||||
mainフ256ヨ0
|
mainフ256ヨ0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user