Merge pull request #1090 from eightyeight/anon-functions

Anonymous functions in Torquescript
This commit is contained in:
Daniel Buckmaster 2015-01-02 12:50:08 +11:00
commit e446502bbc
7 changed files with 2943 additions and 4107 deletions

View file

@ -456,6 +456,21 @@ expr
{ $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, NULL); } { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, NULL); }
| VAR '[' aidx_expr ']' | VAR '[' aidx_expr ']'
{ $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); } { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); }
| rwDEFINE '(' var_list_decl ')' '{' statement_list '}'
{
const U32 bufLen = 64;
UTF8 buffer[bufLen];
dSprintf(buffer, bufLen, "__anonymous_function%d", gAnonFunctionID++);
StringTableEntry fName = StringTable->insert(buffer);
StmtNode *fndef = FunctionDeclStmtNode::alloc($1.lineNumber, fName, NULL, $3, $6);
if(!gAnonFunctionList)
gAnonFunctionList = fndef;
else
gAnonFunctionList->append(fndef);
$$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fName, false );
}
; ;
slot_acc slot_acc

File diff suppressed because it is too large Load diff

View file

@ -575,6 +575,8 @@ struct FunctionDeclStmtNode : StmtNode
}; };
extern StmtNode *gStatementList; extern StmtNode *gStatementList;
extern ExprEvalState gEvalState;; extern StmtNode *gAnonFunctionList;
extern U32 gAnonFunctionID;
extern ExprEvalState gEvalState;
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,119 +1,20 @@
/* A Bison parser, made by GNU Bison 2.3. */ typedef union {
Token< char > c;
/* Skeleton interface for Bison's Yacc-like parsers in C Token< int > i;
Token< const char* > s;
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Token< char* > str;
Free Software Foundation, Inc. Token< double > f;
StmtNode* stmt;
This program is free software; you can redistribute it and/or modify ExprNode* expr;
it under the terms of the GNU General Public License as published by SlotAssignNode* slist;
the Free Software Foundation; either version 2, or (at your option) VarNode* var;
any later version. SlotDecl slot;
InternalSlotDecl intslot;
This program is distributed in the hope that it will be useful, ObjectBlockDecl odcl;
but WITHOUT ANY WARRANTY; without even the implied warranty of ObjectDeclNode* od;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the AssignDecl asn;
GNU General Public License for more details. IfStmtNode* ifnode;
} YYSTYPE;
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
rwDEFINE = 258,
rwENDDEF = 259,
rwDECLARE = 260,
rwDECLARESINGLETON = 261,
rwBREAK = 262,
rwELSE = 263,
rwCONTINUE = 264,
rwGLOBAL = 265,
rwIF = 266,
rwNIL = 267,
rwRETURN = 268,
rwWHILE = 269,
rwDO = 270,
rwENDIF = 271,
rwENDWHILE = 272,
rwENDFOR = 273,
rwDEFAULT = 274,
rwFOR = 275,
rwFOREACH = 276,
rwFOREACHSTR = 277,
rwIN = 278,
rwDATABLOCK = 279,
rwSWITCH = 280,
rwCASE = 281,
rwSWITCHSTR = 282,
rwCASEOR = 283,
rwPACKAGE = 284,
rwNAMESPACE = 285,
rwCLASS = 286,
rwASSERT = 287,
ILLEGAL_TOKEN = 288,
CHRCONST = 289,
INTCONST = 290,
TTAG = 291,
VAR = 292,
IDENT = 293,
TYPEIDENT = 294,
DOCBLOCK = 295,
STRATOM = 296,
TAGATOM = 297,
FLTCONST = 298,
opINTNAME = 299,
opINTNAMER = 300,
opMINUSMINUS = 301,
opPLUSPLUS = 302,
STMT_SEP = 303,
opSHL = 304,
opSHR = 305,
opPLASN = 306,
opMIASN = 307,
opMLASN = 308,
opDVASN = 309,
opMODASN = 310,
opANDASN = 311,
opXORASN = 312,
opORASN = 313,
opSLASN = 314,
opSRASN = 315,
opCAT = 316,
opEQ = 317,
opNE = 318,
opGE = 319,
opLE = 320,
opAND = 321,
opOR = 322,
opSTREQ = 323,
opCOLONCOLON = 324,
opNTASN = 325,
opNDASN = 326,
opMDASN = 327,
opSTRNE = 328,
UNARY = 329
};
#endif
/* Tokens. */
#define rwDEFINE 258 #define rwDEFINE 258
#define rwENDDEF 259 #define rwENDDEF 259
#define rwDECLARE 260 #define rwDECLARE 260
@ -181,42 +82,11 @@
#define opOR 322 #define opOR 322
#define opSTREQ 323 #define opSTREQ 323
#define opCOLONCOLON 324 #define opCOLONCOLON 324
#define opNTASN 325 #define opMDASN 325
#define opNDASN 326 #define opNDASN 326
#define opMDASN 327 #define opNTASN 327
#define opSTRNE 328 #define opSTRNE 328
#define UNARY 329 #define UNARY 329
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 82 "CMDgram.y"
{
Token< char > c;
Token< int > i;
Token< const char* > s;
Token< char* > str;
Token< double > f;
StmtNode* stmt;
ExprNode* expr;
SlotAssignNode* slist;
VarNode* var;
SlotDecl slot;
InternalSlotDecl intslot;
ObjectBlockDecl odcl;
ObjectDeclNode* od;
AssignDecl asn;
IfStmtNode* ifnode;
}
/* Line 1529 of yacc.c. */
#line 215 "cmdgram.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE CMDlval; extern YYSTYPE CMDlval;

View file

@ -468,6 +468,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
STEtoCode = compileSTEtoCode; STEtoCode = compileSTEtoCode;
gStatementList = NULL; gStatementList = NULL;
gAnonFunctionList = NULL;
// Set up the parser. // Set up the parser.
smCurrentParser = getParserForFile(fileName); smCurrentParser = getParserForFile(fileName);
@ -477,6 +478,17 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
smCurrentParser->setScanBuffer(script, fileName); smCurrentParser->setScanBuffer(script, fileName);
smCurrentParser->restart(NULL); smCurrentParser->restart(NULL);
smCurrentParser->parse(); smCurrentParser->parse();
if (gStatementList)
{
if (gAnonFunctionList)
{
// Prepend anonymous functions to statement list, so they're defined already when
// the statements run.
gAnonFunctionList->append(gStatementList);
gStatementList = gAnonFunctionList;
}
}
if(gSyntaxError) if(gSyntaxError)
{ {
@ -599,6 +611,7 @@ const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inStri
addToCodeList(); addToCodeList();
gStatementList = NULL; gStatementList = NULL;
gAnonFunctionList = NULL;
// Set up the parser. // Set up the parser.
smCurrentParser = getParserForFile(fileName); smCurrentParser = getParserForFile(fileName);
@ -608,6 +621,16 @@ const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inStri
smCurrentParser->setScanBuffer(string, fileName); smCurrentParser->setScanBuffer(string, fileName);
smCurrentParser->restart(NULL); smCurrentParser->restart(NULL);
smCurrentParser->parse(); smCurrentParser->parse();
if (gStatementList)
{
if (gAnonFunctionList)
{
// Prepend anonymous functions to statement list, so they're defined already when
// the statements run.
gAnonFunctionList->append(gStatementList);
gStatementList = gAnonFunctionList;
}
}
if(!gStatementList) if(!gStatementList)
{ {

View file

@ -47,6 +47,8 @@ extern ConsoleValueStack CSTK;
ConsoleDocFragment* ConsoleDocFragment::smFirst; ConsoleDocFragment* ConsoleDocFragment::smFirst;
ExprEvalState gEvalState; ExprEvalState gEvalState;
StmtNode *gStatementList; StmtNode *gStatementList;
StmtNode *gAnonFunctionList;
U32 gAnonFunctionID = 0;
ConsoleConstructor *ConsoleConstructor::first = NULL; ConsoleConstructor *ConsoleConstructor::first = NULL;
bool gWarnUndefinedScriptVariables; bool gWarnUndefinedScriptVariables;