pike.git / src / lex.c

version» Context lines:

pike.git/src/lex.c:1:   /*\ - ||| This file a part of uLPC, and is copyright by Fredrik Hubinette - ||| uLPC is distributed as GPL (General Public License) + ||| This file a part of Pike, and is copyright by Fredrik Hubinette + ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   #include "global.h"   #include "language.h"   #include "array.h"   #include "lex.h"   #include "stralloc.h"   #include "dynamic_buffer.h" - #include "add_efun.h" + #include "constants.h"   #include "hashtable.h"   #include "stuff.h"   #include "memory.h"   #include "interpret.h"   #include "error.h"   #include "object.h"   #include "las.h"   #include "operators.h"   #include "opcodes.h" - #include "builtin_efuns.h" + #include "builtin_functions.h" + #include "main.h"      #include "macros.h"   #include <sys/param.h>   #include <ctype.h>   #include <math.h>   #include <fcntl.h>   #include <errno.h> - #ifdef HAVE_TIME_H - #include <time.h> - #endif + #include "time_stuff.h"      #define LEXDEBUG 0 - #define EXPANDMAX 50000 + #define EXPANDMAX 500000    - struct lpc_string *current_file; + struct pike_string *current_file;      INT32 current_line;   INT32 old_line;   INT32 total_lines;   INT32 nexpands;   int pragma_all_inline; /* inline all possible inlines */    - struct lpc_predef_s + struct pike_predef_s   {    char *name;    char *value; -  struct lpc_predef_s *next; +  struct pike_predef_s *next;   };    - struct lpc_predef_s *lpc_predefs=0; + struct pike_predef_s *pike_predefs=0;      static int calc();   static void calc1();      void exit_lex()   { -  + #ifdef DEBUG +  if(p_flag > 2) +  { +  int e; +  fprintf(stderr,"Opcode usage: (opcode, runned, compiled)\n"); +  for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++) +  { +  fprintf(stderr,":: %-20s %8ld %8ld\n", +  low_get_f_name(e+F_OFFSET,0), +  (long)instrs[e].runs, +  (long)instrs[e].compiles); +  } +  } + #endif +  +     while(local_variables)    {    int e;    struct locals *l;    for(e=0;e<local_variables->current_number_of_locals;e++)    {    free_string(local_variables->variable[e].name);    free_string(local_variables->variable[e].type);    }    if(local_variables->current_type)
pike.git/src/lex.c:81:   struct keyword reserved_words[] =   {   { "array", F_ARRAY_ID, },   { "break", F_BREAK, },   { "case", F_CASE, },   { "catch", F_CATCH, },   { "class", F_CLASS, },   { "continue", F_CONTINUE, },   { "default", F_DEFAULT, },   { "do", F_DO, }, - { "efun", F_EFUN, }, + { "predef", F_PREDEF, },   { "else", F_ELSE, },   { "float", F_FLOAT_ID, },   { "for", F_FOR, },   { "foreach", F_FOREACH, },   { "function", F_FUNCTION_ID, },   { "gauge", F_GAUGE, },   { "if", F_IF, },   { "inherit", F_INHERIT, },   { "inline", F_INLINE, },   { "int", F_INT_ID, },   { "lambda", F_LAMBDA, }, - { "list", F_LIST_ID, }, + { "multiset", F_MULTISET_ID, },   { "mapping", F_MAPPING_ID, },   { "mixed", F_MIXED_ID, },   { "nomask", F_NO_MASK, },   { "object", F_OBJECT_ID, },   { "private", F_PRIVATE, },   { "program", F_PROGRAM_ID, },   { "protected", F_PROTECTED, },   { "public", F_PUBLIC, },   { "return", F_RETURN, },   { "sscanf", F_SSCANF, },   { "static", F_STATIC, },   { "string", F_STRING_ID, },   { "switch", F_SWITCH, }, -  + { "typeof", F_TYPEOF, },   { "varargs", F_VARARGS, },   { "void", F_VOID_ID, },   { "while", F_WHILE, },   };      struct keyword instr_names[]=   {   { "!", F_NOT },   { "!=", F_NE },   { "%", F_MOD },
pike.git/src/lex.c:189:   { "do-while", F_DO },   { "dumb return", F_DUMB_RETURN },   { "float number", F_FLOAT },   { "for", F_FOR },   { "foreach", F_FOREACH },   { "global", F_GLOBAL },   { "index", F_INDEX },   { "indirect", F_INDIRECT },   { "jump", F_BRANCH },   { "local function call",F_CALL_LFUN }, + { "local function call and pop",F_CALL_LFUN_AND_POP },   { "local function", F_LFUN },   { "local", F_LOCAL },   { "ltosval2", F_LTOSVAL2 },   { "lvalue to svalue", F_LTOSVAL },   { "lvalue_list", F_LVALUE_LIST },   { "mark", F_MARK }, -  + { "mark mark", F_MARK2 },   { "negative number", F_NEG_NUMBER },   { "number", F_NUMBER },   { "pop", F_POP_VALUE },   { "pop_n_elems", F_POP_N_ELEMS },   { "push 0", F_CONST0 },   { "push 1", F_CONST1 }, -  + { "push 0x7fffffff", F_BIGNUM },   { "range", F_RANGE },   { "return", F_RETURN },   { "return 0", F_RETURN_0 },   { "sscanf", F_SSCANF },   { "string", F_STRING },   { "switch", F_SWITCH },   { "unary minus", F_NEGATE },   { "while", F_WHILE },   { "x++ and pop", F_INC_AND_POP },   { "x++", F_POST_INC },   { "x-- and pop", F_DEC_AND_POP },   { "x--", F_POST_DEC },   { "|", F_OR },   { "|=", F_OR_EQ },   { "||", F_LOR },   { "~", F_COMPL }, -  + { "label", F_LABEL }, + { "data", F_POINTER }, + { "align", F_ALIGN }, + { "call", F_APPLY }, + { "clear local", F_CLEAR_LOCAL }, + { "++local", F_INC_LOCAL }, + { "++local and pop", F_INC_LOCAL_AND_POP }, + { "local++", F_POST_INC_LOCAL }, + { "--local", F_DEC_LOCAL }, + { "--local and pop", F_DEC_LOCAL_AND_POP }, + { "local--", F_POST_DEC_LOCAL }, + { "branch if <", F_BRANCH_WHEN_LT }, + { "branch if >", F_BRANCH_WHEN_GT }, + { "branch if <=", F_BRANCH_WHEN_LE }, + { "branch if >=", F_BRANCH_WHEN_GE }, + { "branch if ==", F_BRANCH_WHEN_EQ }, + { "branch if !=", F_BRANCH_WHEN_NE }, + { "sizeof", F_SIZEOF }, + { "sizeof local", F_SIZEOF_LOCAL }, + { "throw(0)", F_THROW_ZERO }, + { "string index", F_STRING_INDEX }, + { "local index", F_LOCAL_INDEX }, + { "int index", F_POS_INT_INDEX }, + { "-int index", F_NEG_INT_INDEX },   };      struct instr instrs[F_MAX_INSTR - F_OFFSET];      struct reserved   {    struct hash_entry link;    int token;   };   
pike.git/src/lex.c:320:    if (n<F_MAX_INSTR && instrs[n-F_OFFSET].name)    {    return instrs[n-F_OFFSET].name;    }else{    sprintf(buf, "<OTHER %d>", n);    return buf;    }   }      /* foo must be a shared string */ - static int lookup_resword(struct lpc_string *s) + static int lookup_resword(struct pike_string *s)   {    struct hash_entry *h;    h=hash_lookup(reswords, s);    if(!h) return -1;    return BASEOF(h, reserved, link)->token;   }            /*** input routines ***/
pike.git/src/lex.c:659:    void (*magic)();    int args;    struct array *parts;   };      struct hash_table *defines = 0;      #define find_define(N) (defines?BASEOF(hash_lookup(defines, N), define, link):0)      /* argument must be shared string */ - static void undefine(struct lpc_string *name) + static void undefine(struct pike_string *name)   {    struct define *d;       d=find_define(name);       if(!d) return;       defines=hash_unlink(defines, & d->link);    free_string(d->link.s);    free_array(d->parts);    free((char *)d);   }      /* name and as are supposed to be SHARED strings */ - static void add_define(struct lpc_string *name, + static void add_define(struct pike_string *name,    int args,    int parts_on_stack,    void (*magic)())   {    struct define *d;       f_aggregate(parts_on_stack);    if(sp[-1].type != T_ARRAY)    {    yyerror("Define failed for unknown reason.\n");
pike.git/src/lex.c:716:    d->parts=sp[-1].u.array;    sp--;       defines=hash_insert(defines, & d->link);   }      static void simple_add_define(char *name,char *as,void (*magic)())   {    if(magic)    { -  add_define(make_shared_string(name),0,0,magic); +  add_define(make_shared_string(name),-1,0,magic);    }else{    push_string(make_shared_string(as)); -  add_define(make_shared_string(name),0,1,magic); +  add_define(make_shared_string(name),-1,1,magic);    }   }      void free_one_define(struct hash_entry *h)   {    struct define *d;    d=BASEOF(h, define, link);    if(d->parts) free_array(d->parts);    free((void *)d);   }
pike.git/src/lex.c:742:   {    if(defines)    free_hashtable(defines, free_one_define);    defines=0;   }      static void do_define()   {    int c,e,t,argc;    struct svalue *save_sp=sp; -  struct lpc_string *s, *s2; +  struct svalue *args_sp; +  struct pike_string *s, *s2;       SKIPWHITE();    READBUF(isidchar(C));       s=make_shared_string(buf);       if(GOBBLE('('))    {    argc=0;   
pike.git/src/lex.c:773:    READBUF(isidchar(C));    push_string(make_shared_string(buf));    argc++;    }    }    SKIPWHITE();       if(!GOBBLE(')'))    yyerror("Missing ')'");    }else{ -  argc=0; +  argc=-1;    }    -  +  args_sp=sp; +     init_buf();    t=0;    sp->type=T_STRING;    sp->u.string=make_shared_string("");    sp++;       while(1)    { -  +  int tmp; +     c=GETC();    if(c=='\\') if(GOBBLE('\n')) continue;    if( (t!=!!isidchar(c) && argc>0) || c=='\n' || c==MY_EOF)    {    s2=free_buf(); -  +  tmp=0;    for(e=0;e<argc;e++)    {    if(save_sp[e].u.string==s2)    {    free_string(s2);    push_int(e); -  +  tmp=1;    break;    }    } -  if(e==argc) +  if(!tmp)    {    push_string(s2); -  if(sp[-2].type==T_STRING) f_add(); +  if(sp[-2].type==T_STRING) f_add(2);    }    if(c=='\n' || c==MY_EOF)    {    push_string(make_shared_string(" ")); -  if(sp[-2].type==T_STRING) f_add(); +  if(sp[-2].type==T_STRING) f_add(2);    break;    }    t=!!isidchar(c);    init_buf();    }    my_putchar(c);    }    UNGETC(c); -  add_define(s,argc,sp-save_sp-argc,0); +  add_define(s,argc,sp-args_sp,0);    while(sp>save_sp) pop_stack();   }      /* s is a shared string */ - static int expand_define(struct lpc_string *s, int save_newline) + static int expand_define(struct pike_string *s, int save_newline)   {    struct svalue *save_sp=sp;    struct define *d;    int len,e,tmp,args;    d=find_define(s);    if(!d) return 0;       if(nexpands>EXPANDMAX)    {    yyerror("Macro limit exceeded.");    return 0;    }       if(d->magic)    {    d->magic();    return 1;    }    -  +  if(d->args >= 0) +  {    if(!save_newline)    {    SKIPWHITE();    }else{    do { e=GETC(); }while(isspace(e) && e!='\n');    UNGETC(e);    }       if(GOBBLE('('))    {
pike.git/src/lex.c:892:    push_string(free_buf());    if(args==0 && !d->args && !sp[-1].u.string->len)    {    pop_stack();    }else{    args++;    }    }else{    args=0;    } +  } else { +  args=-1; +  }       if(args>d->args)    {    my_yyerror("Too many arguments to macro '%s'.\n",s->str);    while(sp>save_sp) pop_stack();    return 0;    }       if(args<d->args)    {
pike.git/src/lex.c:932:    }    len+=tmp;    }    while(sp>save_sp) pop_stack();    nexpands+=len;    return 1;   }      /*** Handle include ****/    - static void handle_include(char *name) + static void handle_include(char *name, int local_include)   {    int fd;    char buf[400]; -  +  struct pike_string *s;    -  push_string(make_shared_string(name)); +  s=make_shared_string(name); +  push_string(s); +  reference_shared_string(s);    push_string(current_file);    reference_shared_string(current_file); -  +  push_int(local_include);    -  SAFE_APPLY_MASTER("handle_include",2); +  SAFE_APPLY_MASTER("handle_include",3);       if(sp[-1].type != T_STRING)    { -  my_yyerror("Couldn't include file '%s'.",name); +  my_yyerror("Couldn't include file '%s'.",s->str);    return;    } -  +  free_string(s);       retry:    fd=open(sp[-1].u.string->str,O_RDONLY);    if(fd < 0)    {    if(errno == EINTR) goto retry;       my_yyerror("Couldn't open file to include '%s'.",sp[-1].u.string->str);    return;    }
pike.git/src/lex.c:1207:    continue;    }    }else{    if(c!=F_STRING)    {    yyerror("Couldn't find include filename.\n");    SKIPUPTO('\n');    continue;    }    } -  handle_include(buf); +  handle_include(buf, c==F_STRING);    break;    }       if(!strcmp("if",buf))    {    if(!calc()) do_skip(SKIPTO_ELSE);    break;    }       if(!strcmp("ifdef",buf))    { -  struct lpc_string *s; +  struct pike_string *s;    SKIPWHITE();    READBUF(isidchar(C));    s=findstring(buf);    if(!s || !find_define(s)) do_skip(SKIPTO_ELSE);    break;    }       if(!strcmp("ifndef",buf))    { -  struct lpc_string *s; +  struct pike_string *s;    SKIPWHITE();    READBUF(isidchar(C));    s=findstring(buf);    if(s && find_define(s)) do_skip(SKIPTO_ELSE);    break;    }    goto badhash;       case 'e':    if(!strcmp("endif",buf)) break;
pike.git/src/lex.c:1264:    SKIPWHITE();    READBUF(C!='\n');    yyerror(buf);    break;    }    goto badhash;       case 'u':    if(!strcmp("undef",buf))    { -  struct lpc_string *s; +  struct pike_string *s;    SKIPWHITE();    READBUF(isidchar(C));    if((s=findstring(buf))) undefine(s);    break;    }    goto badhash;       case 'd':    if(!strcmp("define",buf))    {
pike.git/src/lex.c:1473:    case '<':    if(GOBBLE('<'))    {    if(GOBBLE('=')) return F_LSH_EQ;    return F_LSH;    }    if(GOBBLE('=')) return F_LE;    return '<';       case '>': -  if(GOBBLE(')')) return F_LIST_END; +  if(GOBBLE(')')) return F_MULTISET_END;    if(GOBBLE('=')) return F_GE;    if(GOBBLE('>'))    {    if(GOBBLE('=')) return F_RSH_EQ;    return F_RSH;    }    return '>';       case '!':    if(GOBBLE('=')) return F_NE;    return F_NOT;       case '(': -  if(GOBBLE('<')) return F_LIST_START; +  if(GOBBLE('<')) return F_MULTISET_START;    return '(';       case '?':    case ',':    case '~':    case '@':    case ')':    case '[':    case ']':    case '{':    case ';':    case '}': return c;    -  +  case '`': +  { +  char *tmp; +  switch(GETC()) +  { +  case '+': tmp="`+"; break; +  case '-': tmp="`-"; break; +  case '/': tmp="`/"; break; +  case '%': tmp="`%"; break; +  case '*': tmp="`*"; break; +  case '&': tmp="`&"; break; +  case '|': tmp="`|"; break; +  case '^': tmp="`^"; break; +  case '~': tmp="`~"; break; +  case '[': +  if(GOBBLE(']')) +  { +  tmp="`[]"; +  if(GOBBLE('=')) tmp="`[]="; +  break; +  } +     default: -  +  yyerror("Illegal ` identifier."); +  tmp=""; +  break; +  +  case '<': +  if(GOBBLE('<')) { tmp="`<<"; break; } +  if(GOBBLE('=')) { tmp="`<="; break; } +  tmp="`<"; +  break; +  +  case '>': +  if(GOBBLE('>')) { tmp="`>>"; break; } +  if(GOBBLE('=')) { tmp="`>="; break; } +  tmp="`>"; +  break; +  +  case '!': +  if(GOBBLE('=')) { tmp="`!="; break; } +  tmp="`!"; +  break; +  +  case '=': +  if(GOBBLE('=')) { tmp="`=="; break; } +  tmp="`="; +  break; +  } +  +  if(literal) +  { +  yylval->str=buf; +  }else{ +  yylval->string=make_shared_string(tmp); +  } +  return F_IDENTIFIER; +  } +  +  +  default:    if(isidchar(c))    { -  struct lpc_string *s; +  struct pike_string *s;    UNGETC(c);    READBUF(isidchar(C));       if(!literal)    {    /* identify identifier, if it is not a shared string,    * then it is neither a define, reserved word, local variable    * or efun, at least not yet.    */   
pike.git/src/lex.c:1563:    return do_lex(0, yylval);   }      static YYSTYPE my_yylval;   static int lookahead;      static void low_lex()   {    while(1)    { -  struct lpc_string *s; +  struct pike_string *s;       lookahead=do_lex(1, &my_yylval);    if(lookahead == F_IDENTIFIER)    {    if(!strcmp("defined",my_yylval.str))    {    SKIPWHITE();    if(!GOBBLE('('))    {    yyerror("Missing '(' in defined.\n");
pike.git/src/lex.c:1592:    s=findstring(buf);       if(s && find_define(s))    UNGETSTR(" 1 ",3);    else    UNGETSTR(" 0 ",3);       continue;    }    -  if(!strcmp("efun",my_yylval.str)) +  if(!strcmp("efun",my_yylval.str) || !strcmp("constant",my_yylval.str))    {    SKIPWHITE();    if(!GOBBLE('('))    { -  yyerror("Missing '(' in #if efun().\n"); +  yyerror("Missing '(' in #if constant().\n");    return;    }    READBUF(isidchar(C));    if(!GOBBLE(')'))    { -  yyerror("Missing ')' in #if efun().\n"); +  yyerror("Missing ')' in #if constant().\n");    return;    }    s=findstring(buf);       if(s && lookup_efun(s))    UNGETSTR(" 1 ",3);    else    UNGETSTR(" 0 ",3);       continue;
pike.git/src/lex.c:1672:    error("Missing ']'\n");    else    low_lex();    }   }      static void calcB()   {    switch(lookahead)    { -  case '-': low_lex(); calcB(); f_negate(); break; -  case F_NOT: low_lex(); calcB(); f_not(); break; -  case '~': low_lex(); calcB(); f_compl(); break; +  case '-': low_lex(); calcB(); o_negate(); break; +  case F_NOT: low_lex(); calcB(); o_not(); break; +  case '~': low_lex(); calcB(); o_compl(); break;    default: calcC();    }   }      static void calcA()   {    calcB();    while(1)    {    switch(lookahead)    { -  case '/': low_lex(); calcB(); f_divide(); continue; -  case '*': low_lex(); calcB(); f_multiply(); continue; -  case '%': low_lex(); calcB(); f_mod(); continue; +  case '/': low_lex(); calcB(); o_divide(); continue; +  case '*': low_lex(); calcB(); o_multiply(); continue; +  case '%': low_lex(); calcB(); o_mod(); continue;    }    break;    }   }      static void calc9()   {    calcA();       while(1)    {    switch(lookahead)    { -  case '+': low_lex(); calcA(); f_add(); continue; -  case '-': low_lex(); calcA(); f_subtract(); continue; +  case '+': low_lex(); calcA(); f_add(2); continue; +  case '-': low_lex(); calcA(); o_subtract(); continue;    }    break;    }   }      static void calc8()   {    calc9();       while(1)    {    switch(lookahead)    { -  case F_LSH: low_lex(); calc9(); f_lsh(); continue; -  case F_RSH: low_lex(); calc9(); f_rsh(); continue; +  case F_LSH: low_lex(); calc9(); o_lsh(); continue; +  case F_RSH: low_lex(); calc9(); o_rsh(); continue;    }    break;    }   }      static void calc7b()   {    calc8();       while(1)    {    switch(lookahead)    { -  case '<': low_lex(); calc8(); f_lt(); continue; -  case '>': low_lex(); calc8(); f_gt(); continue; -  case F_GE: low_lex(); calc8(); f_ge(); continue; -  case F_LE: low_lex(); calc8(); f_le(); continue; +  case '<': low_lex(); calc8(); f_lt(2); continue; +  case '>': low_lex(); calc8(); f_gt(2); continue; +  case F_GE: low_lex(); calc8(); f_ge(2); continue; +  case F_LE: low_lex(); calc8(); f_le(2); continue;    }    break;    }   }      static void calc7()   {    calc7b();       while(1)    {    switch(lookahead)    { -  case F_EQ: low_lex(); calc7b(); f_eq(); continue; -  case F_NE: low_lex(); calc7b(); f_ne(); continue; +  case F_EQ: low_lex(); calc7b(); f_eq(2); continue; +  case F_NE: low_lex(); calc7b(); f_ne(2); continue;    }    break;    }   }      static void calc6()   {    calc7();       while(lookahead=='&')    {    low_lex();    calc7(); -  f_and(); +  o_and();    }   }      static void calc5()   {    calc6();       while(lookahead=='^')    {    low_lex();    calc6(); -  f_xor(); +  o_xor();    }   }      static void calc4()   {    calc5();       while(lookahead=='|')    {    low_lex();    calc5(); -  f_or(); +  o_or();    }   }      static void calc3()   {    calc4();       while(lookahead==F_LAND)    {    low_lex();
pike.git/src/lex.c:1935:    UNGETSTR("\"",1);    UNGETSTR(buf+19, 5);    UNGETSTR(buf+4, 6);    UNGETSTR("\"",1);   }      /*** ***/      static void start_new()   { -  struct lpc_predef_s *tmpf; +  struct pike_predef_s *tmpf;       free_all_defines();    -  simple_add_define("__uLPC__", "1",0); +  simple_add_define("__PIKE__", "1",0);    -  for (tmpf=lpc_predefs; tmpf; tmpf=tmpf->next) +  for (tmpf=pike_predefs; tmpf; tmpf=tmpf->next)    simple_add_define(tmpf->name, tmpf->value,0);       simple_add_define("__LINE__",0,insert_current_line);    simple_add_define("__FILE__",0,insert_current_file_as_string);    simple_add_define("__DATE__",0,insert_current_date_as_string);    simple_add_define("__TIME__",0,insert_current_time_as_string);       free_inputstate(istate);    istate=NULL;    link_inputstate(end_inputstate());    old_line=current_line = 1;    pragma_all_inline=0;    nexpands=0;    if(current_file) free_string(current_file);    current_file=0;   }    - void start_new_file(int fd,struct lpc_string *filename) + void start_new_file(int fd,struct pike_string *filename)   {    start_new();    copy_shared_string(current_file,filename);       link_inputstate(file_inputstate(fd));    UNGETSTR("\n",1);   }    - void start_new_string(char *s,INT32 len,struct lpc_string *name) + void start_new_string(char *s,INT32 len,struct pike_string *name)   {    start_new();    copy_shared_string(current_file,name);    link_inputstate(prot_memory_inputstate(s,len));    UNGETSTR("\n",1);   }      void end_new_file()   {    if(current_file)
pike.git/src/lex.c:1994:    free_inputstate(istate);    istate=NULL;    free_all_defines();    total_lines+=current_line-old_line;   }         void add_predefine(char *s)   {    char buffer1[100],buffer2[10000]; -  struct lpc_predef_s *tmp; +  struct pike_predef_s *tmp;       if(sscanf(s,"%[^=]=%[ -~=]",buffer1,buffer2) ==2)    {    s=buffer1;    }else{    buffer2[0]='1';    buffer2[1]=0;    } -  tmp=ALLOC_STRUCT(lpc_predef_s); +  tmp=ALLOC_STRUCT(pike_predef_s);    tmp->name=(char *)xalloc(strlen(s)+1);    strcpy(tmp->name,s);    tmp->value=(char *)xalloc(strlen(buffer2)+1);    strcpy(tmp->value,buffer2); -  tmp->next=lpc_predefs; -  lpc_predefs=tmp; +  tmp->next=pike_predefs; +  pike_predefs=tmp;   }