pike.git / src / language.y

version» Context lines:

pike.git/src/language.y: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.   \*/   %pure_parser      /*    * These values are used by the stack machine, and can not be directly -  * called from LPC. +  * called from Pike.    */   %token F_ADD_256 F_ADD_512 F_ADD_768 F_ADD_1024 F_ADD_256X   %token F_PREFIX_256 F_PREFIX_512 F_PREFIX_768 F_PREFIX_1024   %token F_PREFIX_CHARX256 F_PREFIX_WORDX256 F_PREFIX_24BITX256 - %token F_POP_VALUE F_POP_N_ELEMS F_MARK F_CALL_LFUN + %token F_POP_VALUE F_POP_N_ELEMS F_MARK F_MARK2 + %token F_CALL_LFUN F_CALL_LFUN_AND_POP      %token F_BRANCH F_BRANCH_WHEN_ZERO F_BRANCH_WHEN_NON_ZERO -  + %token F_BRANCH_WHEN_LT F_BRANCH_WHEN_GT + %token F_BRANCH_WHEN_LE F_BRANCH_WHEN_GE + %token F_BRANCH_WHEN_EQ F_BRANCH_WHEN_NE   %token F_INC_LOOP F_DEC_LOOP   %token F_INC_NEQ_LOOP F_DEC_NEQ_LOOP    - %token F_INDEX F_INDIRECT + %token F_INDEX F_INDIRECT F_STRING_INDEX F_LOCAL_INDEX + %token F_POS_INT_INDEX F_NEG_INT_INDEX   %token F_LTOSVAL F_LTOSVAL2   %token F_PUSH_ARRAY   %token F_RANGE F_COPY_VALUE      /*    * Basic value pushing    */   %token F_LFUN F_GLOBAL F_LOCAL   %token F_GLOBAL_LVALUE F_LOCAL_LVALUE -  + %token F_CLEAR_LOCAL   %token F_CONSTANT F_FLOAT F_STRING - %token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 -  + %token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 F_BIGNUM   /* -  * These are the predefined functions that can be accessed from LPC. +  * These are the predefined functions that can be accessed from Pike.    */      %token F_INC F_DEC F_POST_INC F_POST_DEC F_INC_AND_POP F_DEC_AND_POP - %token F_RETURN F_DUMB_RETURN F_RETURN_0 + %token F_INC_LOCAL F_INC_LOCAL_AND_POP F_POST_INC_LOCAL + %token F_DEC_LOCAL F_DEC_LOCAL_AND_POP F_POST_DEC_LOCAL + %token F_RETURN F_DUMB_RETURN F_RETURN_0 F_THROW_ZERO      %token F_ASSIGN F_ASSIGN_AND_POP   %token F_ASSIGN_LOCAL F_ASSIGN_LOCAL_AND_POP   %token F_ASSIGN_GLOBAL F_ASSIGN_GLOBAL_AND_POP   %token F_ADD F_SUBTRACT   %token F_MULTIPLY F_DIVIDE F_MOD      %token F_LT F_GT F_EQ F_GE F_LE F_NE   %token F_NEGATE F_NOT F_COMPL   %token F_AND F_OR F_XOR   %token F_LSH F_RSH   %token F_LAND F_LOR      %token F_SWITCH F_SSCANF F_CATCH   %token F_CAST   %token F_FOREACH    -  + %token F_SIZEOF F_SIZEOF_LOCAL +    /*    * These are token values that needn't have an associated code for the    * compiled file    */      %token F_MAX_OPCODE   %token F_ADD_EQ   %token F_AND_EQ   %token F_APPLY   %token F_ARG_LIST
pike.git/src/language.y:70:   %token F_CASE   %token F_CLASS   %token F_COLON_COLON   %token F_COMMA   %token F_CONTINUE   %token F_DEFAULT   %token F_DIV_EQ   %token F_DO   %token F_DOT_DOT   %token F_DOT_DOT_DOT - %token F_EFUN + %token F_PREDEF   %token F_EFUN_CALL   %token F_ELSE   %token F_FLOAT_ID   %token F_FOR   %token F_FUNCTION_ID   %token F_GAUGE   %token F_IDENTIFIER   %token F_IF   %token F_INHERIT   %token F_INLINE   %token F_INT_ID   %token F_LAMBDA - %token F_LIST_ID - %token F_LIST_END - %token F_LIST_START + %token F_MULTISET_ID + %token F_MULTISET_END + %token F_MULTISET_START   %token F_LOCAL   %token F_LSH_EQ   %token F_LVALUE_LIST   %token F_MAPPING_ID   %token F_MIXED_ID   %token F_MOD_EQ   %token F_MULT_EQ   %token F_NO_MASK   %token F_OBJECT_ID   %token F_OR_EQ   %token F_PRIVATE   %token F_PROGRAM_ID   %token F_PROTECTED   %token F_PUBLIC   %token F_RSH_EQ   %token F_STATIC   %token F_STATUS   %token F_STRING_ID   %token F_SUBSCRIPT   %token F_SUB_EQ -  + %token F_TYPEOF   %token F_VAL_LVAL   %token F_VARARGS   %token F_VOID_ID   %token F_WHILE   %token F_XOR_EQ    -  + %token F_ALIGN + %token F_POINTER + %token F_LABEL +    %token F_MAX_INSTR      %right '='   %right '?'   %left F_LOR   %left F_LAND   %left '|'   %left '^'   %left '&'   %left F_EQ F_NE   %left '>' F_GE '<' F_LE /* nonassoc? */   %left F_LSH F_RSH   %left '+' '-'   %left '*' '%' '/'   %right F_NOT '~'   %nonassoc F_INC F_DEC         %{ - /* This is the grammar definition of LPC. */ + /* This is the grammar definition of Pike. */      #include "global.h"   #ifdef HAVE_MEMORY_H   #include <memory.h>   #endif    - #include <setjmp.h> +    #include "interpret.h"   #include "array.h"   #include "object.h"   #include "stralloc.h"   #include "las.h"   #include "interpret.h"   #include "lex.h"   #include "program.h" - #include "lpc_types.h" - #include "add_efun.h" + #include "pike_types.h" + #include "constants.h"   #include "macros.h"   #include "error.h"   #include "docode.h"      #define YYMAXDEPTH 600      static void push_locals();   static void pop_locals();   void free_all_local_names(); - void add_local_name(struct lpc_string *,struct lpc_string *); + void add_local_name(struct pike_string *,struct pike_string *);      /*    * The names and types of arguments and auto variables.    */   struct locals *local_variables;      static int varargs;   static INT32 current_modifiers;      void fix_comp_stack(int sp)
pike.git/src/language.y:185:    fatal("Compiler stack frame underflow.");    }   }      %}   %union   {    int number;    FLOAT_TYPE fnum;    unsigned int address; /* Address of an instruction */ -  struct lpc_string *string; +  struct pike_string *string;    char *str;    unsigned short type;    struct node_s *n;    struct efun *efun;   }      %type <fnum> F_FLOAT   %type <number> modifiers modifier optional_dot_dot_dot   %type <number> assign F_NUMBER F_LOCAL arguments arguments2   %type <number> optional_stars modifier_list   %type <string> F_IDENTIFIER F_STRING string_constant low_string   %type <string> optional_identifier cast simple_type   %type <string> optional_rename_inherit      %type <number> F_ARRAY_ID F_BREAK F_CASE F_CATCH F_CONTINUE F_DEFAULT F_DO - %type <number> F_EFUN F_ELSE F_FLOAT_ID F_FOR F_FOREACH F_FUNCTION_ID F_GAUGE - %type <number> F_IF F_INHERIT F_INLINE F_INT_ID F_LAMBDA F_LIST_ID F_MAPPING_ID + %type <number> F_PREDEF F_ELSE F_FLOAT_ID F_FOR F_FOREACH F_FUNCTION_ID F_GAUGE + %type <number> F_IF F_INHERIT F_INLINE F_INT_ID F_LAMBDA F_MULTISET_ID F_MAPPING_ID   %type <number> F_MIXED_ID F_NO_MASK F_OBJECT_ID F_PRIVATE F_PROGRAM_ID   %type <number> F_PROTECTED F_PUBLIC F_RETURN F_SSCANF F_STATIC   %type <number> F_STRING_ID F_SWITCH F_VARARGS F_VOID_ID F_WHILE      /* The following symbos return type information */    - %type <n> string expr01 expr00 comma_expr + %type <n> string expr01 expr00 comma_expr comma_expr_or_zero   %type <n> expr2 expr1 expr3 expr0 expr4 catch lvalue_list   %type <n> lambda for_expr block assoc_pair new_local_name   %type <n> expr_list2 m_expr_list m_expr_list2 statement gauge sscanf   %type <n> for do cond optional_else_part while statements - %type <n> local_name_list class catch_arg + %type <n> local_name_list class catch_arg comma_expr_or_maxint   %type <n> unused2 foreach unused switch case return expr_list default - %type <n> continue break block_or_semi + %type <n> continue break block_or_semi typeof   %%      all: program;      program: program def optional_semi_colon    | /* empty */ ;      optional_semi_colon: /* empty */    | ';' { yyerror("Extra ';'. Ignored."); };      string_constant: low_string    | string_constant '+' low_string    {    $$=add_shared_strings($1,$3);    free_string($1);    free_string($3);    }    ;    - optional_rename_inherit: ':' F_IDENTIFIER { $$=$2 } + optional_rename_inherit: ':' F_IDENTIFIER { $$=$2; }    | { $$=0; }    ;      inheritance: modifiers F_INHERIT string_constant optional_rename_inherit ';'    {    simple_do_inherit($3,$1,$4);    };      block_or_semi: block { $$ = mknode(F_ARG_LIST,$1,mknode(F_RETURN,mkintnode(0),0)); }    | ';' { $$ = NULL;}
pike.git/src/language.y:302:    push_type(T_VOID);    push_type(T_OR);    }    }    push_type(T_FUNCTION);       $<string>$=pop_type();    define_function($4,    $<string>$,    $1, -  IDENTIFIER_LPC_FUNCTION, +  IDENTIFIER_PIKE_FUNCTION,    0);    }    block_or_semi    {    int e;    if($9)    {    union idptr tmp;    int args, vargs;    for(e=0; e<$6; e++)
pike.git/src/language.y:337:    }else{    vargs=0;    }    ins_byte(local_variables->max_number_of_locals, A_PROGRAM);    ins_byte(args, A_PROGRAM);    dooptcode($4, $9, $6);       define_function($4,    $<string>8,    $1, -  IDENTIFIER_LPC_FUNCTION | vargs, +  IDENTIFIER_PIKE_FUNCTION | vargs,    &tmp);    }    if(local_variables->current_return_type)    {    free_string(local_variables->current_return_type);    local_variables->current_return_type=0;    }    free_all_local_names();    free_string($4);    free_string($<string>8);
pike.git/src/language.y:397:   arguments2: new_arg_name { $$ = 1; }    | arguments2 ',' new_arg_name { $$ = $1 + 1; }    ;      modifier: F_NO_MASK { $$ = ID_NOMASK; }    | F_STATIC { $$ = ID_STATIC; }    | F_PRIVATE { $$ = ID_PRIVATE; }    | F_PUBLIC { $$ = ID_PUBLIC; }    | F_VARARGS { $$ = ID_VARARGS; }    | F_PROTECTED { $$ = ID_PROTECTED; } -  | F_INLINE { $$ = ID_INLINE; } +  | F_INLINE { $$ = ID_INLINE | ID_NOMASK; }    ;      modifiers: modifier_list { $$=current_modifiers=$1; }      modifier_list: /* empty */ { $$ = 0; }    | modifier modifier_list    {    $$ = $1 | $2;    }    ;
pike.git/src/language.y:434:      type3: F_INT_ID { push_type(T_INT); }    | F_FLOAT_ID { push_type(T_FLOAT); }    | F_STRING_ID { push_type(T_STRING); }    | F_OBJECT_ID { push_type(T_OBJECT); }    | F_PROGRAM_ID { push_type(T_PROGRAM); }    | F_VOID_ID { push_type(T_VOID); }    | F_MIXED_ID { push_type(T_MIXED); }    | F_MAPPING_ID opt_mapping_type { push_type(T_MAPPING); }    | F_ARRAY_ID opt_array_type { push_type(T_ARRAY); } -  | F_LIST_ID opt_array_type { push_type(T_LIST); } +  | F_MULTISET_ID opt_array_type { push_type(T_MULTISET); }    | F_FUNCTION_ID opt_function_type { push_type(T_FUNCTION); }    ;      opt_function_type: '('    {    type_stack_mark();    type_stack_mark();    }    function_type_list    optional_dot_dot_dot
pike.git/src/language.y:515:    }    ;            name_list: new_name    | name_list ',' new_name;      new_name: optional_stars F_IDENTIFIER    { -  struct lpc_string *type; +  struct pike_string *type;    push_finished_type(local_variables->current_type);    while($1--) push_type(T_ARRAY);    type=pop_type();    define_variable($2, type, current_modifiers);    free_string(type);    free_string($2);    }    | optional_stars F_IDENTIFIER '='    { -  struct lpc_string *type; +  struct pike_string *type;    push_finished_type(local_variables->current_type);    while($1--) push_type(T_ARRAY);    type=pop_type();    $<number>$=define_variable($2, type, current_modifiers);    free_string(type);    }    expr0    {    init_node=mknode(F_ARG_LIST,init_node,    mkcastnode(void_type_string, mknode(F_ASSIGN,$5,mkidentifiernode($<number>4))));
pike.git/src/language.y:608:    | cond    | while    | do    | for    | switch    | case    | default    | return ';'    | block {}    | foreach -  | break -  | continue +  | break ';' +  | continue ';'    | error ';' { $$=0; }    | ';' { $$=0; }    ;         break: F_BREAK { $$=mknode(F_BREAK,0,0); } ;   default: F_DEFAULT ':' { $$=mknode(F_DEFAULT,0,0); } ;   continue: F_CONTINUE { $$=mknode(F_CONTINUE,0,0); } ;      lambda: F_LAMBDA    {    push_locals();    $<number>$=comp_stackp;       if(local_variables->current_return_type)    free_string(local_variables->current_return_type);    copy_shared_string(local_variables->current_return_type,any_type_string);    }    '(' arguments ')' block    { -  struct lpc_string *type; +  struct pike_string *type;    char buf[40];    int f,e,args,vargs;    union idptr func; -  struct lpc_string *name; +  struct pike_string *name;       setup_fake_program();    fix_comp_stack($<number>2);       push_type(T_MIXED);       e=$4-1;    if(varargs)    {    push_finished_type(local_variables->variable[e].type);
pike.git/src/language.y:678:    ins_byte(local_variables->max_number_of_locals, A_PROGRAM);    ins_byte(args, A_PROGRAM);       sprintf(buf,"__lambda_%ld",    (long)fake_program.num_identifier_references);    name=make_shared_string(buf);    dooptcode(name,mknode(F_ARG_LIST,$6,mknode(F_RETURN,mkintnode(0),0)),$4);    f=define_function(name,    type,    0, -  IDENTIFIER_LPC_FUNCTION | vargs, +  IDENTIFIER_PIKE_FUNCTION | vargs,    &func);    free_string(name);    free_string(type);    pop_locals();    $$=mkidentifiernode(f);    } ;      class: F_CLASS '{'    {    start_new_program();
pike.git/src/language.y:872:    ;      assoc_pair: expr0 ':' expr1    {    $$=mknode(F_ARG_LIST,$1,$3);    } ;      expr1: expr2    | expr1 F_LOR expr1 { $$=mknode(F_LOR,$1,$3); }    | expr1 F_LAND expr1 { $$=mknode(F_LAND,$1,$3); } -  | expr1 '|' expr1 { $$=mknode(F_OR,$1,$3); } -  | expr1 '^' expr1 { $$=mknode(F_XOR,$1,$3); } -  | expr1 '&' expr1 { $$=mknode(F_AND,$1,$3); } -  | expr1 F_EQ expr1 { $$=mknode(F_EQ,$1,$3); } -  | expr1 F_NE expr1 { $$=mknode(F_NE,$1,$3); } -  | expr1 '>' expr1 { $$=mknode(F_GT,$1,$3); } -  | expr1 F_GE expr1 { $$=mknode(F_GE,$1,$3); } -  | expr1 '<' expr1 { $$=mknode(F_LT,$1,$3); } -  | expr1 F_LE expr1 { $$=mknode(F_LE,$1,$3); } -  | expr1 F_LSH expr1 { $$=mknode(F_LSH,$1,$3); } -  | expr1 F_RSH expr1 { $$=mknode(F_RSH,$1,$3); } -  | expr1 '+' expr1 { $$=mknode(F_ADD,$1,$3); } -  | expr1 '-' expr1 { $$=mknode(F_SUBTRACT,$1,$3); } -  | expr1 '*' expr1 { $$=mknode(F_MULTIPLY,$1,$3); } -  | expr1 '%' expr1 { $$=mknode(F_MOD,$1,$3); } -  | expr1 '/' expr1 { $$=mknode(F_DIVIDE,$1,$3); } +  | expr1 '|' expr1 { $$=mkopernode("`|",$1,$3); } +  | expr1 '^' expr1 { $$=mkopernode("`^",$1,$3); } +  | expr1 '&' expr1 { $$=mkopernode("`&",$1,$3); } +  | expr1 F_EQ expr1 { $$=mkopernode("`==",$1,$3); } +  | expr1 F_NE expr1 { $$=mkopernode("`!=",$1,$3); } +  | expr1 '>' expr1 { $$=mkopernode("`>",$1,$3); } +  | expr1 F_GE expr1 { $$=mkopernode("`>=",$1,$3); } +  | expr1 '<' expr1 { $$=mkopernode("`<",$1,$3); } +  | expr1 F_LE expr1 { $$=mkopernode("`<=",$1,$3); } +  | expr1 F_LSH expr1 { $$=mkopernode("`<<",$1,$3); } +  | expr1 F_RSH expr1 { $$=mkopernode("`>>",$1,$3); } +  | expr1 '+' expr1 { $$=mkopernode("`+",$1,$3); } +  | expr1 '-' expr1 { $$=mkopernode("`-",$1,$3); } +  | expr1 '*' expr1 { $$=mkopernode("`*",$1,$3); } +  | expr1 '%' expr1 { $$=mkopernode("`%",$1,$3); } +  | expr1 '/' expr1 { $$=mkopernode("`/",$1,$3); }    ;      expr2: expr3    | cast expr2    {    $$=mkcastnode($1,$2);    free_string($1);    }    | F_INC expr4 { $$=mknode(F_INC,$2,0); }    | F_DEC expr4 { $$=mknode(F_DEC,$2,0); } -  | F_NOT expr2 { $$=mknode(F_NOT,$2,0); } -  | '~' expr2 { $$=mknode(F_COMPL,$2,0); } -  | '-' expr2 { $$=mknode(F_NEGATE,$2,0); } +  | F_NOT expr2 { $$=mkopernode("`!",$2,0); } +  | '~' expr2 { $$=mkopernode("`~",$2,0); } +  | '-' expr2 { $$=mkopernode("`-",$2,0); }    ;      expr3: expr4    | expr4 F_INC { $$=mknode(F_POST_INC,$1,0); }    | expr4 F_DEC { $$=mknode(F_POST_DEC,$1,0); }    ;      expr4: string    | F_NUMBER { $$=mkintnode($1); }    | F_FLOAT { $$=mkfloatnode($1); }    | catch    | gauge -  +  | typeof    | sscanf    | lambda    | class    | F_IDENTIFIER    {    int i;    struct efun *f;    if((i=islocal($1))>=0)    {    $$=mklocalnode(i);    }else if((i=isidentifier($1))>=0){    $$=mkidentifiernode(i);    }else if((f=lookup_efun($1))){    $$=mkconstantsvaluenode(&f->function);    }else{    my_yyerror("'%s' undefined.",$1->str);    $$=0;    }    free_string($1);    } -  | F_EFUN F_COLON_COLON F_IDENTIFIER +  | F_PREDEF F_COLON_COLON F_IDENTIFIER    {    struct efun *f;    f=lookup_efun($3);    if(!f)    {    my_yyerror("Unknown efun: %s.",$3->str);    $$=mkintnode(0);    }else{    $$=mksvaluenode(&f->function);    }    free_string($3);    }    | expr4 '(' expr_list ')' { $$=mkapplynode($1,$3); }    | expr4 '[' expr0 ']' { $$=mknode(F_INDEX,$1,$3); } -  | expr4 '[' comma_expr F_DOT_DOT comma_expr ']' +  | expr4 '[' comma_expr_or_zero F_DOT_DOT comma_expr_or_maxint ']'    {    $$=mknode(F_RANGE,$1,mknode(F_ARG_LIST,$3,$5));    }    | '(' comma_expr ')' { $$=$2; }    | '(' '{' expr_list '}' ')'    { $$=mkefuncallnode("aggregate",$3); }    | '(' '[' m_expr_list ']' ')'    { $$=mkefuncallnode("aggregate_mapping",$3); }; -  | F_LIST_START expr_list F_LIST_END -  { $$=mkefuncallnode("aggregate_list",$2); } +  | F_MULTISET_START expr_list F_MULTISET_END +  { $$=mkefuncallnode("aggregate_multiset",$2); }    | expr4 F_ARROW F_IDENTIFIER    {    $$=mknode(F_INDEX,$1,mkstrnode($3));    free_string($3);    }    | F_IDENTIFIER F_COLON_COLON F_IDENTIFIER    {    int f;    struct reference *idp;   
pike.git/src/language.y:1011:    if(!$$)    {    $$=mkintnode(0);    }else{    if($$->token==F_ARG_LIST) $$=mkefuncallnode("aggregate",$$);    }    free_string($2);    }    ;    - gauge: F_GAUGE '(' unused ')' + comma_expr_or_zero: /* empty */ { $$=mkintnode(0); } +  | comma_expr +  ; +  + comma_expr_or_maxint: /* empty */ { $$=mkintnode(0x7fffffff); } +  | comma_expr +  ; +  + gauge: F_GAUGE catch_arg    { -  $$=mknode(F_NEGATE, -  mknode(F_SUBTRACT, +  $$=mkopernode("`-", +  mkopernode("`-",    mknode(F_INDEX,mkefuncallnode("rusage",0),    mkintnode(GAUGE_RUSAGE_INDEX)), -  mknode(F_ARG_LIST,$3, +  mknode(F_ARG_LIST,$2,    mknode(F_INDEX,mkefuncallnode("rusage",0),    mkintnode(GAUGE_RUSAGE_INDEX)))),0);    } ;    -  + typeof: F_TYPEOF '(' expr0 ')' +  { +  node *tmp; +  tmp=mknode(F_ARG_LIST,$3,0); +  $$=mkstrnode(describe_type($3->type)); +  free_node(tmp); +  } ;    - catch_arg: '(' unused ')' { $$=$2; } + catch_arg: '(' comma_expr ')' { $$=$2; }    | block    ;      catch: F_CATCH catch_arg    {    $$=mknode(F_CATCH,$2,NULL);    } ;      sscanf: F_SSCANF '(' expr0 ',' expr0 lvalue_list ')'    {
pike.git/src/language.y:1092:    }else{    (void)fprintf(stderr, "%s:%ld: %s\n",    current_file->str,    (long)current_line,    str);    fflush(stderr);    }   }      /* argument must be a shared string (no need to free it) */ - void add_local_name(struct lpc_string *str, -  struct lpc_string *type) + void add_local_name(struct pike_string *str, +  struct pike_string *type)   {    if (local_variables->current_number_of_locals == MAX_LOCAL)    {    yyerror("Too many local variables");    }else {    local_variables->variable[local_variables->current_number_of_locals].type = type;    local_variables->variable[local_variables->current_number_of_locals].name = str;    local_variables->current_number_of_locals++;    if(local_variables->current_number_of_locals >    local_variables->max_number_of_locals)    {    local_variables->max_number_of_locals=    local_variables->current_number_of_locals;    }    }   }      /* argument must be a shared string */ - int islocal(struct lpc_string *str) + int islocal(struct pike_string *str)   {    int e;    for(e=local_variables->current_number_of_locals-1;e>=0;e--)    if(local_variables->variable[e].name==str)    return e;    return -1;   }      void free_all_local_names()   {