pike.git / src / language.yacc

version» Context lines:

pike.git/src/language.yacc:177:   %left F_LSH F_RSH   %left '+' '-'   %left '*' '%' '/'   %right F_NOT '~'   %nonassoc F_INC F_DEC      %{   /* This is the grammar definition of Pike. */      #include "global.h" - RCSID("$Id: language.yacc,v 1.144 1999/12/14 00:24:36 grubba Exp $"); + RCSID("$Id: language.yacc,v 1.145 1999/12/14 08:38:47 hubbe 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"
pike.git/src/language.yacc:207:   #define YYMAXDEPTH 1000      #ifdef PIKE_DEBUG   #ifndef YYDEBUG   /* May also be defined by machine.h */   #define YYDEBUG 1   #endif /* YYDEBUG */   #endif       - void add_local_name(struct pike_string *,struct pike_string *); + void add_local_name(struct pike_string *,struct pike_string *,node *);   static node *lexical_islocal(struct pike_string *);      static int varargs;   static INT32 current_modifiers;   static struct pike_string *last_identifier=0;         /*    * Kludge for Bison not using prototypes.    */
pike.git/src/language.yacc:369:   %type <n> sscanf   %type <n> statement   %type <n> statements   %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   %%      all: program { YYACCEPT; }    | program F_LEX_EOF { YYACCEPT; }   /* | error F_LEX_EOF { YYABORT; } */    ;      program: program def optional_semi_colon   /* | error { yyerrok; } */    | /* empty */
pike.git/src/language.yacc:788:    MAKE_CONSTANT_SHARED_STRING(s,"");    $3=mkstrnode(s);    free_string(s);    }       if($3->u.sval.u.string->len &&    islocal($3->u.sval.u.string) >= 0)    my_yyerror("Variable '%s' appears twice in argument list.",    $3->u.sval.u.string->str);    -  add_local_name($3->u.sval.u.string, compiler_pop_type()); +  add_local_name($3->u.sval.u.string, compiler_pop_type(),0);    free_node($3);    }    ;      func_args: '(' arguments close_paren_or_missing { $$=$2; }    | error { $$=0; yyerrok; }    ;      arguments: /* empty */ optional_comma { $$=0; }    | arguments2 optional_comma
pike.git/src/language.yacc:1142:    {    free_node($4);    }    ;         new_local_name: optional_stars F_IDENTIFIER    {    push_finished_type($<n>0->u.sval.u.string);    while($1--) push_type(T_ARRAY); -  add_local_name($2->u.sval.u.string, compiler_pop_type()); +  add_local_name($2->u.sval.u.string, compiler_pop_type(),0);    $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($2->u.sval.u.string),0));    free_node($2);    }    | optional_stars bad_identifier { $$=0; }    | optional_stars F_IDENTIFIER '=' expr0    {    push_finished_type($<n>0->u.sval.u.string);    while($1--) push_type(T_ARRAY); -  add_local_name($2->u.sval.u.string, compiler_pop_type()); +  add_local_name($2->u.sval.u.string, compiler_pop_type(),0);    $$=mknode(F_ASSIGN,$4,mklocalnode(islocal($2->u.sval.u.string),0));    free_node($2);    }    | optional_stars bad_identifier '=' expr0    {    free_node($4);    $$=0;    }    | optional_stars F_IDENTIFIER '=' error    {
pike.git/src/language.yacc:1178:    yyerror("Unexpected end of file in local variable definition.");    free_node($2);    /* No yyerok here since we aren't done yet. */    $$=0;    }    ;      new_local_name2: F_IDENTIFIER    {    add_ref($<n>0->u.sval.u.string); -  add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string); +  add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string, 0);    $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($1->u.sval.u.string),0));    free_node($1);    }    | bad_identifier { $$=0; }    | F_IDENTIFIER '=' safe_expr0    {    add_ref($<n>0->u.sval.u.string); -  add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string); +  add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string, 0);    $$=mknode(F_ASSIGN,$3, mklocalnode(islocal($1->u.sval.u.string),0));    free_node($1);    }    | bad_identifier '=' safe_expr0 { $$=$3; }    ;      block:'{'    {    $<number>1=num_used_modules;    $<number>$=compiler_frame->current_number_of_locals;
pike.git/src/language.yacc:1293:    free_string(compiler_frame->current_return_type);    copy_shared_string(compiler_frame->current_return_type,any_type_string);    }    func_args failsafe_block    {    struct pike_string *type;    char buf[40];    int f,e;    struct pike_string *name;    +  debug_malloc_touch($4);    $4=mknode(F_COMMA_EXPR,$4,mknode(F_RETURN,mkintnode(0),0));    type=find_return_type($4);       if(type) {    push_finished_type(type);    free_string(type);    } else    push_type(T_MIXED);       e=$3-1;
pike.git/src/language.yacc:1346:    $$ = mktrampolinenode(f);    } else {    $$ = mkidentifiernode(f);    }    free_string(name);    free_string(type);    pop_compiler_frame();    }    ;    + local_function: F_IDENTIFIER +  { +  push_compiler_frame(1); +  +  debug_malloc_touch(compiler_frame->current_return_type); +  if(compiler_frame->current_return_type) +  free_string(compiler_frame->current_return_type); +  copy_shared_string(compiler_frame->current_return_type,$<n>0->u.sval.u.string); +  } +  func_args failsafe_block +  { +  struct pike_string *type; +  char buf[40]; +  int f,e; +  struct pike_string *name; +  +  $4=mknode(F_COMMA_EXPR,$4,mknode(F_RETURN,mkintnode(0),0)); +  +  push_finished_type(compiler_frame->current_return_type); +  +  e=$3-1; +  if(varargs) +  { +  push_finished_type(compiler_frame->variable[e].type); +  e--; +  varargs=0; +  pop_type_stack(); +  }else{ +  push_type(T_VOID); +  } +  push_type(T_MANY); +  for(; e>=0; e--) +  push_finished_type(compiler_frame->variable[e].type); +  +  push_type(T_FUNCTION); +  +  type=compiler_pop_type(); +  +  sprintf(buf,"__lambda_%ld_%ld", +  (long)new_program->id, +  (long)(local_class_counter++ & 0xffffffff)); /* OSF/1 cc bug. */ +  name=make_shared_string(buf); +  + #ifdef LAMBDA_DEBUG +  fprintf(stderr, "%d: LAMBDA: %s 0x%08lx 0x%08lx\n", +  compiler_pass, buf, (long)new_program->id, local_class_counter-1); + #endif /* LAMBDA_DEBUG */ +  debug_malloc_touch($4); +  f=dooptcode(name, +  $4, +  type, +  ID_PRIVATE | ID_INLINE); +  +  if(compiler_frame->lexical_scope == 2) { +  $$ = mktrampolinenode(f); +  } else { +  $$ = mkidentifiernode(f); +  } +  debug_malloc_touch($$); +  pop_compiler_frame(); +  add_local_name($1->u.sval.u.string, type, copy_node( $$ )); +  free_node($1); +  free_string(name); +  } +  ; +  + local_function2: optional_stars F_IDENTIFIER +  { +  push_compiler_frame(1); +  debug_malloc_touch(compiler_frame->current_return_type); +  +  push_finished_type($<n>0->u.sval.u.string); +  while($1--) push_type(T_ARRAY); +  +  if(compiler_frame->current_return_type) +  free_string(compiler_frame->current_return_type); +  compiler_frame->current_return_type=compiler_pop_type(); +  } +  func_args failsafe_block +  { +  struct pike_string *type; +  char buf[40]; +  int f,e; +  struct pike_string *name; +  +  debug_malloc_touch($5); +  $5=mknode(F_COMMA_EXPR,$5,mknode(F_RETURN,mkintnode(0),0)); +  +  push_finished_type(compiler_frame->current_return_type); +  +  e=$4-1; +  if(varargs) +  { +  push_finished_type(compiler_frame->variable[e].type); +  e--; +  varargs=0; +  pop_type_stack(); +  }else{ +  push_type(T_VOID); +  } +  push_type(T_MANY); +  for(; e>=0; e--) +  push_finished_type(compiler_frame->variable[e].type); +  +  push_type(T_FUNCTION); +  +  type=compiler_pop_type(); +  +  sprintf(buf,"__lambda_%ld_%ld", +  (long)new_program->id, +  (long)(local_class_counter++ & 0xffffffff)); /* OSF/1 cc bug. */ +  name=make_shared_string(buf); +  + #ifdef LAMBDA_DEBUG +  fprintf(stderr, "%d: LAMBDA: %s 0x%08lx 0x%08lx\n", +  compiler_pass, buf, (long)new_program->id, local_class_counter-1); + #endif /* LAMBDA_DEBUG */ +  +  debug_malloc_touch($5); +  f=dooptcode(name, +  $5, +  type, +  ID_PRIVATE | ID_INLINE); +  +  if(compiler_frame->lexical_scope == 2) { +  $$ = mktrampolinenode(f); +  } else { +  $$ = mkidentifiernode(f); +  } +  debug_malloc_touch($$); +  pop_compiler_frame(); +  add_local_name($2->u.sval.u.string, type, copy_node( $$ )); +  free_node($2); +  free_string(name); +  } +  ; +  +    failsafe_program: '{' program end_block    | error { yyerrok; }    | F_LEX_EOF    {    yyerror("End of file where program definition expected.");    }    ;      class: modifiers F_CLASS optional_identifier    {
pike.git/src/language.yacc:1622:    | safe_comma_expr    ;      safe_comma_expr: comma_expr    | error { $$=0; }    ;      comma_expr: comma_expr2    | simple_type2 local_name_list { $$=$2; free_node($1); }    | simple_identifier_type local_name_list2 { $$=$2; free_node($1); } +  | simple_identifier_type local_function { $$=$2; free_node($1); } +  | simple_type2 local_function2 { $$=$2; free_node($1); }    ;         comma_expr2: expr0    | comma_expr2 ',' expr0    {    $$ = mknode(F_COMMA_EXPR,mkcastnode(void_type_string,$1),$3);    }    ;   
pike.git/src/language.yacc:2134:    yyerror("Unexpected end of file.");    }    | F_SSCANF '(' error '}' { $$=0; yyerror("Missing ')'."); }    | F_SSCANF '(' error ';' { $$=0; yyerror("Missing ')'."); }    ;      lvalue: expr4    | '[' low_lvalue_list ']' { $$=mknode(F_ARRAY_LVALUE, $2,0); }    | type6 F_IDENTIFIER    { -  add_local_name($2->u.sval.u.string,compiler_pop_type()); +  add_local_name($2->u.sval.u.string,compiler_pop_type(),0);    $$=mklocalnode(islocal($2->u.sval.u.string),0);    free_node($2);    }    | bad_expr_ident    { $$=mknewintnode(0); }    ;   low_lvalue_list: lvalue lvalue_list { $$=mknode(F_LVALUE_LIST,$1,$2); }    ;      lvalue_list: /* empty */ { $$ = 0; }
pike.git/src/language.yacc:2306:    (void)fprintf(stderr, "NULL:%ld: %s\n",    (long)lex.current_line,    str);    }    fflush(stderr);    }   }      /* argument must be a shared string */   /* Note that this function eats a reference to 'type' */ + /* If def is nonzero, it also eats a ref to def */   void add_local_name(struct pike_string *str, -  struct pike_string *type) +  struct pike_string *type, +  node *def)   { -  +  debug_malloc_touch(def); +  debug_malloc_touch(type); +  debug_malloc_touch(str);    reference_shared_string(str);    if (compiler_frame->current_number_of_locals == MAX_LOCAL)    {    yyerror("Too many local variables.");    }else {   #ifdef PIKE_DEBUG    check_type_string(type);   #endif /* PIKE_DEBUG */    compiler_frame->variable[compiler_frame->current_number_of_locals].type = type;    compiler_frame->variable[compiler_frame->current_number_of_locals].name = str; -  +  compiler_frame->variable[compiler_frame->current_number_of_locals].def = def;    compiler_frame->current_number_of_locals++;    if(compiler_frame->current_number_of_locals >    compiler_frame->max_number_of_locals)    {    compiler_frame->max_number_of_locals=    compiler_frame->current_number_of_locals;    }    }   }   
pike.git/src/language.yacc:2352:    int e,depth=0;    struct compiler_frame *f=compiler_frame;       while(1)    {    for(e=f->current_number_of_locals-1;e>=0;e--)    {    if(f->variable[e].name==str)    {    struct compiler_frame *q=compiler_frame; +  if(f->variable[e].def) +  return copy_node(f->variable[e].def);    while(q!=f)    {    q->lexical_scope=2;    q=q->previous;    }    return mklocalnode(e,depth);    }    }    if(!f->lexical_scope) return 0;    depth++;