Update angelscript to 2.30.2

This commit is contained in:
Odd0002
2016-02-17 22:07:55 -06:00
parent 1e0586dc40
commit fdd6f36b46
37 changed files with 2406 additions and 978 deletions

View File

@@ -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;
}
}
}