pike.git / src / docode.c

version» Context lines:

pike.git/src/docode.c:1:   /*\   ||| 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" - RCSID("$Id: docode.c,v 1.132 2001/09/24 14:26:52 grubba Exp $"); + RCSID("$Id: docode.c,v 1.133 2001/09/28 00:01:44 hubbe Exp $");   #include "las.h"   #include "program.h"   #include "pike_types.h"   #include "stralloc.h"   #include "interpret.h"   #include "constants.h"   #include "array.h"   #include "pike_macros.h"   #include "pike_error.h"   #include "pike_memory.h"
pike.git/src/docode.c:447:   #endif       emit0(F_MARK);    PUSH_CLEANUP_FRAME(do_pop_mark, 0);    do_docode(args,0);    emit1(F_CALL_LFUN, id);    POP_AND_DONT_CLEANUP;    return 1;   }    + /* +  * FIXME: this can be optimized, but is not really used +  * enough to be worth it yet. +  */ + static void emit_apply_builtin(char *func) + { +  INT32 tmp1; +  struct pike_string *n1=make_shared_string(func); +  node *n=find_module_identifier(n1,0); +  free_string(n1); +  +  switch(n?n->token:0) +  { +  case F_CONSTANT: +  tmp1=store_constant(&n->u.sval, +  n->tree_info & OPT_EXTERNAL_DEPEND, +  n->name); +  if(n->u.sval.type == T_FUNCTION && +  n->u.sval.subtype == FUNCTION_BUILTIN) +  emit1(F_CALL_BUILTIN, DO_NOT_WARN((INT32)tmp1)); +  else +  emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1)); +  break; +  +  default: +  my_yyerror("docode: Failed to make call to %s",func); +  } +  free_node(n); + } +  + static int do_encode_automap_arg_list(node *n, +  INT16 flags) + { +  int stack_depth_save = current_stack_depth; +  if(!n) return 0; +  switch(n->token) +  { +  default: +  return do_docode(n, flags); +  +  case F_ARG_LIST: +  { +  int ret; +  ret=do_encode_automap_arg_list(CAR(n), flags); +  current_stack_depth=stack_depth_save + ret; +  ret+=do_encode_automap_arg_list(CDR(n), flags); +  current_stack_depth=stack_depth_save + ret; +  return ret; +  } +  +  case F_AUTO_MAP_MARKER: +  { +  int depth=0; +  while(n->token == F_AUTO_MAP_MARKER) +  { +  n=CAR(n); +  depth++; +  } +  emit0(F_MARK); +  code_expression(n, 0, "[*]"); +  emit1(F_NUMBER, depth); +  emit_apply_builtin("__builtin.automap_marker"); +  return 1; +  } +  } + } +  +    static int do_docode2(node *n, INT16 flags)   {    ptrdiff_t tmp1,tmp2,tmp3;       if(!n) return 0;       if(flags & DO_LVALUE)    {    switch(n->token)    {
pike.git/src/docode.c:473:    case F_ARRAY_LVALUE:    case F_LVALUE_LIST:    case F_LOCAL:    case F_GLOBAL:    case F_IDENTIFIER:    case F_INDEX:    case F_ARROW:    case F_ARG_LIST:    case F_COMMA_EXPR:    case F_EXTERNAL: +  case F_AUTO_MAP_MARKER:    break;    }    }       if(flags & DO_LVALUE_IF_POSSIBLE)    {    flags|=DO_INDIRECT;    flags &=~DO_LVALUE_IF_POSSIBLE;    }else{    flags &=~DO_INDIRECT;
pike.git/src/docode.c:648:    case F_SUB_EQ:    case F_MULT_EQ:    case F_MOD_EQ:    case F_DIV_EQ:    tmp1=do_docode(CAR(n),DO_LVALUE);   #ifdef PIKE_DEBUG    if(tmp1 != 2)    fatal("HELP! FATAL INTERNAL COMPILER ERROR (7)\n");   #endif    +  +  if(CAR(n)->token == F_AUTO_MAP_MARKER || +  CDR(n)->token == F_AUTO_MAP_MARKER) +  { +  char *opname; +  struct pike_string *opstr; +  node *op; +  +  emit0(F_MARK); +  +  if(CAR(n)->token == F_AUTO_MAP_MARKER) +  { +  int depth=0; +  node *tmp=CAR(n); +  while(tmp->token == F_AUTO_MAP_MARKER) +  { +  depth++; +  tmp=CAR(tmp); +  } +  emit0(F_MARK); +  emit0(F_LTOSVAL); +  emit1(F_NUMBER,depth); +  emit_apply_builtin("__builtin.automap_marker"); +  }else{ +  emit0(F_LTOSVAL); +  } +  +  switch(n->token) +  { +  case F_ADD_EQ: opname="`+"; break; +  case F_AND_EQ: opname="`&"; break; +  case F_OR_EQ: opname="`|"; break; +  case F_XOR_EQ: opname="`^"; break; +  case F_LSH_EQ: opname="`<<"; break; +  case F_RSH_EQ: opname="`>>"; break; +  case F_SUB_EQ: opname="`-"; break; +  case F_MULT_EQ:opname="`*"; break; +  case F_MOD_EQ: opname="`%"; break; +  case F_DIV_EQ: opname="`/"; break; +  default: +  fatal("Really???\n"); +  opname="`make gcc happy"; +  } +  +  opstr=findstring(opname); +  if(!opstr || !(op=find_module_identifier(opstr, 0))) +  { +  my_yyerror("Failed to find operator %s\n",opname); +  do_pop(2); +  return 1; +  } +  +  code_expression(op, 0, "assignment"); +  free_node(op); +  emit0(F_SWAP); +  +  if(CDR(n)->token == F_AUTO_MAP) +  { +  do_encode_automap_arg_list(CDR(n), 0); +  }else{ +  code_expression(CDR(n), 0, "assignment"); +  } +  emit_apply_builtin("__automap__"); +  }else{    if(n->token == F_ADD_EQ && (flags & DO_POP))    {    code_expression(CDR(n), 0, "assignment");    emit0(F_ADD_TO_AND_POP);    return 0;    }    -  if(match_types(CAR(n)->type, array_type_string) || +  if(CAR(n)->token != F_AUTO_MAP && +  (match_types(CAR(n)->type, array_type_string) ||    match_types(CAR(n)->type, string_type_string) ||    match_types(CAR(n)->type, mapping_type_string) || -  match_types(CAR(n)->type, object_type_string)) +  match_types(CAR(n)->type, object_type_string)))    {    code_expression(CDR(n), 0, "assignment");    emit0(F_LTOSVAL2);    }else{    emit0(F_LTOSVAL);    code_expression(CDR(n), 0, "assignment");    }          switch(n->token)
pike.git/src/docode.c:694:    case F_AND_EQ: emit0(F_AND); break;    case F_OR_EQ: emit0(F_OR); break;    case F_XOR_EQ: emit0(F_XOR); break;    case F_LSH_EQ: emit0(F_LSH); break;    case F_RSH_EQ: emit0(F_RSH); break;    case F_SUB_EQ: emit0(F_SUBTRACT); break;    case F_MULT_EQ:emit0(F_MULTIPLY);break;    case F_MOD_EQ: emit0(F_MOD); break;    case F_DIV_EQ: emit0(F_DIVIDE); break;    } +  }       if(flags & DO_POP)    {    emit0(F_ASSIGN_AND_POP);    return 0;    }else{    emit0(F_ASSIGN);    return 1;    }   
pike.git/src/docode.c:1898:    }else{    emit1(F_GLOBAL,n->u.id.number);    }    }    return 1;       case F_VAL_LVAL:    return do_docode(CAR(n),flags) +    do_docode(CDR(n), (INT16)(flags | DO_LVALUE));    +  case F_AUTO_MAP: +  emit0(F_MARK); +  code_expression(CAR(n), 0, "automap function"); +  do_encode_automap_arg_list(CDR(n),0); +  emit_apply_builtin("__automap__"); +  return 1; +  +  case F_AUTO_MAP_MARKER: +  if(flags & DO_LVALUE) return do_docode(CAR(n), flags); +  yyerror("[*] not supported here.\n"); +  emit0(F_CONST0); +  return 1; +     default:    fatal("Infernal compiler error (unknown parse-tree-token %d).\n", n->token);    return 0; /* make gcc happy */    }   }      INT32 do_code_block(node *n)   {    INT32 ret;   #ifdef PIKE_DEBUG