Branch: Tag:

1995-08-09

1995-08-09 10:21:55 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>

ulpc dist

Rev: bin/create_testsuite:1.1.1.1
Rev: bin/hilfe.lpc:1.1.1.1
Rev: bin/rsif:1.1.1.1
Rev: bin/uhttpd.lpc:1.1.1.1
Rev: doc/README:1.1.1.1
Rev: doc/builtin/aggregate:1.1.1.1
Rev: doc/builtin/aggregate_list:1.1.1.1
Rev: doc/builtin/aggregate_mapping:1.1.1.1
Rev: doc/builtin/all_efuns:1.1.1.1
Rev: doc/builtin/allocate:1.1.1.1
Rev: doc/builtin/arrayp:1.1.1.1
Rev: doc/builtin/backtrace:1.1.1.1
Rev: doc/builtin/call_function:1.1.1.1
Rev: doc/builtin/call_out:1.1.1.1
Rev: doc/builtin/call_out_info:1.1.1.1
Rev: doc/builtin/catch:1.1.1.1
Rev: doc/builtin/clone:1.1.1.1
Rev: doc/builtin/combine_path:1.1.1.1
Rev: doc/builtin/compile_file:1.1.1.1
Rev: doc/builtin/compile_string:1.1.1.1
Rev: doc/builtin/copy_value:1.1.1.1
Rev: doc/builtin/crypt:1.1.1.1
Rev: doc/builtin/ctime:1.1.1.1
Rev: doc/builtin/destruct:1.1.1.1
Rev: doc/builtin/equal:1.1.1.1
Rev: doc/builtin/exit:1.1.1.1
Rev: doc/builtin/explode:1.1.1.1
Rev: doc/builtin/find_call_out:1.1.1.1
Rev: doc/builtin/floatp:1.1.1.1
Rev: doc/builtin/function_name:1.1.1.1
Rev: doc/builtin/function_object:1.1.1.1
Rev: doc/builtin/functionp:1.1.1.1
Rev: doc/builtin/hash:1.1.1.1
Rev: doc/builtin/implode:1.1.1.1
Rev: doc/builtin/indices:1.1.1.1
Rev: doc/builtin/intp:1.1.1.1
Rev: doc/builtin/listp:1.1.1.1
Rev: doc/builtin/lower_case:1.1.1.1
Rev: doc/builtin/m_delete:1.1.1.1
Rev: doc/builtin/mappingp:1.1.1.1
Rev: doc/builtin/mkmapping:1.1.1.1
Rev: doc/builtin/next_object:1.1.1.1
Rev: doc/builtin/object_program:1.1.1.1
Rev: doc/builtin/objectp:1.1.1.1
Rev: doc/builtin/programp:1.1.1.1
Rev: doc/builtin/query_host_name:1.1.1.1
Rev: doc/builtin/query_num_arg:1.1.1.1
Rev: doc/builtin/random:1.1.1.1
Rev: doc/builtin/regexpp:1.1.1.1
Rev: doc/builtin/remove_call_out:1.1.1.1
Rev: doc/builtin/replace:1.1.1.1
Rev: doc/builtin/reverse:1.1.1.1
Rev: doc/builtin/rusage:1.1.1.1
Rev: doc/builtin/search:1.1.1.1
Rev: doc/builtin/sizeof:1.1.1.1
Rev: doc/builtin/sscanf:1.1.1.1
Rev: doc/builtin/stringp:1.1.1.1
Rev: doc/builtin/sum:1.1.1.1
Rev: doc/builtin/this_object:1.1.1.1
Rev: doc/builtin/throw:1.1.1.1
Rev: doc/builtin/time:1.1.1.1
Rev: doc/builtin/trace:1.1.1.1
Rev: doc/builtin/upper_case:1.1.1.1
Rev: doc/builtin/values:1.1.1.1
Rev: doc/builtin/zero_type:1.1.1.1
Rev: doc/files/cd:1.1.1.1
Rev: doc/files/exec:1.1.1.1
Rev: doc/files/file:1.1.1.1
Rev: doc/files/file_stat:1.1.1.1
Rev: doc/files/fork:1.1.1.1
Rev: doc/files/get_dir:1.1.1.1
Rev: doc/files/getcwd:1.1.1.1
Rev: doc/files/mkdir:1.1.1.1
Rev: doc/files/mv:1.1.1.1
Rev: doc/files/perror:1.1.1.1
Rev: doc/files/port:1.1.1.1
Rev: doc/files/rm:1.1.1.1
Rev: doc/lpc/command_line_options:1.1.1.1
Rev: doc/lpc/control_structures:1.1.1.1
Rev: doc/lpc/hilfe.hilfe:1.1.1.1
Rev: doc/lpc/how_to_make_modules:1.1.1.1
Rev: doc/manual/i-overview.html:1.1.1.1
Rev: doc/manual/index.html:1.1.1.1
Rev: doc/manual/t-hello.html:1.1.1.1
Rev: doc/manual/ulpc-inside3.gif:1.1.1.1
Rev: doc/math/acos:1.1.1.1
Rev: doc/math/asin:1.1.1.1
Rev: doc/math/atan:1.1.1.1
Rev: doc/math/ceil:1.1.1.1
Rev: doc/math/cos:1.1.1.1
Rev: doc/math/exp:1.1.1.1
Rev: doc/math/floor:1.1.1.1
Rev: doc/math/log:1.1.1.1
Rev: doc/math/pow:1.1.1.1
Rev: doc/math/sin:1.1.1.1
Rev: doc/math/sqrt:1.1.1.1
Rev: doc/math/tan:1.1.1.1
Rev: doc/operators/addition:1.1.1.1
Rev: doc/regexp/regexp:1.1.1.1
Rev: doc/simulated/PI:1.1.1.1
Rev: doc/simulated/capitalize:1.1.1.1
Rev: doc/simulated/code_value:1.1.1.1
Rev: doc/simulated/describe_backtrace:1.1.1.1
Rev: doc/simulated/file_size:1.1.1.1
Rev: doc/simulated/filter_array:1.1.1.1
Rev: doc/simulated/get_function:1.1.1.1
Rev: doc/simulated/getenv:1.1.1.1
Rev: doc/simulated/l_sizeof:1.1.1.1
Rev: doc/simulated/m_indices:1.1.1.1
Rev: doc/simulated/m_sizeof:1.1.1.1
Rev: doc/simulated/m_values:1.1.1.1
Rev: doc/simulated/map_array:1.1.1.1
Rev: doc/simulated/master:1.1.1.1
Rev: doc/simulated/member_array:1.1.1.1
Rev: doc/simulated/popen:1.1.1.1
Rev: doc/simulated/previous_object:1.1.1.1
Rev: doc/simulated/read_bytes:1.1.1.1
Rev: doc/simulated/regexp:1.1.1.1
Rev: doc/simulated/search_array:1.1.1.1
Rev: doc/simulated/sort_array:1.1.1.1
Rev: doc/simulated/spawn:1.1.1.1
Rev: doc/simulated/strlen:1.1.1.1
Rev: doc/simulated/strstr:1.1.1.1
Rev: doc/simulated/sum_arrays:1.1.1.1
Rev: doc/simulated/this_function:1.1.1.1
Rev: doc/simulated/write:1.1.1.1
Rev: doc/simulated/write_file:1.1.1.1
Rev: doc/sprintf/sprintf:1.1.1.1
Rev: doc/types/array:1.1.1.1
Rev: doc/types/float:1.1.1.1
Rev: doc/types/function:1.1.1.1
Rev: doc/types/int:1.1.1.1
Rev: doc/types/list:1.1.1.1
Rev: doc/types/mapping:1.1.1.1
Rev: doc/types/object:1.1.1.1
Rev: doc/types/program:1.1.1.1
Rev: doc/types/string:1.1.1.1
Rev: lib/conftest.h:1.1.1.1
Rev: lib/master.lpc:1.1.1.1
Rev: lib/simulate.lpc:1.1.1.1
Rev: lib/testsuite.lpc:1.1.1.1
Rev: src/BUGS:1.1.1.1
Rev: src/COPYING:1.1.1.1
Rev: src/COPYRIGHT:1.1.1.1
Rev: src/DISCLAIMER:1.1.1.1
Rev: src/Makefile.in:1.1.1.1
Rev: src/README:1.1.1.1
Rev: src/add_efun.c:1.1.1.1
Rev: src/add_efun.h:1.1.1.1
Rev: src/alloca.c:1.1.1.1
Rev: src/array.c:1.1.1.1
Rev: src/array.h:1.1.1.1
Rev: src/backend.c:1.1.1.1
Rev: src/backend.h:1.1.1.1
Rev: src/builtin_efuns.c:1.1.1.1
Rev: src/builtin_efuns.h:1.1.1.1
Rev: src/call_out.c:1.1.1.1
Rev: src/call_out.h:1.1.1.1
Rev: src/callback.c:1.1.1.1
Rev: src/callback.h:1.1.1.1
Rev: src/config.h:1.1.1.1
Rev: src/configure.in:1.1.1.1
Rev: src/debug.c:1.1.1.1
Rev: src/debug.h:1.1.1.1
Rev: src/docode.c:1.1.1.1
Rev: src/docode.h:1.1.1.1
Rev: src/dynamic_buffer.c:1.1.1.1
Rev: src/dynamic_buffer.h:1.1.1.1
Rev: src/efun.h:1.1.1.1
Rev: src/error.c:1.1.1.1
Rev: src/error.h:1.1.1.1
Rev: src/fd_control.c:1.1.1.1
Rev: src/fd_control.h:1.1.1.1
Rev: src/fsort.c:1.1.1.1
Rev: src/fsort.h:1.1.1.1
Rev: src/global.h:1.1.1.1
Rev: src/hashtable.c:1.1.1.1
Rev: src/hashtable.h:1.1.1.1
Rev: src/install-sh:1.1.1.1
Rev: src/interpret.c:1.1.1.1
Rev: src/interpret.h:1.1.1.1
Rev: src/language.y:1.1.1.1
Rev: src/las.c:1.1.1.1
Rev: src/las.h:1.1.1.1
Rev: src/lex.c:1.1.1.1
Rev: src/lex.h:1.1.1.1
Rev: src/list.c:1.1.1.1
Rev: src/list.h:1.1.1.1
Rev: src/lpc_types.c:1.1.1.1
Rev: src/lpc_types.h:1.1.1.1
Rev: src/machine.h.in:1.1.1.1
Rev: src/macros.h:1.1.1.1
Rev: src/main.c:1.1.1.1
Rev: src/main.h:1.1.1.1
Rev: src/mapping.c:1.1.1.1
Rev: src/mapping.h:1.1.1.1
Rev: src/memory.c:1.1.1.1
Rev: src/memory.h:1.1.1.1
Rev: src/module.c:1.1.1.1
Rev: src/module.h:1.1.1.1
Rev: src/modules/efuns.c:1.1.1.1
Rev: src/modules/files/Makefile.in:1.1.1.1
Rev: src/modules/files/configure.in:1.1.1.1
Rev: src/modules/files/datagram.c:1.1.1.1
Rev: src/modules/files/efuns.c:1.1.1.1
Rev: src/modules/files/file.c:1.1.1.1
Rev: src/modules/files/file.h:1.1.1.1
Rev: src/modules/files/file_machine.h.in:1.1.1.1
Rev: src/modules/files/socket.c:1.1.1.1
Rev: src/modules/math/Makefile.in:1.1.1.1
Rev: src/modules/math/configure.in:1.1.1.1
Rev: src/modules/math/math.c:1.1.1.1
Rev: src/modules/regexp/Makefile.in:1.1.1.1
Rev: src/modules/regexp/configure.in:1.1.1.1
Rev: src/modules/regexp/glue.c:1.1.1.1
Rev: src/modules/regexp/regexp.c:1.1.1.1
Rev: src/modules/regexp/regexp.h:1.1.1.1
Rev: src/modules/sprintf/Makefile.in:1.1.1.1
Rev: src/modules/sprintf/configure.in:1.1.1.1
Rev: src/modules/sprintf/sprintf.c:1.1.1.1
Rev: src/object.c:1.1.1.1
Rev: src/object.h:1.1.1.1
Rev: src/opcodes.c:1.1.1.1
Rev: src/opcodes.h:1.1.1.1
Rev: src/operators.c:1.1.1.1
Rev: src/operators.h:1.1.1.1
Rev: src/otable.h:1.1.1.1
Rev: src/port.c:1.1.1.1
Rev: src/port.h:1.1.1.1
Rev: src/program.c:1.1.1.1
Rev: src/program.h:1.1.1.1
Rev: src/rusage.c:1.1.1.1
Rev: src/rusage.h:1.1.1.1
Rev: src/stralloc.c:1.1.1.1
Rev: src/stralloc.h:1.1.1.1
Rev: src/stuff.c:1.1.1.1
Rev: src/stuff.h:1.1.1.1
Rev: src/svalue.c:1.1.1.1
Rev: src/svalue.h:1.1.1.1
Rev: src/todo:1.1.1.1
Rev: src/types.h:1.1.1.1
Rev: src/ualarm.c:1.1.1.1

