Browse Source

Added anomymous functions as in Konrad Kiss's resource.

Daniel Buckmaster 10 years ago
parent
commit
1204b81a78

+ 13 - 0
Engine/source/console/CMDgram.y

@@ -456,6 +456,19 @@ 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 '}'
+      {
+         String fnname = String("__anonymous_function_" + String::ToString(gAnonFunctionID++));
+         StringTableEntry afnName = StringTable->insert(fnname.c_str());
+         StmtNode *fndef = FunctionDeclStmtNode::alloc($1.lineNumber, afnName, NULL, $3, $6);
+
+         if(!gAnonFunctionList)
+            gAnonFunctionList = fndef;
+         else
+            gAnonFunctionList->append(fndef);
+
+         $$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fnname.utf8(), false );
+      }
    ;
    ;
 
 
 slot_acc
 slot_acc

+ 3 - 1
Engine/source/console/ast.h

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

+ 17 - 0
Engine/source/console/codeBlock.cpp

@@ -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,14 @@ 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)
+      {
+         gStatementList->append(gAnonFunctionList);
+      }
+   }
+
 
 
    if(gSyntaxError)
    if(gSyntaxError)
    {
    {
@@ -599,6 +608,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 +618,13 @@ 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)
+      {
+         gStatementList->append(gAnonFunctionList);
+      }
+   }
 
 
    if(!gStatementList)
    if(!gStatementList)
    {
    {

+ 2 - 0
Engine/source/console/console.cpp

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