#ifndef RAY_EVAL_H
#define RAY_EVAL_H
#include <rayforce.h>
#include <stdio.h>
#include "lang/nfo.h"
#define RAY_FN_NONE 0x00
#define RAY_FN_LEFT_ATOMIC 0x01
#define RAY_FN_RIGHT_ATOMIC 0x02
#define RAY_FN_ATOMIC 0x04
#define RAY_FN_AGGR 0x08
#define RAY_FN_SPECIAL_FORM 0x10
#define RAY_FN_RESTRICTED 0x20
#define RAY_ATTR_NAME 0x20
typedef ray_t* (*ray_unary_fn)(ray_t*);
typedef ray_t* (*ray_binary_fn)(ray_t*, ray_t*);
typedef ray_t* (*ray_vary_fn)(ray_t**, int64_t);
#define RAY_FN_OPCODE(fn) (*(uint16_t*)(fn)->nullmap)
#define RAY_FN_SET_OPCODE(fn,op) (*(uint16_t*)(fn)->nullmap = (uint16_t)(op))
enum {
OP_RET = 0,
OP_JMP,
OP_JMPF,
OP_LOADCONST,
OP_LOADENV,
OP_STOREENV,
OP_POP,
OP_RESOLVE,
OP_CALL1,
OP_CALL2,
OP_CALLN,
OP_CALLF,
OP_CALLS,
OP_CALLD,
OP_DUP,
OP_LOADCONST_W,
OP_RESOLVE_W,
OP_TRAP,
OP_TRAP_END,
OP__COUNT
};
#define RAY_FN_COMPILED 0x40
#define LAMBDA_PARAMS(lam) (((ray_t**)ray_data(lam))[0])
#define LAMBDA_BODY(lam) (((ray_t**)ray_data(lam))[1])
#define LAMBDA_BC(lam) (((ray_t**)ray_data(lam))[2])
#define LAMBDA_CONSTS(lam) (((ray_t**)ray_data(lam))[3])
#define LAMBDA_NLOCALS(lam) (*((int32_t*)&((ray_t**)ray_data(lam))[4]))
#define LAMBDA_NFO(lam) (((ray_t**)ray_data(lam))[5])
#define LAMBDA_DBG(lam) (((ray_t**)ray_data(lam))[6])
#define LAMBDA_IS_COMPILED(lam) ((lam)->attrs & RAY_FN_COMPILED)
#define VM_STACK_SIZE 1024
typedef struct {
ray_t *fn;
int32_t fp;
int32_t ip;
} vm_ctx_t;
typedef struct {
int32_t rp;
int32_t sp;
int32_t handler_ip;
ray_t *fn;
int32_t fp;
int32_t n_locals;
} vm_trap_t;
#define VM_TRAP_SIZE 16
typedef struct {
int32_t sp;
int32_t fp;
int32_t rp;
int32_t id;
ray_t *fn;
void *heap;
int32_t tp;
ray_t *ps[VM_STACK_SIZE];
vm_ctx_t rs[VM_STACK_SIZE];
vm_trap_t ts[VM_TRAP_SIZE];
} ray_vm_t;
ray_err_t ray_lang_init(void);
void ray_lang_destroy(void);
ray_t* ray_eval(ray_t* obj);
ray_t* ray_eval_str(const char* source);
void ray_compile(ray_t* lambda);
void ray_compile_reset(void);
ray_span_t ray_bc_dbg_get(ray_t* dbg, int32_t ip);
void ray_lang_print(FILE* fp, ray_t* val);
void ray_eval_request_interrupt(void);
void ray_eval_clear_interrupt(void);
int ray_eval_is_interrupted(void);
ray_t* ray_eval_get_nfo(void);
void ray_eval_set_nfo(ray_t* nfo);
ray_t* ray_get_error_trace(void);
void ray_clear_error_trace(void);
void ray_eval_set_restricted(bool on);
bool ray_eval_get_restricted(void);
ray_t* ray_add_fn(ray_t* a, ray_t* b);
ray_t* ray_sub_fn(ray_t* a, ray_t* b);
ray_t* ray_mul_fn(ray_t* a, ray_t* b);
ray_t* ray_div_fn(ray_t* a, ray_t* b);
ray_t* ray_mod_fn(ray_t* a, ray_t* b);
ray_t* ray_gt_fn(ray_t* a, ray_t* b);
ray_t* ray_lt_fn(ray_t* a, ray_t* b);
ray_t* ray_gte_fn(ray_t* a, ray_t* b);
ray_t* ray_lte_fn(ray_t* a, ray_t* b);
ray_t* ray_eq_fn(ray_t* a, ray_t* b);
ray_t* ray_neq_fn(ray_t* a, ray_t* b);
ray_t* ray_and_fn(ray_t* a, ray_t* b);
ray_t* ray_or_fn(ray_t* a, ray_t* b);
ray_t* ray_and_vary_fn(ray_t** args, int64_t n);
ray_t* ray_or_vary_fn(ray_t** args, int64_t n);
ray_t* ray_not_fn(ray_t* x);
ray_t* ray_neg_fn(ray_t* x);
ray_t* ray_sum_fn(ray_t* x);
ray_t* ray_count_fn(ray_t* x);
ray_t* ray_avg_fn(ray_t* x);
ray_t* ray_min_fn(ray_t* x);
ray_t* ray_max_fn(ray_t* x);
ray_t* ray_first_fn(ray_t* x);
ray_t* ray_last_fn(ray_t* x);
ray_t* ray_med_fn(ray_t* x);
ray_t* ray_dev_fn(ray_t* x);
ray_t* ray_stddev_fn(ray_t* x);
ray_t* ray_stddev_pop_fn(ray_t* x);
ray_t* ray_var_fn(ray_t* x);
ray_t* ray_var_pop_fn(ray_t* x);
ray_t* ray_map_fn(ray_t** args, int64_t n);
ray_t* ray_pmap_fn(ray_t** args, int64_t n);
ray_t* ray_fold_fn(ray_t** args, int64_t n);
ray_t* ray_scan_fn(ray_t** args, int64_t n);
ray_t* ray_filter_fn(ray_t* vec, ray_t* mask);
ray_t* ray_apply_fn(ray_t** args, int64_t n);
ray_t* ray_distinct_fn(ray_t* x);
ray_t* ray_in_fn(ray_t* val, ray_t* vec);
ray_t* ray_except_fn(ray_t* vec1, ray_t* vec2);
ray_t* ray_union_fn(ray_t* vec1, ray_t* vec2);
ray_t* ray_sect_fn(ray_t* vec1, ray_t* vec2);
ray_t* ray_take_fn(ray_t* vec, ray_t* n_obj);
ray_t* ray_at_fn(ray_t* vec, ray_t* idx);
ray_t* ray_find_fn(ray_t* vec, ray_t* val);
ray_t* ray_til_fn(ray_t* x);
ray_t* ray_reverse_fn(ray_t* x);
ray_t* ray_list_fn(ray_t** args, int64_t n);
ray_t* ray_table_fn(ray_t* names, ray_t* cols);
ray_t* ray_key_fn(ray_t* x);
ray_t* ray_value_fn(ray_t* x);
ray_t* ray_select_fn(ray_t** args, int64_t n);
ray_t* ray_update_fn(ray_t** args, int64_t n);
ray_t* ray_insert_fn(ray_t** args, int64_t n);
ray_t* ray_upsert_fn(ray_t** args, int64_t n);
ray_t* ray_xbar_fn(ray_t* col, ray_t* bucket);
ray_t* ray_left_join_fn(ray_t** args, int64_t n);
ray_t* ray_inner_join_fn(ray_t** args, int64_t n);
ray_t* ray_window_join_fn(ray_t** args, int64_t n);
ray_t* ray_println_fn(ray_t** args, int64_t n);
ray_t* ray_read_csv_fn(ray_t** args, int64_t n);
ray_t* ray_write_csv_fn(ray_t** args, int64_t n);
ray_t* ray_read_file_fn(ray_t* path_obj);
ray_t* ray_write_file_fn(ray_t* path_obj, ray_t* content);
ray_t* ray_cos_dist_fn(ray_t* a, ray_t* b);
ray_t* ray_inner_prod_fn(ray_t* a, ray_t* b);
ray_t* ray_l2_dist_fn(ray_t* a, ray_t* b);
ray_t* ray_norm_fn(ray_t* x);
ray_t* ray_knn_fn(ray_t** args, int64_t n);
ray_t* ray_hnsw_build_fn(ray_t** args, int64_t n);
ray_t* ray_ann_fn(ray_t** args, int64_t n);
ray_t* ray_hnsw_free_fn(ray_t* h);
ray_t* ray_hnsw_save_fn(ray_t* h, ray_t* path);
ray_t* ray_hnsw_load_fn(ray_t* path);
ray_t* ray_hnsw_info_fn(ray_t* h);
ray_t* ray_cast_fn(ray_t* type_sym, ray_t* val);
ray_t* ray_type_fn(ray_t* val);
ray_t* ray_set_fn(ray_t* name_obj, ray_t* val_expr);
ray_t* ray_let_fn(ray_t* name_obj, ray_t* val_expr);
ray_t* ray_cond_fn(ray_t** args, int64_t n);
ray_t* ray_do_fn(ray_t** args, int64_t n);
ray_t* ray_fn(ray_t** args, int64_t n);
ray_t* ray_raise_fn(ray_t* val);
ray_t* ray_try_fn(ray_t* expr, ray_t* handler_expr);
#endif