SLVAL sl_float_pow(sl_vm_t* vm, SLVAL self, SLVAL other) { if(sl_is_a(vm, other, vm->lib.Bignum)) { return sl_float_pow(vm, self, sl_bignum_to_f(vm, other)); } if(sl_is_a(vm, other, vm->lib.Int)) { return sl_float_pow(vm, self, sl_make_float(vm, sl_get_int(other))); } return sl_make_float(vm, pow(sl_get_float(vm, self), sl_get_float(vm, other))); }
static int on_double(void* ctx, double val) { json_parse_t* json = ctx; SLVAL f = sl_make_float(json->vm, val); JSON_ADD_VALUE(f); return 1; }
static SLVAL sl_string_to_f(sl_vm_t* vm, SLVAL self) { char* str = sl_to_cstr(vm, self); double dbl = 0; sscanf(str, "%lf", &dbl); return sl_make_float(vm, dbl); }
SLVAL sl_float_cmp(sl_vm_t* vm, SLVAL self, SLVAL other) { if(sl_is_a(vm, other, vm->lib.Int)) { return sl_float_cmp(vm, self, sl_make_float(vm, sl_get_int(other))); } if(sl_is_a(vm, other, vm->lib.Bignum)) { return sl_make_int(vm, -sl_get_int(sl_bignum_cmp(vm, other, self))); } sl_expect(vm, other, vm->lib.Float); if(sl_get_float(vm, self) < sl_get_float(vm, other)) { return sl_make_int(vm, -1); } else if(sl_get_float(vm, self) > sl_get_float(vm, other)) { return sl_make_int(vm, 1); } else { return sl_make_int(vm, 0); } }
SLVAL sl_float_eq(sl_vm_t* vm, SLVAL self, SLVAL other) { if(sl_is_a(vm, other, vm->lib.Int)) { return sl_float_eq(vm, self, sl_make_float(vm, sl_get_int(other))); } if(sl_is_a(vm, other, vm->lib.Bignum)) { if(fmod(sl_get_float(vm, self), 1.0) == 0.0) { return sl_bignum_eq(vm, sl_make_bignum_f(vm, sl_get_float(vm, self)), other); } else { return vm->lib._false; } } if(!sl_is_a(vm, other, vm->lib.Float)) { return vm->lib._false; } return sl_make_bool(vm, sl_get_float(vm, self) == sl_get_float(vm, other)); }
static SLVAL sl_float_floor(sl_vm_t* vm, SLVAL self) { return sl_make_float(vm, floor(sl_get_float(vm, self))); }
static SLVAL sl_float_negate(sl_vm_t* vm, SLVAL self) { return sl_make_float(vm, -sl_get_float(vm, self)); }
static SLVAL sl_float_pred(sl_vm_t* vm, SLVAL self) { return sl_make_float(vm, sl_get_float(vm, self) - 1.0); }
static SLVAL sl_float_succ(sl_vm_t* vm, SLVAL self) { return sl_make_float(vm, sl_get_float(vm, self) + 1.0); }
static sl_node_base_t* primary_expression(sl_parse_state_t* ps) { sl_token_t* tok; sl_node_base_t* node; switch(peek_token(ps)->type) { case SL_TOK_INTEGER: tok = next_token(ps); return sl_make_immediate_node(ps, sl_integer_parse(ps->vm, tok->as.str.buff, tok->as.str.len)); case SL_TOK_FLOAT: return sl_make_immediate_node(ps, sl_make_float(ps->vm, next_token(ps)->as.dbl)); case SL_TOK_STRING: tok = next_token(ps); return sl_make_immediate_node(ps, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); case SL_TOK_REGEXP: return regexp_expression(ps); case SL_TOK_CONSTANT: tok = next_token(ps); return sl_make_const_node(ps, NULL, sl_intern2(ps->vm, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len))); case SL_TOK_IDENTIFIER: tok = next_token(ps); return sl_make_var_node(ps, SL_NODE_VAR, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); case SL_TOK_TRUE: next_token(ps); return sl_make_immediate_node(ps, ps->vm->lib._true); case SL_TOK_FALSE: next_token(ps); return sl_make_immediate_node(ps, ps->vm->lib._false); case SL_TOK_NIL: next_token(ps); return sl_make_immediate_node(ps, ps->vm->lib.nil); case SL_TOK_SELF: next_token(ps); return sl_make_self_node(ps); case SL_TOK_IVAR: tok = next_token(ps); node = sl_make_var_node(ps, SL_NODE_IVAR, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); return node; case SL_TOK_CVAR: tok = next_token(ps); node = sl_make_var_node(ps, SL_NODE_CVAR, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)); return node; case SL_TOK_IF: case SL_TOK_UNLESS: return if_expression(ps); case SL_TOK_WHILE: case SL_TOK_UNTIL: return while_expression(ps); case SL_TOK_FOR: return for_expression(ps); case SL_TOK_CLASS: return class_expression(ps); case SL_TOK_DEF: return def_expression(ps); case SL_TOK_LAMBDA: return lambda_expression(ps); case SL_TOK_TRY: return try_expression(ps); case SL_TOK_OPEN_BRACKET: return array_expression(ps); case SL_TOK_OPEN_PAREN: return bracketed_expression(ps); case SL_TOK_OPEN_BRACE: return dict_expression(ps); case SL_TOK_NEXT: tok = next_token(ps); if(!(ps->scope->flags & SL_PF_CAN_NEXT_LAST)) { error(ps, sl_make_cstring(ps->vm, "next invalid outside loop"), tok); } return sl_make_singleton_node(ps, SL_NODE_NEXT); case SL_TOK_LAST: tok = next_token(ps); if(!(ps->scope->flags & SL_PF_CAN_NEXT_LAST)) { error(ps, sl_make_cstring(ps->vm, "last invalid outside loop"), tok); } return sl_make_singleton_node(ps, SL_NODE_LAST); case SL_TOK_RANGE_EX: next_token(ps); return sl_make_singleton_node(ps, SL_NODE_YADA_YADA); default: unexpected(ps, peek_token(ps)); return NULL; } }