Define a primitive data type

From Rosetta Code
Revision as of 04:41, 15 May 2007 by rosettacode>Crc (Added Toka)
Task
Define a primitive data type
You are encouraged to solve this task according to the task description, using any language you may know.

Demonstrate how to define a type that behaves like an integer but has a lowest valid value of 1 and a highest valid value of 10. Include all bounds checking you need to write, or explain how the compiler or interpreter creates those bounds checks for you.

Ada

type My_Type is range 1..10;

The compiler identifies the range of valid values from the range specification 1..10 and automatically builds in bounds checking where it is needed. The compiler is smart enough to omit bounds checking when it is not needed.

A : My_Type := 3;
B : My_Type := A;

The compiler will omit bounds checking for the assignment of A to B above because both values are of My_Type. A cannot hold a value outside the range of 1..10, therefore the assignment cannot produce an out of bounds result.

C++

Compiler: GCC

This class relies on implicit conversions to do most int operations; however the combined operations with assignment have to be coded explicitly.

#include <stdexcept>

class tiny_int
{
public:
  tiny_int(int i):
    value(i)
  {
    if (value < 1)
      throw std::out_of_range("tiny_int: value smaller than 1");
    if (value > 10)
      throw std::out_of_range("tiny_int: value larger than 10");
  }
  operator int() const
  {
    return value;
  }
  tiny_int& operator+=(int i)
  {
    // by assigning to *this instead of directly modifying value, the
    // constructor is called and thus the check is enforced
    *this = value + i;
    return *this;
  }
  tiny_int& operator-=(int i)
  {
    *this = value - i;
    return *this;
  }
  tiny_int& operator*=(int i)
  {
    *this = value * i;
    return *this;
  }
  tiny_int& operator/=(int i)
  {
    *this = value / i;
    return *this;
  }
  tiny_int& operator<<=(int i)
  {
    *this = value << i;
    return *this;
  }
  tiny_int& operator>>=(int i)
  {
    *this = value >> i;
    return *this;
  }
  tiny_int& operator&=(int i)
  {
    *this = value & i;
    return *this;
  }
  tiny_int& operator|=(int i)
  {
    *this = value | i;
    return *this;
  }
private:
  unsigned char value; // we don't need more space
};

E

def MyNumber := 1..10
for i :MyNumber in [0, 5, 10, 15, 20, 25] {
    println(i)
}

(Note: The region guard, while provided with E, is entirely unprivileged code, and could be argued not to be "primitive".)

Perl

Interpreter: Perl 5.x

Perl internally handles variables. As far as simple variables go, there are strings and there are numerical variables. Perl also automatically converts from one to the other based on your use.

If you wanted to force a variable to contain a number of 1 .. 10 you could do this:

$var = undef if ($var !~ /^\d+$/ or $var < 1 or $var > 10);

Which is a check I expect you would have to do in any other language anyway to prevent the program from having problems if the user provided data out side the acceptable range.

Toka

needs quotes
{
  variable update
  [ update @ [ ! ] [ @ ] ifTrueFalse update off ] is action
  [ dup >r 0 11 r> within [ update on ] [ drop ." Out of bounds\n " ] ifTrueFalse ]
  [ ` [ invoke cell-size malloc # ` action compile ` ] invoke is ]
} is value:1-10:
  is to

value:1-10: foo
1 to foo
foo .