Beispiel #1
0
var Int_Eq(var self, var other) {
  IntData* io = cast(self, Int);
  if (type_implements(type_of(other), AsLong)) {
    return (var)(intptr_t)(io->value == as_long(other));
  } else {
    return False;
  }
}
 friend closure_value 
 operator! (closure_value const &rhs)
 {
     switch (rhs.type) {
     case is_int:    return closure_value(!as_long(rhs), rhs.valid);
     case is_bool:   return closure_value(!as_bool(rhs), rhs.valid); 
     case is_uint:   break;
     }
     return closure_value(!as_ulong(rhs), rhs.valid);
 }
    friend closure_value 
    operator- (closure_value const &rhs)
    {
        switch (rhs.type) {
        case is_int:
            {
                long value = as_long(rhs);
                if (value != 0 && value == -value)
                    return closure_value(-value, error_integer_overflow);
                return closure_value(-value, rhs.valid);
            }
            
        case is_bool:   return closure_value(-as_long(rhs), rhs.valid); 
        case is_uint:   break;
        }

        long value = as_ulong(rhs);
        if (value != 0 && value == -value)
            return closure_value(-value, error_integer_overflow);
        return closure_value(-value, rhs.valid);
    }
 friend closure_value 
 operator< (closure_value const &lhs, closure_value const &rhs)
 {
     bool cmp = false;
     switch (lhs.type) {
     case is_int:
         switch(rhs.type) {
         case is_bool:   cmp = lhs.value.i < as_long(rhs); break;
         case is_int:    cmp = lhs.value.i < rhs.value.i; break;
         case is_uint:   cmp = lhs.value.ui < rhs.value.ui; break;
         }
         break;
         
     case is_uint:   cmp = lhs.value.ui < as_ulong(rhs); break;
     case is_bool:   cmp = as_bool(lhs) < as_bool(rhs); break;
     }
     return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
 }
    closure_value &operator%= (closure_value const &rhs)
    {
        switch (type) {
        case is_int:    
            switch(rhs.type) {
            case is_bool:   
            case is_int:
                if (as_long(rhs) != 0) {
                    if (value.i == -value.i && -1 == rhs.value.i) {
                    // LONG_MIN % -1 on two's complement
                        valid = error_integer_overflow;
                    }
                    else {
                        value.i %= as_long(rhs); 
                    }
                }
                else {
                    valid = error_division_by_zero;      // division by zero
                }
                break;
                
            case is_uint:
                if (rhs.value.ui != 0) {
                    value.ui %= rhs.value.ui; 
                    type = is_uint; 
                }
                else {
                    valid = error_division_by_zero;      // division by zero
                }
                break;
            }
            break;
            
        case is_uint: 
            if (as_ulong(rhs) != 0) 
                value.ui %= as_ulong(rhs); 
            else
                valid = error_division_by_zero;      // division by zero
            break;

        case is_bool:  
            if (as_bool(rhs)) {
                switch(rhs.type) {
                case is_int:
                    value.i = (value.b ? 1 : 0) % rhs.value.i;
                    type = is_int;
                    break;
                    
                case is_uint:
                    value.i = (value.b ? 1 : 0) % rhs.value.ui;
                    type = is_int;
                    break;
                    
                case is_bool:
                    break;
                }                    
            }
            else {
                valid = error_division_by_zero;      // division by zero
            }
        }
        return *this;
    }
 closure_value &operator*= (closure_value const &rhs)
 {
     switch (type) {
     case is_int:    
         switch(rhs.type) {
         case is_bool:   value.i *= as_long(rhs); break;
         case is_int:
             {
                 long result = value.i * rhs.value.i; 
                 if (0 != value.i && 0 != rhs.value.i &&
                     (result / value.i != rhs.value.i ||
                      result / rhs.value.i != value.i)
                    )
                 {
                     valid = error_integer_overflow;
                 }
                 else {
                     value.i = result;
                 }
             }
             break;
             
         case is_uint:
             {
                 unsigned long result = value.ui * rhs.value.ui; 
                 if (0 != value.ui && 0 != rhs.value.ui &&
                     (result / value.ui != rhs.value.ui ||
                      result / rhs.value.ui != value.ui)
                    )
                 {
                     valid = error_integer_overflow;
                 }
                 else {
                     value.ui = result;
                     type = is_uint; 
                 }
             }
             break;
         }
         break;
         
     case is_uint:
         {
             unsigned long rhs_val = as_ulong(rhs);
             unsigned long result = value.ui * rhs_val; 
             if (0 != value.ui && 0 != rhs_val &&
                 (result / value.ui != rhs_val ||
                   result / rhs_val != value.ui)
                 )
             {
                 valid = error_integer_overflow;
             }
             else {
                 value.ui = result;
                 type = is_uint; 
             }
         }
         break;
         
     case is_bool:
         switch (rhs.type) {
         case is_int:
             value.i = (value.b ? 1 : 0) * rhs.value.i; 
             type = is_int; 
             break;
             
         case is_uint:
             value.ui = (value.b ? 1 : 0) * rhs.value.ui; 
             type = is_uint; 
             break;
             
         case is_bool:
             value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
             break;
         }
     }
     valid = (value_error)(valid | rhs.valid);
     return *this;
 }
    closure_value &operator-= (closure_value const &rhs)
    {
        switch (type) {
        case is_int:
            switch(rhs.type) {
            case is_bool:
                {
                    long result = value.i - as_long(rhs); 
                    if (rhs.value.i > 0L && result > value.i || 
                        rhs.value.i < 0L && result < value.i)
                    {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;

            case is_int:
                {
                    long result = value.i - rhs.value.i;
                    if (rhs.value.i > 0L && result > value.i || 
                        rhs.value.i < 0L && result < value.i)
                    {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    unsigned long result = value.ui - rhs.value.ui; 
                    if (result > value.ui) {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.ui = result;
                        type = is_uint; 
                    }
                }
                break;
            }
            break;
            
        case is_uint:
            switch(rhs.type) {
            case is_bool:
                {
                    unsigned long result = value.ui - as_ulong(rhs); 
                    if (result > value.ui)
                    {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.ui = result;
                    }
                }
                break;

            case is_int:
                {
                    unsigned long result = value.ui - rhs.value.i;
                    if (rhs.value.i > 0L && result > value.ui || 
                        rhs.value.i < 0L && result < value.ui)
                    {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.ui = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    unsigned long result = value.ui - rhs.value.ui; 
                    if (result > value.ui) {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.ui = result;
                    }
                }
                break;
            }
            break;

        case is_bool:   
            value.i = value.b - as_bool(rhs);
            type = is_int;
        }
        valid = (value_error)(valid | rhs.valid);
        return *this;
    }
Beispiel #8
0
local var TestType_New(var self, var_list vl)
{
	TestTypeData *ttd = cast(self, TestType);
	ttd->test_data = as_long(var_list_get(vl));
	return self;
}
Beispiel #9
0
	x = cast(x, Int);
	y = cast(y, Real);

	PT_ASSERT(x);
	PT_ASSERT(y);

}

PT_FUNC(test_new)
{

	var x = new(Int, $(Int, 1));

	PT_ASSERT(x);
	PT_ASSERT(type_of(x) is Int);
	PT_ASSERT(as_long(x) is 1);

	delete(x);

	var y = $(Real, 0.0);
	construct(y, $(Real, 1.0));
	PT_ASSERT(as_double(y) is 1.0);

	var z = allocate(String);
	PT_ASSERT(z);
	construct(z, $(String, "Hello"));
	PT_ASSERT_STR_EQ(as_str(z), "Hello");
	z = destruct(z);
	deallocate(z);

}
Beispiel #10
0
int print_to_va(var out, int pos, const char* fmt, va_list va) {

  char fmt_buf[strlen(fmt)+1]; 
  
  while(true) {
    
    if (*fmt == '\0') { break; }
    
    const char* start = fmt;
    
    /* Match String */
    while(!strchr("%\0", *fmt)) { fmt++; }
    
    if (start != fmt) {
      strncpy(fmt_buf, start, (fmt - start));
      fmt_buf[(fmt - start)] = '\0';
      int off = format_to(out, pos, fmt_buf);
      if (off < 0) { throw(FormatError, "Unable to output format!"); }
      pos += off;
      continue;
    }
    
    /* Match %% */
    if (*fmt == '%' && *(fmt+1) == '%') {
      int off = format_to(out, pos, "%%");
      if (off < 0) { throw(FormatError, "Unable to output '%%%%'!"); }
      pos += off;
      fmt += 2;
      continue;
    }
    
    /* Match Format Specifier */
    while(!strchr("diuoxXfFeEgGaAxcsp$\0", *fmt)) { fmt++; }
    
    if (start != fmt) {
    
      strncpy(fmt_buf, start, (fmt - start)+1);
      fmt_buf[(fmt - start)+1] = '\0';
      
      var a = va_arg(va, var);
      
      if (*fmt == '$') { pos = show_to(a, out, pos); }
      
      if (*fmt == 's') {      
        int off = format_to(out, pos, fmt_buf, as_str(a));
        if (off < 0) { throw(FormatError, "Unable to output String!"); }
        pos += off;
      }
      
      if (strchr("diouxX", *fmt)) {
        int off = format_to(out, pos, fmt_buf, as_long(a));
        if (off < 0) { throw(FormatError, "Unable to output Int!"); }
        pos += off;
      }
      
      if (strchr("fFeEgGaA", *fmt)) { 
        int off = format_to(out, pos, fmt_buf, as_double(a));
        if (off < 0) { throw(FormatError, "Unable to output Real!"); }
        pos += off;
      }
      
      if (*fmt == 'c') {
        int off = format_to(out, pos, fmt_buf, as_char(a));
        if (off < 0) { throw(FormatError, "Unable to output Char!"); }
        pos += off;
      }
      
      if (*fmt == 'p') {
        int off = format_to(out, pos, fmt_buf, a);
        if (off < 0) { throw(FormatError, "Unable to output Object!"); }
        pos += off;
      }

      fmt++;
      continue;
    }
    
    throw(FormatError, "Invalid Format String!");
  }
  
  return pos;
  
}
Beispiel #11
0
void Int_Assign(var self, var obj) {
  IntData* intdata = cast(self, Int);
  intdata->value = as_long(obj);
}
Beispiel #12
0
void Int_Div(var self, var other) {
  IntData* io = cast(self, Int);
  io->value /= as_long(other);
}
Beispiel #13
0
void Int_Mul(var self, var other) {
  IntData* io = cast(self, Int);
  io->value *= as_long(other);
}
Beispiel #14
0
void Int_Sub(var self, var other) {
  IntData* io = cast(self, Int);
  io->value -= as_long(other);
}
Beispiel #15
0
void Int_Add(var self, var other) {
  IntData* io = cast(self, Int);
  io->value += as_long(other);
}
Beispiel #16
0
var Int_Lt(var self, var other) {
  IntData* io = cast(self, Int);
  return (var)(intptr_t)(io->value < as_long(other));
}
Beispiel #17
0
 long as_long_suffix() const { return as_long(true); }
    closure_value &
    operator<<= (closure_value const &rhs)
    {
        switch (type) {
        case is_bool:
        case is_int:
            switch (rhs.type) {
            case is_bool:
            case is_int:
                {
                long shift_by = as_long(rhs);
                    
                    if (shift_by > 64) 
                        shift_by = 64;
                    else if (shift_by < -64)
                        shift_by = -64;
                    value.i <<= shift_by; 
                }
                break;
                
            case is_uint:
                {
                unsigned long shift_by = as_ulong(rhs);
                    
                    if (shift_by > 64) 
                        shift_by = 64;
                    value.ui <<= shift_by; 
                
                // Note: The usual arithmetic conversions are not performed on 
                //       bit shift operations.
                }
                break;
            }
            break;

        case is_uint:
            switch (rhs.type) {
            case is_bool:
            case is_int:
                {
                long shift_by = as_long(rhs);
                    
                    if (shift_by > 64) 
                        shift_by = 64;
                    else if (shift_by < -64)
                        shift_by = -64;
                    value.ui <<= shift_by; 
                }
                break;
                
            case is_uint:
                {
                unsigned long shift_by = as_ulong(rhs);
                    
                    if (shift_by > 64) 
                        shift_by = 64;
                    value.ui <<= shift_by; 
                }
                break;
            }
        }
        valid = (value_error)(valid | rhs.valid);
        return *this;
    }
// arithmetics
    closure_value &operator+= (closure_value const &rhs)
    {
        switch (type) {
        case is_int:    
            switch(rhs.type) {
            case is_bool:
                {
                    int_literal_type result = value.i + as_long(rhs); 
                    if ((rhs.value.i > 0L && value.i > result) || 
                        (rhs.value.i < 0L && value.i < result))
                    {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_int:
                {
                    int_literal_type result = value.i + rhs.value.i;
                    if ((rhs.value.i > 0L && value.i > result) || 
                        (rhs.value.i < 0L && value.i < result))
                    {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.i = result;
                    }
                }
                break;
                
            case is_uint:
                {
                    uint_literal_type result = value.ui + rhs.value.ui; 
                    if (result < value.ui) {
                        valid = error_integer_overflow;
                    }
                    else {
                        value.ui = result;
                        type = is_uint; 
                    }
                }
                break;
            }
            break;
            
        case is_uint:
            {
                uint_literal_type result = value.ui + as_ulong(rhs); 
                if (result < value.ui) {
                    valid = error_integer_overflow;
                }
                else {
                    value.ui = result;
                }
            }
            break;
            
        case is_bool:   
            value.i = value.b + as_bool(rhs);
            type = is_int;
        }
        valid = (value_error)(valid | rhs.valid);
        return *this;
    }