2828
2929#define TOKEN_CONST_KW 15 + MAX_TOKEN_LIMIT
3030
31- #define END 16 + MAX_TOKEN_LIMIT
31+ #define TOKEN_BEGIN_GROUP 16 + MAX_TOKEN_LIMIT
32+ #define TOKEN_END_GROUP 17 + MAX_TOKEN_LIMIT
33+
34+ #define END 18 + MAX_TOKEN_LIMIT
3235
3336// throws an exception if the token type doesn't match the expected type
3437inline void match_tok (token* token, unsigned char type) {
@@ -49,7 +52,7 @@ inline function_call_token* print_encapsulate(token* token) {
4952 }
5053 std::list<class token *> args;
5154 args.push_back (token);
52- return new function_call_token (new identifier_token (new char [ 0 ], 275790354 ), args);
55+ return new function_call_token (new identifier_token (" print " ), args);
5356}
5457
5558lexer::lexer (const char * source, unsigned long source_length, std::map<unsigned long , value*>* constants) {
@@ -135,6 +138,10 @@ token* lexer::read_token() {
135138 return last_tok = new token (TOKEN_INCLUDE);
136139 case 264645514 : // break
137140 return last_tok = new token (TOKEN_BREAK);
141+ case 271304754 :
142+ return last_tok = new token (TOKEN_BEGIN_GROUP);
143+ case 303295209 :
144+ return last_tok = new token (TOKEN_END_GROUP);
138145 default : {
139146 if (constants->count (hash)) {
140147 delete[] id_buf;
@@ -311,6 +318,26 @@ std::list<token*> lexer::tokenize(bool interactive_mode) {
311318token* lexer::tokenize_statement (bool interactive_mode) {
312319 switch (last_tok->type )
313320 {
321+ case TOKEN_BEGIN_GROUP: {
322+ delete last_tok;
323+ match_tok (read_token (), TOKEN_IDENTIFIER);
324+ identifier_token* id = (identifier_token*)last_tok;
325+ id->no_delete ();
326+ group_stack.push_back ((char *)id->get_identifier ());
327+ group_defined_ids.push_back (std::set<unsigned long >());
328+ delete id;
329+ read_token ();
330+ return nullptr ;
331+ }
332+ case TOKEN_END_GROUP:
333+ if (group_stack.empty ()) {
334+ throw ERROR_UNEXPECTED_TOKEN;
335+ }
336+ delete[] group_stack.back ();
337+ group_stack.pop_back ();
338+ group_defined_ids.pop_back ();
339+ read_token ();
340+ return nullptr ;
314341 case TOKEN_CONST_KW: {
315342 delete last_tok;
316343 match_tok (read_token (), TOKEN_IDENTIFIER);
@@ -401,7 +428,7 @@ token* lexer::tokenize_statement(bool interactive_mode) {
401428 case TOKEN_STRUCT_KW: {
402429 delete last_tok;
403430 match_tok (read_token (), TOKEN_IDENTIFIER);
404- identifier_token* proto_id = ( identifier_token*)last_tok;
431+ identifier_token* proto_id = apply_groups (( identifier_token*)last_tok, true ) ;
405432 match_tok (read_token (), TOKEN_OPEN_BRACE);
406433 delete last_tok;
407434 std::list<identifier_token*> properties;
@@ -419,7 +446,7 @@ token* lexer::tokenize_statement(bool interactive_mode) {
419446 case TOKEN_FUNC_KW: {
420447 delete last_tok;
421448 match_tok (read_token (), TOKEN_IDENTIFIER);
422- identifier_token* proto_id = ( identifier_token*)last_tok;
449+ identifier_token* proto_id = apply_groups (( identifier_token*)last_tok, true ) ;
423450 match_tok (read_token (), TOKEN_OPEN_PARAM);
424451 delete last_tok;
425452 std::list<identifier_token*> params;
@@ -507,6 +534,34 @@ variable_access_token* lexer::tokenize_var_access(identifier_token* identifier)
507534 return new variable_access_token (toks);
508535}
509536
537+ identifier_token* lexer::apply_groups (identifier_token* id, bool creating) {
538+ if (group_stack.empty () || (!creating && !group_defined_ids.back ().count (id->id_hash )))
539+ return id;
540+ char * base_id = (char *)id->get_identifier ();
541+ id->no_delete ();
542+ group_defined_ids.back ().insert (id->id_hash );
543+ delete id;
544+
545+ std::list<char > chars;
546+
547+ for (size_t i = 0 ; i < strlen (base_id); i++)
548+ chars.push_back (base_id[i]);
549+
550+ for (auto group_kw = group_stack.rbegin (); group_kw != group_stack.rend (); ++group_kw) {
551+ chars.push_back (' @' );
552+ for (size_t i = 0 ; i < strlen (*group_kw); i++)
553+ chars.push_back ((*group_kw)[i]);
554+ }
555+
556+ char * id_buf = new char [chars.size () + 1 ];
557+ unsigned int i = 0 ;
558+ for (auto it = chars.begin (); it != chars.end (); ++it)
559+ id_buf[i++] = (*it);
560+ id_buf[i] = 0 ;
561+
562+ return new identifier_token (id_buf, insecure_hash (id_buf));
563+ }
564+
510565token* lexer::tokenize_value () {
511566 if (last_tok->type == TOKEN_IDENTIFIER) {
512567 identifier_token* identifier = (identifier_token*)last_tok;
@@ -529,6 +584,7 @@ token* lexer::tokenize_value() {
529584 match_tok (last_tok, TOKEN_CLOSE_PARAM);
530585 delete last_tok;
531586 read_token ();
587+ identifier = apply_groups (identifier, false );
532588 return new function_call_token (identifier, arguments);
533589 }
534590 else
@@ -588,7 +644,7 @@ token* lexer::tokenize_value() {
588644 else if (last_tok->type == TOKEN_NEW_KW) {
589645 delete last_tok;
590646 match_tok (read_token (), TOKEN_IDENTIFIER);
591- create_struct_token* new_struct = new create_struct_token (( identifier_token*)last_tok);
647+ create_struct_token* new_struct = new create_struct_token (apply_groups (( identifier_token*)last_tok, false ) );
592648 read_token ();
593649 return new_struct;
594650 }
0 commit comments