1: + #include <math.h> + #include "global.h" + #include "interpret.h" + #include "svalue.h" + #include "list.h" + #include "mapping.h" + #include "array.h" + #include "stralloc.h" + #include "opcodes.h" + #include "operators.h" + #include "language.h" + #include "memory.h" + #include "error.h"    -  + #define COMPARISON(ID,EXPR) \ + void ID() \ + { \ +  int i=EXPR; \ +  pop_n_elems(2); \ +  sp->type=T_INT; \ +  sp->u.integer=i; \ +  sp++; \ + } +  + COMPARISON(f_eq, is_eq(sp-2,sp-1)) + COMPARISON(f_ne,!is_eq(sp-2,sp-1)) + COMPARISON(f_lt, is_lt(sp-2,sp-1)) + COMPARISON(f_le,!is_gt(sp-2,sp-1)) + COMPARISON(f_gt, is_gt(sp-2,sp-1)) + COMPARISON(f_ge,!is_lt(sp-2,sp-1)) +  + void f_sum(INT32 args) + { +  INT32 e,size; +  TYPE_FIELD types; +  +  types=0; +  for(e=-args;e<0;e++) types|=1<<sp[e].type; +  +  switch(types) +  { +  default: +  if(args) +  { +  switch(sp[-args].type) +  { +  case T_OBJECT: +  case T_PROGRAM: +  case T_FUNCTION: +  error("Bad argument 1 to summation\n"); +  } +  } +  error("Incompatible types to sum() or +\n"); +  return; /* compiler hint */ +  +  case BIT_STRING: +  { +  struct lpc_string *r; +  char *buf; +  +  if(args==1) return; +  size=0; +  +  for(e=-args;e<0;e++) size+=sp[e].u.string->len; +  +  if(args==2) +  { +  r=add_shared_strings(sp[-2].u.string,sp[-1].u.string); +  }else{ +  r=begin_shared_string(size); +  buf=r->str; +  for(e=-args;e<0;e++) +  { +  MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len); +  buf+=sp[e].u.string->len; +  } +  r=end_shared_string(r); +  } +  for(e=-args;e<0;e++) +  { +  free_string(sp[e].u.string); +  } +  sp-=args; +  push_string(r); +  break; +  } +  +  case BIT_STRING | BIT_INT: +  case BIT_STRING | BIT_FLOAT: +  case BIT_STRING | BIT_FLOAT | BIT_INT: +  { +  struct lpc_string *r; +  char *buf,*str; +  size=0; +  for(e=-args;e<0;e++) +  { +  switch(sp[e].type) +  { +  case T_STRING: +  size+=sp[e].u.string->len; +  break; +  +  case T_INT: +  size+=14; +  break; +  +  case T_FLOAT: +  size+=22; +  break; +  } +  } +  str=buf=xalloc(size+1); +  size=0; +  +  for(e=-args;e<0;e++) +  { +  switch(sp[e].type) +  { +  case T_STRING: +  MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len); +  buf+=sp[e].u.string->len; +  break; +  +  case T_INT: +  sprintf(buf,"%ld",sp[e].u.integer); +  buf+=strlen(buf); +  break; +  +  case T_FLOAT: +  sprintf(buf,"%f",(double)sp[e].u.float_number); +  buf+=strlen(buf); +  break; +  } +  } +  r=make_shared_binary_string(str,buf-str); +  free(str); +  pop_n_elems(args); +  push_string(r); +  break; +  } +  +  case BIT_INT: +  size=0; +  for(e=-args; e<0; e++) size+=sp[e].u.integer; +  sp-=args-1; +  sp[-1].u.integer=size; +  break; +  +  case BIT_FLOAT: +  { +  FLOAT_TYPE sum; +  sum=0.0; +  for(e=-args; e<0; e++) sum+=sp[e].u.float_number; +  sp-=args-1; +  sp[-1].u.float_number=sum; +  break; +  } +  +  case BIT_ARRAY: +  { +  struct array *a; +  a=add_arrays(sp-args,args); +  pop_n_elems(args); +  push_array(a); +  break; +  } +  +  case BIT_MAPPING: +  { +  struct mapping *m; +  +  m = add_mappings(sp - args, args); +  pop_n_elems(args); +  push_mapping(m); +  break; +  } +  +  case BIT_LIST: +  { +  struct list *l; +  +  l = add_lists(sp - args, args); +  pop_n_elems(args); +  push_list(l); +  break; +  } +  } + } +  + void f_add() { f_sum(2); } +  + void f_subtract() + { +  if (sp[-2].type != sp[-1].type ) +  error("Subtract on different types.\n"); +  +  switch(sp[-1].type) +  { +  case T_ARRAY: +  { +  struct array *a; +  +  check_array_for_destruct(sp[-2].u.array); +  check_array_for_destruct(sp[-1].u.array); +  a = subtract_arrays(sp[-2].u.array, sp[-1].u.array); +  pop_n_elems(2); +  push_array(a); +  return; +  } +  +  case T_MAPPING: +  { +  struct mapping *m; +  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping,OP_SUB); +  pop_n_elems(2); +  push_mapping(m); +  return; +  } +  +  case T_LIST: +  { +  struct list *l; +  l=merge_lists(sp[-2].u.list, sp[-1].u.list, OP_SUB); +  pop_n_elems(2); +  push_list(l); +  return; +  } +  +  case T_FLOAT: +  sp--; +  sp[-1].u.float_number -= sp[0].u.float_number; +  return; +  +  case T_INT: +  sp--; +  sp[-1].u.integer -= sp[0].u.integer; +  return; +  +  case T_STRING: +  { +  struct lpc_string *s,*ret; +  sp--; +  s=make_shared_string(""); +  ret=string_replace(sp[-1].u.string,sp[0].u.string,s); +  free_string(sp[-1].u.string); +  free_string(sp[0].u.string); +  free_string(s); +  sp[-1].u.string=ret; +  return; +  } +  +  default: +  error("Bad argument 1 to subtraction.\n"); +  } + } +  + void f_and() + { +  if(sp[-1].type != sp[-2].type) +  error("Bitwise and on different types.\n"); +  +  switch(sp[-2].type) +  { +  case T_INT: +  sp--; +  sp[-1].u.integer &= sp[0].u.integer; +  break; +  +  case T_MAPPING: +  { +  struct mapping *m; +  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, OP_AND); +  pop_n_elems(2); +  push_mapping(m); +  return; +  } +  +  case T_LIST: +  { +  struct list *l; +  l=merge_lists(sp[-2].u.list, sp[-1].u.list, OP_AND); +  pop_n_elems(2); +  push_list(l); +  return; +  } +  +  case T_ARRAY: +  { +  struct array *a; +  a=and_arrays(sp[-2].u.array, sp[-1].u.array); +  pop_n_elems(2); +  push_array(a); +  return; +  } +  default: +  error("Bitwise and on illegal type.\n"); +  } + } +  + void f_or() + { +  if(sp[-1].type != sp[-2].type) +  error("Bitwise or on different types.\n"); +  +  switch(sp[-2].type) +  { +  case T_INT: +  sp--; +  sp[-1].u.integer |= sp[0].u.integer; +  break; +  +  case T_MAPPING: +  { +  struct mapping *m; +  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, OP_OR); +  pop_n_elems(2); +  push_mapping(m); +  return; +  } +  +  case T_LIST: +  { +  struct list *l; +  l=merge_lists(sp[-2].u.list, sp[-1].u.list, OP_OR); +  pop_n_elems(2); +  push_list(l); +  return; +  } +  +  case T_ARRAY: +  { +  struct array *a; +  a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, OP_OR); +  pop_n_elems(2); +  push_array(a); +  return; +  } +  +  default: +  error("Bitwise or on illegal type.\n"); +  } + } +  + void f_xor() + { +  if(sp[-1].type != sp[-2].type) +  error("Bitwise xor on different types.\n"); +  +  switch(sp[-2].type) +  { +  case T_INT: +  sp--; +  sp[-1].u.integer ^= sp[0].u.integer; +  break; +  +  case T_MAPPING: +  { +  struct mapping *m; +  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, OP_XOR); +  pop_n_elems(2); +  push_mapping(m); +  return; +  } +  +  case T_LIST: +  { +  struct list *l; +  l=merge_lists(sp[-2].u.list, sp[-1].u.list, OP_XOR); +  pop_n_elems(2); +  push_list(l); +  return; +  } +  +  case T_ARRAY: +  { +  struct array *a; +  a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, OP_XOR); +  pop_n_elems(2); +  push_array(a); +  return; +  } +  default: +  error("Bitwise xor on illegal type.\n"); +  } + } +  + void f_lsh() + { +  if(sp[-2].type != T_INT) error("Bad argument 1 to <<\n"); +  if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n"); +  sp--; +  sp[-1].u.integer <<= sp[0].u.integer; + } +  + void f_rsh() + { +  if(sp[-2].type != T_INT) error("Bad argument 1 to >>\n"); +  if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n"); +  sp--; +  sp[-1].u.integer >>= sp[0].u.integer; + } +  + void f_multiply() + { +  switch(sp[-2].type) +  { +  case T_ARRAY: +  if(sp[-1].type!=T_STRING) +  { +  error("Bad argument 2 to multiply.\n"); +  }else{ +  struct lpc_string *ret; +  sp--; +  ret=implode(sp[-1].u.array,sp[0].u.string); +  free_string(sp[0].u.string); +  free_array(sp[-1].u.array); +  sp[-1].type=T_STRING; +  sp[-1].u.string=ret; +  return; +  } +  +  case T_FLOAT: +  if(sp[-1].type!=T_FLOAT) error("Bad argument 2 to multiply.\n"); +  sp--; +  sp[-1].u.float_number *= sp[0].u.float_number; +  return; +  +  case T_INT: +  if(sp[-1].type!=T_INT) error("Bad argument 2 to multiply.\n"); +  sp--; +  sp[-1].u.integer *= sp[0].u.integer; +  return; +  +  default: +  error("Bad argument 1 to multiply.\n"); +  } + } +  + void f_divide() + { +  if(sp[-2].type!=sp[-1].type) +  error("Division on different types.\n"); +  +  switch(sp[-2].type) +  { +  case T_STRING: +  { +  struct array *ret; +  sp--; +  ret=explode(sp[-1].u.string,sp[0].u.string); +  free_string(sp[-1].u.string); +  free_string(sp[0].u.string); +  sp[-1].type=T_ARRAY; +  sp[-1].u.array=ret; +  return; +  } +  +  case T_FLOAT: +  if(sp[-1].u.float_number == 0.0) +  error("Division by zero.\n"); +  sp--; +  sp[-1].u.float_number /= sp[0].u.float_number; +  return; +  +  case T_INT: +  if (sp[-1].u.integer == 0) +  error("Division by zero\n"); +  sp--; +  sp[-1].u.integer /= sp[0].u.integer; +  return; +  +  default: +  error("Bad argument 1 to divide.\n"); +  } + } +  + void f_mod() + { +  if(sp[-2].type != sp[-1].type) +  error("Modulo on different types.\n"); +  +  switch(sp[-1].type) +  { +  case T_FLOAT: +  { +  FLOAT_TYPE foo; +  if(sp[-1].u.float_number == 0.0) +  error("Modulo by zero.\n"); +  sp--; +  foo=sp[-1].u.float_number / sp[0].u.float_number; +  foo=sp[-1].u.float_number - sp[0].u.float_number * floor(foo); +  sp[-1].u.float_number=foo; +  return; +  } +  case T_INT: +  if (sp[-1].u.integer == 0) error("Modulo by zero.\n"); +  sp--; +  sp[-1].u.integer %= sp[0].u.integer; +  return; +  +  default: +  error("Bad argument 1 to modulo.\n"); +  } + } +  + void f_not() + { +  if(sp[-1].type==T_INT) +  { +  sp[-1].u.integer = !sp[-1].u.integer; +  }else{ +  pop_stack(); +  sp->type=T_INT; +  sp->u.integer=0; +  sp++; +  } + } +  + void f_compl() + { +  if (sp[-1].type != T_INT) error("Bad argument to ~\n"); +  sp[-1].u.integer = ~ sp[-1].u.integer; + } +  + void f_negate() + { +  switch(sp[-1].type) +  { +  case T_FLOAT: +  sp[-1].u.float_number=-sp[-1].u.float_number; +  return; +  +  case T_INT: +  sp[-1].u.integer = - sp[-1].u.integer; +  return; +  +  default: +  error("Bad argument to unary minus\n"); +  } + } +  +  + void f_range() + { +  INT32 from,to; +  if(sp[-2].type != T_INT) +  error("Bad argument 1 to [ .. ]\n"); +  +  if(sp[-1].type != T_INT) +  error("Bad argument 2 to [ .. ]\n"); +  +  from=sp[-2].u.integer; +  if(from<0) from=0; +  to=sp[-1].u.integer; +  if(to<from-1) to=from-1; +  sp-=2; +  +  switch(sp[-1].type) +  { +  case T_STRING: +  { +  struct lpc_string *s; +  if(to>=sp[-1].u.string->len-1) +  { +  if(from==0) return; +  to=sp[-1].u.string->len-1; +  +  if(from>to+1) from=to+1; +  } +  +  s=make_shared_binary_string(sp[-1].u.string->str+from,to-from+1); +  free_string(sp[-1].u.string); +  sp[-1].u.string=s; +  break; +  } +  +  case T_ARRAY: +  { +  struct array *a; +  if(to>=sp[-1].u.array->size-1) +  { +  to=sp[-1].u.array->size-1; +  +  if(from>to+1) from=to+1; +  } +  +  a=slice_array(sp[-1].u.array,from,to+1); +  free_array(sp[-1].u.array); +  sp[-1].u.array=a; +  break; +  } +  +  default: +  error("[ .. ] can only be done on strings and arrays.\n"); +  } + }   Newline at end of file added.