pike.git / src / language.yacc

version» Context lines:

pike.git/src/language.yacc:42:   %token TOK_CASE   %token TOK_CLASS   %token TOK_COLON_COLON   %token TOK_CONTINUE   %token TOK_DEFAULT   %token TOK_DIV_EQ   %token TOK_DO   %token TOK_DOT_DOT   %token TOK_DOT_DOT_DOT   %token TOK_ELSE + %token TOK_ENUM   %token TOK_EXTERN   %token TOK_FLOAT_ID   %token TOK_FOR   %token TOK_FUNCTION_ID   %token TOK_GAUGE   %token TOK_IDENTIFIER   %token TOK_IF   %token TOK_IMPORT   %token TOK_INHERIT   %token TOK_INLINE
pike.git/src/language.yacc:76:   %token TOK_OR_EQ   %token TOK_PRIVATE   %token TOK_PROGRAM_ID   %token TOK_PROTECTED   %token TOK_PREDEF   %token TOK_PUBLIC   %token TOK_RSH_EQ   %token TOK_STATIC   %token TOK_STRING_ID   %token TOK_SUB_EQ + %token TOK_TYPEDEF   %token TOK_TYPEOF   %token TOK_VARIANT   %token TOK_VOID_ID   %token TOK_WHILE   %token TOK_XOR_EQ   %token TOK_OPTIONAL         %right '='   %right '?'
pike.git/src/language.yacc:103:   %left TOK_LSH TOK_RSH   %left '+' '-'   %left '*' '%' '/'   %right TOK_NOT '~'   %nonassoc TOK_INC TOK_DEC      %{   /* This is the grammar definition of Pike. */      #include "global.h" - RCSID("$Id: language.yacc,v 1.223 2001/01/20 01:15:44 grubba Exp $"); + RCSID("$Id: language.yacc,v 1.224 2001/04/02 22:09:35 grubba Exp $");   #ifdef HAVE_MEMORY_H   #include <memory.h>   #endif      #include "interpret.h"   #include "array.h"   #include "object.h"   #include "stralloc.h"   #include "las.h"   #include "interpret.h"   #include "program.h"   #include "pike_types.h"   #include "constants.h"   #include "pike_macros.h"   #include "pike_error.h"   #include "docode.h"   #include "machine.h"   #include "main.h"   #include "opcodes.h" -  + #include "operators.h"      #define YYMAXDEPTH 1000      #ifdef PIKE_DEBUG   #ifndef YYDEBUG   /* May also be defined by machine.h */   #define YYDEBUG 1   #endif /* YYDEBUG */   #endif         int add_local_name(struct pike_string *,struct pike_string *,node *);   int low_add_local_name(struct compiler_frame *,    struct pike_string *,struct pike_string *,node *);   static node *lexical_islocal(struct pike_string *); -  + static void safe_inc_enum(void);    -  +    static int inherit_depth;   static struct program_state *inherit_state = NULL;      /*    * Kludge for Bison not using prototypes.    */   #ifndef __GNUC__   #ifndef __cplusplus   static void __yy_memcpy(char *to, char *from, YY_COUNT_TYPE count);   #endif /* !__cplusplus */
pike.git/src/language.yacc:265:   %type <n> block   %type <n> optional_block   %type <n> failsafe_block   %type <n> close_paren_or_missing   %type <n> block_or_semi   %type <n> break   %type <n> case   %type <n> catch   %type <n> catch_arg   %type <n> class + %type <n> enum   %type <n> safe_comma_expr   %type <n> comma_expr   %type <n> comma_expr2   %type <n> comma_expr_or_maxint   %type <n> comma_expr_or_zero   %type <n> cond   %type <n> continue   %type <n> default   %type <n> do   %type <n> safe_expr0
pike.git/src/language.yacc:319:   %type <n> switch   %type <n> typeof   %type <n> unused   %type <n> unused2   %type <n> while   %type <n> optional_comma_expr   %type <n> low_program_ref   %type <n> local_function   %type <n> local_function2   %type <n> magic_identifier + %type <n> simple_identifier   %%      all: program { YYACCEPT; }    | program TOK_LEX_EOF { YYACCEPT; }   /* | error TOK_LEX_EOF { YYABORT; } */    ;      program: program def    | program ';'    | /* empty */
pike.git/src/language.yacc:856:    }    '(' arguments ')' block_or_semi    {    if ($9) free_node($9);    }    | modifiers type_or_error name_list ';' {}    | inheritance {}    | import {}    | constant {}    | class { free_node($1); } +  | enum { free_node($1); } +  | typedef {}    | error TOK_LEX_EOF    {    reset_type_stack();    yyerror("Missing ';'.");    yyerror("Unexpected end of file");    }    | error ';'    {    reset_type_stack();    yyerrok;
pike.git/src/language.yacc:989:    | TOK_MIXED_ID { $$ = "mixed"; }    | TOK_ARRAY_ID { $$ = "array"; }    | TOK_MAPPING_ID { $$ = "mapping"; }    | TOK_MULTISET_ID { $$ = "multiset"; }    | TOK_OBJECT_ID { $$ = "object"; }    | TOK_FUNCTION_ID { $$ = "function"; }    | TOK_PROGRAM_ID { $$ = "program"; }    | TOK_STRING_ID { $$ = "string"; }    | TOK_FLOAT_ID { $$ = "float"; }    | TOK_INT_ID { $$ = "int"; } +  | TOK_ENUM { $$ = "enum"; } +  | TOK_TYPEDEF { $$ = "typedef"; }    ;      magic_identifiers3:    TOK_IF { $$ = "if"; }    | TOK_DO { $$ = "do"; }    | TOK_FOR { $$ = "for"; }    | TOK_WHILE { $$ = "while"; }    | TOK_ELSE { $$ = "else"; }    | TOK_FOREACH { $$ = "foreach"; }    | TOK_CATCH { $$ = "catch"; }
pike.git/src/language.yacc:1057:    ;      soft_cast: '[' type ']'    {    struct pike_string *s=compiler_pop_type();    $$=mkstrnode(s);    free_string(s);    }    ;    + full_type: type4 +  | full_type '*' +  { +  if (Pike_compiler->compiler_pass == 2) { +  yywarning("The *-syntax in types is obsolete. Use array instead."); +  } +  push_type(T_ARRAY); +  } +  ; +    type6: type | identifier_type ;      type: type '*'    {    if (Pike_compiler->compiler_pass == 2) {    yywarning("The *-syntax in types is obsolete. Use array instead.");    }    push_type(T_ARRAY);    }    | type2
pike.git/src/language.yacc:2266:    free_program(p);    }       $$=mkidentifiernode($<number>4);       free_node($3);    check_tree($$,0);    }    ;    + simple_identifier: TOK_IDENTIFIER +  | bad_identifier { $$ = 0; } +  ; +  + enum_value: /* EMPTY */ +  { +  safe_inc_enum(); +  } +  | '=' safe_expr0 +  { +  pop_stack(); +  +  /* This can be made more lenient in the future */ +  +  /* Ugly hack to make sure that $2 is optimized */ +  { +  int tmp=Pike_compiler->compiler_pass; +  $2=mknode(F_COMMA_EXPR,$2,0); +  Pike_compiler->compiler_pass=tmp; +  } +  +  if(!is_const($2)) +  { +  if(Pike_compiler->compiler_pass==2) +  yyerror("Enum definition is not constant."); +  push_int(0); +  } else { +  if(!Pike_compiler->num_parse_error) +  { +  ptrdiff_t tmp=eval_low($2); +  if(tmp < 1) +  { +  yyerror("Error in enum definition."); +  push_int(0); +  }else{ +  pop_n_elems(DO_NOT_WARN((INT32)(tmp - 1))); +  } +  } else { +  push_int(0); +  } +  } +  if($2) free_node($2); +  } +  ; +  + enum_def: /* EMPTY */ +  | simple_identifier enum_value +  { +  if ($1) { +  add_constant($1->u.sval.u.string, Pike_sp-1, +  Pike_compiler->current_modifiers & ~ID_EXTERN); +  } +  free_node($1); +  /* Update the type. */ +  { +  struct pike_type *current = pop_unfinished_type(); +  struct pike_type *new = get_type_of_svalue(Pike_sp-1); +  struct pike_type *res = or_pike_types(new, current, 1); +  free_type(current); +  free_type(new); +  type_stack_mark(); +  push_finished_type(res); +  } +  } +  ; +  + enum_list: enum_def +  | enum_list ',' enum_def +  ; +  + enum: modifiers TOK_ENUM +  { +  if ((Pike_compiler->current_modifiers & ID_EXTERN) && +  (Pike_compiler->compiler_pass == 1)) { +  yywarning("Extern declared enum."); +  } +  +  push_int(-1); /* Last enum-value. */ +  type_stack_mark(); +  push_type(T_ZERO); /* Joined type so far. */ +  } +  optional_identifier '{' enum_list end_block +  { +  struct pike_type *t = pop_unfinished_type(); +  pop_stack(); +  if ($4) { +  ref_push_type_value(t); +  add_constant($4->u.sval.u.string, Pike_sp-1, +  Pike_compiler->current_modifiers & ~ID_EXTERN); +  pop_stack(); +  free_node($4); +  } +  $$ = mktypenode(t); +  free_type(t); +  } +  ; +  + typedef: modifiers TOK_TYPEDEF full_type simple_identifier ';' +  { +  struct pike_type *t = compiler_pop_type(); +  +  if ((Pike_compiler->current_modifiers & ID_EXTERN) && +  (Pike_compiler->compiler_pass == 1)) { +  yywarning("Extern declared typedef."); +  } +  +  if ($4) { +  ref_push_type_value(t); +  add_constant($4->u.sval.u.string, Pike_sp-1, +  Pike_compiler->current_modifiers & ~ID_EXTERN); +  pop_stack(); +  free_node($4); +  } +  free_type(t); +  } +  ; +    cond: TOK_IF    {    $<number>$=Pike_compiler->compiler_frame->current_number_of_locals;    }    {    /* Trick to store more than one number on compiler stack - Hubbe */    $<number>$=Pike_compiler->compiler_frame->last_block_level;    Pike_compiler->compiler_frame->last_block_level=$<number>2;    }    '(' safe_comma_expr end_cond statement optional_else_part
pike.git/src/language.yacc:2723:      expr4: string    | TOK_NUMBER    | TOK_FLOAT { $$=mkfloatnode((FLOAT_TYPE)$1); }    | catch    | gauge    | typeof    | sscanf    | lambda    | class +  | enum    | idents2    | expr4 '(' expr_list ')' optional_block    {    if($5) $3=mknode(F_ARG_LIST, $3, $5);    $$=mkapplynode($1,$3);    }    | expr4 '(' error ')' { $$=mkapplynode($1, NULL); yyerrok; }    | expr4 '(' error TOK_LEX_EOF    {    yyerror("Missing ')'."); $$=mkapplynode($1, NULL);
pike.git/src/language.yacc:3536:       return mklocalnode(e,depth);    }    }    if(!(f->lexical_scope & SCOPE_LOCAL)) return 0;    depth++;    f=f->previous;    }   }    + static void safe_inc_enum(void) + { +  struct svalue *save_sp = Pike_sp; +  JMP_BUF recovery; +  +  free_svalue(&throw_value); +  throw_value.type = T_INT; +  if (SETJMP(recovery)) { +  yyerror("Bad implicit enum value (failed to add 1)."); +  while(Pike_sp > save_sp) pop_stack(); +  } else { +  push_int(1); +  f_add(2); +  } +  UNSETJMP(recovery); + #ifdef PIKE_DEBUG +  if (Pike_sp != save_sp) { +  fatal("stack thrashed in enum.\n"); +  } + #endif /* PIKE_DEBUG */ + } +    void cleanup_compiler(void)   {   }