Update angelscript to 2.30.2
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
Copyright (c) 2003-2015 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@@ -261,6 +261,13 @@ int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
|
||||
scriptNode->AddChildLast(ParseType(true));
|
||||
if( isSyntaxError ) return -1;
|
||||
|
||||
// Allow optional '&' to indicate that the property is indirect, i.e. stored as reference
|
||||
sToken t;
|
||||
GetToken(&t);
|
||||
RewindTo(&t);
|
||||
if( t.type == ttAmp )
|
||||
scriptNode->AddChildLast(ParseToken(ttAmp));
|
||||
|
||||
// Allow optional namespace to be defined before the identifier in case
|
||||
// the declaration is to be used for searching for an existing property
|
||||
ParseOptionalScope(scriptNode);
|
||||
@@ -269,7 +276,6 @@ int asCParser::ParsePropertyDeclaration(asCScriptCode *script)
|
||||
if( isSyntaxError ) return -1;
|
||||
|
||||
// The declaration should end after the identifier
|
||||
sToken t;
|
||||
GetToken(&t);
|
||||
if( t.type != ttEnd )
|
||||
{
|
||||
@@ -402,9 +408,11 @@ asCScriptNode *asCParser::ParseType(bool allowConst, bool allowVariableType, boo
|
||||
if( isSyntaxError ) return node;
|
||||
|
||||
// If the datatype is a template type, then parse the subtype within the < >
|
||||
GetToken(&t);
|
||||
RewindTo(&t);
|
||||
asCScriptNode *type = node->lastChild;
|
||||
tempString.Assign(&script->code[type->tokenPos], type->tokenLength);
|
||||
if( engine->IsTemplateType(tempString.AddressOf()) )
|
||||
if( engine->IsTemplateType(tempString.AddressOf()) && t.type == ttLessThan )
|
||||
{
|
||||
GetToken(&t);
|
||||
if( t.type != ttLessThan )
|
||||
@@ -602,7 +610,7 @@ asCScriptNode *asCParser::ParseIdentifier()
|
||||
return node;
|
||||
}
|
||||
|
||||
// BNF: PARAMLIST ::= '(' ('void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]}) ')'
|
||||
// BNF: PARAMLIST ::= '(' ['void' | (TYPE TYPEMOD [IDENTIFIER] ['=' EXPR] {',' TYPE TYPEMOD [IDENTIFIER] ['=' EXPR]})] ')'
|
||||
asCScriptNode *asCParser::ParseParameterList()
|
||||
{
|
||||
asCScriptNode *node = CreateNode(snParameterList);
|
||||
@@ -1104,10 +1112,13 @@ bool asCParser::CheckTemplateType(sToken &t)
|
||||
tempString.Assign(&script->code[t.pos], t.length);
|
||||
if( engine->IsTemplateType(tempString.AddressOf()) )
|
||||
{
|
||||
// Expect the sub type within < >
|
||||
// If the next token is a < then parse the sub-type too
|
||||
GetToken(&t);
|
||||
if( t.type != ttLessThan )
|
||||
return false;
|
||||
{
|
||||
RewindTo(&t);
|
||||
return true;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
@@ -1232,7 +1243,7 @@ asCScriptNode *asCParser::ParseCast()
|
||||
return node;
|
||||
}
|
||||
|
||||
// BNF: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')'
|
||||
// BNF: EXPRVALUE ::= 'void' | CONSTRUCTCALL | FUNCCALL | VARACCESS | CAST | LITERAL | '(' ASSIGN ')' | LAMBDA
|
||||
asCScriptNode *asCParser::ParseExprValue()
|
||||
{
|
||||
asCScriptNode *node = CreateNode(snExprValue);
|
||||
@@ -1250,44 +1261,54 @@ asCScriptNode *asCParser::ParseExprValue()
|
||||
node->AddChildLast(ParseConstructCall());
|
||||
else if( t1.type == ttIdentifier || t1.type == ttScope )
|
||||
{
|
||||
// Determine the last identifier in order to check if it is a type
|
||||
sToken t;
|
||||
if( t1.type == ttScope ) t = t2; else t = t1;
|
||||
RewindTo(&t);
|
||||
GetToken(&t2);
|
||||
while( t.type == ttIdentifier )
|
||||
// Check if the expression is an anonymous function
|
||||
if( IsLambda() )
|
||||
{
|
||||
t2 = t;
|
||||
GetToken(&t);
|
||||
if( t.type == ttScope )
|
||||
GetToken(&t);
|
||||
else
|
||||
break;
|
||||
node->AddChildLast(ParseLambda());
|
||||
}
|
||||
|
||||
bool isDataType = IsDataType(t2);
|
||||
bool isTemplateType = false;
|
||||
if( isDataType )
|
||||
{
|
||||
// Is this a template type?
|
||||
tempString.Assign(&script->code[t2.pos], t2.length);
|
||||
if( engine->IsTemplateType(tempString.AddressOf()) )
|
||||
isTemplateType = true;
|
||||
}
|
||||
|
||||
// Rewind so the real parsing can be done, after deciding what to parse
|
||||
RewindTo(&t1);
|
||||
|
||||
// Check if this is a construct call
|
||||
if( isDataType && (t.type == ttOpenParanthesis || // type()
|
||||
t.type == ttOpenBracket) ) // type[]()
|
||||
node->AddChildLast(ParseConstructCall());
|
||||
else if( isTemplateType && t.type == ttLessThan ) // type<t>()
|
||||
node->AddChildLast(ParseConstructCall());
|
||||
else if( IsFunctionCall() )
|
||||
node->AddChildLast(ParseFunctionCall());
|
||||
else
|
||||
node->AddChildLast(ParseVariableAccess());
|
||||
{
|
||||
// Determine the last identifier in order to check if it is a type
|
||||
sToken t;
|
||||
if( t1.type == ttScope ) t = t2; else t = t1;
|
||||
RewindTo(&t);
|
||||
GetToken(&t2);
|
||||
while( t.type == ttIdentifier )
|
||||
{
|
||||
t2 = t;
|
||||
GetToken(&t);
|
||||
if( t.type == ttScope )
|
||||
GetToken(&t);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
bool isDataType = IsDataType(t2);
|
||||
bool isTemplateType = false;
|
||||
if( isDataType )
|
||||
{
|
||||
// Is this a template type?
|
||||
tempString.Assign(&script->code[t2.pos], t2.length);
|
||||
if( engine->IsTemplateType(tempString.AddressOf()) )
|
||||
isTemplateType = true;
|
||||
}
|
||||
|
||||
GetToken(&t2);
|
||||
|
||||
// Rewind so the real parsing can be done, after deciding what to parse
|
||||
RewindTo(&t1);
|
||||
|
||||
// Check if this is a construct call
|
||||
if( isDataType && (t.type == ttOpenParanthesis || // type()
|
||||
(t.type == ttOpenBracket && t2.type == ttCloseBracket)) ) // type[]()
|
||||
node->AddChildLast(ParseConstructCall());
|
||||
else if( isTemplateType && t.type == ttLessThan ) // type<t>()
|
||||
node->AddChildLast(ParseConstructCall());
|
||||
else if( IsFunctionCall() )
|
||||
node->AddChildLast(ParseFunctionCall());
|
||||
else
|
||||
node->AddChildLast(ParseVariableAccess());
|
||||
}
|
||||
}
|
||||
else if( t1.type == ttCast )
|
||||
node->AddChildLast(ParseCast());
|
||||
@@ -1355,6 +1376,83 @@ asCScriptNode *asCParser::ParseConstant()
|
||||
return node;
|
||||
}
|
||||
|
||||
bool asCParser::IsLambda()
|
||||
{
|
||||
bool isLambda = false;
|
||||
sToken t;
|
||||
GetToken(&t);
|
||||
if( t.type == ttIdentifier && IdentifierIs(t, FUNCTION_TOKEN) )
|
||||
{
|
||||
sToken t2;
|
||||
GetToken(&t2);
|
||||
if( t2.type == ttOpenParanthesis )
|
||||
{
|
||||
// Skip until )
|
||||
while( t2.type != ttCloseParanthesis && t2.type != ttEnd )
|
||||
GetToken(&t2);
|
||||
|
||||
// The next token must be a {
|
||||
GetToken(&t2);
|
||||
if( t2.type == ttStartStatementBlock )
|
||||
isLambda = true;
|
||||
}
|
||||
}
|
||||
|
||||
RewindTo(&t);
|
||||
return isLambda;
|
||||
}
|
||||
|
||||
// BNF: LAMBDA ::= 'function' '(' [IDENTIFIER {',' IDENTIFIER}] ')' STATBLOCK
|
||||
asCScriptNode *asCParser::ParseLambda()
|
||||
{
|
||||
asCScriptNode *node = CreateNode(snFunction);
|
||||
if( node == 0 ) return 0;
|
||||
|
||||
sToken t;
|
||||
GetToken(&t);
|
||||
|
||||
if( t.type != ttIdentifier || !IdentifierIs(t, FUNCTION_TOKEN) )
|
||||
{
|
||||
Error(ExpectedToken("function"), &t);
|
||||
return node;
|
||||
}
|
||||
|
||||
GetToken(&t);
|
||||
if( t.type != ttOpenParanthesis )
|
||||
{
|
||||
Error(ExpectedToken("("), &t);
|
||||
return node;
|
||||
}
|
||||
|
||||
GetToken(&t);
|
||||
if( t.type == ttIdentifier )
|
||||
{
|
||||
RewindTo(&t);
|
||||
node->AddChildLast(ParseIdentifier());
|
||||
|
||||
GetToken(&t);
|
||||
while( t.type == ttListSeparator )
|
||||
{
|
||||
node->AddChildLast(ParseIdentifier());
|
||||
if( isSyntaxError ) return node;
|
||||
|
||||
GetToken(&t);
|
||||
}
|
||||
}
|
||||
|
||||
if( t.type != ttCloseParanthesis )
|
||||
{
|
||||
Error(ExpectedToken(")"), &t);
|
||||
return node;
|
||||
}
|
||||
|
||||
// We should just find the end of the statement block here. The statements
|
||||
// will be parsed on request by the compiler once it starts the compilation.
|
||||
node->AddChildLast(SuperficiallyParseStatementBlock());
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
asCScriptNode *asCParser::ParseStringConstant()
|
||||
{
|
||||
asCScriptNode *node = CreateNode(snConstant);
|
||||
@@ -1618,7 +1716,7 @@ asCScriptNode *asCParser::ParseCondition()
|
||||
return node;
|
||||
}
|
||||
|
||||
// BNF: EXPR ::= (TYPE '=' INILIST) | (EXPRTERM {EXPROP EXPRTERM})
|
||||
// BNF: EXPR ::= (TYPE '=' INITLIST) | (EXPRTERM {EXPROP EXPRTERM})
|
||||
asCScriptNode *asCParser::ParseExpression()
|
||||
{
|
||||
asCScriptNode *node = CreateNode(snExpression);
|
||||
@@ -2459,7 +2557,22 @@ bool asCParser::IsVirtualPropertyDecl()
|
||||
// as it may wrongly identify the statement as a non-declaration if the user typed
|
||||
// the name incorrectly. The real type is validated in ParseDeclaration where a
|
||||
// proper error message can be given.
|
||||
if( !IsRealType(t1.type) && t1.type != ttIdentifier )
|
||||
if( t1.type == ttScope )
|
||||
GetToken(&t1);
|
||||
|
||||
if( t1.type == ttIdentifier )
|
||||
{
|
||||
sToken t2;
|
||||
GetToken(&t2);
|
||||
while( t1.type == ttIdentifier && t2.type == ttScope )
|
||||
{
|
||||
GetToken(&t1);
|
||||
GetToken(&t2);
|
||||
}
|
||||
|
||||
RewindTo(&t2);
|
||||
}
|
||||
else if( !IsRealType(t1.type) )
|
||||
{
|
||||
RewindTo(&t);
|
||||
return false;
|
||||
@@ -3201,61 +3314,37 @@ asCScriptNode *asCParser::SuperficiallyParseVarInit()
|
||||
if( t.type == ttAssignment )
|
||||
{
|
||||
GetToken(&t);
|
||||
if( t.type == ttStartStatementBlock )
|
||||
sToken start = t;
|
||||
|
||||
// Find the end of the expression
|
||||
int indentParan = 0;
|
||||
int indentBrace = 0;
|
||||
while( indentParan || indentBrace || (t.type != ttListSeparator && t.type != ttEndStatement && t.type != ttEndStatementBlock) )
|
||||
{
|
||||
sToken start = t;
|
||||
|
||||
// Find the end of the initialization list
|
||||
int indent = 1;
|
||||
while( indent )
|
||||
if( t.type == ttOpenParanthesis )
|
||||
indentParan++;
|
||||
else if( t.type == ttCloseParanthesis )
|
||||
indentParan--;
|
||||
else if( t.type == ttStartStatementBlock )
|
||||
indentBrace++;
|
||||
else if( t.type == ttEndStatementBlock )
|
||||
indentBrace--;
|
||||
else if( t.type == ttNonTerminatedStringConstant )
|
||||
{
|
||||
GetToken(&t);
|
||||
if( t.type == ttStartStatementBlock )
|
||||
indent++;
|
||||
else if( t.type == ttEndStatementBlock )
|
||||
indent--;
|
||||
else if( t.type == ttNonTerminatedStringConstant )
|
||||
{
|
||||
Error(TXT_NONTERMINATED_STRING, &t);
|
||||
break;
|
||||
}
|
||||
else if( t.type == ttEnd )
|
||||
{
|
||||
Error(TXT_UNEXPECTED_END_OF_FILE, &t);
|
||||
Info(TXT_WHILE_PARSING_INIT_LIST, &start);
|
||||
break;
|
||||
}
|
||||
Error(TXT_NONTERMINATED_STRING, &t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sToken start = t;
|
||||
|
||||
// Find the end of the expression
|
||||
int indent = 0;
|
||||
while( indent || (t.type != ttListSeparator && t.type != ttEndStatement && t.type != ttEndStatementBlock) )
|
||||
else if( t.type == ttEnd )
|
||||
{
|
||||
if( t.type == ttOpenParanthesis )
|
||||
indent++;
|
||||
else if( t.type == ttCloseParanthesis )
|
||||
indent--;
|
||||
else if( t.type == ttNonTerminatedStringConstant )
|
||||
{
|
||||
Error(TXT_NONTERMINATED_STRING, &t);
|
||||
break;
|
||||
}
|
||||
else if( t.type == ttEnd )
|
||||
{
|
||||
Error(TXT_UNEXPECTED_END_OF_FILE, &t);
|
||||
Info(TXT_WHILE_PARSING_EXPRESSION, &start);
|
||||
break;
|
||||
}
|
||||
GetToken(&t);
|
||||
Error(TXT_UNEXPECTED_END_OF_FILE, &t);
|
||||
Info(TXT_WHILE_PARSING_EXPRESSION, &start);
|
||||
break;
|
||||
}
|
||||
|
||||
// Rewind so that the next token read is the list separator, end statement, or end statement block
|
||||
RewindTo(&t);
|
||||
GetToken(&t);
|
||||
}
|
||||
|
||||
// Rewind so that the next token read is the list separator, end statement, or end statement block
|
||||
RewindTo(&t);
|
||||
}
|
||||
else if( t.type == ttOpenParanthesis )
|
||||
{
|
||||
@@ -3872,7 +3961,7 @@ asCScriptNode *asCParser::ParseIf()
|
||||
return node;
|
||||
}
|
||||
|
||||
// BNF: FOR ::= 'for' '(' (VAR | EXPRSTAT) EXPRSTAT [ASSIGN] ')' STATEMENT
|
||||
// BNF: FOR ::= 'for' '(' (VAR | EXPRSTAT) EXPRSTAT [ASSIGN {',' ASSIGN}] ')' STATEMENT
|
||||
asCScriptNode *asCParser::ParseFor()
|
||||
{
|
||||
asCScriptNode *node = CreateNode(snFor);
|
||||
@@ -3911,18 +4000,27 @@ asCScriptNode *asCParser::ParseFor()
|
||||
{
|
||||
RewindTo(&t);
|
||||
|
||||
asCScriptNode *n = CreateNode(snExpressionStatement);
|
||||
if( n == 0 ) return 0;
|
||||
node->AddChildLast(n);
|
||||
n->AddChildLast(ParseAssignment());
|
||||
if( isSyntaxError ) return node;
|
||||
|
||||
GetToken(&t);
|
||||
if( t.type != ttCloseParanthesis )
|
||||
// Parse N increment statements separated by ,
|
||||
for(;;)
|
||||
{
|
||||
Error(ExpectedToken(")"), &t);
|
||||
Error(InsteadFound(t), &t);
|
||||
return node;
|
||||
asCScriptNode *n = CreateNode(snExpressionStatement);
|
||||
if( n == 0 ) return 0;
|
||||
node->AddChildLast(n);
|
||||
n->AddChildLast(ParseAssignment());
|
||||
if( isSyntaxError ) return node;
|
||||
|
||||
GetToken(&t);
|
||||
if( t.type == ttListSeparator )
|
||||
continue;
|
||||
else if( t.type == ttCloseParanthesis )
|
||||
break;
|
||||
else
|
||||
{
|
||||
const char *tokens[] = {",", ")"};
|
||||
Error(ExpectedOneOf(tokens, 2), &t);
|
||||
Error(InsteadFound(t), &t);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user