+ // New block
+ case TOK_BRACE_OPEN:
+ return Parse_DoCodeBlock(Parser);
+
+ // Empty statement
+ case TOK_SEMICOLON:
+ GetToken(Parser);
+ return NULL;
+
+ // Return from a method
+ case TOK_RWD_RETURN:
+ GetToken(Parser);
+ ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser));
+ break;
+
+ // Break / Continue (end a loop / go to next iteration)
+ case TOK_RWD_CONTINUE:
+ case TOK_RWD_BREAK:
+ {
+ int tok;
+ char *ident = NULL;
+ tok = GetToken(Parser);
+ // Get the number of nesting levels to break
+ if(LookAhead(Parser) == TOK_IDENT)
+ {
+ GetToken(Parser);
+ ident = strndup(Parser->TokenStr, Parser->TokenLen);
+ }
+ // Get the action
+ switch(tok)
+ {
+ case TOK_RWD_BREAK: ret = AST_NewBreakout(Parser, NODETYPE_BREAK, ident); break;
+ case TOK_RWD_CONTINUE: ret = AST_NewBreakout(Parser, NODETYPE_CONTINUE, ident); break;
+ default:
+ SyntaxError(Parser, 1, "BUG Unhandled break/continue (%s)",
+ csaTOKEN_NAMES[tok]);
+ return NULL;
+ }
+ if(ident) free(ident);
+ }
+ break;
+
+ // Control Statements
+ case TOK_RWD_IF:
+ {
+ tAST_Node *cond, *true, *false = NULL;
+ GetToken(Parser); // eat the if
+
+ SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN);
+ cond = Parse_DoExpr0(Parser); // Get condition
+ SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
+ true = Parse_DoCodeBlock(Parser);
+ if( LookAhead(Parser) == TOK_RWD_ELSE ) {
+ GetToken(Parser);
+ false = Parse_DoCodeBlock(Parser);
+ }
+ else
+ false = AST_NewNop(Parser);
+ ret = AST_NewIf(Parser, cond, true, false);
+ }
+ return ret;
+
+ case TOK_RWD_FOR:
+ {
+ char *tag = NULL;
+ tAST_Node *init=NULL, *cond=NULL, *inc=NULL, *code;
+ GetToken(Parser); // Eat 'for'
+
+ #if SUPPORT_BREAK_TAGS
+ if(LookAhead(Parser) == TOK_LT)
+ {
+ GetToken(Parser);
+ SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
+ tag = strndup(Parser->TokenStr, Parser->TokenLen);
+ SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
+ }
+ #endif
+
+ SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN);
+
+ if(LookAhead(Parser) != TOK_SEMICOLON)
+ init = Parse_DoExpr0(Parser);
+
+ SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
+
+ if(LookAhead(Parser) != TOK_SEMICOLON)
+ cond = Parse_DoExpr0(Parser);
+
+ SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
+
+ if(LookAhead(Parser) != TOK_PAREN_CLOSE)
+ inc = Parse_DoExpr0(Parser);
+
+ SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
+
+ code = Parse_DoCodeBlock(Parser);
+ ret = AST_NewLoop(Parser, tag, init, 0, cond, inc, code);
+ if(tag) free(tag);
+ }
+ return ret;
+
+ case TOK_RWD_DO:
+ {
+ const char *tag = "";
+ tAST_Node *code, *cond;
+ GetToken(Parser); // Eat 'do'
+
+ #if SUPPORT_BREAK_TAGS
+ if(LookAhead(Parser) == TOK_LT)
+ {
+ GetToken(Parser);
+ SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
+ tag = strndup(Parser->TokenStr, Parser->TokenLen);
+ SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
+ }
+ #endif
+
+ code = Parse_DoCodeBlock(Parser);
+ SyntaxAssert( Parser, GetToken(Parser), TOK_RWD_WHILE );
+ SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
+ cond = Parse_DoExpr0(Parser);
+ SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
+ ret = AST_NewLoop(Parser, tag, AST_NewNop(Parser), 1, cond, AST_NewNop(Parser), code);
+ }
+ break;
+ case TOK_RWD_WHILE:
+ {
+ const char *tag = "";
+ tAST_Node *code, *cond;
+ GetToken(Parser); // Eat 'while'
+
+ #if SUPPORT_BREAK_TAGS
+ if(LookAhead(Parser) == TOK_LT)
+ {
+ GetToken(Parser);
+ SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
+ tag = strndup(Parser->TokenStr, Parser->TokenLen);
+ SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
+ }
+ #endif
+
+ SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
+ cond = Parse_DoExpr0(Parser);
+ SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
+ code = Parse_DoCodeBlock(Parser);
+ ret = AST_NewLoop(Parser, tag, AST_NewNop(Parser), 0, cond, AST_NewNop(Parser), code);
+ }
+ return ret;
+
+ // Define Variables
+ case TOKEN_GROUP_TYPES:
+ {
+ int type;
+ GetToken(Parser);
+ TOKEN_GET_DATATYPE(type, Parser->Token);
+
+ SyntaxAssert(Parser, GetToken(Parser), TOK_VARIABLE);
+
+ ret = Parse_GetVarDef(Parser, type);
+ }
+ break;
+
+ // Default
+ default:
+ //printf("exp0\n");
+ ret = Parse_DoExpr0(Parser);
+ break;