#ifndef hvm_h_INCLUDED
#define hvm_h_INCLUDED
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef int32_t i32;
typedef uint64_t u64;
typedef float f32;
typedef double f64;
typedef u8 Tag; typedef u32 Val; typedef u32 Port; typedef u64 Pair;
typedef u32 Numb;
#define VAR 0x0
#define REF 0x1
#define ERA 0x2
#define NUM 0x3
#define CON 0x4
#define DUP 0x5
#define OPR 0x6
#define SWI 0x7
static const f32 U24_MAX = (f32) (1 << 24) - 1;
static const f32 U24_MIN = 0.0;
static const f32 I24_MAX = (f32) (1 << 23) - 1;
static const f32 I24_MIN = (f32) (i32) ((-1u) << 23);
#define TY_SYM 0x00
#define TY_U24 0x01
#define TY_I24 0x02
#define TY_F24 0x03
#define OP_ADD 0x04
#define OP_SUB 0x05
#define FP_SUB 0x06
#define OP_MUL 0x07
#define OP_DIV 0x08
#define FP_DIV 0x09
#define OP_REM 0x0A
#define FP_REM 0x0B
#define OP_EQ 0x0C
#define OP_NEQ 0x0D
#define OP_LT 0x0E
#define OP_GT 0x0F
#define OP_AND 0x10
#define OP_OR 0x11
#define OP_XOR 0x12
#define OP_SHL 0x13
#define FP_SHL 0x14
#define OP_SHR 0x15
#define FP_SHR 0x16
typedef struct Net Net;
typedef struct Book Book;
typedef struct {
char x[13];
} Show;
void put_u16(char* B, u16 val);
Show show_port(Port port);
void print_net(Net* net);
void pretty_print_numb(Numb word);
void pretty_print_port(Net* net, Book* book, Port port);
static inline Port new_port(Tag tag, Val val) {
return (val << 3) | tag;
}
static inline Tag get_tag(Port port) {
return port & 7;
}
static inline Val get_val(Port port) {
return port >> 3;
}
static inline const Pair new_pair(Port fst, Port snd) {
return ((u64)snd << 32) | fst;
}
static inline Port get_fst(Pair pair) {
return pair & 0xFFFFFFFF;
}
static inline Port get_snd(Pair pair) {
return pair >> 32;
}
static inline void swap(Port *a, Port *b) {
Port x = *a; *a = *b; *b = x;
}
static inline u32 min(u32 a, u32 b) {
return (a < b) ? a : b;
}
static inline f32 clamp(f32 x, f32 min, f32 max) {
const f32 t = x < min ? min : x;
return (t > max) ? max : t;
}
static inline Numb new_sym(u32 val) {
return (val << 5) | TY_SYM;
}
static inline u32 get_sym(Numb word) {
return (word >> 5);
}
static inline Numb new_u24(u32 val) {
return (val << 5) | TY_U24;
}
static inline u32 get_u24(Numb word) {
return word >> 5;
}
static inline Numb new_i24(i32 val) {
return ((u32)val << 5) | TY_I24;
}
static inline i32 get_i24(Numb word) {
return ((i32)word) << 3 >> 8;
}
static inline Numb new_f24(float val) {
u32 bits = *(u32*)&val;
u32 shifted_bits = bits >> 8;
u32 lost_bits = bits & 0xFF;
shifted_bits += (!isnan(val)) & ((lost_bits - ((lost_bits >> 7) & !shifted_bits)) >> 7);
shifted_bits |= isnan(val);
return (shifted_bits << 5) | TY_F24;
}
static inline float get_f24(Numb word) {
u32 bits = (word << 3) & 0xFFFFFF00;
return *(float*)&bits;
}
static inline Tag get_typ(Numb word) {
return word & 0x1F;
}
static inline bool is_num(Numb word) {
return get_typ(word) >= TY_U24 && get_typ(word) <= TY_F24;
}
static inline bool is_cast(Numb word) {
return get_typ(word) == TY_SYM && get_sym(word) >= TY_U24 && get_sym(word) <= TY_F24;
}
static inline Numb partial(Numb a, Numb b) {
return (b & ~0x1F) | get_sym(a);
}
typedef struct Tup {
u32 elem_len;
Port elem_buf[8];
} Tup;
extern Tup readback_tup(Net* net, Book* book, Port port, u32 size);
typedef struct Str {
u32 len;
char *buf;
} Str;
extern Str readback_str(Net* net, Book* book, Port port);
typedef struct Bytes {
u32 len;
char *buf;
} Bytes;
extern Bytes readback_bytes(Net* net, Book* book, Port port);
extern Port inject_bytes(Net* net, Bytes *bytes);
#endif