Compare commits
13 commits
master
...
wip-struct
Author | SHA1 | Date | |
---|---|---|---|
923fe987dc | |||
3ed7a19270 | |||
6787e607a6 | |||
ef819b4711 | |||
3f1397735c | |||
67cec64dfc | |||
98592aa596 | |||
35b747ea15 | |||
39cba1ee57 | |||
583892f10d | |||
d98afc294d | |||
bce52e9fcf | |||
21bb33193a |
28 changed files with 1289 additions and 759 deletions
|
@ -3,70 +3,44 @@
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_angle_as_degrees_to_turns_float ()
|
morph_angle_as_degrees_to_turns_float ()
|
||||||
Angle ~ Degrees ~ ℝ ~ native.Float
|
Angle ~ Degrees ~ ℝ ~ native.Float32
|
||||||
--> Angle ~ Turns ~ ℝ ~ native.Float
|
--> Angle ~ Turns ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = *src / 360.0;```
|
||||||
*dst = *src / 360.0;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_angle_as_degrees_to_turns_double ()
|
morph_angle_as_degrees_to_turns_double ()
|
||||||
Angle ~ Degrees ~ ℝ ~ native.Double
|
Angle ~ Degrees ~ ℝ ~ native.Float64
|
||||||
--> Angle ~ Turns ~ ℝ ~ native.Double
|
--> Angle ~ Turns ~ ℝ ~ native.Float64
|
||||||
```
|
```*dst = *src / 360.0;```
|
||||||
*dst = *src / 360.0;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
morph_angle_as_turns_to_degrees_float ()
|
morph_angle_as_turns_to_degrees_float ()
|
||||||
Angle ~ Turns ~ ℝ ~ native.Float
|
Angle ~ Turns ~ ℝ ~ native.Float32
|
||||||
--> Angle ~ Degrees ~ ℝ ~ native.Float
|
--> Angle ~ Degrees ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = *src * 360.0;```
|
||||||
*dst = *src * 360.0;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_angle_as_turns_to_degrees_double ()
|
morph_angle_as_turns_to_degrees_double ()
|
||||||
Angle ~ Turns ~ ℝ ~ native.Double
|
Angle ~ Turns ~ ℝ ~ native.Float64
|
||||||
--> Angle ~ Degrees ~ ℝ ~ native.Double
|
--> Angle ~ Degrees ~ ℝ ~ native.Float64
|
||||||
```
|
```*dst = *src * 360.0;```
|
||||||
*dst = *src * 360.0;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
morph_angle_as_radians_to_turns_float ()
|
morph_angle_as_radians_to_turns_float ()
|
||||||
Angle ~ Radians ~ ℝ ~ native.Float
|
Angle ~ Radians ~ ℝ ~ native.Float32
|
||||||
--> Angle ~ Turns ~ ℝ ~ native.Float
|
--> Angle ~ Turns ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = *src / PHI;```
|
||||||
*dst = *src / PHI;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_angle_as_radians_to_turns_double ()
|
morph_angle_as_radians_to_turns_double ()
|
||||||
Angle ~ Radians ~ ℝ ~ native.Double
|
Angle ~ Radians ~ ℝ ~ native.Float64
|
||||||
--> Angle ~ Turns ~ ℝ ~ native.Double
|
--> Angle ~ Turns ~ ℝ ~ native.Float64
|
||||||
```
|
```*dst = *src / PHI;```
|
||||||
*dst = *src / PHI;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
morph_angle_as_turns_to_radians_float ()
|
morph_angle_as_turns_to_radians_float ()
|
||||||
Angle ~ Turns ~ ℝ ~ native.Float
|
Angle ~ Turns ~ ℝ ~ native.Float32
|
||||||
--> Angle ~ Radians ~ ℝ ~ native.Float
|
--> Angle ~ Radians ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = *src * PHI;```
|
||||||
*dst = *src * PHI;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_angle_as_degrees_to_radians_double ()
|
morph_angle_as_degrees_to_radians_double ()
|
||||||
Angle ~ Turns ~ ℝ ~ native.Double
|
Angle ~ Turns ~ ℝ ~ native.Float64
|
||||||
--> Angle ~ Radians ~ ℝ ~ native.Double
|
--> Angle ~ Radians ~ ℝ ~ native.Float64
|
||||||
```
|
```*dst = *src * PHI;```
|
||||||
*dst = *src * PHI;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
|
@ -60,8 +60,6 @@ morph_digit_as_uint8_to_char (Radix:ℤ_16)
|
||||||
fprintf(stderr, "digit %u is out of rage for char\n", *dst);
|
fprintf(stderr, "digit %u is out of rage for char\n", *dst);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_digit_as_uint64_to_char (Radix:ℤ_16)
|
morph_digit_as_uint64_to_char (Radix:ℤ_16)
|
||||||
|
@ -76,6 +74,4 @@ morph_digit_as_uint64_to_char (Radix:ℤ_16)
|
||||||
fprintf(stderr, "digit %u is out of rage for char\n", *dst);
|
fprintf(stderr, "digit %u is out of rage for char\n", *dst);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,11 +7,9 @@ morph_array_as_valterm_to_lenpfx (Terminator:native.UInt8)
|
||||||
<Seq~<ValueTerminated Terminator> native.UInt8>
|
<Seq~<ValueTerminated Terminator> native.UInt8>
|
||||||
--> <Seq~<LengthPrefix native.UInt64> native.UInt8>
|
--> <Seq~<LengthPrefix native.UInt64> native.UInt8>
|
||||||
```
|
```
|
||||||
length_prefix_uint64_t_array_uint8_t_clear(dst);
|
length_prefix_nativeUInt64_array_nativeUInt8_clear(dst);
|
||||||
while( *src != Terminator )
|
while( *src != Terminator )
|
||||||
length_prefix_uint64_t_array_uint8_t_push(dst, *src++);
|
length_prefix_nativeUInt64_array_nativeUInt8_push(dst, *src++);
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,8 +21,6 @@ morph_array_as_lenpfx_to_valterm (Terminator:native.UInt8)
|
||||||
*dst++ = src->items[i];
|
*dst++ = src->items[i];
|
||||||
|
|
||||||
*dst = Terminator;
|
*dst = Terminator;
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_array_as_lenpfx_to_continuation_bit (T:Type)
|
morph_array_as_lenpfx_to_continuation_bit (T:Type)
|
||||||
|
@ -42,6 +38,4 @@ morph_array_as_lenpfx_to_continuation_bit (T:Type)
|
||||||
if( i+1 < src->len )
|
if( i+1 < src->len )
|
||||||
dst[i] |= (1<<(n_bits-1));
|
dst[i] |= (1<<(n_bits-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -11,7 +11,6 @@ morph_nat_as_u64_to_pos ()
|
||||||
```
|
```
|
||||||
dst->len = 1;
|
dst->len = 1;
|
||||||
dst->items[0] = *src;
|
dst->items[0] = *src;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_nat_as_pos_to_u64 (Endianness:Type)
|
morph_nat_as_pos_to_u64 (Endianness:Type)
|
||||||
|
@ -22,7 +21,6 @@ morph_nat_as_pos_to_u64 (Endianness:Type)
|
||||||
~ native.UInt64
|
~ native.UInt64
|
||||||
```
|
```
|
||||||
*dst = src->items[0];
|
*dst = src->items[0];
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
|
morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
|
||||||
|
@ -40,20 +38,18 @@ morph_posint_radix_le (SrcRadix:ℤ, DstRadix:ℤ)
|
||||||
value += src->items[src->len - i - 1];
|
value += src->items[src->len - i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
length_prefix_uint64_t_array_uint64_t_clear( dst );
|
length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
|
||||||
|
|
||||||
#if DstRadix==0
|
#if DstRadix==0
|
||||||
length_prefix_uint64_t_array_uint64_t_push( dst, value );
|
length_prefix_nativeUInt64_array_nativeUInt64_push( dst, value );
|
||||||
#else
|
#else
|
||||||
if( value == 0 ) {
|
if( value == 0 ) {
|
||||||
length_prefix_uint64_t_array_uint64_t_push( dst, 0 );
|
length_prefix_nativeUInt64_array_nativeUInt64_push( dst, 0 );
|
||||||
} else while( value > 0 ) {
|
} else while( value > 0 ) {
|
||||||
length_prefix_uint64_t_array_uint64_t_push( dst, value % DstRadix );
|
length_prefix_nativeUInt64_array_nativeUInt64_push( dst, value % DstRadix );
|
||||||
value /= DstRadix;
|
value /= DstRadix;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
|
morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
|
||||||
|
@ -91,8 +87,6 @@ morph_posint_radix_be (SrcRadix:ℤ, DstRadix:ℤ)
|
||||||
value /= DstRadix;
|
value /= DstRadix;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_posint_endianness (Radix:ℤ)
|
morph_posint_endianness (Radix:ℤ)
|
||||||
|
@ -103,7 +97,7 @@ morph_posint_endianness (Radix:ℤ)
|
||||||
~ <PosInt Radix BigEndian>
|
~ <PosInt Radix BigEndian>
|
||||||
~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
|
~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
|
||||||
```
|
```
|
||||||
return length_prefix_uint64_t_array_uint64_t_reverse( src, dst );
|
return length_prefix_nativeUInt64_array_nativeUInt64_reverse( src, dst );
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_posint_endianness (Radix:ℤ)
|
morph_posint_endianness (Radix:ℤ)
|
||||||
|
@ -114,5 +108,5 @@ morph_posint_endianness (Radix:ℤ)
|
||||||
~ <PosInt Radix LittleEndian>
|
~ <PosInt Radix LittleEndian>
|
||||||
~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
|
~ <Seq~<LengthPrefix native.UInt64> <Digit Radix> ~ native.UInt64>
|
||||||
```
|
```
|
||||||
return length_prefix_uint64_t_array_uint64_t_reverse( src, dst );
|
return length_prefix_nativeUInt64_array_nativeUInt64_reverse( src, dst );
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,102 +4,87 @@
|
||||||
|
|
||||||
morph_real_as_decimalstr_to_float ()
|
morph_real_as_decimalstr_to_float ()
|
||||||
ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
||||||
--> ℝ ~ native.Float
|
--> ℝ ~ native.Float32
|
||||||
```
|
```sscanf(src, "%f", dst);```
|
||||||
sscanf(src, "%f", dst);
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_real_as_decimalstr_to_double ()
|
morph_real_as_decimalstr_to_double ()
|
||||||
ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
||||||
--> ℝ ~ native.Double
|
--> ℝ ~ native.Float64
|
||||||
```
|
```sscanf(src, "%lf", dst);```
|
||||||
sscanf(src, "%lf", dst);
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_real_as_float_to_decimalstr ()
|
morph_real_as_float_to_decimalstr ()
|
||||||
ℝ ~ native.Float
|
ℝ ~ native.Float32
|
||||||
--> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
--> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
||||||
```
|
```sprintf(dst, "%f", *src);```
|
||||||
sprintf(dst, "%f", *src);
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_real_as_double_to_decimalstr ()
|
morph_real_as_double_to_decimalstr ()
|
||||||
ℝ ~ native.Double
|
ℝ ~ native.Float64
|
||||||
--> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
--> ℝ ~ <PosInt 10 BigEndian> ~ <Seq~<ValueTerminated 0> <Digit 10>~Char~Ascii~native.UInt8>
|
||||||
```
|
```sprintf(dst, "%f", *src);```
|
||||||
sprintf(dst, "%f", *src);
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
morph_real_as_float_to_double ()
|
morph_real_as_float_to_double ()
|
||||||
ℝ ~ native.Float
|
ℝ ~ native.Float32
|
||||||
--> ℝ ~ native.Double
|
--> ℝ ~ native.Float64
|
||||||
```
|
```*dst = *src;```
|
||||||
*dst = *src;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_real_as_double_to_float ()
|
morph_real_as_double_to_float ()
|
||||||
ℝ ~ native.Double
|
ℝ ~ native.Float64
|
||||||
--> ℝ ~ native.Float
|
--> ℝ ~ native.Float32
|
||||||
```
|
```
|
||||||
fprintf(stderr, "Warning: morphin Double -> Float. Precision loss!");
|
fprintf(stderr, "Warning: morphin Double -> Float. Precision loss!");
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_real_as_u64_to_float ()
|
morph_real_as_u64_to_float ()
|
||||||
ℝ ~ ℕ ~ native.UInt64
|
ℝ ~ ℕ ~ native.UInt64
|
||||||
--> ℝ ~ native.Float
|
--> ℝ ~ native.Float32
|
||||||
```
|
```
|
||||||
fprintf(stderr, "Warning: morphin UInt64 -> Float. Precision loss!");
|
fprintf(stderr, "Warning: morphin UInt64 -> Float. Precision loss!");
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_real_as_u64_to_double ()
|
morph_real_as_u64_to_double ()
|
||||||
ℝ ~ ℕ ~ native.UInt64
|
ℝ ~ ℕ ~ native.UInt64
|
||||||
--> ℝ ~ native.Double
|
--> ℝ ~ native.Float64
|
||||||
```
|
```
|
||||||
fprintf(stderr, "Warning: morphin UInt64 -> Double. Precision loss!");
|
fprintf(stderr, "Warning: morphin UInt64 -> Double. Precision loss!");
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
return 0;
|
```
|
||||||
|
|
||||||
|
|
||||||
|
morph_real_as_nat_to_quantized_linear ()
|
||||||
|
ℝ ~ ℕ ~ native.UInt64
|
||||||
|
--> ℝ ~ <QuantizedLinear 0 1 1> ~ ℕ ~ native.UInt64
|
||||||
|
```
|
||||||
|
*dst = *src;
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
|
morph_real_as_quantized_linear_to_float (Begin: ℝ, End: ℝ, Steps: ℤ)
|
||||||
ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
||||||
--> ℝ ~ native.Float
|
--> ℝ ~ native.Float32
|
||||||
```
|
```
|
||||||
*dst = (float)Begin + ( *src * ((float)End - (float)Begin) ) / (float)Steps;
|
*dst = (float)Begin + ( *src * ((float)End - (float)Begin) ) / (float)Steps;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
|
morph_real_as_float_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
|
||||||
ℝ ~ native.Float
|
ℝ ~ native.Float32
|
||||||
--> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
--> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
||||||
```
|
```
|
||||||
*dst = ((*src - (float)Begin) * (float)Steps) / ((float)End - (float)Begin);
|
*dst = ((*src - (float)Begin) * (float)Steps) / ((float)End - (float)Begin);
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
morph_real_as_quantized_linear_to_double (Begin: ℝ, End: ℝ, Steps: ℤ)
|
morph_real_as_quantized_linear_to_double (Begin: ℝ, End: ℝ, Steps: ℤ)
|
||||||
ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
||||||
--> ℝ ~ native.Double
|
--> ℝ ~ native.Float64
|
||||||
```
|
```
|
||||||
*dst = (double)Begin + ( *src * ((double)End - (double)Begin) ) / (double)Steps;
|
*dst = (double)Begin + ( *src * ((double)End - (double)Begin) ) / (double)Steps;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_real_as_double_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
|
morph_real_as_double_to_quantized_linear (Begin: ℝ, End: ℝ, Steps: ℤ)
|
||||||
ℝ ~ native.Double
|
ℝ ~ native.Float64
|
||||||
--> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
--> ℝ ~ <QuantizedLinear Begin End Steps> ~ ℕ ~ native.UInt64
|
||||||
```
|
```
|
||||||
*dst = ((*src - (double)Begin) * (double)Steps) / ((double)End - (double)Begin);
|
*dst = ((*src - (double)Begin) * (double)Steps) / ((double)End - (double)Begin);
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,27 +2,37 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
/*
|
||||||
|
typedef struct { \
|
||||||
|
LEN_TYPE len; \
|
||||||
|
ITEM_TYPE items[]; \
|
||||||
|
} __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_; \
|
||||||
|
*/ \
|
||||||
|
|
||||||
|
#define LENGTH_PREFIX_ARRAY_TYPE(LEN_TYPE, ITEM_TYPE) \
|
||||||
|
__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_
|
||||||
|
|
||||||
|
#define LENGTH_PREFIX_ARRAY_CALL(LEN_TYPE, ITEM_TYPE, METHOD) \
|
||||||
|
length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_ ## METHOD
|
||||||
|
|
||||||
|
#define PRESCAN_LENGTH_PREFIX_CALL(LEN, ITEM, METHOD) \
|
||||||
|
LENGTH_PREFIX_ARRAY_CALL(LEN, ITEM, METHOD)
|
||||||
|
|
||||||
#define DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, ITEM_TYPE) \
|
#define DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, ITEM_TYPE) \
|
||||||
typedef struct { \
|
static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, clear) \
|
||||||
LEN_TYPE len; \
|
(__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data) { \
|
||||||
ITEM_TYPE items[]; \
|
|
||||||
} LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE; \
|
|
||||||
\
|
|
||||||
static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_clear( \
|
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data) { \
|
|
||||||
data->len = 0; \
|
data->len = 0; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_push( \
|
static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, push) \
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *data, \
|
(__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *data, \
|
||||||
ITEM_TYPE value) { \
|
ITEM_TYPE value) { \
|
||||||
data->items[data->len++] = value; \
|
data->items[data->len++] = value; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline int length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_reverse( \
|
static inline int PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, reverse) \
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * restrict src, \
|
( __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * restrict src, \
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE *restrict dst) { \
|
__Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ *restrict dst) { \
|
||||||
for (LEN_TYPE i = 0; i < src->len; i++) { \
|
for (LEN_TYPE i = 0; i < src->len; i++) { \
|
||||||
dst->items[i] = src->items[src->len - 1 - i]; \
|
dst->items[i] = src->items[src->len - 1 - i]; \
|
||||||
} \
|
} \
|
||||||
|
@ -30,60 +40,11 @@
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void length_prefix_##LEN_TYPE##_array_##ITEM_TYPE##_dump( \
|
static inline void PRESCAN_LENGTH_PREFIX_CALL(LEN_TYPE, ITEM_TYPE, dump) \
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##ITEM_TYPE const * data) { \
|
( __Seq__LengthPrefix_##LEN_TYPE##___##ITEM_TYPE##_ const * data) { \
|
||||||
printf("Length: %llu\n", (unsigned long long) data->len); \
|
printf("Length: %llu\n", (unsigned long long) data->len); \
|
||||||
for (LEN_TYPE i = 0; i < data->len; i++) { \
|
for (LEN_TYPE i = 0; i < data->len; i++) { \
|
||||||
printf("%llu ", (unsigned long long) data->items[i]); \
|
printf("%llu ", (unsigned long long) data->items[i]); \
|
||||||
} \
|
} \
|
||||||
printf("\n"); \
|
printf("\n"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_ALL_LENGTH_PREFIX_ARRAYS(LEN_TYPE) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint8_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint16_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint32_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY(LEN_TYPE, uint64_t)
|
|
||||||
|
|
||||||
DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint8_t)
|
|
||||||
DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint16_t)
|
|
||||||
DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint32_t)
|
|
||||||
DEFINE_ALL_LENGTH_PREFIX_ARRAYS(uint64_t)
|
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, SRC_ITEM_TYPE, DST_ITEM_TYPE) \
|
|
||||||
static inline int length_prefix_##LEN_TYPE##_array_map_##SRC_ITEM_TYPE##_to_##DST_ITEM_TYPE( \
|
|
||||||
int (*f)(SRC_ITEM_TYPE const * restrict, DST_ITEM_TYPE * restrict), \
|
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##SRC_ITEM_TYPE const * restrict src, \
|
|
||||||
LengthPrefix_##LEN_TYPE##_Array_##DST_ITEM_TYPE * restrict dst) \
|
|
||||||
{ \
|
|
||||||
if (dst->len < src->len) return -1; /* Ensure enough space */ \
|
|
||||||
for (LEN_TYPE i = 0; i < src->len; i++) { \
|
|
||||||
if (f(&src->items[i], &dst->items[i]) != 0) return -1; \
|
|
||||||
} \
|
|
||||||
dst->len = src->len; \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_ALL_MAPS(LEN_TYPE) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint8_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint16_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint32_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint8_t, uint64_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint8_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint16_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint32_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint16_t, uint64_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint8_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint16_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint32_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint32_t, uint64_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint8_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint16_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint32_t) \
|
|
||||||
DEFINE_LENGTH_PREFIX_ARRAY_MAP(LEN_TYPE, uint64_t, uint64_t)
|
|
||||||
|
|
||||||
DEFINE_ALL_MAPS(uint8_t)
|
|
||||||
DEFINE_ALL_MAPS(uint16_t)
|
|
||||||
DEFINE_ALL_MAPS(uint32_t)
|
|
||||||
DEFINE_ALL_MAPS(uint64_t)
|
|
||||||
|
|
|
@ -2,33 +2,21 @@
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_celsius_to_kelvin ()
|
morph_celsius_to_kelvin ()
|
||||||
Temperature ~ Celsius ~ ℝ ~ native.Float
|
Temperature ~ Celsius ~ ℝ ~ native.Float32
|
||||||
--> Temperature ~ Kelvin ~ ℝ ~ native.Float
|
--> Temperature ~ Kelvin ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = *src + 273.15;```
|
||||||
*dst = *src + 273.15;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_kelvin_to_celsius ()
|
morph_kelvin_to_celsius ()
|
||||||
Temperature ~ Kelvin ~ ℝ ~ native.Float
|
Temperature ~ Kelvin ~ ℝ ~ native.Float32
|
||||||
--> Temperature ~ Celsius ~ ℝ ~ native.Float
|
--> Temperature ~ Celsius ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = *src - 273.15;```
|
||||||
*dst = *src - 273.15;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_celsius_to_fahrenheit ()
|
morph_celsius_to_fahrenheit ()
|
||||||
Temperature ~ Celsius ~ ℝ ~ native.Float
|
Temperature ~ Celsius ~ ℝ ~ native.Float32
|
||||||
--> Temperature ~ Fahrenheit ~ ℝ ~ native.Float
|
--> Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = (*src * 9.0 / 5.0) + 32.0;```
|
||||||
*dst = (*src * 9.0 / 5.0) + 32.0;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
morph_fahrenheit_to_celsius ()
|
morph_fahrenheit_to_celsius ()
|
||||||
Temperature ~ Fahrenheit ~ ℝ ~ native.Float
|
Temperature ~ Fahrenheit ~ ℝ ~ native.Float32
|
||||||
--> Temperature ~ Celsius ~ ℝ ~ native.Float
|
--> Temperature ~ Celsius ~ ℝ ~ native.Float32
|
||||||
```
|
```*dst = (*src - 32.0) * 5.0 / 9.0;```
|
||||||
*dst = (*src - 32.0) * 5.0 / 9.0;
|
|
||||||
return 0;
|
|
||||||
```
|
|
||||||
|
|
|
@ -11,5 +11,4 @@ morph_unixtime_to_iso ()
|
||||||
if (!timeinfo) return -1;
|
if (!timeinfo) return -1;
|
||||||
|
|
||||||
strftime((char*)dst, 20, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
|
strftime((char*)dst, 20, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
17
morphisms/uint.morphism-base
Normal file
17
morphisms/uint.morphism-base
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
morph_nat_as_u8_to_u16 ()
|
||||||
|
ℕ ~ native.UInt8
|
||||||
|
--> ℕ ~ native.UInt16
|
||||||
|
```*dst = *src;```
|
||||||
|
|
||||||
|
morph_nat_as_u16_to_u32 ()
|
||||||
|
ℕ ~ native.UInt16
|
||||||
|
--> ℕ ~ native.UInt32
|
||||||
|
```*dst = *src;```
|
||||||
|
|
||||||
|
morph_nat_as_u32_to_u64 ()
|
||||||
|
ℕ ~ native.UInt32
|
||||||
|
--> ℕ ~ native.UInt64
|
||||||
|
```*dst = *src;```
|
|
@ -28,7 +28,6 @@ morph_string_as_utf8_to_ascii ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*dst = 0;
|
*dst = 0;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_string_as_ascii_to_utf32 ()
|
morph_string_as_ascii_to_utf32 ()
|
||||||
|
@ -39,7 +38,6 @@ morph_string_as_ascii_to_utf32 ()
|
||||||
```
|
```
|
||||||
while( *src ) { *dst++ = *src++; }
|
while( *src ) { *dst++ = *src++; }
|
||||||
*dst = 0;
|
*dst = 0;
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_string_as_utf8_to_utf32 ()
|
morph_string_as_utf8_to_utf32 ()
|
||||||
|
@ -89,6 +87,4 @@ morph_string_as_utf8_to_utf32 ()
|
||||||
*dst++ = val;
|
*dst++ = val;
|
||||||
|
|
||||||
*dst++ = 0;
|
*dst++ = 0;
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -12,23 +12,21 @@ morph_seqseq_valsep_uint8 (T: Type, SrcDelim: T, DstDelim: T)
|
||||||
~ < ValueSep DstDelim T >
|
~ < ValueSep DstDelim T >
|
||||||
~ < Seq~<LengthPrefix native.UInt64> T >
|
~ < Seq~<LengthPrefix native.UInt64> T >
|
||||||
```
|
```
|
||||||
length_prefix_uint64_t_array_uint8_t_clear( dst );
|
PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, clear)( dst );
|
||||||
|
|
||||||
uint8_t * dst_items = dst->items;
|
uint8_t * dst_items = dst->items;
|
||||||
for( uint64_t i = 0; i < src->len; ++i ) {
|
for( uint64_t i = 0; i < src->len; ++i ) {
|
||||||
if( src->items[i] == SrcDelim ) {
|
if( src->items[i] == SrcDelim ) {
|
||||||
length_prefix_uint64_t_array_uint8_t_push( dst, DstDelim );
|
PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, DstDelim );
|
||||||
} else if( src->items[i] == DstDelim ) {
|
} else if( src->items[i] == DstDelim ) {
|
||||||
if( DstDelim == '\n' ) {
|
if( DstDelim == '\n' ) {
|
||||||
length_prefix_uint64_t_array_uint8_t_push( dst, '\\' );
|
PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, '\\' );
|
||||||
length_prefix_uint64_t_array_uint8_t_push( dst, 'n' );
|
PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, 'n' );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
length_prefix_uint64_t_array_uint8_t_push( dst, src->items[i] );
|
PRESCAN_LENGTH_PREFIX_CALL(nativeUInt64, T, push)( dst, src->items[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,9 +42,9 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
|
||||||
~ native.UInt64
|
~ native.UInt64
|
||||||
>
|
>
|
||||||
```
|
```
|
||||||
length_prefix_uint64_t_array_uint64_t_clear( dst );
|
length_prefix_nativeUInt64_array_nativeUInt64_clear( dst );
|
||||||
|
|
||||||
struct LengthPrefix_uint64_t_Array_uint8_t * cur_item = NULL;
|
struct LengthPrefix_nativeUInt64_Array_nativeUInt8 * cur_item = NULL;
|
||||||
|
|
||||||
uint8_t const * start = &src->items[0];
|
uint8_t const * start = &src->items[0];
|
||||||
uint8_t const * cur = start;
|
uint8_t const * cur = start;
|
||||||
|
@ -60,14 +58,12 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
|
||||||
cur_item->len = len;
|
cur_item->len = len;
|
||||||
memcpy( cur_item->items, start, len );
|
memcpy( cur_item->items, start, len );
|
||||||
|
|
||||||
length_prefix_uint64_t_array_uint64_t_push( dst, (uint64_t)cur_item );
|
length_prefix_nativeUInt64_array_nativeUInt64_push( dst, (uint64_t)cur_item );
|
||||||
start = ++cur;
|
start = ++cur;
|
||||||
} else {
|
} else {
|
||||||
cur++;
|
cur++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
|
morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
|
||||||
|
@ -81,19 +77,17 @@ morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
|
||||||
~ < ValueSep T Delim >
|
~ < ValueSep T Delim >
|
||||||
~ < Seq~<LengthPrefix native.UInt64> T >
|
~ < Seq~<LengthPrefix native.UInt64> T >
|
||||||
```
|
```
|
||||||
length_prefix_uint64_t_array_uint8_t_clear( dst );
|
length_prefix_nativeUInt64_array_nativeUInt8_clear( dst );
|
||||||
|
|
||||||
for( uint64_t i = 0; i < src->len; ++i ) {
|
for( uint64_t i = 0; i < src->len; ++i ) {
|
||||||
LengthPrefix_uint64_t_Array_uint8_t * item = src->items[i];
|
LengthPrefix_nativeUInt64_Array_nativeUInt8_t * item = src->items[i];
|
||||||
|
|
||||||
for( uint64_t j = 0; j < item->len; ++j ) {
|
for( uint64_t j = 0; j < item->len; ++j ) {
|
||||||
length_prefix_uint64_t_array_uint8_t_push( items->items[j] );
|
length_prefix_nativeUInt64_array_nativeUInt8_push( items->items[j] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i+1 < src->len ) {
|
if( i+1 < src->len ) {
|
||||||
length_prefix_uint64_t_array_uint8_t_push( Delim );
|
length_prefix_nativeUInt64_array_nativeUInt8_push( Delim );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -10,8 +10,6 @@ morph_i64_as_twos_complement_to_zigzag ()
|
||||||
} else {
|
} else {
|
||||||
*dst = (2 * (uint64_t)(- *src)) - 1;
|
*dst = (2 * (uint64_t)(- *src)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
morph_i64_as_zigzag_to_twos_complement ()
|
morph_i64_as_zigzag_to_twos_complement ()
|
||||||
|
|
100
platforms/json.lt
Normal file
100
platforms/json.lt
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
|
||||||
|
type UTF8-String = <Seq Char~Unicode> ~ UTF-8 ~ <Seq~<ValueTerminated 0> native.UInt8> ;
|
||||||
|
|
||||||
|
type SerializedJson.Value = json.Value
|
||||||
|
~ <Enum
|
||||||
|
<Null json.Null ~ SerializedJson.Null >
|
||||||
|
<String json.String ~ SerializedJson.String >
|
||||||
|
<Number json.Number ~ SerializedJson.Number >
|
||||||
|
<Bool json.Bool ~ SerializedJson.Bool >
|
||||||
|
<Array json.Array ~ SerializedJson.Array >
|
||||||
|
<Object json.Object ~ SerializedJson.Object >>
|
||||||
|
~ <Seq Char> ;
|
||||||
|
|
||||||
|
type SerializedJson.Null = < Struct~<Seq Char> "\"null\"" > ;
|
||||||
|
|
||||||
|
type SerializedJson.String = <Seq Char>
|
||||||
|
~ <Struct~<Seq Char> "\"" <Seq Char> "\"">
|
||||||
|
~ <Seq Char> ;
|
||||||
|
|
||||||
|
type SerializedJson.Number = ℝ
|
||||||
|
~ <PosInt 10 BigEndian>
|
||||||
|
~ <Seq <Digit 10> ~ Char> ;
|
||||||
|
|
||||||
|
type SerializedJson.Bool = Bool
|
||||||
|
~ <Enum~<Seq Char>
|
||||||
|
<True~"\"true\"" <>>
|
||||||
|
<False~"\"false\"" <>>>
|
||||||
|
~ <Seq Char> ;
|
||||||
|
|
||||||
|
type SerializedJson.Array = <Struct~<Seq Char>
|
||||||
|
"["
|
||||||
|
<Seq json.Value>
|
||||||
|
~ <ValueSep ',' Char>
|
||||||
|
~ <Seq Char>
|
||||||
|
"]" >
|
||||||
|
~ <Seq Char> ;
|
||||||
|
|
||||||
|
type SerializedJson.Object = <Struct~<Seq Char>
|
||||||
|
"{"
|
||||||
|
<members <Seq
|
||||||
|
<Struct~<Seq Char>
|
||||||
|
<key json.String>
|
||||||
|
":"
|
||||||
|
<value json.Value>>>>
|
||||||
|
"}"
|
||||||
|
>
|
||||||
|
~ <Seq Char>;
|
||||||
|
|
||||||
|
type parsedJson.Value = json.Value ~ <Enum~native.UInt8
|
||||||
|
< parsedJson_Null~0 <> >
|
||||||
|
< parsedJson_String~1 <Ref UTF8-String> ~ native.Address >
|
||||||
|
< parsedJson_Int~2 ℝ~ℕ~native.UInt64 >
|
||||||
|
< parsedJson_Float~2 ℝ~native.Float64 >
|
||||||
|
< parsedJson_Bool~3 Bool ~ native.UInt8 >
|
||||||
|
|
||||||
|
< parsedJson_Array~4 <Ref <Seq ~ <LengthPrefix native.UInt64>
|
||||||
|
parsedJsonValue
|
||||||
|
>
|
||||||
|
>
|
||||||
|
~ native.Address >
|
||||||
|
|
||||||
|
< parsedJson_Object~5 <Ref <Seq ~ <LengthPrefix native.UInt64>
|
||||||
|
<Struct
|
||||||
|
<key <Ref UTF8-String> ~ native.Address>
|
||||||
|
<val parsedJsonValue>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
~ native.Address >>
|
||||||
|
~ <Struct
|
||||||
|
<tag native.UInt8>
|
||||||
|
native.UInt64 >;
|
||||||
|
|
||||||
|
parse_json_value ()
|
||||||
|
json.Value ~ UTF8-String
|
||||||
|
--> json.Value ~ parsedJsonValue
|
||||||
|
```
|
||||||
|
|
||||||
|
{
|
||||||
|
dst->tag = PARSED_JSON_NULL;
|
||||||
|
dst->parsedJson_Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
dst->tag = PARSED_JSON_STRING;
|
||||||
|
dst->parsedJson_String = malloc(len);
|
||||||
|
strncpy(dst->parsedJson_String, src, len);
|
||||||
|
src += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
dst->tag = PARSED_JSON_NUMBER;
|
||||||
|
|
||||||
|
MORPH(
|
||||||
|
"ℝ ~ ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ Char> ~ UTF8-String",
|
||||||
|
"ℝ ~ ℕ ~ native.UInt64",
|
||||||
|
src,
|
||||||
|
&dst->parsedJson_Number
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
0
platforms/json5.lt
Normal file
0
platforms/json5.lt
Normal file
3
platforms/protobuf.lt
Normal file
3
platforms/protobuf.lt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
type protobuf.Varint = ℕ ~ <PosInt 128 LittleEndian> ~ <Seq~MsbCont <Digit 128> ~ ℤ_128 ~ native.UInt8> ;
|
||||||
|
type protobuf.String = <Seq Char ~ Unicode> ~ UTF-8 ~ <Seq ~ <LengthPrefix protobuf.Varint> Byte> ;
|
0
platforms/spapod.lt
Normal file
0
platforms/spapod.lt
Normal file
5
platforms/x86.lt
Normal file
5
platforms/x86.lt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
type x86.UInt64 = ℤ_2/\64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >;
|
||||||
|
type x86.UInt32 = ℤ_2/\32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >;
|
||||||
|
type x86.UInt16 = ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >;
|
||||||
|
type x86.UInt8 = ℤ_256 ~ <Posint 2 BigEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>;
|
419
src/c_gen.rs
419
src/c_gen.rs
|
@ -1,419 +0,0 @@
|
||||||
use {
|
|
||||||
laddertypes::{TypeDict, TypeTerm, parser::*, unparser::*, morphism::{Morphism, MorphismInstance}},
|
|
||||||
crate::morphism::{LdmcPrimCMorphism, LdmcMorphism}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
pub fn get_c_repr_kind(kind: String) -> Option<String> {
|
|
||||||
match kind.as_str() {
|
|
||||||
"ℤ" => Some("uint64_t".into()),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for a given ladder type `t`, get the corresponding C type
|
|
||||||
*/
|
|
||||||
pub fn get_c_repr_type(dict: &mut impl TypeDict, t: laddertypes::TypeTerm, skip_pointer: bool) -> Option<String> {
|
|
||||||
let lnf = t.normalize().decurry().get_lnf_vec();
|
|
||||||
|
|
||||||
match lnf.last() {
|
|
||||||
Some(t) => {
|
|
||||||
if t == &dict.parse("Byte").expect("parse")
|
|
||||||
|| t == &dict.parse("native.UInt8").expect("parse")
|
|
||||||
|| t == &dict.parse("<StaticLength 8 Bit>").expect("parse")
|
|
||||||
{
|
|
||||||
Some("uint8_t".into())
|
|
||||||
} else if t == &dict.parse("native.UInt16").expect("parse") {
|
|
||||||
Some("uint16_t".into())
|
|
||||||
} else if t == &dict.parse("native.UInt32").expect("parse") {
|
|
||||||
Some("uint32_t".into())
|
|
||||||
} else if t == &dict.parse("native.UInt64").expect("parse") {
|
|
||||||
Some("uint64_t".into())
|
|
||||||
} else if t == &dict.parse("native.Float").expect("parse") {
|
|
||||||
Some("float".into())
|
|
||||||
} else if t == &dict.parse("native.Double").expect("parse") {
|
|
||||||
Some("double".into())
|
|
||||||
} else {
|
|
||||||
match t {
|
|
||||||
laddertypes::TypeTerm::App(args) => {
|
|
||||||
if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"LengthPrefix".into()).unwrap())
|
|
||||||
{
|
|
||||||
let length_c_type : String = get_c_repr_type(dict, args[1].clone(), false)?;
|
|
||||||
let item_c_type : String = get_c_repr_type(dict, args[2].clone(), false)?;
|
|
||||||
|
|
||||||
match length_c_type.as_str() {
|
|
||||||
"uint8_t" |
|
|
||||||
"uint16_t" |
|
|
||||||
"uint32_t" |
|
|
||||||
"uint64_t" => {}
|
|
||||||
_ => {
|
|
||||||
eprintln!("invalid length type!");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match item_c_type.as_str() {
|
|
||||||
"uint8_t" |
|
|
||||||
"uint16_t" |
|
|
||||||
"uint32_t" |
|
|
||||||
"uint64_t" => {}
|
|
||||||
_ => {
|
|
||||||
eprintln!("invalid item type!");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(format!("LengthPrefix_{}_Array_{}", length_c_type, item_c_type))
|
|
||||||
}
|
|
||||||
else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"ValueTerminated".into()).unwrap())
|
|
||||||
{
|
|
||||||
let _delim_val = args[1].clone();
|
|
||||||
let c_type = get_c_repr_type(dict, args[2].clone(), false)?;
|
|
||||||
if skip_pointer {
|
|
||||||
Some(c_type)
|
|
||||||
} else {
|
|
||||||
Some(format!("{} *", c_type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if args[0] == laddertypes::TypeTerm::TypeID(dict.get_typeid(&"MsbCont".into()).unwrap())
|
|
||||||
{
|
|
||||||
let c_type = get_c_repr_type(dict, args[1].clone(), false)?;
|
|
||||||
if skip_pointer {
|
|
||||||
Some(c_type)
|
|
||||||
} else {
|
|
||||||
Some(format!("{} *", c_type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn encode_type_to_symbol(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
|
|
||||||
match t {
|
|
||||||
laddertypes::TypeTerm::Char(c) => {
|
|
||||||
match c {
|
|
||||||
'.' => format!("_dot_"),
|
|
||||||
_ =>
|
|
||||||
format!("{}", (*c as u64))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
laddertypes::TypeTerm::Num(n) => {
|
|
||||||
format!("{}", n)
|
|
||||||
}
|
|
||||||
laddertypes::TypeTerm::TypeID(ty_id) => {
|
|
||||||
if let Some(name) = dict.get_typename(ty_id) {
|
|
||||||
format!("{}", name.replace(".", "_dot_"))
|
|
||||||
} else {
|
|
||||||
format!("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
laddertypes::TypeTerm::Ladder(rs) |
|
|
||||||
laddertypes::TypeTerm::App(rs) => {
|
|
||||||
let mut s = String::new();
|
|
||||||
for r in rs {
|
|
||||||
s.push('_');
|
|
||||||
s.push_str(&encode_type_to_symbol(dict, r));
|
|
||||||
}
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
|
|
||||||
dict.unparse(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn generate_main(type_dict: &mut impl TypeDict, path: Vec<MorphismInstance<LdmcMorphism>>, src_type: TypeTerm, dst_type: TypeTerm) {
|
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
/* todo: collect include files from morphism base */
|
|
||||||
println!(r#"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
"#);
|
|
||||||
|
|
||||||
let mut existing_instantiations = Vec::new();
|
|
||||||
for morph_inst in path.iter() {
|
|
||||||
match &morph_inst.m {
|
|
||||||
LdmcMorphism::Primitive( item_morph ) => {
|
|
||||||
let name = item_morph.instantiated_symbol_name(type_dict, &morph_inst.σ);
|
|
||||||
if ! existing_instantiations.contains(&name) {
|
|
||||||
if let Some(s) = item_morph.generate_instantiation(type_dict, &morph_inst.σ) {
|
|
||||||
println!("{}", s);
|
|
||||||
} else {
|
|
||||||
eprintln!("couldnt generate instance {}", name);
|
|
||||||
}
|
|
||||||
existing_instantiations.push( name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => {
|
|
||||||
let name = item_morph.instantiated_symbol_name(type_dict, &morph_inst.σ);
|
|
||||||
if ! existing_instantiations.contains(&name) {
|
|
||||||
if let Some(s) = item_morph.generate_instantiation(type_dict, &morph_inst.σ) {
|
|
||||||
println!("{}", s);
|
|
||||||
} else {
|
|
||||||
eprintln!("couldnt generate instance {}", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
existing_instantiations.push( name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!(r#"
|
|
||||||
int main() {{
|
|
||||||
uint8_t bufA[128];
|
|
||||||
uint8_t bufB[128];
|
|
||||||
|
|
||||||
memset(bufA, 0, sizeof(bufA));
|
|
||||||
memset(bufB, 0, sizeof(bufB));
|
|
||||||
|
|
||||||
char in_str[] = "read :: {} \n";
|
|
||||||
char out_str[]= "write:: {} \n";
|
|
||||||
write(2, in_str, strlen(in_str));
|
|
||||||
write(2, out_str, strlen(out_str));
|
|
||||||
|
|
||||||
int l = read(0, bufA, sizeof(bufA));
|
|
||||||
//fprintf(stderr, "read %d bytes\n", l);
|
|
||||||
|
|
||||||
"#,
|
|
||||||
type_dict.unparse(&src_type).replace("\\", "\\\\"),
|
|
||||||
type_dict.unparse(&dst_type).replace("\\", "\\\\") );
|
|
||||||
|
|
||||||
for morph_inst in path.iter() {
|
|
||||||
println!(r#"
|
|
||||||
/* morph to {}
|
|
||||||
|
|
||||||
...with
|
|
||||||
morph {}
|
|
||||||
---> {},
|
|
||||||
subst σ = {:?},
|
|
||||||
halo Ψ = {}
|
|
||||||
*/"#,
|
|
||||||
type_dict.unparse(&morph_inst.get_type().dst_type.param_normalize().decurry()),
|
|
||||||
type_dict.unparse(&morph_inst.m.get_type().src_type),
|
|
||||||
type_dict.unparse(&morph_inst.m.get_type().dst_type),
|
|
||||||
morph_inst.σ,
|
|
||||||
type_dict.unparse(&morph_inst.halo),
|
|
||||||
);
|
|
||||||
morph_inst.m.generate_call(type_dict, &morph_inst.σ, i);
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let out_buf = if i%2==0 { "bufA" } else { "bufB" };
|
|
||||||
|
|
||||||
let is_string = false;
|
|
||||||
if let Ok((halo, σ)) = laddertypes::subtype_unify(
|
|
||||||
&dst_type,
|
|
||||||
&type_dict.parse("<Seq~<ValueTerminated 0> native.UInt8>").unwrap()
|
|
||||||
) {
|
|
||||||
println!(r#"
|
|
||||||
printf("%s\n", {});"#, out_buf);
|
|
||||||
} else if let Ok((halo, σ)) = laddertypes::subtype_unify(
|
|
||||||
&dst_type,
|
|
||||||
&type_dict.parse("<Seq~<LengthPrefix native.UInt64> native.UInt8>").unwrap()
|
|
||||||
) {
|
|
||||||
println!(r#"
|
|
||||||
/* write output
|
|
||||||
*/
|
|
||||||
{{
|
|
||||||
LengthPrefix_uint64_t_Array_uint8_t * buf = (void*){};
|
|
||||||
write(1, {}, sizeof(uint64_t) + buf->len);
|
|
||||||
}}"#, out_buf, out_buf);
|
|
||||||
} else {
|
|
||||||
println!(r#"
|
|
||||||
write(1, {}, sizeof({}));"#,
|
|
||||||
out_buf,
|
|
||||||
out_buf
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
println!(r#"
|
|
||||||
return 0;
|
|
||||||
}}
|
|
||||||
"#);
|
|
||||||
|
|
||||||
eprintln!("Success: generated C code");
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LdmcPrimCMorphism {
|
|
||||||
pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict,
|
|
||||||
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> String {
|
|
||||||
let mut s = self.symbol.clone();
|
|
||||||
for (k_id,v) in self.type_args.iter() {
|
|
||||||
if let Some(val_trm) = σ.get(k_id) {
|
|
||||||
if let laddertypes::TypeID::Var(var_id) = k_id {
|
|
||||||
let name = dict.get_varname(*var_id).unwrap();
|
|
||||||
let val_str = encode_type_to_symbol(dict, val_trm);
|
|
||||||
s.push_str(&format!("_{}_{}", name, val_str));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let laddertypes::TypeID::Var(var_id) = k_id {
|
|
||||||
let k = dict.get_varname(*var_id).unwrap();
|
|
||||||
s.push_str(&format!("_{:?}_MISSING", k));
|
|
||||||
eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing {} ({})", k, var_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
|
|
||||||
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> String {
|
|
||||||
format!("int {} ({} const * restrict src, {} * restrict dst);",
|
|
||||||
self.instantiated_symbol_name(dict, σ),
|
|
||||||
get_c_repr_type(dict, self.src_type.clone(), true).expect("cant get c-repr type for src type"),
|
|
||||||
get_c_repr_type(dict, self.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>) -> Option<String> {
|
|
||||||
let mut s = String::new();
|
|
||||||
|
|
||||||
s.push_str(&format!(r#"
|
|
||||||
int {} ( {} const * restrict src, {} * restrict dst ) {{
|
|
||||||
"#,
|
|
||||||
self.instantiated_symbol_name(dict, &σ),
|
|
||||||
get_c_repr_type(dict, self.src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr-type"),
|
|
||||||
get_c_repr_type(dict, self.dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr-type"),
|
|
||||||
));
|
|
||||||
for (ty_id, kind) in self.type_args.iter() {
|
|
||||||
if let Some(val) = σ.get(ty_id) {
|
|
||||||
eprintln!("val = {}", dict.unparse(&val));
|
|
||||||
|
|
||||||
let type_var_value =
|
|
||||||
if let Some(c_repr_type) = get_c_repr_type(dict, val.clone(), true) {
|
|
||||||
c_repr_type
|
|
||||||
} else {
|
|
||||||
encode_type_to_value(dict, val)
|
|
||||||
};
|
|
||||||
|
|
||||||
s.push_str(&format!(" #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.push_str(&self.c_source);
|
|
||||||
|
|
||||||
for (ty_id, kind) in self.type_args.iter() {
|
|
||||||
s.push_str(&format!("\n #undef {}", dict.get_typename(&ty_id).unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
s.push_str(&format!(r#"
|
|
||||||
}}
|
|
||||||
"#));
|
|
||||||
Some(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LdmcMorphism {
|
|
||||||
pub fn generate_call(&self, dict: &mut impl TypeDict, σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>, i: u64) {
|
|
||||||
match self {
|
|
||||||
LdmcMorphism::Primitive(prim_morph) => {
|
|
||||||
let src_c_type = get_c_repr_type(dict, prim_morph.src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for src type");
|
|
||||||
let dst_c_type = get_c_repr_type(dict, prim_morph.dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone(), true).expect("cant get c-repr type for dst type");
|
|
||||||
|
|
||||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
|
||||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
|
||||||
|
|
||||||
println!(r#"
|
|
||||||
{}
|
|
||||||
{} const * restrict src = (void*) {};
|
|
||||||
{} * restrict dst = (void*) {};
|
|
||||||
{} ( src, dst );
|
|
||||||
{}"#,
|
|
||||||
'{',
|
|
||||||
src_c_type, src_buf,
|
|
||||||
dst_c_type, dst_buf,
|
|
||||||
prim_morph.instantiated_symbol_name(dict, σ),
|
|
||||||
'}');
|
|
||||||
}
|
|
||||||
LdmcMorphism::LengthPrefixMap { length_prefix_type, item_morph } => {
|
|
||||||
let src_type = self.get_type().src_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
|
|
||||||
let dst_type = self.get_type().dst_type.clone().apply_substitution(&|k| σ.get(k).cloned()).clone();
|
|
||||||
|
|
||||||
eprintln!("length prefix type ={:?}", length_prefix_type);
|
|
||||||
eprintln!("src_type ={:?}", src_type);
|
|
||||||
eprintln!("dst_type = {:?}", dst_type);
|
|
||||||
|
|
||||||
dict.add_varname("S".into());
|
|
||||||
|
|
||||||
let γ_src = laddertypes::unify(
|
|
||||||
&dict.parse("<Seq~<LengthPrefix S> T>").expect("parse template"),
|
|
||||||
&src_type
|
|
||||||
).expect("cant get src item type");
|
|
||||||
|
|
||||||
let γ_dst = laddertypes::unify(
|
|
||||||
&dict.parse("<Seq~<LengthPrefix S> T>").expect("parse template"),
|
|
||||||
&dst_type
|
|
||||||
).expect("cant get dst item type");
|
|
||||||
|
|
||||||
let src_length_type = γ_src.get(&dict.get_typeid(&"S".into()).unwrap()).expect("cant get src-length type").clone();
|
|
||||||
let dst_length_type = γ_src.get(&dict.get_typeid(&"S".into()).unwrap()).expect("cant get dst-length type").clone();
|
|
||||||
|
|
||||||
let length_type = src_length_type;
|
|
||||||
|
|
||||||
let src_item_type = γ_src.get(&dict.get_typeid(&"T".into()).unwrap()).expect("cant get src-item type").clone();
|
|
||||||
let dst_item_type = γ_dst.get(&dict.get_typeid(&"T".into()).unwrap()).expect("cant get src-item type").clone();
|
|
||||||
|
|
||||||
let length_c_type = get_c_repr_type(dict, length_type, true).expect("cant c-repr type for array length");
|
|
||||||
let src_item_c_type = get_c_repr_type(dict, src_item_type, true).expect("cant c-repr type for src item");
|
|
||||||
let dst_item_c_type = get_c_repr_type(dict, dst_item_type, true).expect("cant c-repr type for dst item");
|
|
||||||
let src_c_type = get_c_repr_type(dict, src_type, true).expect("cant get c-repr type for src type");
|
|
||||||
let dst_c_type = get_c_repr_type(dict, dst_type, true).expect("cant get c-repr type for dst type");
|
|
||||||
|
|
||||||
let map_fn = format!("length_prefix_{}_array_map_{}_to_{}",
|
|
||||||
length_c_type, src_item_c_type, dst_item_c_type
|
|
||||||
);
|
|
||||||
|
|
||||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
|
||||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
|
||||||
println!(r#"
|
|
||||||
{}
|
|
||||||
{} const * restrict src = (void*) {};
|
|
||||||
{} * restrict dst = (void*) {};
|
|
||||||
{} ( {}, src, dst );
|
|
||||||
{}"#,
|
|
||||||
'{',
|
|
||||||
src_c_type, src_buf,
|
|
||||||
dst_c_type, dst_buf,
|
|
||||||
map_fn,
|
|
||||||
item_morph.instantiated_symbol_name(dict, σ),
|
|
||||||
'}');
|
|
||||||
}
|
|
||||||
LdmcMorphism::ValueDelimMap { delim, item_morph } => {
|
|
||||||
let src_c_type = get_c_repr_type(dict, item_morph.src_type.clone(), false).expect("cant get c-repr type for src type");
|
|
||||||
let dst_c_type = get_c_repr_type(dict, item_morph.dst_type.clone(), false).expect("cant get c-repr type for dst type");
|
|
||||||
|
|
||||||
let src_buf = if i%2 == 0 { "bufA" } else { "bufB" };
|
|
||||||
let dst_buf = if i%2 == 0 { "bufB" } else { "bufA" };
|
|
||||||
println!(r#"
|
|
||||||
{}
|
|
||||||
{} const * restrict src = (void*) {};
|
|
||||||
{} * restrict dst = (void*) {};
|
|
||||||
value_delim_array_map_8_to_64( {}, src, dst );
|
|
||||||
{}"#,
|
|
||||||
'{',
|
|
||||||
src_c_type, src_buf,
|
|
||||||
dst_c_type, dst_buf,
|
|
||||||
item_morph.instantiated_symbol_name(dict, σ),
|
|
||||||
'}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
49
src/c_gen/gen_main.rs
Normal file
49
src/c_gen/gen_main.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use {
|
||||||
|
laddertypes::{TypeDict, morphism::MorphismInstance, parser::*},
|
||||||
|
crate::LdmcPrimMorph,
|
||||||
|
crate::c_gen::LdmcCTargetMorph,
|
||||||
|
std::collections::HashMap,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn generate_main(dict: &mut impl TypeDict, morph: MorphismInstance<LdmcPrimMorph>) -> Result<String, ()> {
|
||||||
|
let mut target = LdmcCTargetMorph::new();
|
||||||
|
let ty = morph.get_type();
|
||||||
|
match target.add_instantiation(dict, morph) {
|
||||||
|
Ok(inst) => {
|
||||||
|
let mut c_source = target.into_c_source(dict);
|
||||||
|
|
||||||
|
c_source.push_str(&format!(r#"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main() {{
|
||||||
|
uint8_t bufIn[4096];
|
||||||
|
uint8_t bufOut[4096];"#));
|
||||||
|
|
||||||
|
let (src_top, src_floor) = ty.src_type.get_floor_type();
|
||||||
|
if src_floor == dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict) {
|
||||||
|
c_source.push_str("scanf(\"%s\", bufIn);");
|
||||||
|
} else {
|
||||||
|
c_source.push_str("read(0, bufIn, sizeof(bufIn));");
|
||||||
|
}
|
||||||
|
|
||||||
|
c_source.push_str(&format!(r#"FUSE( {}, (void const*)bufIn, (void*)bufOut );"#, inst.instantiated_symbol_name(dict, &HashMap::new())));
|
||||||
|
|
||||||
|
if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
&ty.src_type,
|
||||||
|
&dict.parse_desugared("<Seq~<ValueTerminated 0> native.UInt8>").expect("").sugar(dict)
|
||||||
|
) {
|
||||||
|
c_source.push_str("printf(\"%s\\n\", bufOut);");
|
||||||
|
} else {
|
||||||
|
c_source.push_str("write(1, bufOut, sizeof(bufOut));");
|
||||||
|
}
|
||||||
|
c_source.push_str("
|
||||||
|
return 0;
|
||||||
|
}");
|
||||||
|
Ok(c_source)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to create morphism instatiation");
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/c_gen/mod.rs
Normal file
7
src/c_gen/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pub mod types;
|
||||||
|
pub mod morph;
|
||||||
|
pub mod gen_main;
|
||||||
|
|
||||||
|
pub use {
|
||||||
|
morph::target_morph::LdmcCTargetMorph
|
||||||
|
};
|
76
src/c_gen/morph/mod.rs
Normal file
76
src/c_gen/morph/mod.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
pub mod target_morph;
|
||||||
|
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
c_gen::types::{
|
||||||
|
get_c_repr_arg_type,
|
||||||
|
get_c_repr_definition,
|
||||||
|
get_c_repr_type
|
||||||
|
},
|
||||||
|
morphism::LdmcPrimMorph
|
||||||
|
},
|
||||||
|
laddertypes::{TypeDict, Substitution},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl LdmcPrimMorph {
|
||||||
|
pub fn instantiated_symbol_name(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> String {
|
||||||
|
let mut s = self.symbol.clone();
|
||||||
|
for (k_id,v) in self.type_args.iter() {
|
||||||
|
if let Some(val_trm) = σ.get(k_id) {
|
||||||
|
if let laddertypes::TypeID::Var(var_id) = k_id {
|
||||||
|
|
||||||
|
//if self.get_type().strip_halo().src_type.contains_var(*var_id) ||
|
||||||
|
//self.get_type().strip_halo().dst_type.contains_var(*var_id) {
|
||||||
|
|
||||||
|
let name = dict.get_varname(*var_id).unwrap();
|
||||||
|
let val_str = get_c_repr_type(dict, &val_trm);
|
||||||
|
s.push_str(&format!("_{}_{}", name, val_str));
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let laddertypes::TypeID::Var(var_id) = k_id {
|
||||||
|
let k = dict.get_varname(*var_id).unwrap();
|
||||||
|
s.push_str(&format!("_{:?}_MISSING", k));
|
||||||
|
eprintln!("INCOMPLETE MORPHISM INSTANTIATION, missing type parameter {} ({})", k, var_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expected_c_type_signature(&self, dict: &mut impl TypeDict,
|
||||||
|
σ: &std::collections::HashMap<laddertypes::TypeID, laddertypes::TypeTerm>
|
||||||
|
) -> String {
|
||||||
|
format!("int {} ({} const * restrict src, {} * restrict dst);",
|
||||||
|
self.instantiated_symbol_name(dict, σ),
|
||||||
|
get_c_repr_definition(dict, self.ty.src_type.clone(), true).expect("cant get c-repr type for src type"),
|
||||||
|
get_c_repr_definition(dict, self.ty.dst_type.clone(), true).expect("cant get c-repr type for dst type"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_instantiation(&self, dict: &mut impl TypeDict, σ: &impl Substitution) -> Option<String> {
|
||||||
|
let mut s = String::new();
|
||||||
|
let symbol = self.instantiated_symbol_name(dict, σ);
|
||||||
|
|
||||||
|
eprintln!("generate instantiation:");
|
||||||
|
let ty = self.ty.clone();
|
||||||
|
eprintln!("full type: {} ----> {}", ty.src_type.pretty(dict, 0), ty.dst_type.pretty(dict,0));
|
||||||
|
let ty = ty.strip_halo().apply_subst(σ);
|
||||||
|
eprintln!("stripped type: {} ----> {}", ty.src_type.pretty(dict, 0), ty.dst_type.pretty(dict,0));
|
||||||
|
|
||||||
|
let src_c_symbol = get_c_repr_arg_type(dict, &ty.src_type);
|
||||||
|
let dst_c_symbol = get_c_repr_arg_type(dict, &ty.dst_type);
|
||||||
|
|
||||||
|
s.push_str(&format!(r#"
|
||||||
|
int {} ( {} const * restrict src, {} * restrict dst ) {{
|
||||||
|
"#,
|
||||||
|
symbol, src_c_symbol, dst_c_symbol,
|
||||||
|
));
|
||||||
|
s.push_str(&self.c_source);
|
||||||
|
s.push_str(&format!(r#"
|
||||||
|
return 0;
|
||||||
|
}}
|
||||||
|
"#));
|
||||||
|
Some(s)
|
||||||
|
}
|
||||||
|
}
|
346
src/c_gen/morph/target_morph.rs
Normal file
346
src/c_gen/morph/target_morph.rs
Normal file
|
@ -0,0 +1,346 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
c_gen::types::{
|
||||||
|
encode_morph_type_to_symbol, get_c_repr_definition, get_c_repr_type, encode_type_to_value
|
||||||
|
},
|
||||||
|
morphism::LdmcPrimMorph
|
||||||
|
},
|
||||||
|
laddertypes::{
|
||||||
|
parser::*, MorphismInstance, TypeDict, TypeTerm, Morphism
|
||||||
|
},
|
||||||
|
std::collections::HashMap
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct LdmcCTargetMorph {
|
||||||
|
includes: Vec< String >,
|
||||||
|
active_types: Vec< TypeTerm >,
|
||||||
|
active_instantiations: Vec< LdmcPrimMorph >,
|
||||||
|
active_lenpfx_types: Vec< (TypeTerm, TypeTerm) >,
|
||||||
|
typedefs: Vec< String >,
|
||||||
|
macro_calls: Vec< String >
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LdmcCTargetMorph {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
LdmcCTargetMorph {
|
||||||
|
includes: vec![
|
||||||
|
"#include <stdint.h>".into(),
|
||||||
|
"#include <array/length-prefix.h>".into(),
|
||||||
|
"#define FUSE(morph, src, dst) { int result = morph(src,dst); if(result) return result; }".into(),
|
||||||
|
],
|
||||||
|
active_instantiations: Vec::new(),
|
||||||
|
active_types: Vec::new(),
|
||||||
|
active_lenpfx_types: Vec::new(),
|
||||||
|
typedefs: Vec::new(),
|
||||||
|
macro_calls: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_type(&mut self, dict: &mut impl TypeDict, ty: TypeTerm) {
|
||||||
|
let ty = ty.strip();
|
||||||
|
if ! self.active_types.contains(&ty) {
|
||||||
|
eprintln!("add type {}", ty.pretty(dict,0));
|
||||||
|
|
||||||
|
let (ht,ft) = ty.get_floor_type();
|
||||||
|
if ht.is_empty() {
|
||||||
|
|
||||||
|
match &ft {
|
||||||
|
TypeTerm::Seq { seq_repr, items } => {
|
||||||
|
let item_type = items.first().unwrap().clone();
|
||||||
|
self.add_type(dict, item_type.clone());
|
||||||
|
|
||||||
|
if let Some(seq_repr) = seq_repr {
|
||||||
|
dict.add_varname("LengthType".into());
|
||||||
|
if let Ok(σ) =
|
||||||
|
laddertypes::constraint_system::unify(
|
||||||
|
seq_repr.as_ref(),
|
||||||
|
&dict.parse_desugared("<LengthPrefix LengthType>").expect("").sugar(dict)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let length_type = σ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get Length type");
|
||||||
|
self.add_type(dict, length_type.clone());
|
||||||
|
self.macro_calls.push(
|
||||||
|
format!("DEFINE_LENGTH_PREFIX_ARRAY({}, {})\n",
|
||||||
|
get_c_repr_type(dict, &length_type),
|
||||||
|
get_c_repr_type(dict, &item_type)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.active_types.push(ty.clone());
|
||||||
|
if let Some(type_def) = get_c_repr_definition(dict, ft, false) {
|
||||||
|
let type_name = get_c_repr_type(dict, &ty);
|
||||||
|
self.typedefs.push(format!("typedef {} {};\n", type_def, type_name));
|
||||||
|
} else {
|
||||||
|
eprintln!("cant get c-repr type for type '{}'", ty.pretty(dict,0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let type_name = get_c_repr_type(dict, &ty);
|
||||||
|
let type_def = get_c_repr_type(dict, &ft);
|
||||||
|
self.add_type(dict, ft);
|
||||||
|
self.typedefs.push(format!("typedef {} {};\n", type_def, type_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_instantiation(
|
||||||
|
&mut self,
|
||||||
|
dict: &mut impl TypeDict,
|
||||||
|
morph: MorphismInstance<LdmcPrimMorph>,
|
||||||
|
) -> Result<LdmcPrimMorph, ()> {
|
||||||
|
let new_inst = self.bake_morphism(dict, morph)?;
|
||||||
|
if ! self.active_instantiations.contains(&new_inst) {
|
||||||
|
self.active_instantiations.push(new_inst.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let ty = new_inst.get_type().strip_halo();
|
||||||
|
self.add_type(dict, ty.src_type);
|
||||||
|
self.add_type(dict, ty.dst_type);
|
||||||
|
|
||||||
|
Ok(new_inst)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_c_source(mut self, dict: &mut impl TypeDict) -> String {
|
||||||
|
let mut source = String::new();
|
||||||
|
self.includes.dedup();
|
||||||
|
self.macro_calls.dedup();
|
||||||
|
self.active_types.dedup();
|
||||||
|
|
||||||
|
for inc in self.includes {
|
||||||
|
source.push_str(&inc);
|
||||||
|
source.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
source.push('\n');
|
||||||
|
|
||||||
|
for typedef in self.typedefs {
|
||||||
|
source.push_str(&typedef);
|
||||||
|
}
|
||||||
|
|
||||||
|
source.push('\n');
|
||||||
|
|
||||||
|
|
||||||
|
for m in self.macro_calls {
|
||||||
|
source.push_str(&m);
|
||||||
|
source.push('\n');
|
||||||
|
}
|
||||||
|
source.push('\n');
|
||||||
|
|
||||||
|
for m in self.active_instantiations {
|
||||||
|
source.push_str(&m.generate_instantiation(dict, &HashMap::new()).expect("cant create function"));
|
||||||
|
}
|
||||||
|
source
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bake_morphism(
|
||||||
|
&mut self,
|
||||||
|
dict: &mut impl laddertypes::TypeDict,
|
||||||
|
morph_inst: MorphismInstance<LdmcPrimMorph>,
|
||||||
|
) -> Result<LdmcPrimMorph, ()> {
|
||||||
|
let ty = morph_inst.get_type();
|
||||||
|
let symbol = encode_morph_type_to_symbol(dict, &ty);
|
||||||
|
|
||||||
|
match &morph_inst {
|
||||||
|
MorphismInstance::Primitive { ψ, σ, morph } => {
|
||||||
|
let mut c_source = String::new();
|
||||||
|
for (ty_id, kind) in morph.type_args.iter() {
|
||||||
|
if let laddertypes::TypeID::Var(var_id) = ty_id {
|
||||||
|
//if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
|
||||||
|
//morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
|
||||||
|
if let Some(val) = σ.get(ty_id) {
|
||||||
|
let type_var_value = get_c_repr_type(dict, val);
|
||||||
|
c_source.push_str(&format!(" #define {} {}\n", dict.get_typename(&ty_id).unwrap(), type_var_value));
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c_source.push_str(&morph.c_source);
|
||||||
|
for (ty_id, kind) in morph.type_args.iter() {
|
||||||
|
if let laddertypes::TypeID::Var(var_id) = ty_id {
|
||||||
|
//if morph_inst.get_type().strip_halo().src_type.contains_var(*var_id) ||
|
||||||
|
//morph_inst.get_type().strip_halo().dst_type.contains_var(*var_id) {
|
||||||
|
|
||||||
|
c_source.push_str(&format!("\n #undef {}", dict.get_typename(&ty_id).unwrap()));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(LdmcPrimMorph{
|
||||||
|
symbol: morph.instantiated_symbol_name(dict, σ),
|
||||||
|
type_args: Vec::new(),
|
||||||
|
ty: morph_inst.get_type().apply_subst(σ).strip_halo(),
|
||||||
|
c_source
|
||||||
|
})
|
||||||
|
},
|
||||||
|
MorphismInstance::Chain { path } => {
|
||||||
|
let mut c_source = String::new();
|
||||||
|
|
||||||
|
if path.len() > 1 {
|
||||||
|
c_source.push_str(r#"
|
||||||
|
uint8_t bufA[4096];
|
||||||
|
uint8_t bufB[4096];
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i,morph) in path.iter().enumerate() {
|
||||||
|
if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
|
||||||
|
let morph_symbol = inst.instantiated_symbol_name(dict, &morph.get_subst());
|
||||||
|
let src_buf = if i == 0 { "(void*)src" } else if i%2 == 0 { "(void*)bufA" } else { "(void*)bufB" };
|
||||||
|
let dst_buf = if i+1 == path.len() { "(void*)dst" } else if i%2 == 0 { "(void*)bufB" } else { "(void*)bufA" };
|
||||||
|
|
||||||
|
c_source.push_str(&format!(r#"
|
||||||
|
FUSE( {}, {}, {} );"#,
|
||||||
|
morph_symbol, src_buf, dst_buf,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
c_source.push_str(&format!("/* ERROR: missing morphism */"));
|
||||||
|
eprintln!("failed to add instantiation of item morphism");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(LdmcPrimMorph {
|
||||||
|
symbol, type_args: Vec::new(), ty,
|
||||||
|
c_source
|
||||||
|
})
|
||||||
|
}
|
||||||
|
MorphismInstance::MapSeq { ψ, seq_repr, item_morph } => {
|
||||||
|
if let Ok(item_morph_inst) = self.add_instantiation(dict, item_morph.as_ref().clone()) {
|
||||||
|
if let Some(seq_repr) = seq_repr {
|
||||||
|
dict.add_varname("Length".into());
|
||||||
|
dict.add_varname("LengthType".into());
|
||||||
|
dict.add_varname("TerminatorValue".into());
|
||||||
|
|
||||||
|
if let Ok(γ) = laddertypes::constraint_system::unify(
|
||||||
|
&dict.parse_desugared("<StaticLength Length>").expect("parse type template").sugar(dict),
|
||||||
|
seq_repr.as_ref()
|
||||||
|
) {
|
||||||
|
let length = γ.get(&dict.get_typeid(&"Length".into()).expect("")).expect("cant get Length");
|
||||||
|
match length {
|
||||||
|
TypeTerm::Num(l) => {
|
||||||
|
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
|
||||||
|
|
||||||
|
self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
|
||||||
|
self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
|
||||||
|
|
||||||
|
let c_source = format!(r#"
|
||||||
|
for( size_t i = 0; i < {}; ++i ) {{
|
||||||
|
FUSE( {}, &src->items[i], &dst->items[i] );
|
||||||
|
}}
|
||||||
|
"#,
|
||||||
|
l,
|
||||||
|
item_morph_symbol,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(LdmcPrimMorph{
|
||||||
|
symbol, type_args: Vec::new(), ty,
|
||||||
|
c_source
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
eprintln!("invalid length '{}'", length.pretty(dict, 0));
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if let Ok(γ) = laddertypes::constraint_system::unify(
|
||||||
|
&dict.parse_desugared("<LengthPrefix LengthType>").expect("parse type template").sugar(dict),
|
||||||
|
seq_repr.as_ref()
|
||||||
|
) {
|
||||||
|
// todo: assert that length type is native.UIntX
|
||||||
|
//let length_type = γ.get(&dict.get_typeid(&"LengthType".into()).expect("")).expect("cant get LengthType");
|
||||||
|
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
|
||||||
|
|
||||||
|
self.add_type( dict, morph_inst.get_type().strip_halo().src_type );
|
||||||
|
self.add_type( dict, morph_inst.get_type().strip_halo().dst_type );
|
||||||
|
|
||||||
|
let c_source = format!(r#"
|
||||||
|
for( size_t i = 0; i < src->len; ++i ) {{
|
||||||
|
FUSE( {}, &src->items[i], &dst->items[i] );
|
||||||
|
}}
|
||||||
|
dst->len = src->len;
|
||||||
|
"#,
|
||||||
|
item_morph_symbol,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(LdmcPrimMorph{
|
||||||
|
symbol, type_args: Vec::new(), ty,
|
||||||
|
c_source
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
else if let Ok(γ) = laddertypes::constraint_system::unify(
|
||||||
|
&dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("parse type template").sugar(dict),
|
||||||
|
seq_repr.as_ref()
|
||||||
|
) {
|
||||||
|
let terminator_value = γ.get(&dict.get_typeid(&"TerminatorValue".into()).expect("")).expect("cant get TerminatorValue");
|
||||||
|
let item_morph_symbol = item_morph_inst.instantiated_symbol_name(dict, &HashMap::new());
|
||||||
|
let terminator = encode_type_to_value(dict, terminator_value);
|
||||||
|
|
||||||
|
let c_source = format!(r#"
|
||||||
|
while( *src != {} ) {{
|
||||||
|
FUSE( {}, src, dst );
|
||||||
|
++src;
|
||||||
|
++dst;
|
||||||
|
}}
|
||||||
|
*dst = {};"#,
|
||||||
|
terminator,
|
||||||
|
item_morph_symbol,
|
||||||
|
terminator
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(LdmcPrimMorph{
|
||||||
|
symbol, type_args: Vec::new(), ty,
|
||||||
|
c_source
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else {
|
||||||
|
eprintln!("Error: Unknown Seq- Representation!!");
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("Error: missing Seq- Representation!!");
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("failed to add item-morph instantiation");
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MorphismInstance::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => {
|
||||||
|
|
||||||
|
let mut c_source = String::new();
|
||||||
|
|
||||||
|
for (name, morph) in member_morph.iter() {
|
||||||
|
if let Ok(inst) = self.add_instantiation(dict, morph.clone()) {
|
||||||
|
let name = name.replace("-", "_").replace(".","_dot_");
|
||||||
|
c_source.push_str(
|
||||||
|
&format!("
|
||||||
|
FUSE( {}, &src->{}, &dst->{} );",
|
||||||
|
inst.symbol,
|
||||||
|
name, name
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
c_source.push_str(&format!("/* ERROR: missing morphism for struct member '{}' */", name));
|
||||||
|
eprintln!("failed to create morphism instantiation for struct member");
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(LdmcPrimMorph{
|
||||||
|
symbol, type_args: Vec::new(), ty,
|
||||||
|
c_source
|
||||||
|
})
|
||||||
|
}
|
||||||
|
MorphismInstance::MapEnum { ψ, enum_repr, variant_morph } => {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
257
src/c_gen/types/mod.rs
Normal file
257
src/c_gen/types/mod.rs
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
use {
|
||||||
|
crate::struct_layout::LayoutType,
|
||||||
|
chumsky::chain::Chain, laddertypes::{morphism::MorphismType,
|
||||||
|
parser::*,
|
||||||
|
substitution::Substitution,
|
||||||
|
unparser::*, EnumVariant, StructMember, TypeTerm, TypeDict}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
pub fn get_c_repr_kind(kind: String) -> Option<String> {
|
||||||
|
match kind.as_str() {
|
||||||
|
"ℤ" => Some("uint64_t".into()),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a given ladder type `t`, get the corresponding C type
|
||||||
|
*/
|
||||||
|
pub fn get_c_repr_definition(dict: &mut impl TypeDict, t: TypeTerm, skip_pointer: bool) -> Option<String> {
|
||||||
|
match t {
|
||||||
|
TypeTerm::TypeID(tyid) => {
|
||||||
|
if tyid == dict.get_typeid_creat("native.UInt8") {
|
||||||
|
Some("uint8_t".into())
|
||||||
|
} else if tyid == dict.get_typeid_creat("native.UInt16") {
|
||||||
|
Some("uint16_t".into())
|
||||||
|
} else if tyid == dict.get_typeid_creat("native.UInt32") {
|
||||||
|
Some("uint32_t".into())
|
||||||
|
} else if tyid == dict.get_typeid_creat("native.UInt64") {
|
||||||
|
Some("uint64_t".into())
|
||||||
|
} else if tyid == dict.get_typeid_creat("native.Address") {
|
||||||
|
Some("void*".into())
|
||||||
|
} else if tyid == dict.get_typeid_creat("native.Float32") {
|
||||||
|
Some("float".into())
|
||||||
|
} else if tyid == dict.get_typeid_creat("native.Float64") {
|
||||||
|
Some("double".into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTerm::Seq{ seq_repr, items } => {
|
||||||
|
if let Some(seq_repr) = seq_repr {
|
||||||
|
let item_type = items.first().expect("no item type specified!").clone();
|
||||||
|
let item_c_type : String = get_c_repr_type(dict, &item_type);
|
||||||
|
|
||||||
|
dict.add_varname("Length".into()); // Kind: Num
|
||||||
|
dict.add_varname("LengthType".into()); // Kind: Type
|
||||||
|
dict.add_varname("TermValue".into()); // Kind: Value of Type ItemType
|
||||||
|
|
||||||
|
if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
seq_repr.as_ref(),
|
||||||
|
&dict.parse_desugared("<StaticLength Length>").expect("parse template type").sugar(dict)
|
||||||
|
) {
|
||||||
|
let length = match
|
||||||
|
σ.get(
|
||||||
|
&dict.get_typeid(&"Length".into()).expect("no Length ID")
|
||||||
|
).expect("no length specified!")
|
||||||
|
{
|
||||||
|
TypeTerm::Num(l) => l,
|
||||||
|
_ => {
|
||||||
|
eprintln!("invalid Length!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(format!("struct {{ {} items[{}]; }} ", item_c_type, length))
|
||||||
|
}
|
||||||
|
else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
seq_repr.as_ref(),
|
||||||
|
&dict.parse_desugared("<LengthPrefix LengthType>").expect("parse template type").sugar(dict)
|
||||||
|
) {
|
||||||
|
let length_type = σ.get(
|
||||||
|
&dict.get_typeid(&"LengthType".into()).expect("no LengthType ID")
|
||||||
|
).expect("no length type specified");
|
||||||
|
|
||||||
|
let length_c_type = get_c_repr_type(dict, &length_type);
|
||||||
|
|
||||||
|
Some(format!("struct {{ {} len; {} items[]; }} ", length_c_type, item_c_type))
|
||||||
|
}
|
||||||
|
else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
seq_repr.as_ref(),
|
||||||
|
&dict.parse_desugared("<ValueTerminated TermValue>").expect("parse template type").sugar(dict)
|
||||||
|
) {
|
||||||
|
if skip_pointer {
|
||||||
|
Some(item_c_type)
|
||||||
|
} else {
|
||||||
|
Some(format!("{} *", item_c_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if let Ok((ψ, σ)) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
seq_repr.as_ref(),
|
||||||
|
&dict.parse_desugared("MsbCont").expect("parse template type").sugar(dict)
|
||||||
|
) {
|
||||||
|
if skip_pointer {
|
||||||
|
Some(item_c_type)
|
||||||
|
} else {
|
||||||
|
Some(format!("{} *", item_c_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eprintln!("can't get C-repr for sequence type `{}`!", seq_repr.pretty(dict, 0));
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("no sequence-representation type specified!");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTerm::Struct{ struct_repr, members } => {
|
||||||
|
let c_struct_attribute =
|
||||||
|
if let Some(sr) = struct_repr {
|
||||||
|
let sr = sr.desugar(dict);
|
||||||
|
match LayoutType::parse(dict, &sr).expect("layout type") {
|
||||||
|
LayoutType::Aligned => "",
|
||||||
|
LayoutType::Packed => "__attribute((packed))__"
|
||||||
|
}
|
||||||
|
} else {""};
|
||||||
|
|
||||||
|
let mut c_type = format!("struct {} {{\n", c_struct_attribute);
|
||||||
|
|
||||||
|
for StructMember{ symbol, ty } in members {
|
||||||
|
let field_c_type = get_c_repr_definition(dict, ty, false).expect("");
|
||||||
|
c_type.push_str(&format!(" {} {};\n",
|
||||||
|
field_c_type,
|
||||||
|
symbol.replace("-", "_").replace(".","_dot_")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
c_type.push_str("}");
|
||||||
|
Some(c_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTerm::Enum { enum_repr, variants } => {
|
||||||
|
let mut c_type = format!("
|
||||||
|
struct {{
|
||||||
|
enum {{
|
||||||
|
");
|
||||||
|
|
||||||
|
for (i, EnumVariant{ symbol, ty }) in variants.iter().enumerate() {
|
||||||
|
c_type.push_str(&format!(
|
||||||
|
" {} = {}", symbol.replace("-", "_").replace(".","_dot_").to_uppercase(), i
|
||||||
|
));
|
||||||
|
|
||||||
|
if i+1 < variants.len() {
|
||||||
|
c_type.push_str(",\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c_type.push_str("
|
||||||
|
} tag;
|
||||||
|
|
||||||
|
union {
|
||||||
|
");
|
||||||
|
|
||||||
|
for EnumVariant{ symbol, ty } in variants {
|
||||||
|
let variant_c_type = get_c_repr_definition(dict, ty, false).expect("cant get C-Repr type for variant");
|
||||||
|
c_type.push_str(&format!(
|
||||||
|
" {} {};\n", variant_c_type, symbol.replace("-", "_").replace(".","_dot_")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
c_type.push_str("
|
||||||
|
};
|
||||||
|
}");
|
||||||
|
|
||||||
|
Some(c_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTerm::Ladder(rungs) => {
|
||||||
|
if let Some(t) = rungs.last() {
|
||||||
|
get_c_repr_definition(dict, t.clone(), false)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => { None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_c_repr_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
|
||||||
|
let t = t.clone().strip();
|
||||||
|
|
||||||
|
match t.desugar(dict) {
|
||||||
|
laddertypes::DesugaredTypeTerm::Char(c) => {
|
||||||
|
match c {
|
||||||
|
'.' => format!("_dot_"),
|
||||||
|
'-' => format!("_minus_"),
|
||||||
|
_ =>
|
||||||
|
format!("{}", (c as u64))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
laddertypes::DesugaredTypeTerm::Num(n) => {
|
||||||
|
format!("{}", n)
|
||||||
|
}
|
||||||
|
laddertypes::DesugaredTypeTerm::TypeID(ty_id) => {
|
||||||
|
if let Some(name) = dict.get_typename(&ty_id) {
|
||||||
|
name
|
||||||
|
.replace("-", "_")
|
||||||
|
.replace(".", "")
|
||||||
|
} else {
|
||||||
|
format!("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
laddertypes::DesugaredTypeTerm::Ladder(rs) |
|
||||||
|
laddertypes::DesugaredTypeTerm::App(rs) => {
|
||||||
|
let mut s = String::new();
|
||||||
|
s.push('_');
|
||||||
|
for r in rs {
|
||||||
|
let r = r.sugar(dict);
|
||||||
|
s.push_str(&get_c_repr_type(dict, &r));
|
||||||
|
s.push('_');
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_c_repr_arg_type(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm)-> String {
|
||||||
|
let t = t.clone().strip().get_floor_type().1;
|
||||||
|
dict.add_varname("TerminatorValue".into());
|
||||||
|
match &t {
|
||||||
|
TypeTerm::Seq { seq_repr, items } => {
|
||||||
|
if let Some(seq_repr) = seq_repr.as_ref() {
|
||||||
|
if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
seq_repr,
|
||||||
|
&dict.parse_desugared("<ValueTerminated TerminatorValue>").expect("").sugar(dict)
|
||||||
|
) {
|
||||||
|
return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
|
||||||
|
}
|
||||||
|
else if let Ok(ψ) = laddertypes::constraint_system::subtype_unify(
|
||||||
|
seq_repr,
|
||||||
|
&dict.parse_desugared("MsbCont").expect("").sugar(dict)
|
||||||
|
) {
|
||||||
|
return get_c_repr_type(dict, &items[0].clone().strip().get_floor_type().1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
get_c_repr_type(dict, &t)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode_morph_type_to_symbol(dict: &mut impl TypeDict, t: &MorphismType) -> String {
|
||||||
|
format!(
|
||||||
|
"morph__{}___TO__{}",
|
||||||
|
get_c_repr_type(dict, &t.strip_halo().src_type),
|
||||||
|
get_c_repr_type(dict, &t.strip_halo().dst_type)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode_type_to_value(dict: &mut impl TypeDict, t: &laddertypes::TypeTerm) -> String {
|
||||||
|
let t = t.clone().desugar(dict);
|
||||||
|
dict.unparse(&t)
|
||||||
|
}
|
49
src/main.rs
49
src/main.rs
|
@ -3,44 +3,41 @@
|
||||||
mod morphism;
|
mod morphism;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod c_gen;
|
mod c_gen;
|
||||||
|
mod struct_layout;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
crate::{
|
||||||
|
morphism::LdmcPrimMorph,
|
||||||
|
parser::morphism_base_parser,
|
||||||
|
},
|
||||||
ariadne::{Color, Label, Report, ReportKind, Source},
|
ariadne::{Color, Label, Report, ReportKind, Source},
|
||||||
chumsky::prelude::*,
|
chumsky::prelude::*,
|
||||||
laddertypes::{
|
laddertypes::{
|
||||||
parser::ParseLadderType, BimapTypeDict, MorphismType
|
morphism::MorphismType,
|
||||||
|
parser::ParseLadderType, BimapTypeDict
|
||||||
},
|
},
|
||||||
std::sync::{Arc, RwLock},
|
std::{sync::{Arc, RwLock}},
|
||||||
tiny_ansi::TinyAnsi,
|
tiny_ansi::TinyAnsi
|
||||||
|
|
||||||
|
|
||||||
crate::{
|
|
||||||
morphism::LdmcMorphism,
|
|
||||||
parser::morphism_base_parser,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
|
let mut type_dict = Arc::new(RwLock::new(BimapTypeDict::new()));
|
||||||
let mut morphism_base = laddertypes::MorphismBase::<LdmcMorphism>::new(vec![
|
|
||||||
//type_dict.parse("Seq~MsbCont").expect(""),
|
let mut morphism_base = laddertypes::morphism_base::MorphismBase::<LdmcPrimMorph>::new();
|
||||||
//type_dict.parse("Seq~<ValueTerminated '\\0'>").expect(""),
|
|
||||||
type_dict.parse("Seq~<LengthPrefix native.UInt64>").expect("")
|
|
||||||
]);
|
|
||||||
|
|
||||||
let mut args = std::env::args().skip(1);
|
let mut args = std::env::args().skip(1);
|
||||||
let src_type_arg = args.next().expect("src type expected");
|
let src_type_arg = args.next().expect("src type expected");
|
||||||
let dst_type_arg = args.next().expect("dst type expected");
|
let dst_type_arg = args.next().expect("dst type expected");
|
||||||
|
|
||||||
for mb_path in args {
|
for mb_path in args {
|
||||||
let src = std::fs::read_to_string(mb_path.clone()).expect("read");
|
let src = std::fs::read_to_string(mb_path.clone()).expect("failed to read morphism base");
|
||||||
let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
|
let result = morphism_base_parser(type_dict.clone()).parse(src.clone());
|
||||||
match result {
|
match result {
|
||||||
Ok((includes, morphisms)) => {
|
Ok((includes, morphisms)) => {
|
||||||
|
println!("{}",includes);
|
||||||
eprintln!("[{}] parse ok.", mb_path.bright_yellow());
|
eprintln!("[{}] parse ok.", mb_path.bright_yellow());
|
||||||
println!("{}", includes);
|
|
||||||
for m in morphisms {
|
for m in morphisms {
|
||||||
morphism_base.add_morphism(LdmcMorphism::Primitive(m));
|
morphism_base.add_morphism(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
|
@ -60,22 +57,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
|
let src_type = type_dict.parse( src_type_arg.as_str() ).expect("");
|
||||||
let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
|
let dst_type = type_dict.parse( dst_type_arg.as_str() ).expect("");
|
||||||
|
|
||||||
let path = morphism_base.find_morphism_path(MorphismType {
|
let ty = MorphismType{ src_type, dst_type };
|
||||||
src_type: src_type.clone(),
|
let m = morphism_base.get_morphism_instance( &ty ).expect("failed to find morphism");
|
||||||
dst_type: dst_type.clone(),
|
println!("{}", crate::c_gen::gen_main::generate_main(&mut type_dict, m).expect("failed to generate main function"));
|
||||||
});
|
|
||||||
|
|
||||||
match path {
|
|
||||||
Some(path) => {
|
|
||||||
c_gen::generate_main(&mut type_dict, path, src_type, dst_type);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
eprintln!("Error: could not find morphism path");
|
|
||||||
std::process::exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +1,16 @@
|
||||||
|
|
||||||
use laddertypes::morphism::Morphism;
|
use laddertypes::morphism::{Morphism, MorphismType};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct LdmcPrimCMorphism {
|
pub struct LdmcPrimMorph {
|
||||||
pub symbol: String,
|
pub symbol: String,
|
||||||
pub type_args: Vec<(laddertypes::TypeID, String)>,
|
pub type_args: Vec<(laddertypes::TypeID, String)>,
|
||||||
pub src_type: laddertypes::TypeTerm,
|
pub ty: MorphismType,
|
||||||
pub dst_type: laddertypes::TypeTerm,
|
|
||||||
pub c_source: String
|
pub c_source: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
impl Morphism for LdmcPrimMorph {
|
||||||
pub enum LdmcMorphism {
|
fn get_type(&self) -> MorphismType {
|
||||||
Primitive( LdmcPrimCMorphism ),
|
self.ty.clone()
|
||||||
LengthPrefixMap{
|
|
||||||
length_prefix_type: laddertypes::TypeTerm,
|
|
||||||
item_morph: Box<LdmcPrimCMorphism>
|
|
||||||
},
|
|
||||||
ValueDelimMap{
|
|
||||||
delim: u64,
|
|
||||||
item_morph: Box<LdmcPrimCMorphism>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Morphism for LdmcMorphism {
|
|
||||||
fn weight(&self) -> u64 {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_type(&self) -> laddertypes::MorphismType {
|
|
||||||
match self {
|
|
||||||
LdmcMorphism::Primitive(prim_morph) =>
|
|
||||||
laddertypes::MorphismType {
|
|
||||||
src_type: prim_morph.src_type.clone().normalize(),
|
|
||||||
dst_type: prim_morph.dst_type.clone().normalize()
|
|
||||||
},
|
|
||||||
LdmcMorphism::LengthPrefixMap{ length_prefix_type, item_morph } => {
|
|
||||||
laddertypes::MorphismType {
|
|
||||||
src_type: laddertypes::TypeTerm::App(vec![ length_prefix_type.clone(), item_morph.src_type.clone() ]),
|
|
||||||
dst_type: laddertypes::TypeTerm::App(vec![ length_prefix_type.clone(), item_morph.dst_type.clone() ]),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
LdmcMorphism::ValueDelimMap{ delim, item_morph } => {
|
|
||||||
let value_delim_type = laddertypes::TypeTerm::App(vec![]);
|
|
||||||
laddertypes::MorphismType {
|
|
||||||
src_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.src_type.clone() ]),
|
|
||||||
dst_type: laddertypes::TypeTerm::App(vec![ value_delim_type.clone(), item_morph.dst_type.clone() ]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.normalize()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_morphism(&self, seq_type: laddertypes::TypeTerm) -> Option< Self > {
|
|
||||||
match self {
|
|
||||||
LdmcMorphism::Primitive(prim) => {
|
|
||||||
let item_morph = Box::new(prim.clone());
|
|
||||||
/*
|
|
||||||
if seq_type == self.length_prefix_type {
|
|
||||||
*/
|
|
||||||
Some(LdmcMorphism::LengthPrefixMap{
|
|
||||||
length_prefix_type: seq_type,
|
|
||||||
item_morph,
|
|
||||||
})
|
|
||||||
/*
|
|
||||||
} else if seq_type == self.value_delim_type {
|
|
||||||
Some(LdmcMorphism::ValueDelimMap { delim, item_morph })
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
use {
|
use {
|
||||||
chumsky::{
|
crate::morphism::LdmcPrimMorph, chumsky::{
|
||||||
prelude::*, text::*
|
prelude::*, text::*
|
||||||
},
|
}, laddertypes::{morphism::MorphismType, parser::*, BimapTypeDict, TypeDict}, std::sync::{Arc, RwLock}
|
||||||
std::sync::{Arc, RwLock},
|
|
||||||
|
|
||||||
laddertypes::{TypeDict, BimapTypeDict, parser::*},
|
|
||||||
crate::morphism::LdmcPrimCMorphism
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* morphism-base text format:
|
/* morphism-base text format:
|
||||||
|
@ -18,12 +14,12 @@ use {
|
||||||
*/
|
*/
|
||||||
pub fn morphism_base_parser(
|
pub fn morphism_base_parser(
|
||||||
type_dict: Arc<RwLock< BimapTypeDict >>
|
type_dict: Arc<RwLock< BimapTypeDict >>
|
||||||
) -> impl Parser<char, (String, Vec<LdmcPrimCMorphism>), Error = Simple<char>> {
|
) -> impl Parser<char, (String, Vec<LdmcPrimMorph>), Error = Simple<char>> {
|
||||||
|
|
||||||
just("```")
|
just("```")
|
||||||
.then(take_until(just("```")))
|
.then(take_until(just("```")))
|
||||||
.map(
|
.map(
|
||||||
move |(a, (b, c))| {
|
move |(_a, (b, _c))| {
|
||||||
b.iter().collect()
|
b.iter().collect()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -63,14 +59,16 @@ pub fn morphism_base_parser(
|
||||||
ty_args.push((var_id, kind));
|
ty_args.push((var_id, kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
let src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type");
|
let src_type = type_dict.parse_desugared(&src_type.iter().collect::<String>()).expect("couldnt parse src type").sugar(&mut *type_dict);
|
||||||
let dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type");
|
let dst_type = type_dict.parse_desugared(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type").sugar(&mut *type_dict);
|
||||||
|
|
||||||
LdmcPrimCMorphism {
|
LdmcPrimMorph {
|
||||||
symbol,
|
symbol,
|
||||||
type_args: ty_args,
|
type_args: ty_args,
|
||||||
src_type,
|
ty: MorphismType{
|
||||||
dst_type,
|
src_type,
|
||||||
|
dst_type
|
||||||
|
},
|
||||||
c_source
|
c_source
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
43
src/platform/x86.rs
Normal file
43
src/platform/x86.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub fn example_substitution() {
|
||||||
|
let mut γ = HashMap::new();
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"Byte"),
|
||||||
|
type_dict.parse("<Seq~<StaticLength 8> Bit>").expect("parse")
|
||||||
|
.apply_subst(&γ)
|
||||||
|
.clone()
|
||||||
|
);
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"x86.UInt8"),
|
||||||
|
type_dict.parse("ℤ_2^8 ~ <PosInt 2 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 2> ~ Bit>").expect("parse")
|
||||||
|
.apply_subst(&γ)
|
||||||
|
.clone()
|
||||||
|
);
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"x86.UInt16"),
|
||||||
|
type_dict.parse("ℤ_2^16 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 2> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||||
|
.apply_subst(&γ)
|
||||||
|
.clone()
|
||||||
|
);
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"x86.UInt32"),
|
||||||
|
type_dict.parse("ℤ_2^32 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 4> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||||
|
.apply_subst(&γ).clone()
|
||||||
|
);
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"x86.UInt64"),
|
||||||
|
type_dict.parse("ℤ_2^64 ~ <PosInt 256 LittleEndian> ~ <Seq~<StaticLength 8> <Digit 256> ~ x86.UInt8 >").expect("parse")
|
||||||
|
.apply_subst(&γ).clone()
|
||||||
|
);
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"x86.Float32"),
|
||||||
|
type_dict.parse("ℝ ~ IEEE-754.Float32 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
|
||||||
|
.apply_subst(&γ).clone()
|
||||||
|
);
|
||||||
|
γ.insert(
|
||||||
|
type_dict.get_typeid_creat(&"x86.Float64"),
|
||||||
|
type_dict.parse("ℝ ~ IEEE-754.Float64 ~ <Seq~<StaticLength 4> Byte>").expect("parse")
|
||||||
|
.apply_subst(&γ).clone()
|
||||||
|
);
|
||||||
|
}
|
244
src/struct_layout.rs
Normal file
244
src/struct_layout.rs
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
|
||||||
|
|
||||||
|
use laddertypes::{parser::*, StructMember, TypeTerm, TypeDict, DesugaredTypeTerm};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum ObjectSize {
|
||||||
|
Static(u64),
|
||||||
|
Dynamic(/* function to get size at runtime */),
|
||||||
|
Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Add for ObjectSize {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self {
|
||||||
|
match (self, rhs) {
|
||||||
|
(ObjectSize::Unknown, _) |
|
||||||
|
(_, ObjectSize::Unknown)
|
||||||
|
=> ObjectSize::Unknown,
|
||||||
|
|
||||||
|
(ObjectSize::Dynamic(), _) |
|
||||||
|
(_, ObjectSize::Dynamic())
|
||||||
|
=> ObjectSize::Dynamic(),
|
||||||
|
|
||||||
|
(ObjectSize::Static(s1), ObjectSize::Static(s2)) => ObjectSize::Static(s1 + s2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Mul for ObjectSize {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, rhs: Self) -> Self {
|
||||||
|
match (self, rhs) {
|
||||||
|
(ObjectSize::Unknown, _) |
|
||||||
|
(_, ObjectSize::Unknown)
|
||||||
|
=> ObjectSize::Unknown,
|
||||||
|
|
||||||
|
(ObjectSize::Dynamic(), _) |
|
||||||
|
(_, ObjectSize::Dynamic())
|
||||||
|
=> ObjectSize::Dynamic(),
|
||||||
|
|
||||||
|
(ObjectSize::Static(s1), ObjectSize::Static(s2)) => ObjectSize::Static(s1 * s2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_type_size( dict: &mut impl TypeDict, ty: TypeTerm ) -> ObjectSize {
|
||||||
|
match &ty {
|
||||||
|
TypeTerm::TypeID(tyid) => {
|
||||||
|
if tyid == &dict.get_typeid_creat("native.UInt8") { ObjectSize::Static(1) }
|
||||||
|
else if tyid == &dict.get_typeid_creat("native.UInt16") { ObjectSize::Static(2) }
|
||||||
|
else if tyid == &dict.get_typeid_creat("native.UInt32") { ObjectSize::Static(4) }
|
||||||
|
else if tyid == &dict.get_typeid_creat("native.UInt64") { ObjectSize::Static(8) }
|
||||||
|
else if tyid == &dict.get_typeid_creat("native.Address") { ObjectSize::Static(8) }
|
||||||
|
else if tyid == &dict.get_typeid_creat("native.Float32") { ObjectSize::Static(4) }
|
||||||
|
else if tyid == &dict.get_typeid_creat("native.Float64") { ObjectSize::Static(8) }
|
||||||
|
else {
|
||||||
|
ObjectSize::Unknown
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
TypeTerm::Ladder(rungs) => {
|
||||||
|
get_type_size(dict, rungs.last().unwrap().clone() )
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTerm::Struct { struct_repr, members } => {
|
||||||
|
let layout = StructLayout::parse_sugared(dict, ty).expect("invalid struct");
|
||||||
|
layout.get_size()
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeTerm::Seq { seq_repr, items } => {
|
||||||
|
if let Some(seq_repr) = seq_repr {
|
||||||
|
dict.add_typename("Length".into());
|
||||||
|
dict.add_typename("LengthType".into());
|
||||||
|
dict.add_typename("TerminatorValue".into());
|
||||||
|
|
||||||
|
if let Ok(σ) = laddertypes::unify(
|
||||||
|
&seq_repr.clone(),
|
||||||
|
&dict.parse("<StaticLength Length>").expect("")
|
||||||
|
) {
|
||||||
|
if let Some(TypeTerm::Num(len)) = σ.get(&dict.get_typeid(&"Length".into()).expect("")) {
|
||||||
|
ObjectSize::Static(*len as u64) * get_type_size(dict, items.first().unwrap().clone())
|
||||||
|
} else {
|
||||||
|
ObjectSize::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if let Ok(σ) = laddertypes::unify(
|
||||||
|
&seq_repr.clone(),
|
||||||
|
&dict.parse("<LengthPrefix LengthType>").expect("")
|
||||||
|
) {
|
||||||
|
ObjectSize::Dynamic()
|
||||||
|
}
|
||||||
|
else if let Ok(σ) = laddertypes::unify(
|
||||||
|
&seq_repr.clone(),
|
||||||
|
&dict.parse("<ValueTerminated TerminatorValue>").expect("")
|
||||||
|
) {
|
||||||
|
ObjectSize::Dynamic()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ObjectSize::Unknown
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ObjectSize::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => ObjectSize::Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub enum LayoutType {
|
||||||
|
Aligned,
|
||||||
|
Packed
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutType {
|
||||||
|
pub fn parse( dict: &mut impl TypeDict, ty: &DesugaredTypeTerm ) -> Option< LayoutType > {
|
||||||
|
if ty == &dict.parse_desugared("Aligned").expect("parse") {
|
||||||
|
Some(LayoutType::Aligned)
|
||||||
|
} else if ty == &dict.parse_desugared("Packed").expect("parse") {
|
||||||
|
Some(LayoutType::Packed)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unparse(&self, dict: &mut impl TypeDict) -> DesugaredTypeTerm {
|
||||||
|
match self {
|
||||||
|
LayoutType::Aligned => dict.parse_desugared("Aligned").unwrap(),
|
||||||
|
LayoutType::Packed => dict.parse_desugared("Packed").unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct StructLayout {
|
||||||
|
pub ty: laddertypes::DesugaredTypeTerm,
|
||||||
|
pub layout: LayoutType,
|
||||||
|
pub members: Vec< StructMember >,
|
||||||
|
offsets: std::collections::HashMap< String, u64 >,
|
||||||
|
size: ObjectSize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StructLayout {
|
||||||
|
pub fn get_type(&self) -> DesugaredTypeTerm {
|
||||||
|
self.ty.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> ObjectSize {
|
||||||
|
self.size
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_offset(&self, name: &String) -> u64 {
|
||||||
|
*self.offsets.get(name).expect("")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_offsets(&mut self, dict: &mut impl TypeDict) {
|
||||||
|
let mut offset = 0;
|
||||||
|
|
||||||
|
for StructMember{symbol: field_name, ty: field_type} in self.members.iter() {
|
||||||
|
//let field_c_type = crate::c_gen::get_c_repr_type(dict, field_type.clone(), true).expect("cant get c-repr for struct field");
|
||||||
|
match get_type_size( dict, field_type.clone() ) {
|
||||||
|
ObjectSize::Static(field_size) => {
|
||||||
|
match self.layout {
|
||||||
|
LayoutType::Aligned => {
|
||||||
|
// add padding to get natural alignment of current member
|
||||||
|
if offset % field_size > 0 {
|
||||||
|
offset = field_size * ((offset / field_size)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LayoutType::Packed => {
|
||||||
|
// no padding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// take offset
|
||||||
|
self.offsets.insert(field_name.clone(), offset);
|
||||||
|
|
||||||
|
// advance by current size
|
||||||
|
offset += field_size;
|
||||||
|
}
|
||||||
|
ObjectSize::Dynamic() => {
|
||||||
|
eprintln!("dynamically sized Field in struct!");
|
||||||
|
self.offsets.insert(field_name.clone(), offset);
|
||||||
|
self.size = ObjectSize::Dynamic();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ObjectSize::Unknown => {
|
||||||
|
eprintln!("Struct member `{}` has unknown size!", field_name);
|
||||||
|
self.offsets.insert(field_name.clone(), offset);
|
||||||
|
self.size = ObjectSize::Unknown;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.size {
|
||||||
|
ObjectSize::Dynamic() => {
|
||||||
|
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.size = ObjectSize::Static(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(dict: &mut impl TypeDict, struct_type: &DesugaredTypeTerm) -> Option <Self> {
|
||||||
|
let st = struct_type.clone().strip().sugar(dict).normalize();
|
||||||
|
Self::parse_sugared(dict, st)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_sugared(dict: &mut impl TypeDict, st: TypeTerm) -> Option <Self> {
|
||||||
|
eprintln!("{}", st.pretty(dict, 0));
|
||||||
|
match st.clone() {
|
||||||
|
TypeTerm::Struct{ struct_repr, members } => {
|
||||||
|
let mut sl = StructLayout {
|
||||||
|
ty: st.desugar(dict),
|
||||||
|
layout: if let Some(sr) = struct_repr {
|
||||||
|
let sr = sr.desugar(dict);
|
||||||
|
LayoutType::parse( dict, &sr ).expect("invalid struct layout type")
|
||||||
|
} else {
|
||||||
|
eprintln!("choose default struct repr");
|
||||||
|
LayoutType::Aligned
|
||||||
|
},
|
||||||
|
|
||||||
|
members,
|
||||||
|
offsets: std::collections::HashMap::new(),
|
||||||
|
size: ObjectSize::Unknown
|
||||||
|
};
|
||||||
|
sl.init_offsets(dict);
|
||||||
|
|
||||||
|
Some(sl)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
eprintln!("not a struct");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue