Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // embellishment on comment in issue #1595
- enum NumberGroupType {
- // Measure types:
- // (* and /) yield compound types by adding or subtracting exponent arrays of the operands
- // (+ and -) restricted to work only on operands with same exponent array
- // comparators (==, <=, ..) restricted to work only on operands with same exponent array
- // e.g OK: 1[km] + 4[km] or 2[km] == 2.1[km] .. Not OK: 2[km] == 2[s].
- Measure_f64,
- Measure_i32,
- // Bitflag types:
- // No operators allowed except equality checks and bitwise AND, OR, and NOT
- Bitflag_u32,
- // only equality check allowed
- Key_u32,
- // all operators allowed, exponent array ignored, but cannot be mixed
- // with numbers from another NumberGroup or primitives
- Normal,
- }
- // used as an interface
- struct NumberGroup{
- // used by compiler to check compatability between operands
- getExponentArray : fn(self: @This()) []i8,
- // used by compiler to create correct types after operations
- fromExponentArray : fn([]i8) : @This(),
- // used by compiler to create a "named type" from an exponent array when possible
- // also to used to check 2nd parameter to "@distinct(number,NumberGroupInstance)" call
- namedTypes : []@This(),
- // used by compiler to select which rules to apply regarding operand compatability,
- // which subset of operators are available, and which primitive number type to accept
- numberType : NumberGroupType,
- }
- // assume <...> means "implements ..." in some form
- const PhysicalUnit = struct<NumberGroup>{
- const numberType: NumberType = NumberType.Measure_f64;
- e10: i8 = 0, //unit prefix, e.g kilo when e10=3, nano when e10=-9
- e60: i8 = 0 // unit prefix for time, e.g minute when e60=1, hour when e60=2
- m: i8 = 0, // meter
- s: i8 = 0, // second
- kg: i8 = 0, // kilogram
- k: i8 = 0, // kelvin
- mi: i8 = 0, // miles, imperial unit
- mo: i8 = 0, // mole
- A: i8 = 0, // ampere
- cd : i8 = 0, // candela
- const getExponentArray = fn(self:PhysicalUnit) [_]i8{
- return []i8{e10,e60,m,s,kg,k,mi,mo,A,cd};
- }
- const fromExponentArray = fn(arr : []i8) PhysicalUnit{
- return PhysicalUnit{
- .e10 = arr[0],
- .e60 = arr[1],
- .m = arr[2],
- // ...
- .cd = arr[9],
- }
- }
- const namedtypes : [_]PhysicalUnit = [_]{
- phys_UnitLess = PhysicalUnit{};
- phys_Meter = PhysicalUnit{.m=1};
- phys_Second = PhysicalUnit{.s=1};
- phys_PrSecond = PhysicalUnit{.s=-1};
- phys_Newton = PhysicalUnit{.s=-2,kg=1,m=1}
- // ..
- phys_SiMomentum = PhysicalUnit{.m=1,s=-1,kg=1};
- phys_KmPrHr = PhysicalUnit{.e10=3, .m=1, .e60=-2, .s=-1}
- }
- }
- }
- // Usage example:
- // * const x = @distinct( NUMBER , NUMBERGROUP_IMPL_INSTANCE);
- // * Where:
- // * - ´NUMBER´ is any builtin number type: u8, f64, i32,
- // * - ´NUMBERGROUP_IMPL_INSTANCE´ is an instance of a struct that implements (or embeds) a built in
- // * NumberGroup interface that the compiler recognizes and can use for compile time checks.
- // "phys_..." variables are instances of the struct PhysicalUnit
- const x = @distinct(0.13,phys_Second);
- const y = @distinct(20.3,phys_Meter);
- const z = y/z; // same as @distinct(20.3/0.13,phys_MeterPrSecond);
- // the two below expressions become compile errors as they are not allowed by NumberType.Measure_f64
- _ = z >> 2;
- _ = z & 5;
- // usage in function. assume workaround for treating instance ´phys_Newton' as a type
- fn calculateAcceleration(ball: Ball, force: phys_Newton) phys_MeterPrSecond2{
- // ... use fields like ball.mass : phys_Kilogram, etc in calculations
- //
- }
- // "db_..." variables are instances of the struct MyDbKeys, not shown
- const x = @distinct(4,db_Person);
- const y = @distinct(2,db_Task);
- // the 5 below expressions become compile errors as they are not allowed by NumberType.Key_u32
- _ = x + y;
- _ = x / y;
- _ = x + x
- _ = x == y;
- _ = x > y;
- // the below expressions are allowed
- const x2 = @distinct(5,db_Person);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement