cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
f90e541995-08-17Fredrik Hübinette (Hubbe) #include "global.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) RCSID("$Id: docode.c,v 1.24 1998/01/13 22:56:42 hubbe Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "las.h" #include "program.h" #include "language.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "stralloc.h" #include "interpret.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "array.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "error.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "svalue.h" #include "main.h" #include "lex.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "builtin_functions.h"
7a82f91996-04-13Fredrik Hübinette (Hubbe) #include "peep.h" #include "docode.h"
419fab1997-03-09Fredrik Hübinette (Hubbe) #include "operators.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe) INT32 current_break=-1; INT32 current_continue=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  static INT32 current_switch_case; static INT32 current_switch_default; static INT32 current_switch_values_on_stack; static INT32 *current_switch_jumptable =0;
7a82f91996-04-13Fredrik Hübinette (Hubbe) void upd_int(int offset, INT32 tmp)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  MEMCPY(new_program->program+offset, (char *)&tmp,sizeof(tmp));
5267b71995-08-09Fredrik Hübinette (Hubbe) }
7a82f91996-04-13Fredrik Hübinette (Hubbe) INT32 read_int(int offset)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return EXTRACT_INT(new_program->program+offset);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
7a82f91996-04-13Fredrik Hübinette (Hubbe) int store_linenumbers=1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  /*
e02b611997-01-28Fredrik Hübinette (Hubbe)  * A mechanism to remember addresses on a stack.
5267b71995-08-09Fredrik Hübinette (Hubbe)  */ int comp_stackp; INT32 comp_stack[COMPILER_STACK_SIZE];
be478c1997-08-30Henrik Grubbström (Grubba) void push_address(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { if (comp_stackp >= COMPILER_STACK_SIZE) { yyerror("Compiler stack overflow"); comp_stackp++; return; } comp_stack[comp_stackp++] = PC; } void push_explicit(INT32 address) { if (comp_stackp >= COMPILER_STACK_SIZE) { yyerror("Compiler stack overflow"); comp_stackp++; return; } comp_stack[comp_stackp++] = address; }
be478c1997-08-30Henrik Grubbström (Grubba) INT32 pop_address(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { if (comp_stackp == 0) fatal("Compiler stack underflow.\n"); if (comp_stackp > COMPILER_STACK_SIZE) { --comp_stackp; return 0; } return comp_stack[--comp_stackp]; }
7a82f91996-04-13Fredrik Hübinette (Hubbe) static int label_no=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
be478c1997-08-30Henrik Grubbström (Grubba) int alloc_label(void) { return ++label_no; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a7622c1996-08-06Fredrik Hübinette (Hubbe) int do_jump(int token,INT32 lbl)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(lbl==-1) lbl=alloc_label(); emit(token, lbl); return lbl;
5267b71995-08-09Fredrik Hübinette (Hubbe) } static int do_docode2(node *n,int flags);
7a82f91996-04-13Fredrik Hübinette (Hubbe) #define ins_label(L) do_jump(F_LABEL, L)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a7622c1996-08-06Fredrik Hübinette (Hubbe) void do_pop(int x)
7a82f91996-04-13Fredrik Hübinette (Hubbe) { switch(x)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  case 0: return; case 1: emit2(F_POP_VALUE); break; default: emit(F_POP_N_ELEMS,x); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
66d51c1997-03-04Fredrik Hübinette (Hubbe)  #define DO_CODE_BLOCK(X) do_pop(do_docode((X),DO_NOT_COPY | DO_POP));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) int do_docode(node *n,INT16 flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int i;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int save_current_line=lex.current_line;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!n) return 0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line=n->line_number;
5267b71995-08-09Fredrik Hübinette (Hubbe)  i=do_docode2(n, flags);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line=save_current_line;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; }
419fab1997-03-09Fredrik Hübinette (Hubbe) static int is_efun(node *n, c_fun fun) { return n && n->token == F_CONSTANT && n->u.sval.subtype == FUNCTION_BUILTIN && n->u.sval.u.efun->function == fun; }
c64e8a1997-04-17Fredrik Hübinette (Hubbe) static void code_expression(node *n, int flags, char *err) { switch(do_docode(n, flags & ~ DO_POP)) { case 0: my_yyerror("Void expression for %s",err); case 1: return; case 2: fatal("Internal compiler error (%s), line %ld, file %s\n", err,
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  (long)lex.current_line, lex.current_file?lex.current_file->str:"Unknown");
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  } }
2d12341997-03-10Fredrik Hübinette (Hubbe) void do_cond_jump(node *n, int label, int iftrue, int flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
2d12341997-03-10Fredrik Hübinette (Hubbe)  iftrue=!!iftrue; if((flags & DO_POP) && node_is_tossable(n))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
2d12341997-03-10Fredrik Hübinette (Hubbe)  int t,f; t=!!node_is_true(n); f=!!node_is_false(n); if(t || f)
a7622c1996-08-06Fredrik Hübinette (Hubbe)  {
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(t == iftrue) do_jump(F_BRANCH, label);
a7622c1996-08-06Fredrik Hübinette (Hubbe)  return; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a7622c1996-08-06Fredrik Hübinette (Hubbe)  switch(n->token) {
419fab1997-03-09Fredrik Hübinette (Hubbe)  case F_LAND: case F_LOR:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(iftrue == (n->token==F_LAND))
a7622c1996-08-06Fredrik Hübinette (Hubbe)  {
2d12341997-03-10Fredrik Hübinette (Hubbe)  int tmp=alloc_label(); do_cond_jump(CAR(n), tmp, !iftrue, flags | DO_POP); do_cond_jump(CDR(n), label, iftrue, flags); emit(F_LABEL,tmp); }else{ do_cond_jump(CAR(n), label, iftrue, flags); do_cond_jump(CDR(n), label, iftrue, flags);
a7622c1996-08-06Fredrik Hübinette (Hubbe)  }
2d12341997-03-10Fredrik Hübinette (Hubbe)  return;
419fab1997-03-09Fredrik Hübinette (Hubbe)  case F_APPLY:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(!is_efun(CAR(n), f_not)) break;
419fab1997-03-09Fredrik Hübinette (Hubbe) 
a7622c1996-08-06Fredrik Hübinette (Hubbe)  case F_NOT:
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(!(flags & DO_POP)) break; do_cond_jump(CDR(n), label , !iftrue, flags | DO_NOT_COPY);
a7622c1996-08-06Fredrik Hübinette (Hubbe)  return; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(n, flags | DO_NOT_COPY, "condition");
2d12341997-03-10Fredrik Hübinette (Hubbe)  if(flags & DO_POP) { if(iftrue) do_jump(F_BRANCH_WHEN_NON_ZERO, label); else do_jump(F_BRANCH_WHEN_ZERO, label); }else{ if(iftrue) do_jump(F_LOR, label); else do_jump(F_LAND, label); }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
2d12341997-03-10Fredrik Hübinette (Hubbe) #define do_jump_when_zero(N,L) do_cond_jump(N,L,0,DO_POP|DO_NOT_COPY) #define do_jump_when_non_zero(N,L) do_cond_jump(N,L,1,DO_POP|DO_NOT_COPY)
5267b71995-08-09Fredrik Hübinette (Hubbe) static INT32 count_cases(node *n) { INT32 ret; if(!n) return 0; switch(n->token) { case F_DO: case F_FOR: case F_FOREACH: case F_INC_LOOP: case F_DEC_LOOP: case F_INC_NEQ_LOOP: case F_DEC_NEQ_LOOP: case F_SWITCH: case '?': return 0; case F_CASE: return !!CAR(n)+!!CDR(n); default: ret=0; if(car_is_node(n)) ret += count_cases(CAR(n)); if(cdr_is_node(n)) ret += count_cases(CDR(n)); return ret; } } static int do_docode2(node *n,int flags) { INT32 tmp1,tmp2,tmp3; if(!n) return 0; if(flags & DO_LVALUE) { switch(n->token) { default: yyerror("Illegal lvalue.");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_NUMBER,0);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_LVALUE_LIST: case F_LOCAL: case F_GLOBAL: case F_IDENTIFIER: case F_INDEX:
dffa011997-01-15Fredrik Hübinette (Hubbe)  case F_ARROW:
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_ARG_LIST:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } } switch(n->token) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case F_EXTERNAL: emit(F_LDA, n->u.integer.a); if(flags & DO_LVALUE) { emit(F_EXTERNAL_LVALUE, n->u.integer.b); return 2; }else{ emit(F_EXTERNAL, n->u.integer.b); return 1; } break; case F_UNDEFINED: yyerror("Undefined identifier"); emit(F_NUMBER,0); return 1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_PUSH_ARRAY:
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CAR(n), 0, "`@");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_PUSH_ARRAY);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return -0x7ffffff; case '?': {
2e4e451997-02-13Fredrik Hübinette (Hubbe)  INT32 *prev_switch_jumptable = current_switch_jumptable;
9d61521996-08-03Fredrik Hübinette (Hubbe)  int adroppings , bdroppings;
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
9d61521996-08-03Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!CDDR(n)) {
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label(); do_jump_when_zero(CAR(n), tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CADR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LABEL, tmp1);
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } if(!CADR(n)) {
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label(); do_jump_when_non_zero(CAR(n), tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDDR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LABEL,tmp1);
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }
a7622c1996-08-06Fredrik Hübinette (Hubbe)  tmp1=alloc_label(); do_jump_when_zero(CAR(n),tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  adroppings=do_docode(CADR(n), flags); tmp3=emit(F_POP_N_ELEMS,0);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  /* Else */ tmp2=do_jump(F_BRANCH,-1); emit(F_LABEL, tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  bdroppings=do_docode(CDDR(n), flags); if(adroppings < bdroppings) { do_pop(bdroppings - adroppings); }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
9d61521996-08-03Fredrik Hübinette (Hubbe)  if(adroppings > bdroppings) { update_arg(tmp3,adroppings-bdroppings); adroppings=bdroppings; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LABEL, tmp2);
2e4e451997-02-13Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
9d61521996-08-03Fredrik Hübinette (Hubbe)  return adroppings;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } case F_AND_EQ: case F_OR_EQ: case F_XOR_EQ: case F_LSH_EQ: case F_RSH_EQ: case F_ADD_EQ: case F_SUB_EQ: case F_MULT_EQ: case F_MOD_EQ: case F_DIV_EQ: tmp1=do_docode(CAR(n),DO_LVALUE); #ifdef DEBUG if(tmp1 != 2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("HELP! FATAL INTERNAL COMPILER ERROR (7)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
f53bab1997-01-26Fredrik Hübinette (Hubbe)  if(match_types(CAR(n)->type,array_type_string) || match_types(CAR(n)->type,string_type_string))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDR(n), 0, "assignment");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_LTOSVAL2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_LTOSVAL);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDR(n), 0, "assignment");
5267b71995-08-09Fredrik Hübinette (Hubbe)  } switch(n->token) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  case F_ADD_EQ: emit2(F_ADD); break; case F_AND_EQ: emit2(F_AND); break; case F_OR_EQ: emit2(F_OR); break; case F_XOR_EQ: emit2(F_XOR); break; case F_LSH_EQ: emit2(F_LSH); break; case F_RSH_EQ: emit2(F_RSH); break; case F_SUB_EQ: emit2(F_SUBTRACT); break; case F_MULT_EQ:emit2(F_MULTIPLY);break; case F_MOD_EQ: emit2(F_MOD); break; case F_DIV_EQ: emit2(F_DIVIDE); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } if(flags & DO_POP) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_ASSIGN_AND_POP);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_ASSIGN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_ASSIGN: switch(CAR(n)->token) { case F_AND: case F_OR: case F_XOR: case F_LSH: case F_RSH: case F_ADD: case F_MOD: case F_SUBTRACT: case F_DIVIDE: case F_MULTIPLY: if(node_is_eq(CDR(n),CAAR(n))) { tmp1=do_docode(CDR(n),DO_LVALUE);
f53bab1997-01-26Fredrik Hübinette (Hubbe)  if(match_types(CDR(n)->type,array_type_string) || match_types(CDR(n)->type,string_type_string))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDAR(n), 0, "binary operand");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_LTOSVAL2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_LTOSVAL);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDAR(n), 0, "binary operand");
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(CAR(n)->token);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n->token==F_ASSIGN; } default: switch(CDR(n)->token) { case F_LOCAL:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(CDR(n)->u.number >= compiler_frame->max_number_of_locals)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  yyerror("Illegal to use local variable here.");
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CAR(n), 0, "RHS");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL, CDR(n)->u.number );
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case F_IDENTIFIER:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(new_program, CDR(n)->u.number)->identifier_flags))
06983f1996-09-22Fredrik Hübinette (Hubbe)  {
d2c6081996-11-07Fredrik Hübinette (Hubbe)  yyerror("Cannot assign functions or constants.\n");
06983f1996-09-22Fredrik Hübinette (Hubbe)  }else{
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CAR(n), 0, "RHS");
06983f1996-09-22Fredrik Hübinette (Hubbe)  emit(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL, CDR(n)->u.number); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; default:
06983f1996-09-22Fredrik Hübinette (Hubbe)  tmp1=do_docode(CDR(n),DO_LVALUE); if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } return flags & DO_POP ? 0 : 1; } case F_LAND: case F_LOR:
2d12341997-03-10Fredrik Hübinette (Hubbe)  tmp1=alloc_label(); do_cond_jump(CAR(n), tmp1, n->token == F_LOR, 0);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  if(do_docode(CDR(n),0)!=1) fatal("Compiler logical error.\n");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LABEL,tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case F_EQ: case F_NE: case F_ADD: case F_LT: case F_LE: case F_GT: case F_GE: case F_SUBTRACT: case F_MULTIPLY: case F_DIVIDE: case F_MOD: case F_LSH: case F_RSH: case F_XOR: case F_OR: case F_AND:
6930181996-02-25Fredrik Hübinette (Hubbe)  case F_NOT: case F_COMPL: case F_NEGATE: fatal("Optimizer errror.\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_RANGE: tmp1=do_docode(CAR(n),DO_NOT_COPY); if(do_docode(CDR(n),DO_NOT_COPY)!=2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("Compiler internal error (at %ld).\n",(long)lex.current_line);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return tmp1; case F_INC: case F_POST_INC: tmp1=do_docode(CAR(n),DO_LVALUE); #ifdef DEBUG if(tmp1 != 2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("HELP! FATAL INTERNAL COMPILER ERROR (1)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif if(flags & DO_POP) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_INC_AND_POP);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_DEC: case F_POST_DEC: tmp1=do_docode(CAR(n),DO_LVALUE); #ifdef DEBUG if(tmp1 != 2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fatal("HELP! FATAL INTERNAL COMPILER ERROR (2)\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif if(flags & DO_POP) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_DEC_AND_POP);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(n->token);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_FOR: { INT32 *prev_switch_jumptable = current_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  INT32 break_save = current_break; INT32 continue_save = current_continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=alloc_label(); current_continue=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CDR(n)) {
9d61521996-08-03Fredrik Hübinette (Hubbe)  do_jump_when_zero(CAR(n),current_break);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp2=ins_label(-1);
9d61521996-08-03Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CADR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_continue);
9d61521996-08-03Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDDR(n));
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
9d61521996-08-03Fredrik Hübinette (Hubbe)  tmp2=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } do_jump_when_non_zero(CAR(n),tmp2);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_break);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=break_save; current_continue=continue_save;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case ' ': return do_docode(CAR(n),0)+do_docode(CDR(n),DO_LVALUE); case F_FOREACH: { INT32 *prev_switch_jumptable = current_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  INT32 break_save = current_break; INT32 continue_save = current_continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=alloc_label(); current_continue=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp2=do_docode(CAR(n),DO_NOT_COPY);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_CONST0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp3=do_jump(F_BRANCH,-1);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp1=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_continue); emit(F_LABEL,tmp3);
5267b71995-08-09Fredrik Hübinette (Hubbe)  do_jump(n->token,tmp1);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_break);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=break_save; current_continue=continue_save;
f1c4941996-12-01Fredrik Hübinette (Hubbe)  do_pop(4);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case F_INC_NEQ_LOOP: case F_DEC_NEQ_LOOP: case F_INC_LOOP: case F_DEC_LOOP: { INT32 *prev_switch_jumptable = current_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  INT32 break_save = current_break; INT32 continue_save = current_continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=alloc_label(); current_continue=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp2=do_docode(CAR(n),0); tmp3=do_jump(F_BRANCH,-1);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp1=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CDR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_continue); emit(F_LABEL,tmp3);
5267b71995-08-09Fredrik Hübinette (Hubbe)  do_jump(n->token,tmp1);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_break);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=break_save; current_continue=continue_save;
f1c4941996-12-01Fredrik Hübinette (Hubbe)  do_pop(3);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case F_DO: { INT32 *prev_switch_jumptable = current_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  INT32 break_save = current_break; INT32 continue_save = current_continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=alloc_label(); current_continue=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp2=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(CAR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_continue);
5267b71995-08-09Fredrik Hübinette (Hubbe)  do_jump_when_non_zero(CDR(n),tmp2);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_break);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=break_save; current_continue=continue_save;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case F_CAST: if(n->type==void_type_string) { DO_CODE_BLOCK(CAR(n)); return 0; } tmp1=do_docode(CAR(n),0);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(!tmp1) { emit2(F_CONST0); tmp1=1; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(tmp1>1) do_pop(tmp1-1); tmp1=store_prog_string(n->type);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_STRING,tmp1); emit2(F_CAST);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case F_APPLY: if(CAR(n)->token == F_CONSTANT) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.type == T_FUNCTION)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.subtype == FUNCTION_BUILTIN) /* driver fun? */
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  { if(!CAR(n)->u.sval.u.efun->docode || !CAR(n)->u.sval.u.efun->docode(n)) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_MARK);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_APPLY,tmp1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  } if(n->type == void_type_string) return 0; return 1; }else{ if(CAR(n)->u.sval.u.object == &fake_object) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_MARK);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),0);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_CALL_LFUN, CAR(n)->u.sval.subtype);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_MARK);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_APPLY,tmp1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } else if(CAR(n)->token == F_IDENTIFIER &&
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  IDENTIFIER_IS_FUNCTION(ID_FROM_INT(new_program, CAR(n)->u.number)->identifier_flags))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_MARK);
5267b71995-08-09Fredrik Hübinette (Hubbe)  do_docode(CDR(n),0);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_CALL_LFUN, CAR(n)->u.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } else {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct efun *fun;
f53bab1997-01-26Fredrik Hübinette (Hubbe)  node *foo;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_MARK);
5267b71995-08-09Fredrik Hübinette (Hubbe)  do_docode(CAR(n),0); do_docode(CDR(n),0);
f53bab1997-01-26Fredrik Hübinette (Hubbe)  tmp=findstring("call_function"); if(!tmp) yyerror("No call_function efun.");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  foo=find_module_identifier(tmp); if(!foo || !foo->token==F_CONSTANT)
f53bab1997-01-26Fredrik Hübinette (Hubbe)  { yyerror("No call_function efun."); }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  tmp1=store_constant(& foo->u.sval, 1);
f53bab1997-01-26Fredrik Hübinette (Hubbe)  emit(F_APPLY, tmp1); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  free_node(foo);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_ARG_LIST: tmp1=do_docode(CAR(n),flags & ~DO_LVALUE); tmp1+=do_docode(CDR(n),flags); return tmp1; /* Switch: * So far all switches are implemented with a binsearch lookup. * It stores the case values in the programs area for constants. * It also has a jump-table in the program itself, for every index in * the array of cases, there is 2 indexes in the jumptable, and one extra. * The first entry in the jumptable is used if you call switch with * a value that is ranked lower than all the indexes in the array of * cases. (Ranked by the binsearch that is) The second is used if it * is equal to the first index. The third if it is greater than the * first, but lesser than the second. The fourth if it is equal to * the second.... etc. etc. */ case F_SWITCH: { INT32 e,cases,*order; INT32 *jumptable; INT32 prev_switch_values_on_stack = current_switch_values_on_stack; INT32 prev_switch_case = current_switch_case; INT32 prev_switch_default = current_switch_default; INT32 *prev_switch_jumptable = current_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  INT32 break_save = current_break;
7af7d21997-08-03Fredrik Hübinette (Hubbe) #ifdef DEBUG struct svalue *save_sp=sp; #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(do_docode(CAR(n),0)!=1) fatal("Internal compiler error, time to panic\n");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  cases=count_cases(CDR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  tmp1=emit(F_SWITCH,0); emit(F_ALIGN,sizeof(INT32));
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_values_on_stack=0; current_switch_case=0; current_switch_default=-1; current_switch_jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+1)); jumptable=(INT32 *)xalloc(sizeof(INT32)*(cases*2+1)); for(e=0; e<cases*2+1; e++) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  jumptable[e]=emit(F_POINTER, 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable[e]=-1; } current_switch_jumptable[current_switch_case++]=-1; DO_CODE_BLOCK(CDR(n));
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
7af7d21997-08-03Fredrik Hübinette (Hubbe) #ifdef DEBUG if(sp-save_sp != cases) fatal("Count cases is wrong!\n"); #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  f_aggregate(cases); order=get_switch_order(sp[-1].u.array);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  /* Check for cases inside a range */
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0; e<cases-1; e++) {
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  if(order[e] < cases-1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b504ed1997-09-21Fredrik Hübinette (Hubbe)  int o1=order[e]*2+1;
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  if(current_switch_jumptable[o1]==current_switch_jumptable[o1+1] && current_switch_jumptable[o1]==current_switch_jumptable[o1+2]) { if(order[e]+1 != order[e+1]) yyerror("Case inside range."); e++; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(current_switch_default < 0) current_switch_default = ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0;e<cases*2+1;e++) if(current_switch_jumptable[e]==-1) current_switch_jumptable[e]=current_switch_default; sp[-1].u.array=order_array(sp[-1].u.array,order); reorder((void *)(current_switch_jumptable+1),cases,sizeof(INT32)*2,order); free((char *)order); for(e=0; e<cases*2+1; e++)
7a82f91996-04-13Fredrik Hübinette (Hubbe)  update_arg(jumptable[e], current_switch_jumptable[e]);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  update_arg(tmp1, store_constant(sp-1,1));
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack(); free((char *)jumptable); free((char *)current_switch_jumptable); current_switch_jumptable = prev_switch_jumptable; current_switch_default = prev_switch_default; current_switch_case = prev_switch_case; current_switch_values_on_stack = prev_switch_values_on_stack ;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LABEL, current_break);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=break_save;
7af7d21997-08-03Fredrik Hübinette (Hubbe) #ifdef DEBUG if(recoveries && sp-evaluator_stack < recoveries->sp) fatal("Stack error after F_SWITCH (underflow)\n"); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; } case F_CASE: { if(!current_switch_jumptable) { yyerror("Case outside switch."); }else{
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  node *lower=CAR(n); if(!lower) lower=CDR(n); if(!is_const(lower))
5267b71995-08-09Fredrik Hübinette (Hubbe)  yyerror("Case label isn't constant.");
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  tmp1=eval_low(lower);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(tmp1<1) { yyerror("Error in case label.");
7af7d21997-08-03Fredrik Hübinette (Hubbe)  push_int(0); tmp1=1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } pop_n_elems(tmp1-1); current_switch_values_on_stack++; for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--) if(is_equal(sp-tmp1, sp-1)) yyerror("Duplicate case.");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_switch_jumptable[current_switch_case++]=ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(CDR(n)) {
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  current_switch_jumptable[current_switch_case]= current_switch_jumptable[current_switch_case-1]; current_switch_case++;
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  if(CAR(n)) { if(!is_const(CDR(n))) yyerror("Case label isn't constant.");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_switch_jumptable[current_switch_case]= current_switch_jumptable[current_switch_case-1];
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  current_switch_case++; tmp1=eval_low(CDR(n)); if(tmp1<1) { yyerror("Error in second half of case label."); push_int(0); tmp1=1; } pop_n_elems(tmp1-1); current_switch_values_on_stack++; for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--) if(is_equal(sp-tmp1, sp-1)) yyerror("Duplicate case."); current_switch_jumptable[current_switch_case++]=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
ba62cf1997-09-18Fredrik Hübinette (Hubbe)  }else{ current_switch_jumptable[current_switch_case++]=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return 0; } case F_DEFAULT: if(!current_switch_jumptable) { yyerror("Default outside switch."); }else if(current_switch_default!=-1){ yyerror("Duplicate switch default."); }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_switch_default = ins_label(-1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return 0; case F_BREAK:
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(current_break == -1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { yyerror("Break outside loop or switch."); }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  do_jump(F_BRANCH, current_break);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return 0; case F_CONTINUE:
7a82f91996-04-13Fredrik Hübinette (Hubbe)  if(current_continue == -1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { yyerror("continue outside loop or switch."); }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  do_jump(F_BRANCH, current_continue);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return 0; case F_RETURN:
7a82f91996-04-13Fredrik Hübinette (Hubbe)  do_docode(CAR(n),0); emit2(F_RETURN);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 0; case F_SSCANF: tmp1=do_docode(CAR(n),DO_NOT_COPY); tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_SSCANF,tmp1+tmp2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case F_CATCH: {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  INT32 break_save = current_break; INT32 continue_save = current_continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 *prev_switch_jumptable = current_switch_jumptable;
7a82f91996-04-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable=0;
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=alloc_label(); current_continue=alloc_label();
5267b71995-08-09Fredrik Hübinette (Hubbe)  tmp1=do_jump(F_CATCH,-1); DO_CODE_BLOCK(CAR(n));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  ins_label(current_continue); ins_label(current_break);
9d61521996-08-03Fredrik Hübinette (Hubbe)  emit2(F_THROW_ZERO); ins_label(tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7a82f91996-04-13Fredrik Hübinette (Hubbe)  current_break=break_save; current_continue=continue_save;
5267b71995-08-09Fredrik Hübinette (Hubbe)  current_switch_jumptable = prev_switch_jumptable; return 1; } case F_LVALUE_LIST: return do_docode(CAR(n),DO_LVALUE)+do_docode(CDR(n),DO_LVALUE);
dffa011997-01-15Fredrik Hübinette (Hubbe)  case F_ARROW: if(CDR(n)->token != F_CONSTANT || CDR(n)->u.sval.type!=T_STRING) fatal("Bugg in F_ARROW, index not string."); if(flags & DO_LVALUE) { /* FIXME!!!! */ tmp1=do_docode(CAR(n), 0); emit(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string)); return 2; }else{ tmp1=do_docode(CAR(n), DO_NOT_COPY); emit(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string)); if(!(flags & DO_NOT_COPY)) { while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n); if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND)) emit2(F_COPY_VALUE); } } return tmp1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case F_INDEX: if(flags & DO_LVALUE) { tmp1=do_docode(CAR(n), 0); if(do_docode(CDR(n),0) != 1) fatal("Internal compiler error, please report this (1).");
e82b301997-01-29Fredrik Hübinette (Hubbe)  if(CDR(n)->token != F_CONSTANT && match_types(CDR(n)->type, string_type_string)) emit2(F_CLEAR_STRING_SUBTYPE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 2; }else{ tmp1=do_docode(CAR(n), DO_NOT_COPY);
c64e8a1997-04-17Fredrik Hübinette (Hubbe)  code_expression(CDR(n), DO_NOT_COPY, "index");
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_INDEX);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!(flags & DO_NOT_COPY)) {
dffa011997-01-15Fredrik Hübinette (Hubbe)  while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n);
5683de1995-11-06Fredrik Hübinette (Hubbe)  if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_COPY_VALUE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return tmp1; case F_CONSTANT: switch(n->u.sval.type) { case T_INT:
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_NUMBER,n->u.sval.u.integer);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_STRING: tmp1=store_prog_string(n->u.sval.u.string);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_STRING,tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_FUNCTION:
bdb5091996-09-25Fredrik Hübinette (Hubbe)  if(n->u.sval.subtype!=FUNCTION_BUILTIN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(n->u.sval.u.object == &fake_object) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LFUN,n->u.sval.subtype);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } } default:
5683de1995-11-06Fredrik Hübinette (Hubbe)  tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_CONSTANT,tmp1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; case T_ARRAY: case T_MAPPING:
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5683de1995-11-06Fredrik Hübinette (Hubbe)  tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_CONSTANT,tmp1);
5683de1995-11-06Fredrik Hübinette (Hubbe)  /* copy now or later ? */ if(!(flags & DO_NOT_COPY) && !(n->tree_info & OPT_EXTERNAL_DEPEND))
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit2(F_COPY_VALUE);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_LOCAL:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(n->u.number >= compiler_frame->max_number_of_locals)
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  yyerror("Illegal to use local variable here.");
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(flags & DO_LVALUE) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LOCAL_LVALUE,n->u.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 2; }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LOCAL,n->u.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 1; } case F_IDENTIFIER:
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(new_program, n->u.number)->identifier_flags))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(flags & DO_LVALUE) { yyerror("Cannot assign functions.\n"); }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_LFUN,n->u.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }else{ if(flags & DO_LVALUE) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_GLOBAL_LVALUE,n->u.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return 2; }else{
7a82f91996-04-13Fredrik Hübinette (Hubbe)  emit(F_GLOBAL,n->u.number);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } return 1; case F_VAL_LVAL: return do_docode(CAR(n),flags)+do_docode(CDR(n),flags | DO_LVALUE); default: fatal("Infernal compiler error (unknown parse-tree-token).\n"); return 0; /* make gcc happy */ } } void do_code_block(node *n) {
7a82f91996-04-13Fredrik Hübinette (Hubbe)  init_bytecode(); label_no=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  DO_CODE_BLOCK(n);
7a82f91996-04-13Fredrik Hübinette (Hubbe)  assemble(); } int docode(node *n) { int tmp; int label_no_save = label_no; dynamic_buffer instrbuf_save = instrbuf; instrbuf.s.str=0; label_no=0; init_bytecode(); tmp=do_docode(n,0); assemble(); instrbuf=instrbuf_save; label_no = label_no_save; return tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe) }