First commit removing the integer number type. This should

remove some complexity and unexpected behavior around numbers in
general as all numbers are the same number type, IEEE 754 double
precision numbers. Also update examples and tests, some of which were
out of date.

Some more testing may be needed for new changes to numbers.
This commit is contained in:
Calvin Rose 2018-12-27 13:05:29 -05:00
parent 5a3190d471
commit 6b95326d7c
29 changed files with 543 additions and 790 deletions

View File

@ -43,8 +43,8 @@ int main() {
assert(janet_equals(janet_wrap_integer(INT32_MAX), janet_wrap_integer(INT32_MAX))); assert(janet_equals(janet_wrap_integer(INT32_MAX), janet_wrap_integer(INT32_MAX)));
assert(janet_equals(janet_wrap_integer(-2), janet_wrap_integer(-2))); assert(janet_equals(janet_wrap_integer(-2), janet_wrap_integer(-2)));
assert(janet_equals(janet_wrap_integer(INT32_MIN), janet_wrap_integer(INT32_MIN))); assert(janet_equals(janet_wrap_integer(INT32_MIN), janet_wrap_integer(INT32_MIN)));
assert(janet_equals(janet_wrap_real(1.4), janet_wrap_real(1.4))); assert(janet_equals(janet_wrap_number(1.4), janet_wrap_number(1.4)));
assert(janet_equals(janet_wrap_real(3.14159265), janet_wrap_real(3.14159265))); assert(janet_equals(janet_wrap_number(3.14159265), janet_wrap_number(3.14159265)));
assert(janet_equals(janet_cstringv("a string."), janet_cstringv("a string."))); assert(janet_equals(janet_cstringv("a string."), janet_cstringv("a string.")));
assert(janet_equals(janet_csymbolv("sym"), janet_csymbolv("sym"))); assert(janet_equals(janet_csymbolv("sym"), janet_csymbolv("sym")));

View File

@ -5,10 +5,14 @@
(def solutions @{}) (def solutions @{})
(def len (length s)) (def len (length s))
(for k 0 len (for k 0 len
(put tab s@k k)) (put tab s.k k))
(for i 0 len (for i 0 len
(for j 0 len (for j 0 len
(def k (get tab (- 0 s@i s@j))) (def k (get tab (- 0 s.i s.j)))
(when (and k (not= k i) (not= k j) (not= i j)) (when (and k (not= k i) (not= k j) (not= i j))
(put solutions {i true j true k true} true)))) (put solutions {i true j true k true} true))))
(map keys (keys solution))) (map keys (keys solutions)))
(def arr @[2 4 1 3 8 7 -3 -1 12 -5 -8])
(print "3sum of " (string/pretty arr) ":")
(print (string/pretty (sum3 arr)))

View File

@ -13,7 +13,7 @@
(addim 0 0 -0x1) # $0 = $0 - 1 (addim 0 0 -0x1) # $0 = $0 - 1
(push 0) # push($0) (push 0) # push($0)
(call 0 1) # $0 = call($1) (call 0 1) # $0 = call($1)
(addi 0 0 2) # $0 = $0 + $2 (integers) (add 0 0 2) # $0 = $0 + $2 (integers)
:done :done
(ret 0) # return $0 (ret 0) # return $0
] ]

View File

@ -36,6 +36,6 @@
:bg-bright-white 107}) :bg-bright-white 107})
(loop [[name color] :in (pairs colormap)] (loop [[name color] :in (pairs colormap)]
(defglobal (string.slice name 1) (defglobal (string/slice name 1)
(fn color-wrapper [& pieces] (fn color-wrapper [& pieces]
(string "\e[" color "m" (apply string pieces) "\e[0m")))) (string "\e[" color "m" ;pieces "\e[0m"))))

View File

@ -19,7 +19,7 @@
,state ,state
(do (do
(set ,loaded true) (set ,loaded true)
(set ,state (do ;forms))))))) (set ,state (do ,;forms)))))))
# Use tuples instead of structs to save memory # Use tuples instead of structs to save memory
(def- HEAD 0) (def- HEAD 0)
@ -52,7 +52,7 @@
(defn lazy-range (defn lazy-range
"Return a sequence of integers [start, end)." "Return a sequence of integers [start, end)."
@[start end] [start end &]
(if end (if end
(if (< start end) (if (< start end)
(delay (tuple start (lazy-range (+ 1 start) end))) (delay (tuple start (lazy-range (+ 1 start) end)))
@ -94,7 +94,7 @@
(defn randseq (defn randseq
"Return a sequence of random numbers." "Return a sequence of random numbers."
[] []
(delay (tuple (math.random) (randseq)))) (delay (tuple (math/random) (randseq))))
(defn take-while (defn take-while
"Returns a sequence of values until the predicate is false." "Returns a sequence of values until the predicate is false."

View File

@ -12,3 +12,5 @@
(if (zero? (% i trial)) (set isprime? false))) (if (zero? (% i trial)) (set isprime? false)))
(if isprime? (array/push list i))) (if isprime? (array/push list i)))
list) list)
(print (string/pretty (primes 100)))

View File

@ -178,18 +178,14 @@ static int cfun_slice(JanetArgs args) {
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (janet_checktype(args.v[1], JANET_INTEGER)) {
start = janet_unwrap_integer(args.v[1]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(start, args, 1);
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
end = -1; end = -1;
} else if (janet_checktype(args.v[2], JANET_INTEGER)) {
end = janet_unwrap_integer(args.v[2]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(end, args, 2);
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;

View File

@ -62,9 +62,7 @@ struct JanetAssembler {
* prefix tree. */ * prefix tree. */
static const JanetInstructionDef janet_ops[] = { static const JanetInstructionDef janet_ops[] = {
{"add", JOP_ADD}, {"add", JOP_ADD},
{"addi", JOP_ADD_INTEGER},
{"addim", JOP_ADD_IMMEDIATE}, {"addim", JOP_ADD_IMMEDIATE},
{"addr", JOP_ADD_REAL},
{"band", JOP_BAND}, {"band", JOP_BAND},
{"bnot", JOP_BNOT}, {"bnot", JOP_BNOT},
{"bor", JOP_BOR}, {"bor", JOP_BOR},
@ -73,24 +71,17 @@ static const JanetInstructionDef janet_ops[] = {
{"clo", JOP_CLOSURE}, {"clo", JOP_CLOSURE},
{"cmp", JOP_COMPARE}, {"cmp", JOP_COMPARE},
{"div", JOP_DIVIDE}, {"div", JOP_DIVIDE},
{"divi", JOP_DIVIDE_INTEGER},
{"divim", JOP_DIVIDE_IMMEDIATE}, {"divim", JOP_DIVIDE_IMMEDIATE},
{"divr", JOP_DIVIDE_REAL},
{"eq", JOP_EQUALS}, {"eq", JOP_EQUALS},
{"eqi", JOP_EQUALS_INTEGER},
{"eqim", JOP_EQUALS_IMMEDIATE}, {"eqim", JOP_EQUALS_IMMEDIATE},
{"eqn", JOP_NUMERIC_EQUAL}, {"eqn", JOP_NUMERIC_EQUAL},
{"eqr", JOP_EQUALS_REAL},
{"err", JOP_ERROR}, {"err", JOP_ERROR},
{"get", JOP_GET}, {"get", JOP_GET},
{"geti", JOP_GET_INDEX}, {"geti", JOP_GET_INDEX},
{"gt", JOP_GREATER_THAN}, {"gt", JOP_GREATER_THAN},
{"gti", JOP_GREATER_THAN_INTEGER},
{"gtim", JOP_GREATER_THAN_IMMEDIATE}, {"gtim", JOP_GREATER_THAN_IMMEDIATE},
{"gtn", JOP_NUMERIC_GREATER_THAN}, {"gtn", JOP_NUMERIC_GREATER_THAN},
{"gtr", JOP_GREATER_THAN_REAL},
{"gten", JOP_NUMERIC_GREATER_THAN_EQUAL}, {"gten", JOP_NUMERIC_GREATER_THAN_EQUAL},
{"gter", JOP_GREATER_THAN_EQUAL_REAL},
{"jmp", JOP_JUMP}, {"jmp", JOP_JUMP},
{"jmpif", JOP_JUMP_IF}, {"jmpif", JOP_JUMP_IF},
{"jmpno", JOP_JUMP_IF_NOT}, {"jmpno", JOP_JUMP_IF_NOT},
@ -104,11 +95,8 @@ static const JanetInstructionDef janet_ops[] = {
{"len", JOP_LENGTH}, {"len", JOP_LENGTH},
{"lt", JOP_LESS_THAN}, {"lt", JOP_LESS_THAN},
{"lten", JOP_NUMERIC_LESS_THAN_EQUAL}, {"lten", JOP_NUMERIC_LESS_THAN_EQUAL},
{"lter", JOP_LESS_THAN_EQUAL_REAL},
{"lti", JOP_LESS_THAN_INTEGER},
{"ltim", JOP_LESS_THAN_IMMEDIATE}, {"ltim", JOP_LESS_THAN_IMMEDIATE},
{"ltn", JOP_NUMERIC_LESS_THAN}, {"ltn", JOP_NUMERIC_LESS_THAN},
{"ltr", JOP_LESS_THAN_REAL},
{"mkarr", JOP_MAKE_ARRAY}, {"mkarr", JOP_MAKE_ARRAY},
{"mkbuf", JOP_MAKE_BUFFER}, {"mkbuf", JOP_MAKE_BUFFER},
{"mkstr", JOP_MAKE_STRING}, {"mkstr", JOP_MAKE_STRING},
@ -118,9 +106,7 @@ static const JanetInstructionDef janet_ops[] = {
{"movf", JOP_MOVE_FAR}, {"movf", JOP_MOVE_FAR},
{"movn", JOP_MOVE_NEAR}, {"movn", JOP_MOVE_NEAR},
{"mul", JOP_MULTIPLY}, {"mul", JOP_MULTIPLY},
{"muli", JOP_MULTIPLY_INTEGER},
{"mulim", JOP_MULTIPLY_IMMEDIATE}, {"mulim", JOP_MULTIPLY_IMMEDIATE},
{"mulr", JOP_MULTIPLY_REAL},
{"noop", JOP_NOOP}, {"noop", JOP_NOOP},
{"push", JOP_PUSH}, {"push", JOP_PUSH},
{"push2", JOP_PUSH_2}, {"push2", JOP_PUSH_2},
@ -162,10 +148,8 @@ static const TypeAlias type_aliases[] = {
{":fiber", JANET_TFLAG_FIBER}, {":fiber", JANET_TFLAG_FIBER},
{":function", JANET_TFLAG_FUNCTION}, {":function", JANET_TFLAG_FUNCTION},
{":indexed", JANET_TFLAG_INDEXED}, {":indexed", JANET_TFLAG_INDEXED},
{":integer", JANET_TFLAG_INTEGER},
{":nil", JANET_TFLAG_NIL}, {":nil", JANET_TFLAG_NIL},
{":number", JANET_TFLAG_NUMBER}, {":number", JANET_TFLAG_NUMBER},
{":real", JANET_TFLAG_REAL},
{":string", JANET_TFLAG_STRING}, {":string", JANET_TFLAG_STRING},
{":struct", JANET_TFLAG_STRUCT}, {":struct", JANET_TFLAG_STRUCT},
{":symbol", JANET_TFLAG_SYMBOL}, {":symbol", JANET_TFLAG_SYMBOL},
@ -199,7 +183,7 @@ static void janet_asm_errorv(JanetAssembler *a, const uint8_t *m) {
/* Add a closure environment to the assembler. Sub funcdefs may need /* Add a closure environment to the assembler. Sub funcdefs may need
* to reference outer function environments, and may change the outer environment. * to reference outer function environments, and may change the outer environment.
* Returns the index of the environment in the assembler's environments, or -1 * Returns the index of the environment in the assembler's environments, or -1
* if not found. */ * if not found. */
static int32_t janet_asm_addenv(JanetAssembler *a, Janet envname) { static int32_t janet_asm_addenv(JanetAssembler *a, Janet envname) {
Janet check; Janet check;
JanetFuncDef *def = a->def; JanetFuncDef *def = a->def;
@ -210,8 +194,8 @@ static int32_t janet_asm_addenv(JanetAssembler *a, Janet envname) {
} }
/* Check for memoized value */ /* Check for memoized value */
check = janet_table_get(&a->envs, envname); check = janet_table_get(&a->envs, envname);
if (janet_checktype(check, JANET_INTEGER)) { if (janet_checktype(check, JANET_NUMBER)) {
return janet_unwrap_integer(check); return (int32_t) janet_unwrap_number(check);
} }
if (NULL == a->parent) return -2; if (NULL == a->parent) return -2;
res = janet_asm_addenv(a->parent, envname); res = janet_asm_addenv(a->parent, envname);
@ -219,7 +203,7 @@ static int32_t janet_asm_addenv(JanetAssembler *a, Janet envname) {
return res; return res;
} }
envindex = def->environments_length; envindex = def->environments_length;
janet_table_put(&a->envs, envname, janet_wrap_integer(envindex)); janet_table_put(&a->envs, envname, janet_wrap_number(envindex));
if (envindex >= a->environments_capacity) { if (envindex >= a->environments_capacity) {
int32_t newcap = 2 * envindex; int32_t newcap = 2 * envindex;
def->environments = realloc(def->environments, newcap * sizeof(int32_t)); def->environments = realloc(def->environments, newcap * sizeof(int32_t));
@ -265,9 +249,16 @@ static int32_t doarg_1(
default: default:
goto error; goto error;
break; break;
case JANET_INTEGER: case JANET_NUMBER:
ret = janet_unwrap_integer(x); {
double y = janet_unwrap_number(x);
if (y >= INT32_MIN && y <= INT32_MAX) {
ret = y;
} else {
goto error;
}
break; break;
}
case JANET_TUPLE: case JANET_TUPLE:
{ {
const Janet *t = janet_unwrap_tuple(x); const Janet *t = janet_unwrap_tuple(x);
@ -286,11 +277,11 @@ static int32_t doarg_1(
{ {
if (NULL != c) { if (NULL != c) {
Janet result = janet_table_get(c, x); Janet result = janet_table_get(c, x);
if (janet_checktype(result, JANET_INTEGER)) { if (janet_checktype(result, JANET_NUMBER)) {
if (argtype == JANET_OAT_LABEL) { if (argtype == JANET_OAT_LABEL) {
ret = janet_unwrap_integer(result) - a->bytecode_count; ret = janet_unwrap_integer(result) - a->bytecode_count;
} else { } else {
ret = janet_unwrap_integer(result); ret = (int32_t) janet_unwrap_number(result);
} }
} else { } else {
janet_asm_errorv(a, janet_formatc("unknown name %v", x)); janet_asm_errorv(a, janet_formatc("unknown name %v", x));
@ -469,7 +460,7 @@ static uint32_t read_instruction(
} }
/* Helper to get from a structure */ /* Helper to get from a structure */
static Janet janet_get(Janet ds, Janet key) { static Janet janet_get1(Janet ds, Janet key) {
switch (janet_type(ds)) { switch (janet_type(ds)) {
default: default:
return janet_wrap_nil(); return janet_wrap_nil();
@ -528,29 +519,29 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
"expected struct or table for assembly source"); "expected struct or table for assembly source");
/* Check for function name */ /* Check for function name */
a.name = janet_get(s, janet_csymbolv("name")); a.name = janet_get1(s, janet_csymbolv("name"));
if (!janet_checktype(a.name, JANET_NIL)) { if (!janet_checktype(a.name, JANET_NIL)) {
def->name = janet_to_string(a.name); def->name = janet_to_string(a.name);
} }
/* Set function arity */ /* Set function arity */
x = janet_get(s, janet_csymbolv("arity")); x = janet_get1(s, janet_csymbolv("arity"));
def->arity = janet_checktype(x, JANET_INTEGER) ? janet_unwrap_integer(x) : 0; def->arity = janet_checkint(x) ? janet_unwrap_integer(x) : 0;
/* Check vararg */ /* Check vararg */
x = janet_get(s, janet_csymbolv("vararg")); x = janet_get1(s, janet_csymbolv("vararg"));
if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_VARARG; if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_VARARG;
/* Check strict arity */ /* Check strict arity */
x = janet_get(s, janet_csymbolv("fix-arity")); x = janet_get1(s, janet_csymbolv("fix-arity"));
if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_FIXARITY; if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_FIXARITY;
/* Check source */ /* Check source */
x = janet_get(s, janet_csymbolv("source")); x = janet_get1(s, janet_csymbolv("source"));
if (janet_checktype(x, JANET_STRING)) def->source = janet_unwrap_string(x); if (janet_checktype(x, JANET_STRING)) def->source = janet_unwrap_string(x);
/* Create slot aliases */ /* Create slot aliases */
x = janet_get(s, janet_csymbolv("slots")); x = janet_get1(s, janet_csymbolv("slots"));
if (janet_indexed_view(x, &arr, &count)) { if (janet_indexed_view(x, &arr, &count)) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
Janet v = arr[i]; Janet v = arr[i];
@ -571,7 +562,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
} }
/* Parse constants */ /* Parse constants */
x = janet_get(s, janet_csymbolv("constants")); x = janet_get1(s, janet_csymbolv("constants"));
if (janet_indexed_view(x, &arr, &count)) { if (janet_indexed_view(x, &arr, &count)) {
def->constants_length = count; def->constants_length = count;
def->constants = malloc(sizeof(Janet) * count); def->constants = malloc(sizeof(Janet) * count);
@ -606,7 +597,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
} }
/* Parse sub funcdefs */ /* Parse sub funcdefs */
x = janet_get(s, janet_csymbolv("closures")); x = janet_get1(s, janet_csymbolv("closures"));
if (janet_indexed_view(x, &arr, &count)) { if (janet_indexed_view(x, &arr, &count)) {
int32_t i; int32_t i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
@ -617,7 +608,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
if (subres.status != JANET_ASSEMBLE_OK) { if (subres.status != JANET_ASSEMBLE_OK) {
janet_asm_errorv(&a, subres.error); janet_asm_errorv(&a, subres.error);
} }
subname = janet_get(arr[i], janet_csymbolv("name")); subname = janet_get1(arr[i], janet_csymbolv("name"));
if (!janet_checktype(subname, JANET_NIL)) { if (!janet_checktype(subname, JANET_NIL)) {
janet_table_put(&a.defs, subname, janet_wrap_integer(def->defs_length)); janet_table_put(&a.defs, subname, janet_wrap_integer(def->defs_length));
} }
@ -636,7 +627,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
} }
/* Parse bytecode and labels */ /* Parse bytecode and labels */
x = janet_get(s, janet_csymbolv("bytecode")); x = janet_get1(s, janet_csymbolv("bytecode"));
if (janet_indexed_view(x, &arr, &count)) { if (janet_indexed_view(x, &arr, &count)) {
/* Do labels and find length */ /* Do labels and find length */
int32_t blength = 0; int32_t blength = 0;
@ -692,7 +683,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
a.errindex = -1; a.errindex = -1;
/* Check for source mapping */ /* Check for source mapping */
x = janet_get(s, janet_csymbolv("sourcemap")); x = janet_get1(s, janet_csymbolv("sourcemap"));
if (janet_indexed_view(x, &arr, &count)) { if (janet_indexed_view(x, &arr, &count)) {
janet_asm_assert(&a, count == def->bytecode_length, "sourcemap must have the same length as the bytecode"); janet_asm_assert(&a, count == def->bytecode_length, "sourcemap must have the same length as the bytecode");
def->sourcemap = malloc(sizeof(JanetSourceMapping) * count); def->sourcemap = malloc(sizeof(JanetSourceMapping) * count);
@ -704,10 +695,10 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
janet_asm_error(&a, "expected tuple"); janet_asm_error(&a, "expected tuple");
} }
tup = janet_unwrap_tuple(entry); tup = janet_unwrap_tuple(entry);
if (!janet_checktype(tup[0], JANET_INTEGER)) { if (!janet_checkint(tup[0])) {
janet_asm_error(&a, "expected integer"); janet_asm_error(&a, "expected integer");
} }
if (!janet_checktype(tup[1], JANET_INTEGER)) { if (!janet_checkint(tup[1])) {
janet_asm_error(&a, "expected integer"); janet_asm_error(&a, "expected integer");
} }
mapping.start = janet_unwrap_integer(tup[0]); mapping.start = janet_unwrap_integer(tup[0]);

View File

@ -242,18 +242,14 @@ static int cfun_slice(JanetArgs args) {
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (janet_checktype(args.v[1], JANET_INTEGER)) {
start = janet_unwrap_integer(args.v[1]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(start, args, 1);
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
end = -1; end = -1;
} else if (janet_checktype(args.v[2], JANET_INTEGER)) {
end = janet_unwrap_integer(args.v[2]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(end, args, 2);
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;

View File

@ -30,20 +30,12 @@ enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT] = {
JINT_ST, /* JOP_TYPECHECK, */ JINT_ST, /* JOP_TYPECHECK, */
JINT_S, /* JOP_RETURN, */ JINT_S, /* JOP_RETURN, */
JINT_0, /* JOP_RETURN_NIL, */ JINT_0, /* JOP_RETURN_NIL, */
JINT_SSS, /* JOP_ADD_INTEGER, */
JINT_SSI, /* JOP_ADD_IMMEDIATE, */ JINT_SSI, /* JOP_ADD_IMMEDIATE, */
JINT_SSS, /* JOP_ADD_REAL, */
JINT_SSS, /* JOP_ADD, */ JINT_SSS, /* JOP_ADD, */
JINT_SSS, /* JOP_SUBTRACT_INTEGER, */
JINT_SSS, /* JOP_SUBTRACT_REAL, */
JINT_SSS, /* JOP_SUBTRACT, */ JINT_SSS, /* JOP_SUBTRACT, */
JINT_SSS, /* JOP_MULTIPLY_INTEGER, */
JINT_SSI, /* JOP_MULTIPLY_IMMEDIATE, */ JINT_SSI, /* JOP_MULTIPLY_IMMEDIATE, */
JINT_SSS, /* JOP_MULTIPLY_REAL, */
JINT_SSS, /* JOP_MULTIPLY, */ JINT_SSS, /* JOP_MULTIPLY, */
JINT_SSS, /* JOP_DIVIDE_INTEGER, */
JINT_SSI, /* JOP_DIVIDE_IMMEDIATE, */ JINT_SSI, /* JOP_DIVIDE_IMMEDIATE, */
JINT_SSS, /* JOP_DIVIDE_REAL, */
JINT_SSS, /* JOP_DIVIDE, */ JINT_SSS, /* JOP_DIVIDE, */
JINT_SSS, /* JOP_BAND, */ JINT_SSS, /* JOP_BAND, */
JINT_SSS, /* JOP_BOR, */ JINT_SSS, /* JOP_BOR, */
@ -61,19 +53,11 @@ enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT] = {
JINT_SL, /* JOP_JUMP_IF, */ JINT_SL, /* JOP_JUMP_IF, */
JINT_SL, /* JOP_JUMP_IF_NOT, */ JINT_SL, /* JOP_JUMP_IF_NOT, */
JINT_SSS, /* JOP_GREATER_THAN, */ JINT_SSS, /* JOP_GREATER_THAN, */
JINT_SSS, /* JOP_GREATER_THAN_INTEGER, */
JINT_SSI, /* JOP_GREATER_THAN_IMMEDIATE, */ JINT_SSI, /* JOP_GREATER_THAN_IMMEDIATE, */
JINT_SSS, /* JOP_GREATER_THAN_REAL, */
JINT_SSS, /* JOP_GREATER_THAN_EQUAL_REAL, */
JINT_SSS, /* JOP_LESS_THAN, */ JINT_SSS, /* JOP_LESS_THAN, */
JINT_SSS, /* JOP_LESS_THAN_INTEGER, */
JINT_SSI, /* JOP_LESS_THAN_IMMEDIATE, */ JINT_SSI, /* JOP_LESS_THAN_IMMEDIATE, */
JINT_SSS, /* JOP_LESS_THAN_REAL, */
JINT_SSS, /* JOP_LESS_THAN_EQUAL_REAL, */
JINT_SSS, /* JOP_EQUALS, */ JINT_SSS, /* JOP_EQUALS, */
JINT_SSS, /* JOP_EQUALS_INTEGER, */
JINT_SSI, /* JOP_EQUALS_IMMEDIATE, */ JINT_SSI, /* JOP_EQUALS_IMMEDIATE, */
JINT_SSS, /* JOP_EQUALS_REAL, */
JINT_SSS, /* JOP_COMPARE, */ JINT_SSS, /* JOP_COMPARE, */
JINT_S, /* JOP_LOAD_NIL, */ JINT_S, /* JOP_LOAD_NIL, */
JINT_S, /* JOP_LOAD_TRUE, */ JINT_S, /* JOP_LOAD_TRUE, */

View File

@ -83,11 +83,7 @@
(defn pos? "Check if x is greater than 0." [x] (> x 0)) (defn pos? "Check if x is greater than 0." [x] (> x 0))
(defn neg? "Check if x is less than 0." [x] (< x 0)) (defn neg? "Check if x is less than 0." [x] (< x 0))
(defn one? "Check if x is equal to 1." [x] (== x 1)) (defn one? "Check if x is equal to 1." [x] (== x 1))
(defn integer? "Check if x is an integer." [x] (= (type x) :integer)) (defn number? "Check if x is a number." [x] (= (type x) :number))
(defn real? "Check if x is a real number." [x] (= (type x) :real))
(defn number? "Check if x is a number." [x]
(def t (type x))
(if (= t :integer) true (= t :real)))
(defn fiber? "Check if x is a fiber." [x] (= (type x) :fiber)) (defn fiber? "Check if x is a fiber." [x] (= (type x) :fiber))
(defn string? "Check if x is a string." [x] (= (type x) :string)) (defn string? "Check if x is a string." [x] (= (type x) :string))
(defn symbol? "Check if x is a symbol." [x] (= (type x) :symbol)) (defn symbol? "Check if x is a symbol." [x] (= (type x) :symbol))

View File

@ -156,39 +156,15 @@ static int janet_core_is_abstract(JanetArgs args) {
static int janet_core_scannumber(JanetArgs args) { static int janet_core_scannumber(JanetArgs args) {
const uint8_t *data; const uint8_t *data;
Janet x; double val;
int status = 0;
int32_t len; int32_t len;
JANET_FIXARITY(args, 1); JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(data, len, args, 0); JANET_ARG_BYTES(data, len, args, 0);
x = janet_scan_number(data, len); val = janet_scan_number(data, len, &status);
JANET_RETURN(args, x); if (status)
} JANET_THROW(args, "failed to scan number");
JANET_RETURN_NUMBER(args, val);
static int janet_core_scaninteger(JanetArgs args) {
const uint8_t *data;
int32_t len, ret;
int err = 0;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(data, len, args, 0);
ret = janet_scan_integer(data, len, &err);
if (err) {
JANET_RETURN_NIL(args);
}
JANET_RETURN_INTEGER(args, ret);
}
static int janet_core_scanreal(JanetArgs args) {
const uint8_t *data;
int32_t len;
double ret;
int err = 0;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(data, len, args, 0);
ret = janet_scan_real(data, len, &err);
if (err) {
JANET_RETURN_NIL(args);
}
JANET_RETURN_REAL(args, ret);
} }
static int janet_core_tuple(JanetArgs args) { static int janet_core_tuple(JanetArgs args) {
@ -348,18 +324,6 @@ static const JanetReg cfuns[] = {
"must be in the same format as numbers in janet source code. Will return nil " "must be in the same format as numbers in janet source code. Will return nil "
"on an invalid number." "on an invalid number."
}, },
{"scan-integer", janet_core_scaninteger,
"(scan-integer str)\n\n"
"Parse an integer from a byte sequence an return that number. The integer "
"must be in the same format as integers in janet source code. Will return nil "
"on an invalid integer."
},
{"scan-real", janet_core_scanreal,
"(scan-real str)\n\n"
"Parse a real number from a byte sequence an return that number. The number "
"must be in the same format as numbers in janet source code. Will return nil "
"on an invalid number."
},
{"tuple", janet_core_tuple, {"tuple", janet_core_tuple,
"(tuple & items)\n\n" "(tuple & items)\n\n"
"Creates a new tuple that contains items. Returns the new tuple." "Creates a new tuple that contains items. Returns the new tuple."
@ -502,7 +466,7 @@ static void templatize_varop(
SSS(JOP_GET, 4, 0, 5), /* operand = args[i] */ SSS(JOP_GET, 4, 0, 5), /* operand = args[i] */
SSS(op, 3, 3, 4), /* accum = accum op operand */ SSS(op, 3, 3, 4), /* accum = accum op operand */
SSI(JOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */ SSI(JOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */
SSI(JOP_EQUALS_INTEGER, 2, 5, 1), /* jump? = (i == argn) */ SSI(JOP_EQUALS, 2, 5, 1), /* jump? = (i == argn) */
SI(JOP_JUMP_IF_NOT, 2, -4), /* if not jump? go back 4 */ SI(JOP_JUMP_IF_NOT, 2, -4), /* if not jump? go back 4 */
/* Done, do last and return accumulator */ /* Done, do last and return accumulator */
@ -550,7 +514,7 @@ static void templatize_comparator(
SI(JOP_JUMP_IF_NOT, 2, 7), /* if not jump? goto fail (return false) */ SI(JOP_JUMP_IF_NOT, 2, 7), /* if not jump? goto fail (return false) */
SSI(JOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */ SSI(JOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */
SS(JOP_MOVE_NEAR, 3, 4), /* last = next */ SS(JOP_MOVE_NEAR, 3, 4), /* last = next */
SSI(JOP_EQUALS_INTEGER, 2, 5, 1), /* jump? = (i == argn) */ SSI(JOP_EQUALS, 2, 5, 1), /* jump? = (i == argn) */
SI(JOP_JUMP_IF_NOT, 2, -6), /* if not jump? go back 6 */ SI(JOP_JUMP_IF_NOT, 2, -6), /* if not jump? go back 6 */
/* Done, return true */ /* Done, return true */
@ -592,7 +556,7 @@ static void make_apply(JanetTable *env) {
/* Main loop */ /* Main loop */
SSS(JOP_GET, 5, 1, 4), /* x = args[i] */ SSS(JOP_GET, 5, 1, 4), /* x = args[i] */
SSI(JOP_ADD_IMMEDIATE, 4, 4, 1), /* i++ */ SSI(JOP_ADD_IMMEDIATE, 4, 4, 1), /* i++ */
SSI(JOP_EQUALS_INTEGER, 3, 4, 2), /* jump? = (i == argn) */ SSI(JOP_EQUALS, 3, 4, 2), /* jump? = (i == argn) */
SI(JOP_JUMP_IF, 3, 3), /* if jump? go forward 3 */ SI(JOP_JUMP_IF, 3, 3), /* if jump? go forward 3 */
S(JOP_PUSH, 5), S(JOP_PUSH, 5),
(JOP_JUMP | ((uint32_t)(-5) << 8)), (JOP_JUMP | ((uint32_t)(-5) << 8)),

View File

@ -82,17 +82,17 @@ static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
case JANET_FALSE: case JANET_FALSE:
janetc_emit(c, (reg << 8) | JOP_LOAD_FALSE); janetc_emit(c, (reg << 8) | JOP_LOAD_FALSE);
break; break;
case JANET_INTEGER: case JANET_NUMBER:
{ {
int32_t i = janet_unwrap_integer(k); double dval = janet_unwrap_number(k);
if (i <= INT16_MAX && i >= INT16_MIN) { int32_t i = (int32_t) dval;
janetc_emit(c, if (dval != i || !(dval >= INT16_MIN && dval <= INT16_MAX))
(i << 16) | goto do_constant;
(reg << 8) | janetc_emit(c,
JOP_LOAD_INTEGER); (i << 16) |
break; (reg << 8) |
} JOP_LOAD_INTEGER);
goto do_constant; break;
} }
default: default:
do_constant: do_constant:

View File

@ -357,11 +357,9 @@ static int janet_gc_idequals(Janet lhs, Janet rhs) {
case JANET_TRUE: case JANET_TRUE:
case JANET_FALSE: case JANET_FALSE:
case JANET_NIL: case JANET_NIL:
case JANET_NUMBER:
/* These values don't really matter to the gc so returning 1 al the time is fine. */
return 1; return 1;
case JANET_INTEGER:
return janet_unwrap_integer(lhs) == janet_unwrap_integer(rhs);
case JANET_REAL:
return janet_unwrap_real(lhs) == janet_unwrap_real(rhs);
default: default:
return janet_unwrap_pointer(lhs) == janet_unwrap_pointer(rhs); return janet_unwrap_pointer(lhs) == janet_unwrap_pointer(rhs);
} }

View File

@ -257,7 +257,7 @@ static int janet_io_fread(JanetArgs args) {
} else { } else {
JANET_THROW(args, "expected one of :all, :line"); JANET_THROW(args, "expected one of :all, :line");
} }
} else if (!janet_checktype(args.v[1], JANET_INTEGER)) { } else if (!janet_checkint(args.v[1])) {
JANET_THROW(args, "expected positive integer"); JANET_THROW(args, "expected positive integer");
} else { } else {
int32_t len = janet_unwrap_integer(args.v[1]); int32_t len = janet_unwrap_integer(args.v[1]);

View File

@ -297,9 +297,15 @@ static void marshal_one(MarshalState *st, Janet x, int flags) {
case JANET_TRUE: case JANET_TRUE:
pushbyte(st, 200 + type); pushbyte(st, 200 + type);
goto done; goto done;
case JANET_INTEGER: case JANET_NUMBER:
pushint(st, janet_unwrap_integer(x)); {
goto done; double xval = janet_unwrap_number(x);
if (janet_checkintrange(xval)) {
pushint(st, (int32_t) xval);
goto done;
}
break;
}
} }
#define MARK_SEEN() \ #define MARK_SEEN() \
@ -308,7 +314,7 @@ static void marshal_one(MarshalState *st, Janet x, int flags) {
/* Check reference and registry value */ /* Check reference and registry value */
{ {
Janet check = janet_table_get(&st->seen, x); Janet check = janet_table_get(&st->seen, x);
if (janet_checktype(check, JANET_INTEGER)) { if (janet_checkint(check)) {
pushbyte(st, LB_REFERENCE); pushbyte(st, LB_REFERENCE);
pushint(st, janet_unwrap_integer(check)); pushint(st, janet_unwrap_integer(check));
goto done; goto done;
@ -328,13 +334,13 @@ static void marshal_one(MarshalState *st, Janet x, int flags) {
/* Reference types */ /* Reference types */
switch (type) { switch (type) {
case JANET_REAL: case JANET_NUMBER:
{ {
union { union {
double d; double d;
uint8_t bytes[8]; uint8_t bytes[8];
} u; } u;
u.d = janet_unwrap_real(x); u.d = janet_unwrap_number(x);
#ifdef JANET_BIG_ENDIAN #ifdef JANET_BIG_ENDIAN
/* Swap byte order */ /* Swap byte order */
uint8_t temp; uint8_t temp;
@ -936,7 +942,7 @@ static const uint8_t *unmarshal_one(
#else #else
memcpy(&u.bytes, data + 1, sizeof(double)); memcpy(&u.bytes, data + 1, sizeof(double));
#endif #endif
*out = janet_wrap_real(u.d); *out = janet_wrap_number(u.d);
janet_array_push(&st->lookup, *out); janet_array_push(&st->lookup, *out);
return data + 9; return data + 9;
} }

View File

@ -27,7 +27,7 @@
int janet_rand(JanetArgs args) { int janet_rand(JanetArgs args) {
JANET_FIXARITY(args, 0); JANET_FIXARITY(args, 0);
double r = (rand() % RAND_MAX) / ((double) RAND_MAX); double r = (rand() % RAND_MAX) / ((double) RAND_MAX);
JANET_RETURN_REAL(args, r); JANET_RETURN_NUMBER(args, r);
} }
/* Seed the random number generator */ /* Seed the random number generator */
@ -39,52 +39,12 @@ int janet_srand(JanetArgs args) {
return 0; return 0;
} }
/* Convert a number to an integer */
int janet_int(JanetArgs args) {
JANET_FIXARITY(args, 1);
switch (janet_type(args.v[0])) {
default:
JANET_THROW(args, "could not convert to integer");
case JANET_REAL:
*args.ret = janet_wrap_integer((int32_t) janet_unwrap_real(args.v[0]));
break;
case JANET_INTEGER:
*args.ret = args.v[0];
break;
}
return 0;
}
/* Convert a number to a real number */
int janet_real(JanetArgs args) {
JANET_FIXARITY(args, 1);
switch (janet_type(args.v[0])) {
default:
JANET_THROW(args, "could not convert to real");
case JANET_REAL:
*args.ret = args.v[0];
break;
case JANET_INTEGER:
*args.ret = janet_wrap_real((double) janet_unwrap_integer(args.v[0]));
break;
}
return 0;
}
int janet_remainder(JanetArgs args) { int janet_remainder(JanetArgs args) {
JANET_FIXARITY(args, 2); JANET_FIXARITY(args, 2);
if (janet_checktype(args.v[0], JANET_INTEGER) && double x, y;
janet_checktype(args.v[1], JANET_INTEGER)) { JANET_ARG_NUMBER(x, args, 0);
int32_t x, y; JANET_ARG_NUMBER(y, args, 1);
x = janet_unwrap_integer(args.v[0]); JANET_RETURN_NUMBER(args, fmod(x, y));
y = janet_unwrap_integer(args.v[1]);
JANET_RETURN_INTEGER(args, x % y);
} else {
double x, y;
JANET_ARG_NUMBER(x, args, 0);
JANET_ARG_NUMBER(y, args, 1);
JANET_RETURN_REAL(args, fmod(x, y));
}
} }
#define JANET_DEFINE_MATHOP(name, fop)\ #define JANET_DEFINE_MATHOP(name, fop)\
@ -92,7 +52,7 @@ int janet_##name(JanetArgs args) {\
double x;\ double x;\
JANET_FIXARITY(args, 1);\ JANET_FIXARITY(args, 1);\
JANET_ARG_NUMBER(x, args, 0);\ JANET_ARG_NUMBER(x, args, 0);\
JANET_RETURN_REAL(args, fop(x));\ JANET_RETURN_NUMBER(args, fop(x));\
} }
JANET_DEFINE_MATHOP(acos, acos) JANET_DEFINE_MATHOP(acos, acos)
@ -118,7 +78,7 @@ int janet_##name(JanetArgs args) {\
JANET_FIXARITY(args, 2);\ JANET_FIXARITY(args, 2);\
JANET_ARG_NUMBER(lhs, args, 0);\ JANET_ARG_NUMBER(lhs, args, 0);\
JANET_ARG_NUMBER(rhs, args, 1);\ JANET_ARG_NUMBER(rhs, args, 1);\
JANET_RETURN_REAL(args, fop(lhs, rhs));\ JANET_RETURN_NUMBER(args, fop(lhs, rhs));\
}\ }\
JANET_DEFINE_MATH2OP(atan2, atan2) JANET_DEFINE_MATH2OP(atan2, atan2)
@ -137,15 +97,9 @@ static const JanetReg cfuns[] = {
{"not", janet_not, {"not", janet_not,
"(not x)\n\nReturns the boolen inverse of x." "(not x)\n\nReturns the boolen inverse of x."
}, },
{"int", janet_int,
"(int x)\n\nCast a number x to an integer."
},
{"real", janet_real,
"(real x)\n\nCast a number x to a real number."
},
{"math/random", janet_rand, {"math/random", janet_rand,
"(math/random)\n\n" "(math/random)\n\n"
"Returns a uniformly distrbuted random real number between 0 and 1." "Returns a uniformly distrbuted random number number between 0 and 1."
}, },
{"math/seedrandom", janet_srand, {"math/seedrandom", janet_srand,
"(math/seedrandom seed)\n\n" "(math/seedrandom seed)\n\n"
@ -194,11 +148,11 @@ static const JanetReg cfuns[] = {
}, },
{"math/floor", janet_floor, {"math/floor", janet_floor,
"(math/floor x)\n\n" "(math/floor x)\n\n"
"Returns the largest integer value real number that is not greater than x." "Returns the largest integer value number number that is not greater than x."
}, },
{"math/ceil", janet_ceil, {"math/ceil", janet_ceil,
"(math/ceil x)\n\n" "(math/ceil x)\n\n"
"Returns the smallest integer value real number that is not less than x." "Returns the smallest integer value number number that is not less than x."
}, },
{"math/pow", janet_pow, {"math/pow", janet_pow,
"(math/pow a x)\n\n" "(math/pow a x)\n\n"
@ -212,11 +166,11 @@ int janet_lib_math(JanetArgs args) {
JanetTable *env = janet_env(args); JanetTable *env = janet_env(args);
janet_cfuns(env, NULL, cfuns); janet_cfuns(env, NULL, cfuns);
janet_def(env, "math/pi", janet_wrap_real(3.1415926535897931), janet_def(env, "math/pi", janet_wrap_number(3.1415926535897931),
"The value pi."); "The value pi.");
janet_def(env, "math/e", janet_wrap_real(2.7182818284590451), janet_def(env, "math/e", janet_wrap_number(2.7182818284590451),
"The base of the natural log."); "The base of the natural log.");
janet_def(env, "math/inf", janet_wrap_real(INFINITY), janet_def(env, "math/inf", janet_wrap_number(INFINITY),
"The real number representing positive infinity"); "The number representing positive infinity");
return 0; return 0;
} }

View File

@ -197,7 +197,7 @@ static int os_exit(JanetArgs args) {
JANET_MAXARITY(args, 1); JANET_MAXARITY(args, 1);
if (args.n == 0) { if (args.n == 0) {
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (janet_checktype(args.v[0], JANET_INTEGER)) { } else if (janet_checkint(args.v[0])) {
exit(janet_unwrap_integer(args.v[0])); exit(janet_unwrap_integer(args.v[0]));
} else { } else {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -208,7 +208,7 @@ static int os_exit(JanetArgs args) {
static int os_time(JanetArgs args) { static int os_time(JanetArgs args) {
JANET_FIXARITY(args, 0); JANET_FIXARITY(args, 0);
double dtime = (double)(time(NULL)); double dtime = (double)(time(NULL));
JANET_RETURN_REAL(args, dtime); JANET_RETURN_NUMBER(args, dtime);
} }
/* Clock shims */ /* Clock shims */
@ -244,7 +244,7 @@ static int os_clock(JanetArgs args) {
if (gettime(&tv)) if (gettime(&tv))
JANET_THROW(args, "could not get time"); JANET_THROW(args, "could not get time");
double dtime = tv.tv_sec + (tv.tv_nsec / 1E9); double dtime = tv.tv_sec + (tv.tv_nsec / 1E9);
JANET_RETURN_REAL(args, dtime); JANET_RETURN_NUMBER(args, dtime);
} }
static int os_sleep(JanetArgs args) { static int os_sleep(JanetArgs args) {
@ -326,7 +326,6 @@ static const JanetReg cfuns[] = {
"(os/sleep nsec)\n\n" "(os/sleep nsec)\n\n"
"Suspend the program for nsec seconds. 'nsec' can be a real number. Returns " "Suspend the program for nsec seconds. 'nsec' can be a real number. Returns "
"nil." "nil."
}, },
{"os/cwd", os_cwd, {"os/cwd", os_cwd,
"(os/cwd)\n\n" "(os/cwd)\n\n"

View File

@ -279,8 +279,10 @@ static int check_str_const(const char *cstr, const uint8_t *str, int32_t len) {
} }
static int tokenchar(JanetParser *p, JanetParseState *state, uint8_t c) { static int tokenchar(JanetParser *p, JanetParseState *state, uint8_t c) {
Janet numcheck, ret; Janet ret;
double numval;
int32_t blen; int32_t blen;
int scanerr;
if (is_symbol_char(c)) { if (is_symbol_char(c)) {
push_buf(p, (uint8_t) c); push_buf(p, (uint8_t) c);
if (c > 127) state->argn = 1; /* Use to indicate non ascii */ if (c > 127) state->argn = 1; /* Use to indicate non ascii */
@ -288,9 +290,10 @@ static int tokenchar(JanetParser *p, JanetParseState *state, uint8_t c) {
} }
/* Token finished */ /* Token finished */
blen = (int32_t) p->bufcount; blen = (int32_t) p->bufcount;
numcheck = janet_scan_number(p->buf, blen); scanerr = 0;
if (!janet_checktype(numcheck, JANET_NIL)) { numval = janet_scan_number(p->buf, blen, &scanerr);
ret = numcheck; if (!scanerr) {
ret = janet_wrap_number(numval);
} else if (!check_str_const("nil", p->buf, blen)) { } else if (!check_str_const("nil", p->buf, blen)) {
ret = janet_wrap_nil(); ret = janet_wrap_nil();
} else if (!check_str_const("false", p->buf, blen)) { } else if (!check_str_const("false", p->buf, blen)) {

View File

@ -106,19 +106,19 @@ const uint8_t *janet_cstring(const char *str) {
/* Temporary buffer size */ /* Temporary buffer size */
#define BUFSIZE 64 #define BUFSIZE 64
static int32_t real_to_string_impl(uint8_t *buf, double x) { static int32_t number_to_string_impl(uint8_t *buf, double x) {
int count = snprintf((char *) buf, BUFSIZE, "%.17gr", x); int count = snprintf((char *) buf, BUFSIZE, "%.17g", x);
return (int32_t) count; return (int32_t) count;
} }
static void real_to_string_b(JanetBuffer *buffer, double x) { static void number_to_string_b(JanetBuffer *buffer, double x) {
janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2); janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2);
buffer->count += real_to_string_impl(buffer->data + buffer->count, x); buffer->count += number_to_string_impl(buffer->data + buffer->count, x);
} }
static const uint8_t *real_to_string(double x) { static const uint8_t *number_to_string(double x) {
uint8_t buf[BUFSIZE]; uint8_t buf[BUFSIZE];
return janet_string(buf, real_to_string_impl(buf, x)); return janet_string(buf, number_to_string_impl(buf, x));
} }
/* expects non positive x */ /* expects non positive x */
@ -161,11 +161,6 @@ static void integer_to_string_b(JanetBuffer *buffer, int32_t x) {
buffer->count += integer_to_string_impl(buffer->data + buffer->count, x); buffer->count += integer_to_string_impl(buffer->data + buffer->count, x);
} }
static const uint8_t *integer_to_string(int32_t x) {
uint8_t buf[BUFSIZE];
return janet_string(buf, integer_to_string_impl(buf, x));
}
#define HEX(i) (((uint8_t *) janet_base64)[(i)]) #define HEX(i) (((uint8_t *) janet_base64)[(i)])
/* Returns a string description for a pointer. Truncates /* Returns a string description for a pointer. Truncates
@ -322,11 +317,8 @@ void janet_description_b(JanetBuffer *buffer, Janet x) {
case JANET_FALSE: case JANET_FALSE:
janet_buffer_push_cstring(buffer, "false"); janet_buffer_push_cstring(buffer, "false");
return; return;
case JANET_REAL: case JANET_NUMBER:
real_to_string_b(buffer, janet_unwrap_real(x)); number_to_string_b(buffer, janet_unwrap_number(x));
return;
case JANET_INTEGER:
integer_to_string_b(buffer, janet_unwrap_integer(x));
return; return;
case JANET_SYMBOL: case JANET_SYMBOL:
janet_buffer_push_bytes(buffer, janet_buffer_push_bytes(buffer,
@ -407,10 +399,8 @@ const uint8_t *janet_description(Janet x) {
return janet_cstring("true"); return janet_cstring("true");
case JANET_FALSE: case JANET_FALSE:
return janet_cstring("false"); return janet_cstring("false");
case JANET_REAL: case JANET_NUMBER:
return real_to_string(janet_unwrap_real(x)); return number_to_string(janet_unwrap_number(x));
case JANET_INTEGER:
return integer_to_string(janet_unwrap_integer(x));
case JANET_SYMBOL: case JANET_SYMBOL:
return janet_unwrap_symbol(x); return janet_unwrap_symbol(x);
case JANET_STRING: case JANET_STRING:
@ -494,8 +484,7 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) {
/* Add to seen */ /* Add to seen */
switch (janet_type(x)) { switch (janet_type(x)) {
case JANET_NIL: case JANET_NIL:
case JANET_INTEGER: case JANET_NUMBER:
case JANET_REAL:
case JANET_SYMBOL: case JANET_SYMBOL:
case JANET_TRUE: case JANET_TRUE:
case JANET_FALSE: case JANET_FALSE:
@ -503,7 +492,7 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) {
default: default:
{ {
Janet seenid = janet_table_get(&S->seen, x); Janet seenid = janet_table_get(&S->seen, x);
if (janet_checktype(seenid, JANET_INTEGER)) { if (janet_checktype(seenid, JANET_NUMBER)) {
janet_buffer_push_cstring(S->buffer, "<cycle "); janet_buffer_push_cstring(S->buffer, "<cycle ");
integer_to_string_b(S->buffer, janet_unwrap_integer(seenid)); integer_to_string_b(S->buffer, janet_unwrap_integer(seenid));
janet_buffer_push_u8(S->buffer, '>'); janet_buffer_push_u8(S->buffer, '>');
@ -652,7 +641,7 @@ const uint8_t *janet_formatc(const char *format, ...) {
janet_buffer_push_u8(bufp, format[i]); janet_buffer_push_u8(bufp, format[i]);
break; break;
case 'f': case 'f':
real_to_string_b(bufp, va_arg(args, double)); number_to_string_b(bufp, va_arg(args, double));
break; break;
case 'd': case 'd':
integer_to_string_b(bufp, va_arg(args, int32_t)); integer_to_string_b(bufp, va_arg(args, int32_t));
@ -803,18 +792,14 @@ static int cfun_slice(JanetArgs args) {
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (janet_checktype(args.v[1], JANET_INTEGER)) {
start = janet_unwrap_integer(args.v[1]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(start, args, 1);
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
end = -1; end = -1;
} else if (janet_checktype(args.v[2], JANET_INTEGER)) {
end = janet_unwrap_integer(args.v[2]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(end, args, 2);
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;
@ -870,7 +855,9 @@ static int cfun_frombytes(JanetArgs args) {
int32_t i; int32_t i;
uint8_t *buf; uint8_t *buf;
for (i = 0; i < args.n; i++) { for (i = 0; i < args.n; i++) {
JANET_CHECK(args, i, JANET_INTEGER); if (!janet_checkint(args.v[i])) {
JANET_THROW(args, "expected integer byte values");
}
} }
buf = janet_string_begin(args.n); buf = janet_string_begin(args.n);
for (i = 0; i < args.n; i++) { for (i = 0; i < args.n; i++) {

View File

@ -295,7 +295,7 @@ int32_t janet_scan_integer(
/* Scan a real (double) from a string. If the string cannot be converted into /* Scan a real (double) from a string. If the string cannot be converted into
* and integer, set *err to 1 and return 0. */ * and integer, set *err to 1 and return 0. */
double janet_scan_real( double janet_scan_number(
const uint8_t *str, const uint8_t *str,
int32_t len, int32_t len,
int *err) { int *err) {
@ -310,21 +310,3 @@ double janet_scan_real(
} }
return convert(res.neg, res.mant, res.base, res.ex); return convert(res.neg, res.mant, res.base, res.ex);
} }
/* Scans a number from a string. Can return either an integer or a real if
* the number cannot be represented as an integer. Will return nil in case of
* an error. */
Janet janet_scan_number(
const uint8_t *str,
int32_t len) {
struct JanetScanRes res = janet_scan_impl(str, len);
if (res.error)
return janet_wrap_nil();
if (!res.foundexp && !res.seenpoint) {
int64_t i64 = res.neg ? -(int64_t)res.mant : (int64_t)res.mant;
if (i64 <= INT32_MAX && i64 >= INT32_MIN) {
return janet_wrap_integer((int32_t) i64);
}
}
return janet_wrap_real(convert(res.neg, res.mant, res.base, res.ex));
}

View File

@ -101,18 +101,14 @@ static int cfun_slice(JanetArgs args) {
/* Get start */ /* Get start */
if (args.n < 2) { if (args.n < 2) {
start = 0; start = 0;
} else if (janet_checktype(args.v[1], JANET_INTEGER)) {
start = janet_unwrap_integer(args.v[1]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(start, args, 1);
} }
/* Get end */ /* Get end */
if (args.n < 3) { if (args.n < 3) {
end = -1; end = -1;
} else if (janet_checktype(args.v[2], JANET_INTEGER)) {
end = janet_unwrap_integer(args.v[2]);
} else { } else {
JANET_THROW(args, "expected integer"); JANET_ARG_INTEGER(end, args, 2);
} }
if (start < 0) start = len + start; if (start < 0) start = len + start;
if (end < 0) end = len + end + 1; if (end < 0) end = len + end + 1;

View File

@ -34,13 +34,12 @@ const char janet_base64[65] =
/* The JANET value types in order. These types can be used as /* The JANET value types in order. These types can be used as
* mnemonics instead of a bit pattern for type checking */ * mnemonics instead of a bit pattern for type checking */
const char *const janet_type_names[16] = { const char *const janet_type_names[15] = {
":nil", ":nil",
":boolean", ":boolean",
":boolean", ":boolean",
":fiber", ":fiber",
":integer", ":number",
":real",
":string", ":string",
":symbol", ":symbol",
":array", ":array",
@ -423,3 +422,17 @@ int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstractType *a
"bad slot #%d, expected %s, got %s", "bad slot #%d, expected %s, got %s",
n, at->name, typestr(args, n)))); n, at->name, typestr(args, n))));
} }
int janet_checkint(Janet x) {
if (!janet_checktype(x, JANET_NUMBER))
return 0;
double dval = janet_unwrap_number(x);
return janet_checkintrange(dval);
}
int janet_checkint64(Janet x) {
if (!janet_checktype(x, JANET_NUMBER))
return 0;
double dval = janet_unwrap_number(x);
return janet_checkint64range(dval);
}

View File

@ -38,11 +38,8 @@ int janet_equals(Janet x, Janet y) {
case JANET_FALSE: case JANET_FALSE:
result = 1; result = 1;
break; break;
case JANET_REAL: case JANET_NUMBER:
result = (janet_unwrap_real(x) == janet_unwrap_real(y)); result = (janet_unwrap_number(x) == janet_unwrap_number(y));
break;
case JANET_INTEGER:
result = (janet_unwrap_integer(x) == janet_unwrap_integer(y));
break; break;
case JANET_STRING: case JANET_STRING:
result = janet_string_equal(janet_unwrap_string(x), janet_unwrap_string(y)); result = janet_string_equal(janet_unwrap_string(x), janet_unwrap_string(y));
@ -85,9 +82,6 @@ int32_t janet_hash(Janet x) {
case JANET_STRUCT: case JANET_STRUCT:
hash = janet_struct_hash(janet_unwrap_struct(x)); hash = janet_struct_hash(janet_unwrap_struct(x));
break; break;
case JANET_INTEGER:
hash = janet_unwrap_integer(x);
break;
default: default:
/* TODO - test performance with different hash functions */ /* TODO - test performance with different hash functions */
if (sizeof(double) == sizeof(void *)) { if (sizeof(double) == sizeof(void *)) {
@ -117,25 +111,19 @@ int janet_compare(Janet x, Janet y) {
case JANET_FALSE: case JANET_FALSE:
case JANET_TRUE: case JANET_TRUE:
return 0; return 0;
case JANET_REAL: case JANET_NUMBER:
/* Check for nans to ensure total order */ /* Check for nans to ensure total order */
if (janet_unwrap_real(x) != janet_unwrap_real(x)) if (janet_unwrap_number(x) != janet_unwrap_number(x))
return janet_unwrap_real(y) != janet_unwrap_real(y) return janet_unwrap_number(y) != janet_unwrap_number(y)
? 0 ? 0
: -1; : -1;
if (janet_unwrap_real(y) != janet_unwrap_real(y)) if (janet_unwrap_number(y) != janet_unwrap_number(y))
return 1; return 1;
if (janet_unwrap_real(x) == janet_unwrap_real(y)) { if (janet_unwrap_number(x) == janet_unwrap_number(y)) {
return 0; return 0;
} else { } else {
return janet_unwrap_real(x) > janet_unwrap_real(y) ? 1 : -1; return janet_unwrap_number(x) > janet_unwrap_number(y) ? 1 : -1;
}
case JANET_INTEGER:
if (janet_unwrap_integer(x) == janet_unwrap_integer(y)) {
return 0;
} else {
return janet_unwrap_integer(x) > janet_unwrap_integer(y) ? 1 : -1;
} }
case JANET_STRING: case JANET_STRING:
case JANET_SYMBOL: case JANET_SYMBOL:
@ -154,3 +142,224 @@ int janet_compare(Janet x, Janet y) {
} }
return (janet_type(x) < janet_type(y)) ? -1 : 1; return (janet_type(x) < janet_type(y)) ? -1 : 1;
} }
/* Gets a value and returns. If successful, return 0. If there is an error,
* returns -1 for bad ds, -2 for bad key */
int janet_get(Janet ds, Janet key, Janet *out) {
Janet value;
switch (janet_type(ds)) {
default:
return -1;
case JANET_STRUCT:
value = janet_struct_get(janet_unwrap_struct(ds), key);
break;
case JANET_TABLE:
value = janet_table_get(janet_unwrap_table(ds), key);
break;
case JANET_ARRAY:
{
JanetArray *array = janet_unwrap_array(ds);
int32_t index;
if (!janet_checkint(key)) return -2;
index = janet_unwrap_integer(key);
if (index < 0 || index >= array->count) {
value = janet_wrap_nil();
} else {
value = array->data[index];
}
break;
}
case JANET_TUPLE:
{
const Janet *tuple = janet_unwrap_tuple(ds);
int32_t index;
if (!janet_checkint(key)) return -2;
index = janet_unwrap_integer(key);
if (index < 0 || index >= janet_tuple_length(tuple)) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = tuple[index];
}
break;
}
case JANET_BUFFER:
{
JanetBuffer *buffer = janet_unwrap_buffer(ds);
int32_t index;
if (!janet_checkint(key)) return -2;
index = janet_unwrap_integer(key);
if (index < 0 || index >= buffer->count) {
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(buffer->data[index]);
}
break;
}
case JANET_STRING:
case JANET_SYMBOL:
{
const uint8_t *str = janet_unwrap_string(ds);
int32_t index;
if (!janet_checkint(key)) return -2;
index = janet_unwrap_integer(key);
if (index < 0 || index >= janet_string_length(str)) {
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(str[index]);
}
break;
}
}
*out = value;
return 0;
}
int janet_getindex(Janet ds, int32_t index, Janet *out) {
Janet value;
if (index < 0)
return -2;
switch (janet_type(ds)) {
default:
return -1;
case JANET_STRING:
case JANET_SYMBOL:
if (index >= janet_string_length(janet_unwrap_string(ds))) {
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(janet_unwrap_string(ds)[index]);
}
break;
case JANET_ARRAY:
if (index >= janet_unwrap_array(ds)->count) {
value = janet_wrap_nil();
} else {
value = janet_unwrap_array(ds)->data[index];
}
break;
case JANET_BUFFER:
if (index >= janet_unwrap_buffer(ds)->count) {
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(janet_unwrap_buffer(ds)->data[index]);
}
break;
case JANET_TUPLE:
if (index >= janet_tuple_length(janet_unwrap_tuple(ds))) {
value = janet_wrap_nil();
} else {
value = janet_unwrap_tuple(ds)[index];
}
break;
case JANET_TABLE:
value = janet_table_get(janet_unwrap_table(ds), janet_wrap_integer(index));
break;
case JANET_STRUCT:
value = janet_struct_get(janet_unwrap_struct(ds), janet_wrap_integer(index));
break;
}
*out = value;
return 0;
}
int janet_length(Janet x, int32_t *out) {
int32_t len;
switch (janet_type(x)) {
default:
return -1;
case JANET_STRING:
case JANET_SYMBOL:
len = janet_string_length(janet_unwrap_string(x));
break;
case JANET_ARRAY:
len = janet_unwrap_array(x)->count;
break;
case JANET_BUFFER:
len = janet_unwrap_buffer(x)->count;
break;
case JANET_TUPLE:
len = janet_tuple_length(janet_unwrap_tuple(x));
break;
case JANET_STRUCT:
len = janet_struct_length(janet_unwrap_struct(x));
break;
case JANET_TABLE:
len = janet_unwrap_table(x)->count;
break;
}
*out = len;
return 0;
}
int janet_putindex(Janet ds, int32_t index, Janet value) {
switch (janet_type(ds)) {
default:
return -1;
case JANET_ARRAY:
{
JanetArray *array = janet_unwrap_array(ds);
if (index >= array->count) {
janet_array_ensure(array, index + 1, 2);
array->count = index + 1;
}
array->data[index] = value;
break;
}
case JANET_BUFFER:
{
JanetBuffer *buffer = janet_unwrap_buffer(ds);
if (!janet_checkint(value)) return -3;
if (index >= buffer->count) {
janet_buffer_ensure(buffer, index + 1, 2);
buffer->count = index + 1;
}
buffer->data[index] = janet_unwrap_integer(value);
break;
}
case JANET_TABLE:
{
JanetTable *table = janet_unwrap_table(ds);
janet_table_put(table, janet_wrap_integer(index), value);
break;
}
}
return 0;
}
int janet_put(Janet ds, Janet key, Janet value) {
switch (janet_type(ds)) {
default:
return -1;
case JANET_ARRAY:
{
int32_t index;
JanetArray *array = janet_unwrap_array(ds);
if (!janet_checkint(key)) return -2;
index = janet_unwrap_integer(key);
if (index < 0 || index == INT32_MAX) return -2;
if (index >= array->count) {
janet_array_setcount(array, index + 1);
}
array->data[index] = value;
break;
}
case JANET_BUFFER:
{
int32_t index;
JanetBuffer *buffer = janet_unwrap_buffer(ds);
if (!janet_checkint(key)) return -2;
index = janet_unwrap_integer(key);
if (index < 0 || index == INT32_MAX) return -2;
if (!janet_checkint(value)) return -3;
if (index >= buffer->count) {
janet_buffer_setcount(buffer, index + 1);
}
buffer->data[index] = (uint8_t) (janet_unwrap_integer(value) & 0xFF);
break;
}
case JANET_TABLE:
janet_table_put(janet_unwrap_table(ds), key, value);
break;
}
return 0;
}

View File

@ -122,20 +122,12 @@ static void *op_lookup[255] = {
&&label_JOP_TYPECHECK, &&label_JOP_TYPECHECK,
&&label_JOP_RETURN, &&label_JOP_RETURN,
&&label_JOP_RETURN_NIL, &&label_JOP_RETURN_NIL,
&&label_JOP_ADD_INTEGER,
&&label_JOP_ADD_IMMEDIATE, &&label_JOP_ADD_IMMEDIATE,
&&label_JOP_ADD_REAL,
&&label_JOP_ADD, &&label_JOP_ADD,
&&label_JOP_SUBTRACT_INTEGER,
&&label_JOP_SUBTRACT_REAL,
&&label_JOP_SUBTRACT, &&label_JOP_SUBTRACT,
&&label_JOP_MULTIPLY_INTEGER,
&&label_JOP_MULTIPLY_IMMEDIATE, &&label_JOP_MULTIPLY_IMMEDIATE,
&&label_JOP_MULTIPLY_REAL,
&&label_JOP_MULTIPLY, &&label_JOP_MULTIPLY,
&&label_JOP_DIVIDE_INTEGER,
&&label_JOP_DIVIDE_IMMEDIATE, &&label_JOP_DIVIDE_IMMEDIATE,
&&label_JOP_DIVIDE_REAL,
&&label_JOP_DIVIDE, &&label_JOP_DIVIDE,
&&label_JOP_BAND, &&label_JOP_BAND,
&&label_JOP_BOR, &&label_JOP_BOR,
@ -153,19 +145,11 @@ static void *op_lookup[255] = {
&&label_JOP_JUMP_IF, &&label_JOP_JUMP_IF,
&&label_JOP_JUMP_IF_NOT, &&label_JOP_JUMP_IF_NOT,
&&label_JOP_GREATER_THAN, &&label_JOP_GREATER_THAN,
&&label_JOP_GREATER_THAN_INTEGER,
&&label_JOP_GREATER_THAN_IMMEDIATE, &&label_JOP_GREATER_THAN_IMMEDIATE,
&&label_JOP_GREATER_THAN_REAL,
&&label_JOP_GREATER_THAN_EQUAL_REAL,
&&label_JOP_LESS_THAN, &&label_JOP_LESS_THAN,
&&label_JOP_LESS_THAN_INTEGER,
&&label_JOP_LESS_THAN_IMMEDIATE, &&label_JOP_LESS_THAN_IMMEDIATE,
&&label_JOP_LESS_THAN_REAL,
&&label_JOP_LESS_THAN_EQUAL_REAL,
&&label_JOP_EQUALS, &&label_JOP_EQUALS,
&&label_JOP_EQUALS_INTEGER,
&&label_JOP_EQUALS_IMMEDIATE, &&label_JOP_EQUALS_IMMEDIATE,
&&label_JOP_EQUALS_REAL,
&&label_JOP_COMPARE, &&label_JOP_COMPARE,
&&label_JOP_LOAD_NIL, &&label_JOP_LOAD_NIL,
&&label_JOP_LOAD_TRUE, &&label_JOP_LOAD_TRUE,
@ -229,61 +213,63 @@ static void *op_lookup[255] = {
} \ } \
} while (0) } while (0)
#define vm_binop_integer(op) \
stack[oparg(1, 0xFF)] = janet_wrap_integer(\
janet_unwrap_integer(stack[oparg(2, 0xFF)]) op janet_unwrap_integer(stack[oparg(3, 0xFF)])\
);\
pc++;\
vm_next();
#define vm_binop_real(op)\
stack[oparg(1, 0xFF)] = janet_wrap_real(\
janet_unwrap_real(stack[oparg(2, 0xFF)]) op janet_unwrap_real(stack[oparg(3, 0xFF)])\
);\
pc++;\
vm_next();
#define vm_binop_immediate(op)\ #define vm_binop_immediate(op)\
stack[oparg(1, 0xFF)] = janet_wrap_integer(\
janet_unwrap_integer(stack[oparg(2, 0xFF)]) op (*((int32_t *)pc) >> 24)\
);\
pc++;\
vm_next();
#define vm_binop(op)\
{\ {\
Janet op1 = stack[oparg(2, 0xFF)];\ Janet op1 = stack[oparg(2, 0xFF)];\
Janet op2 = stack[oparg(3, 0xFF)];\ vm_assert_type(op1, JANET_NUMBER);\
vm_assert_types(op1, JANET_TFLAG_NUMBER);\ double x1 = janet_unwrap_number(op1);\
vm_assert_types(op2, JANET_TFLAG_NUMBER);\ int32_t x2 = (*((int32_t *)pc) >> 24);\
stack[oparg(1, 0xFF)] = janet_checktype(op1, JANET_INTEGER)\ stack[oparg(1, 0xFF)] = janet_wrap_number(x1 op x2);\
? (janet_checktype(op2, JANET_INTEGER)\
? janet_wrap_integer(janet_unwrap_integer(op1) op janet_unwrap_integer(op2))\
: janet_wrap_real((double)janet_unwrap_integer(op1) op janet_unwrap_real(op2)))\
: (janet_checktype(op2, JANET_INTEGER)\
? janet_wrap_real(janet_unwrap_real(op1) op (double)janet_unwrap_integer(op2))\
: janet_wrap_real(janet_unwrap_real(op1) op janet_unwrap_real(op2)));\
pc++;\ pc++;\
vm_next();\ vm_next();\
} }
#define vm_numcomp(op)\ #define _vm_bitop_immediate(op, type1)\
{\ {\
Janet op1 = stack[oparg(2, 0xFF)];\ Janet op1 = stack[oparg(2, 0xFF)];\
Janet op2 = stack[oparg(3, 0xFF)];\ vm_assert_type(op1, JANET_NUMBER);\
vm_assert_types(op1, JANET_TFLAG_NUMBER);\ type1 x1 = (type1) janet_unwrap_integer(op1);\
vm_assert_types(op2, JANET_TFLAG_NUMBER);\ int32_t x2 = (*((int32_t *)pc) >> 24);\
stack[oparg(1, 0xFF)] = janet_wrap_boolean(janet_checktype(op1, JANET_INTEGER)\ stack[oparg(1, 0xFF)] = janet_wrap_integer(x1 op x2);\
? (janet_checktype(op2, JANET_INTEGER)\
? janet_unwrap_integer(op1) op janet_unwrap_integer(op2)\
: (double)janet_unwrap_integer(op1) op janet_unwrap_real(op2))\
: (janet_checktype(op2, JANET_INTEGER)\
? janet_unwrap_real(op1) op (double)janet_unwrap_integer(op2)\
: janet_unwrap_real(op1) op janet_unwrap_real(op2)));\
pc++;\ pc++;\
vm_next();\ vm_next();\
} }
#define vm_bitop_immediate(op) _vm_bitop_immediate(op, int32_t);
#define vm_bitopu_immediate(op) _vm_bitop_immediate(op, uint32_t);
#define _vm_binop(op, wrap)\
{\
Janet op1 = stack[oparg(2, 0xFF)];\
Janet op2 = stack[oparg(3, 0xFF)];\
vm_assert_type(op1, JANET_NUMBER);\
vm_assert_type(op2, JANET_NUMBER);\
double x1 = janet_unwrap_number(op1);\
double x2 = janet_unwrap_number(op2);\
stack[oparg(1, 0xFF)] = wrap(x1 op x2);\
pc++;\
vm_next();\
}
#define vm_binop(op) _vm_binop(op, janet_wrap_number)
#define vm_numcomp(op) _vm_binop(op, janet_wrap_boolean)
#define _vm_bitop(op, type1)\
{\
Janet op1 = stack[oparg(2, 0xFF)];\
Janet op2 = stack[oparg(3, 0xFF)];\
vm_assert_type(op1, JANET_NUMBER);\
vm_assert_type(op2, JANET_NUMBER);\
type1 x1 = (type1) janet_unwrap_integer(op1);\
int32_t x2 = janet_unwrap_integer(op2);\
stack[oparg(1, 0xFF)] = janet_wrap_integer(x1 op x2);\
pc++;\
vm_next();\
}
#define vm_bitop(op) _vm_bitop(op, int32_t)
#define vm_bitopu(op) _vm_bitop(op, uint32_t)
/* Main interpreter loop. Semantically is a switch on /* Main interpreter loop. Semantically is a switch on
* (*pc & 0xFF) inside of an infinte loop. */ * (*pc & 0xFF) inside of an infinte loop. */
VM_START(); VM_START();
@ -320,36 +306,18 @@ static void *op_lookup[255] = {
retreg = janet_wrap_nil(); retreg = janet_wrap_nil();
goto vm_return; goto vm_return;
VM_OP(JOP_ADD_INTEGER)
vm_binop_integer(+);
VM_OP(JOP_ADD_IMMEDIATE) VM_OP(JOP_ADD_IMMEDIATE)
vm_binop_immediate(+); vm_binop_immediate(+);
VM_OP(JOP_ADD_REAL)
vm_binop_real(+);
VM_OP(JOP_ADD) VM_OP(JOP_ADD)
vm_binop(+); vm_binop(+);
VM_OP(JOP_SUBTRACT_INTEGER)
vm_binop_integer(-);
VM_OP(JOP_SUBTRACT_REAL)
vm_binop_real(-);
VM_OP(JOP_SUBTRACT) VM_OP(JOP_SUBTRACT)
vm_binop(-); vm_binop(-);
VM_OP(JOP_MULTIPLY_INTEGER)
vm_binop_integer(*);
VM_OP(JOP_MULTIPLY_IMMEDIATE) VM_OP(JOP_MULTIPLY_IMMEDIATE)
vm_binop_immediate(*); vm_binop_immediate(*);
VM_OP(JOP_MULTIPLY_REAL)
vm_binop_real(*);
VM_OP(JOP_MULTIPLY) VM_OP(JOP_MULTIPLY)
vm_binop(*); vm_binop(*);
@ -368,104 +336,47 @@ static void *op_lookup[255] = {
VM_OP(JOP_NUMERIC_EQUAL) VM_OP(JOP_NUMERIC_EQUAL)
vm_numcomp(==); vm_numcomp(==);
VM_OP(JOP_DIVIDE_INTEGER)
vm_assert(janet_unwrap_integer(stack[oparg(3, 0xFF)]) != 0, "integer divide error");
vm_assert(!(janet_unwrap_integer(stack[oparg(3, 0xFF)]) == -1 &&
janet_unwrap_integer(stack[oparg(2, 0xFF)]) == INT32_MIN),
"integer divide error");
vm_binop_integer(/);
VM_OP(JOP_DIVIDE_IMMEDIATE) VM_OP(JOP_DIVIDE_IMMEDIATE)
{ vm_binop_immediate(/);
int32_t op1 = janet_unwrap_integer(stack[oparg(2, 0xFF)]);
int32_t op2 = *((int32_t *)pc) >> 24;
/* Check for degenerate integer division (divide by zero, and dividing
* min value by -1). These checks could be omitted if the arg is not
* 0 or -1. */
if (op2 == 0)
vm_throw("integer divide error");
if (op2 == -1 && op1 == INT32_MIN)
vm_throw("integer divide error");
else
stack[oparg(1, 0xFF)] = janet_wrap_integer(op1 / op2);
pc++;
vm_next();
}
VM_OP(JOP_DIVIDE_REAL)
vm_binop_real(/);
VM_OP(JOP_DIVIDE) VM_OP(JOP_DIVIDE)
vm_binop(/);
VM_OP(JOP_BAND)
vm_bitop(&);
VM_OP(JOP_BOR)
vm_bitop(|);
VM_OP(JOP_BXOR)
vm_bitop(^);
VM_OP(JOP_BNOT)
{ {
Janet op1 = stack[oparg(2, 0xFF)]; Janet op = stack[oparg(2, 0xFFFF)];
Janet op2 = stack[oparg(3, 0xFF)]; vm_assert_type(op, JANET_NUMBER);
vm_assert_types(op1, JANET_TFLAG_NUMBER); stack[oparg(1, 0xFF)] = janet_wrap_integer(~janet_unwrap_integer(op));
vm_assert_types(op2, JANET_TFLAG_NUMBER); ++pc;
if (janet_checktype(op2, JANET_INTEGER) && janet_unwrap_integer(op2) == 0)
vm_throw("integer divide by zero");
if (janet_checktype(op2, JANET_INTEGER) && janet_unwrap_integer(op2) == -1 &&
janet_checktype(op1, JANET_INTEGER) && janet_unwrap_integer(op1) == INT32_MIN)
vm_throw("integer divide out of range");
stack[oparg(1, 0xFF)] = janet_checktype(op1, JANET_INTEGER)
? (janet_checktype(op2, JANET_INTEGER)
? janet_wrap_integer(janet_unwrap_integer(op1) / janet_unwrap_integer(op2))
: janet_wrap_real((double)janet_unwrap_integer(op1) / janet_unwrap_real(op2)))
: (janet_checktype(op2, JANET_INTEGER)
? janet_wrap_real(janet_unwrap_real(op1) / (double)janet_unwrap_integer(op2))
: janet_wrap_real(janet_unwrap_real(op1) / janet_unwrap_real(op2)));
pc++;
vm_next(); vm_next();
} }
VM_OP(JOP_BAND)
vm_binop_integer(&);
VM_OP(JOP_BOR)
vm_binop_integer(|);
VM_OP(JOP_BXOR)
vm_binop_integer(^);
VM_OP(JOP_BNOT)
stack[oparg(1, 0xFF)] = janet_wrap_integer(~janet_unwrap_integer(stack[oparg(2, 0xFFFF)]));
++pc;
vm_next();
VM_OP(JOP_SHIFT_RIGHT_UNSIGNED) VM_OP(JOP_SHIFT_RIGHT_UNSIGNED)
stack[oparg(1, 0xFF)] = janet_wrap_integer( vm_bitopu(>>);
(int32_t)(((uint32_t)janet_unwrap_integer(stack[oparg(2, 0xFF)]))
>>
janet_unwrap_integer(stack[oparg(3, 0xFF)]))
);
pc++;
vm_next();
VM_OP(JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE) VM_OP(JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE)
stack[oparg(1, 0xFF)] = janet_wrap_integer( vm_bitopu_immediate(>>);
(int32_t) (((uint32_t)janet_unwrap_integer(stack[oparg(2, 0xFF)])) >> oparg(3, 0xFF))
);
pc++;
vm_next();
VM_OP(JOP_SHIFT_RIGHT) VM_OP(JOP_SHIFT_RIGHT)
vm_binop_integer(>>); vm_bitop(>>);
VM_OP(JOP_SHIFT_RIGHT_IMMEDIATE) VM_OP(JOP_SHIFT_RIGHT_IMMEDIATE)
stack[oparg(1, 0xFF)] = janet_wrap_integer( vm_bitop_immediate(>>);
(int32_t)(janet_unwrap_integer(stack[oparg(2, 0xFF)]) >> oparg(3, 0xFF))
);
pc++;
vm_next();
VM_OP(JOP_SHIFT_LEFT) VM_OP(JOP_SHIFT_LEFT)
vm_binop_integer(<<); vm_bitop(<<);
VM_OP(JOP_SHIFT_LEFT_IMMEDIATE) VM_OP(JOP_SHIFT_LEFT_IMMEDIATE)
stack[oparg(1, 0xFF)] = janet_wrap_integer( vm_bitop_immediate(<<);
janet_unwrap_integer(stack[oparg(2, 0xFF)]) << oparg(3, 0xFF)
);
pc++;
vm_next();
VM_OP(JOP_MOVE_NEAR) VM_OP(JOP_MOVE_NEAR)
stack[oparg(1, 0xFF)] = stack[oparg(2, 0xFFFF)]; stack[oparg(1, 0xFF)] = stack[oparg(2, 0xFFFF)];
@ -505,14 +416,6 @@ static void *op_lookup[255] = {
pc++; pc++;
vm_next(); vm_next();
/* Candidate */
VM_OP(JOP_LESS_THAN_INTEGER)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_integer(stack[oparg(2, 0xFF)]) <
janet_unwrap_integer(stack[oparg(3, 0xFF)]));
pc++;
vm_next();
/* Candidate */ /* Candidate */
VM_OP(JOP_LESS_THAN_IMMEDIATE) VM_OP(JOP_LESS_THAN_IMMEDIATE)
stack[oparg(1, 0xFF)] = janet_wrap_boolean( stack[oparg(1, 0xFF)] = janet_wrap_boolean(
@ -521,23 +424,6 @@ static void *op_lookup[255] = {
pc++; pc++;
vm_next(); vm_next();
/* Candidate */
VM_OP(JOP_LESS_THAN_REAL)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_real(stack[oparg(2, 0xFF)]) <
janet_unwrap_real(stack[oparg(3, 0xFF)]));
pc++;
vm_next();
/* Candidate */
VM_OP(JOP_LESS_THAN_EQUAL_REAL)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_real(stack[oparg(2, 0xFF)]) <=
janet_unwrap_real(stack[oparg(3, 0xFF)]));
pc++;
vm_next();
VM_OP(JOP_GREATER_THAN) VM_OP(JOP_GREATER_THAN)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(janet_compare( stack[oparg(1, 0xFF)] = janet_wrap_boolean(janet_compare(
stack[oparg(2, 0xFF)], stack[oparg(2, 0xFF)],
@ -546,13 +432,6 @@ static void *op_lookup[255] = {
pc++; pc++;
vm_next(); vm_next();
VM_OP(JOP_GREATER_THAN_INTEGER)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_integer(stack[oparg(2, 0xFF)]) >
janet_unwrap_integer(stack[oparg(3, 0xFF)]));
pc++;
vm_next();
VM_OP(JOP_GREATER_THAN_IMMEDIATE) VM_OP(JOP_GREATER_THAN_IMMEDIATE)
stack[oparg(1, 0xFF)] = janet_wrap_boolean( stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_integer(stack[oparg(2, 0xFF)]) > ((*(int32_t *)pc) >> 24) janet_unwrap_integer(stack[oparg(2, 0xFF)]) > ((*(int32_t *)pc) >> 24)
@ -560,20 +439,6 @@ static void *op_lookup[255] = {
pc++; pc++;
vm_next(); vm_next();
VM_OP(JOP_GREATER_THAN_REAL)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_real(stack[oparg(2, 0xFF)]) >
janet_unwrap_real(stack[oparg(3, 0xFF)]));
pc++;
vm_next();
VM_OP(JOP_GREATER_THAN_EQUAL_REAL)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_real(stack[oparg(2, 0xFF)]) >=
janet_unwrap_real(stack[oparg(3, 0xFF)]));
pc++;
vm_next();
VM_OP(JOP_EQUALS) VM_OP(JOP_EQUALS)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(janet_equals( stack[oparg(1, 0xFF)] = janet_wrap_boolean(janet_equals(
stack[oparg(2, 0xFF)], stack[oparg(2, 0xFF)],
@ -582,22 +447,6 @@ static void *op_lookup[255] = {
pc++; pc++;
vm_next(); vm_next();
VM_OP(JOP_EQUALS_INTEGER)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_integer(stack[oparg(2, 0xFF)]) ==
janet_unwrap_integer(stack[oparg(3, 0xFF)])
);
pc++;
vm_next();
VM_OP(JOP_EQUALS_REAL)
stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_real(stack[oparg(2, 0xFF)]) ==
janet_unwrap_real(stack[oparg(3, 0xFF)])
);
pc++;
vm_next();
VM_OP(JOP_EQUALS_IMMEDIATE) VM_OP(JOP_EQUALS_IMMEDIATE)
stack[oparg(1, 0xFF)] = janet_wrap_boolean( stack[oparg(1, 0xFF)] = janet_wrap_boolean(
janet_unwrap_integer(stack[oparg(2, 0xFF)]) == ((*(int32_t *)pc) >> 24) janet_unwrap_integer(stack[oparg(2, 0xFF)]) == ((*(int32_t *)pc) >> 24)
@ -792,7 +641,7 @@ static void *op_lookup[255] = {
VM_OP(JOP_TAILCALL) VM_OP(JOP_TAILCALL)
{ {
Janet callee = stack[oparg(1, 0xFFFFFF)]; Janet callee = stack[oparg(1, 0xFFFF)];
if (janet_checktype(callee, JANET_FUNCTION)) { if (janet_checktype(callee, JANET_FUNCTION)) {
func = janet_unwrap_function(callee); func = janet_unwrap_function(callee);
if (janet_fiber_funcframe_tail(fiber, func)) if (janet_fiber_funcframe_tail(fiber, func))
@ -842,47 +691,17 @@ static void *op_lookup[255] = {
Janet ds = stack[oparg(1, 0xFF)]; Janet ds = stack[oparg(1, 0xFF)];
Janet key = stack[oparg(2, 0xFF)]; Janet key = stack[oparg(2, 0xFF)];
Janet value = stack[oparg(3, 0xFF)]; Janet value = stack[oparg(3, 0xFF)];
switch (janet_type(ds)) { int status;
default: if ((status = janet_put(ds, key, value))) {
if (status == -1) {
expected_types = JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE; expected_types = JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE;
retreg = ds; retreg = ds;
goto vm_type_error; goto vm_type_error;
case JANET_ARRAY: } else if (status == -2) {
{ vm_throw("expected integer key for data structure");
int32_t index; } else if (status == -3) {
JanetArray *array = janet_unwrap_array(ds); vm_throw("expected integer value for data structure");
vm_assert_type(key, JANET_INTEGER);
if (janet_unwrap_integer(key) < 0)
vm_throw("expected non-negative integer key");
index = janet_unwrap_integer(key);
if (index == INT32_MAX)
vm_throw("key too large");
if (index >= array->count) {
janet_array_setcount(array, index + 1);
}
array->data[index] = value;
break;
} }
case JANET_BUFFER:
{
int32_t index;
JanetBuffer *buffer = janet_unwrap_buffer(ds);
vm_assert_type(key, JANET_INTEGER);
if (janet_unwrap_integer(key) < 0)
vm_throw("expected non-negative integer key");
index = janet_unwrap_integer(key);
if (index == INT32_MAX)
vm_throw("key too large");
vm_assert_type(value, JANET_INTEGER);
if (index >= buffer->count) {
janet_buffer_setcount(buffer, index + 1);
}
buffer->data[index] = (uint8_t) (janet_unwrap_integer(value) & 0xFF);
break;
}
case JANET_TABLE:
janet_table_put(janet_unwrap_table(ds), key, value);
break;
} }
++pc; ++pc;
vm_checkgc_next(); vm_checkgc_next();
@ -893,32 +712,15 @@ static void *op_lookup[255] = {
Janet ds = stack[oparg(1, 0xFF)]; Janet ds = stack[oparg(1, 0xFF)];
Janet value = stack[oparg(2, 0xFF)]; Janet value = stack[oparg(2, 0xFF)];
int32_t index = oparg(3, 0xFF); int32_t index = oparg(3, 0xFF);
switch (janet_type(ds)) { int status;
default: if ((status = janet_putindex(ds, index, value))) {
expected_types = JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER; if (status == -1) {
expected_types = JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE;
retreg = ds; retreg = ds;
goto vm_type_error; goto vm_type_error;
case JANET_ARRAY: } else if (status == -3) {
{ vm_throw("expected integer value for data structure");
JanetArray *array = janet_unwrap_array(ds); }
if (index >= array->count) {
janet_array_ensure(array, index + 1, 2);
array->count = index + 1;
}
array->data[index] = value;
break;
}
case JANET_BUFFER:
{
JanetBuffer *buffer = janet_unwrap_buffer(ds);
vm_assert_type(value, JANET_INTEGER);
if (index >= buffer->count) {
janet_buffer_ensure(buffer, index + 1, 2);
buffer->count = index + 1;
}
buffer->data[index] = janet_unwrap_integer(value);
break;
}
} }
++pc; ++pc;
vm_checkgc_next(); vm_checkgc_next();
@ -928,77 +730,16 @@ static void *op_lookup[255] = {
{ {
Janet ds = stack[oparg(2, 0xFF)]; Janet ds = stack[oparg(2, 0xFF)];
Janet key = stack[oparg(3, 0xFF)]; Janet key = stack[oparg(3, 0xFF)];
Janet value; int status;
switch (janet_type(ds)) { if ((status = janet_get(ds, key, stack + oparg(1, 0xFF)))) {
default: if (status == -1) {
expected_types = JANET_TFLAG_LENGTHABLE; expected_types = JANET_TFLAG_LENGTHABLE;
retreg = ds; retreg = ds;
goto vm_type_error; goto vm_type_error;
case JANET_STRUCT: } else {
value = janet_struct_get(janet_unwrap_struct(ds), key); vm_throw("expected integer key for data structure");
break; }
case JANET_TABLE:
value = janet_table_get(janet_unwrap_table(ds), key);
break;
case JANET_ARRAY:
{
JanetArray *array = janet_unwrap_array(ds);
int32_t index;
vm_assert_type(key, JANET_INTEGER);
index = janet_unwrap_integer(key);
if (index < 0 || index >= array->count) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = array->data[index];
}
break;
}
case JANET_TUPLE:
{
const Janet *tuple = janet_unwrap_tuple(ds);
int32_t index;
vm_assert_type(key, JANET_INTEGER);
index = janet_unwrap_integer(key);
if (index < 0 || index >= janet_tuple_length(tuple)) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = tuple[index];
}
break;
}
case JANET_BUFFER:
{
JanetBuffer *buffer = janet_unwrap_buffer(ds);
int32_t index;
vm_assert_type(key, JANET_INTEGER);
index = janet_unwrap_integer(key);
if (index < 0 || index >= buffer->count) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(buffer->data[index]);
}
break;
}
case JANET_STRING:
case JANET_SYMBOL:
{
const uint8_t *str = janet_unwrap_string(ds);
int32_t index;
vm_assert_type(key, JANET_INTEGER);
index = janet_unwrap_integer(key);
if (index < 0 || index >= janet_string_length(str)) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(str[index]);
}
break;
}
} }
stack[oparg(1, 0xFF)] = value;
++pc; ++pc;
vm_next(); vm_next();
} }
@ -1007,53 +748,11 @@ static void *op_lookup[255] = {
{ {
Janet ds = stack[oparg(2, 0xFF)]; Janet ds = stack[oparg(2, 0xFF)];
int32_t index = oparg(3, 0xFF); int32_t index = oparg(3, 0xFF);
Janet value; if (janet_getindex(ds, index, stack + oparg(1, 0xFF))) {
switch (janet_type(ds)) { expected_types = JANET_TFLAG_LENGTHABLE;
default: retreg = ds;
expected_types = JANET_TFLAG_LENGTHABLE; goto vm_type_error;
retreg = ds;
goto vm_type_error;
case JANET_STRING:
case JANET_SYMBOL:
if (index >= janet_string_length(janet_unwrap_string(ds))) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(janet_unwrap_string(ds)[index]);
}
break;
case JANET_ARRAY:
if (index >= janet_unwrap_array(ds)->count) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = janet_unwrap_array(ds)->data[index];
}
break;
case JANET_BUFFER:
if (index >= janet_unwrap_buffer(ds)->count) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = janet_wrap_integer(janet_unwrap_buffer(ds)->data[index]);
}
break;
case JANET_TUPLE:
if (index >= janet_tuple_length(janet_unwrap_tuple(ds))) {
/*vm_throw("index out of bounds");*/
value = janet_wrap_nil();
} else {
value = janet_unwrap_tuple(ds)[index];
}
break;
case JANET_TABLE:
value = janet_table_get(janet_unwrap_table(ds), janet_wrap_integer(index));
break;
case JANET_STRUCT:
value = janet_struct_get(janet_unwrap_struct(ds), janet_wrap_integer(index));
break;
} }
stack[oparg(1, 0xFF)] = value;
++pc; ++pc;
vm_next(); vm_next();
} }
@ -1062,30 +761,10 @@ static void *op_lookup[255] = {
{ {
Janet x = stack[oparg(2, 0xFFFF)]; Janet x = stack[oparg(2, 0xFFFF)];
int32_t len; int32_t len;
switch (janet_type(x)) { if (janet_length(x, &len)) {
default: expected_types = JANET_TFLAG_LENGTHABLE;
expected_types = JANET_TFLAG_LENGTHABLE; retreg = x;
retreg = x; goto vm_type_error;
goto vm_type_error;
case JANET_STRING:
case JANET_SYMBOL:
len = janet_string_length(janet_unwrap_string(x));
break;
case JANET_ARRAY:
len = janet_unwrap_array(x)->count;
break;
case JANET_BUFFER:
len = janet_unwrap_buffer(x)->count;
break;
case JANET_TUPLE:
len = janet_tuple_length(janet_unwrap_tuple(x));
break;
case JANET_STRUCT:
len = janet_struct_length(janet_unwrap_struct(x));
break;
case JANET_TABLE:
len = janet_unwrap_table(x)->count;
break;
} }
stack[oparg(1, 0xFF)] = janet_wrap_integer(len); stack[oparg(1, 0xFF)] = janet_wrap_integer(len);
++pc; ++pc;

View File

@ -45,10 +45,10 @@ Janet janet_nanbox_from_cpointer(const void *p, uint64_t tagmask) {
Janet janet_nanbox_from_double(double d) { Janet janet_nanbox_from_double(double d) {
Janet ret; Janet ret;
ret.real = d; ret.number = d;
/* Normalize NaNs */ /* Normalize NaNs */
if (d != d) if (d != d)
ret.u64 = janet_nanbox_tag(JANET_REAL); ret.u64 = janet_nanbox_tag(JANET_NUMBER);
return ret; return ret;
} }
@ -80,9 +80,9 @@ void janet_nanbox_memempty(JanetKV *mem, int32_t count) {
#elif defined(JANET_NANBOX_32) #elif defined(JANET_NANBOX_32)
Janet janet_wrap_real(double x) { Janet janet_wrap_number(double x) {
Janet ret; Janet ret;
ret.real = x; ret.number = x;
ret.tagged.type += JANET_DOUBLE_OFFSET; ret.tagged.type += JANET_DOUBLE_OFFSET;
return ret; return ret;
} }
@ -101,9 +101,9 @@ Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer) {
return ret; return ret;
} }
double janet_unwrap_real(Janet x) { double janet_unwrap_number(Janet x) {
x.tagged.type -= JANET_DOUBLE_OFFSET; x.tagged.type -= JANET_DOUBLE_OFFSET;
return x.real; return x.number;
} }
#else #else
@ -151,8 +151,7 @@ Janet janet_wrap_##NAME(TYPE x) {\
return y;\ return y;\
} }
JANET_WRAP_DEFINE(real, double, JANET_REAL, real) JANET_WRAP_DEFINE(number, double, JANET_NUMBER, number)
JANET_WRAP_DEFINE(integer, int32_t, JANET_INTEGER, integer)
JANET_WRAP_DEFINE(string, const uint8_t *, JANET_STRING, cpointer) JANET_WRAP_DEFINE(string, const uint8_t *, JANET_STRING, cpointer)
JANET_WRAP_DEFINE(symbol, const uint8_t *, JANET_SYMBOL, cpointer) JANET_WRAP_DEFINE(symbol, const uint8_t *, JANET_SYMBOL, cpointer)
JANET_WRAP_DEFINE(array, JanetArray *, JANET_ARRAY, pointer) JANET_WRAP_DEFINE(array, JanetArray *, JANET_ARRAY, pointer)

View File

@ -203,7 +203,7 @@ extern "C" {
#include <stdarg.h> #include <stdarg.h>
/* Names of all of the types */ /* Names of all of the types */
extern const char *const janet_type_names[16]; extern const char *const janet_type_names[15];
extern const char *const janet_signal_names[14]; extern const char *const janet_signal_names[14];
extern const char *const janet_status_names[16]; extern const char *const janet_status_names[16];
@ -278,8 +278,7 @@ typedef enum JanetType {
JANET_FALSE, JANET_FALSE,
JANET_TRUE, JANET_TRUE,
JANET_FIBER, JANET_FIBER,
JANET_INTEGER, JANET_NUMBER,
JANET_REAL,
JANET_STRING, JANET_STRING,
JANET_SYMBOL, JANET_SYMBOL,
JANET_ARRAY, JANET_ARRAY,
@ -299,8 +298,7 @@ typedef enum JanetType {
#define JANET_TFLAG_FALSE (1 << JANET_FALSE) #define JANET_TFLAG_FALSE (1 << JANET_FALSE)
#define JANET_TFLAG_TRUE (1 << JANET_TRUE) #define JANET_TFLAG_TRUE (1 << JANET_TRUE)
#define JANET_TFLAG_FIBER (1 << JANET_FIBER) #define JANET_TFLAG_FIBER (1 << JANET_FIBER)
#define JANET_TFLAG_INTEGER (1 << JANET_INTEGER) #define JANET_TFLAG_NUMBER (1 << JANET_NUMBER)
#define JANET_TFLAG_REAL (1 << JANET_REAL)
#define JANET_TFLAG_STRING (1 << JANET_STRING) #define JANET_TFLAG_STRING (1 << JANET_STRING)
#define JANET_TFLAG_SYMBOL (1 << JANET_SYMBOL) #define JANET_TFLAG_SYMBOL (1 << JANET_SYMBOL)
#define JANET_TFLAG_ARRAY (1 << JANET_ARRAY) #define JANET_TFLAG_ARRAY (1 << JANET_ARRAY)
@ -314,7 +312,6 @@ typedef enum JanetType {
/* Some abstractions */ /* Some abstractions */
#define JANET_TFLAG_BOOLEAN (JANET_TFLAG_TRUE | JANET_TFLAG_FALSE) #define JANET_TFLAG_BOOLEAN (JANET_TFLAG_TRUE | JANET_TFLAG_FALSE)
#define JANET_TFLAG_NUMBER (JANET_TFLAG_REAL | JANET_TFLAG_INTEGER)
#define JANET_TFLAG_CALLABLE (JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION) #define JANET_TFLAG_CALLABLE (JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION)
#define JANET_TFLAG_BYTES (JANET_TFLAG_STRING | JANET_TFLAG_SYMBOL | JANET_TFLAG_BUFFER) #define JANET_TFLAG_BYTES (JANET_TFLAG_STRING | JANET_TFLAG_SYMBOL | JANET_TFLAG_BUFFER)
#define JANET_TFLAG_INDEXED (JANET_TFLAG_ARRAY | JANET_TFLAG_TUPLE) #define JANET_TFLAG_INDEXED (JANET_TFLAG_ARRAY | JANET_TFLAG_TUPLE)
@ -349,7 +346,7 @@ typedef enum JanetType {
union Janet { union Janet {
uint64_t u64; uint64_t u64;
int64_t i64; int64_t i64;
double real; double number;
void *pointer; void *pointer;
}; };
#define janet_u64(x) ((x).u64) #define janet_u64(x) ((x).u64)
@ -359,19 +356,19 @@ union Janet {
#define janet_nanbox_lowtag(type) ((uint64_t)(type) | 0x1FFF0) #define janet_nanbox_lowtag(type) ((uint64_t)(type) | 0x1FFF0)
#define janet_nanbox_tag(type) (janet_nanbox_lowtag(type) << 47) #define janet_nanbox_tag(type) (janet_nanbox_lowtag(type) << 47)
#define janet_type(x) \ #define janet_type(x) \
(isnan((x).real) \ (isnan((x).number) \
? (((x).u64 >> 47) & 0xF) \ ? (((x).u64 >> 47) & 0xF) \
: JANET_REAL) : JANET_NUMBER)
#define janet_nanbox_checkauxtype(x, type) \ #define janet_nanbox_checkauxtype(x, type) \
(((x).u64 & JANET_NANBOX_TAGBITS) == janet_nanbox_tag((type))) (((x).u64 & JANET_NANBOX_TAGBITS) == janet_nanbox_tag((type)))
#define janet_nanbox_isreal(x) \ #define janet_nanbox_isnumber(x) \
(!isnan((x).real) || janet_nanbox_checkauxtype((x), JANET_REAL)) (!isnan((x).number) || janet_nanbox_checkauxtype((x), JANET_NUMBER))
#define janet_checktype(x, t) \ #define janet_checktype(x, t) \
(((t) == JANET_REAL) \ (((t) == JANET_NUMBER) \
? janet_nanbox_isreal(x) \ ? janet_nanbox_isnumber(x) \
: janet_nanbox_checkauxtype((x), (t))) : janet_nanbox_checkauxtype((x), (t)))
JANET_API void *janet_nanbox_to_pointer(Janet x); JANET_API void *janet_nanbox_to_pointer(Janet x);
@ -403,15 +400,12 @@ JANET_API Janet janet_nanbox_from_bits(uint64_t bits);
#define janet_wrap_true() janet_nanbox_from_payload(JANET_TRUE, 1) #define janet_wrap_true() janet_nanbox_from_payload(JANET_TRUE, 1)
#define janet_wrap_false() janet_nanbox_from_payload(JANET_FALSE, 1) #define janet_wrap_false() janet_nanbox_from_payload(JANET_FALSE, 1)
#define janet_wrap_boolean(b) janet_nanbox_from_payload((b) ? JANET_TRUE : JANET_FALSE, 1) #define janet_wrap_boolean(b) janet_nanbox_from_payload((b) ? JANET_TRUE : JANET_FALSE, 1)
#define janet_wrap_integer(i) janet_nanbox_from_payload(JANET_INTEGER, (uint32_t)(i)) #define janet_wrap_number(r) janet_nanbox_from_double(r)
#define janet_wrap_real(r) janet_nanbox_from_double(r)
/* Unwrap the simple types */ /* Unwrap the simple types */
#define janet_unwrap_boolean(x) \ #define janet_unwrap_boolean(x) \
(janet_checktype(x, JANET_TRUE)) (janet_checktype(x, JANET_TRUE))
#define janet_unwrap_integer(x) \ #define janet_unwrap_number(x) ((x).number)
((int32_t)((x).u64 & 0xFFFFFFFFlu))
#define janet_unwrap_real(x) ((x).real)
/* Wrap the pointer types */ /* Wrap the pointer types */
#define janet_wrap_struct(s) janet_nanbox_wrap_c((s), JANET_STRUCT) #define janet_wrap_struct(s) janet_nanbox_wrap_c((s), JANET_STRUCT)
@ -459,20 +453,20 @@ union Janet {
uint32_t type; uint32_t type;
#endif #endif
} tagged; } tagged;
double real; double number;
uint64_t u64; uint64_t u64;
}; };
#define JANET_DOUBLE_OFFSET 0xFFFF #define JANET_DOUBLE_OFFSET 0xFFFF
#define janet_u64(x) ((x).u64) #define janet_u64(x) ((x).u64)
#define janet_type(x) (((x).tagged.type < JANET_DOUBLE_OFFSET) ? (x).tagged.type : JANET_REAL) #define janet_type(x) (((x).tagged.type < JANET_DOUBLE_OFFSET) ? (x).tagged.type : JANET_NUMBER)
#define janet_checktype(x, t) ((x).tagged.type == (t)) #define janet_checktype(x, t) ((x).tagged.type == (t))
#define janet_memempty(mem, count) memset((mem), 0, sizeof(JanetKV) * (count)) #define janet_memempty(mem, count) memset((mem), 0, sizeof(JanetKV) * (count))
#define janet_memalloc_empty(count) calloc((count), sizeof(JanetKV)) #define janet_memalloc_empty(count) calloc((count), sizeof(JanetKV))
#define janet_truthy(x) ((x).tagged.type != JANET_NIL && (x).tagged.type != JANET_FALSE) #define janet_truthy(x) ((x).tagged.type != JANET_NIL && (x).tagged.type != JANET_FALSE)
JANET_API Janet janet_wrap_real(double x); JANET_API Janet janet_wrap_number(double x);
JANET_API Janet janet_nanbox32_from_tagi(uint32_t tag, int32_t integer); JANET_API Janet janet_nanbox32_from_tagi(uint32_t tag, int32_t integer);
JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer); JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer);
@ -480,7 +474,6 @@ JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer);
#define janet_wrap_true() janet_nanbox32_from_tagi(JANET_TRUE, 0) #define janet_wrap_true() janet_nanbox32_from_tagi(JANET_TRUE, 0)
#define janet_wrap_false() janet_nanbox32_from_tagi(JANET_FALSE, 0) #define janet_wrap_false() janet_nanbox32_from_tagi(JANET_FALSE, 0)
#define janet_wrap_boolean(b) janet_nanbox32_from_tagi((b) ? JANET_TRUE : JANET_FALSE, 0) #define janet_wrap_boolean(b) janet_nanbox32_from_tagi((b) ? JANET_TRUE : JANET_FALSE, 0)
#define janet_wrap_integer(i) janet_nanbox32_from_tagi(JANET_INTEGER, (i))
/* Wrap the pointer types */ /* Wrap the pointer types */
#define janet_wrap_struct(s) janet_nanbox32_from_tagp(JANET_STRUCT, (void *)(s)) #define janet_wrap_struct(s) janet_nanbox32_from_tagp(JANET_STRUCT, (void *)(s))
@ -508,8 +501,7 @@ JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer);
#define janet_unwrap_function(x) ((JanetFunction *)(x).tagged.payload.pointer) #define janet_unwrap_function(x) ((JanetFunction *)(x).tagged.payload.pointer)
#define janet_unwrap_cfunction(x) ((JanetCFunction)(x).tagged.payload.pointer) #define janet_unwrap_cfunction(x) ((JanetCFunction)(x).tagged.payload.pointer)
#define janet_unwrap_boolean(x) ((x).tagged.type == JANET_TRUE) #define janet_unwrap_boolean(x) ((x).tagged.type == JANET_TRUE)
#define janet_unwrap_integer(x) ((x).tagged.payload.integer) JANET_API double janet_unwrap_number(Janet x);
JANET_API double janet_unwrap_real(Janet x);
#else #else
@ -517,7 +509,7 @@ JANET_API double janet_unwrap_real(Janet x);
struct Janet { struct Janet {
union { union {
uint64_t u64; uint64_t u64;
double real; double number;
int32_t integer; int32_t integer;
void *pointer; void *pointer;
const void *cpointer; const void *cpointer;
@ -546,12 +538,10 @@ struct Janet {
#define janet_unwrap_function(x) ((JanetFunction *)(x).as.pointer) #define janet_unwrap_function(x) ((JanetFunction *)(x).as.pointer)
#define janet_unwrap_cfunction(x) ((JanetCFunction)(x).as.pointer) #define janet_unwrap_cfunction(x) ((JanetCFunction)(x).as.pointer)
#define janet_unwrap_boolean(x) ((x).type == JANET_TRUE) #define janet_unwrap_boolean(x) ((x).type == JANET_TRUE)
#define janet_unwrap_integer(x) ((x).as.integer) #define janet_unwrap_number(x) ((x).as.number)
#define janet_unwrap_real(x) ((x).as.real)
JANET_API Janet janet_wrap_nil(void); JANET_API Janet janet_wrap_nil(void);
JANET_API Janet janet_wrap_real(double x); JANET_API Janet janet_wrap_number(double x);
JANET_API Janet janet_wrap_integer(int32_t x);
JANET_API Janet janet_wrap_true(void); JANET_API Janet janet_wrap_true(void);
JANET_API Janet janet_wrap_false(void); JANET_API Janet janet_wrap_false(void);
JANET_API Janet janet_wrap_boolean(int x); JANET_API Janet janet_wrap_boolean(int x);
@ -570,6 +560,13 @@ JANET_API Janet janet_wrap_abstract(void *x);
/* End of tagged union implementation */ /* End of tagged union implementation */
#endif #endif
JANET_API int janet_checkint(Janet x);
JANET_API int janet_checkint64(Janet x);
#define janet_checkintrange(x) ((x) == (int32_t)(x) && (x) >= INT32_MIN && (x) <= INT32_MAX)
#define janet_checkint64range(x) ((x) == (int64_t)(x))
#define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x))
#define janet_wrap_integer(x) janet_wrap_number((int32_t)(x))
/* Hold components of arguments passed to JanetCFunction. */ /* Hold components of arguments passed to JanetCFunction. */
struct JanetArgs { struct JanetArgs {
Janet *v; Janet *v;
@ -797,20 +794,12 @@ enum JanetOpCode {
JOP_TYPECHECK, JOP_TYPECHECK,
JOP_RETURN, JOP_RETURN,
JOP_RETURN_NIL, JOP_RETURN_NIL,
JOP_ADD_INTEGER,
JOP_ADD_IMMEDIATE, JOP_ADD_IMMEDIATE,
JOP_ADD_REAL,
JOP_ADD, JOP_ADD,
JOP_SUBTRACT_INTEGER,
JOP_SUBTRACT_REAL,
JOP_SUBTRACT, JOP_SUBTRACT,
JOP_MULTIPLY_INTEGER,
JOP_MULTIPLY_IMMEDIATE, JOP_MULTIPLY_IMMEDIATE,
JOP_MULTIPLY_REAL,
JOP_MULTIPLY, JOP_MULTIPLY,
JOP_DIVIDE_INTEGER,
JOP_DIVIDE_IMMEDIATE, JOP_DIVIDE_IMMEDIATE,
JOP_DIVIDE_REAL,
JOP_DIVIDE, JOP_DIVIDE,
JOP_BAND, JOP_BAND,
JOP_BOR, JOP_BOR,
@ -828,19 +817,11 @@ enum JanetOpCode {
JOP_JUMP_IF, JOP_JUMP_IF,
JOP_JUMP_IF_NOT, JOP_JUMP_IF_NOT,
JOP_GREATER_THAN, JOP_GREATER_THAN,
JOP_GREATER_THAN_INTEGER,
JOP_GREATER_THAN_IMMEDIATE, JOP_GREATER_THAN_IMMEDIATE,
JOP_GREATER_THAN_REAL,
JOP_GREATER_THAN_EQUAL_REAL,
JOP_LESS_THAN, JOP_LESS_THAN,
JOP_LESS_THAN_INTEGER,
JOP_LESS_THAN_IMMEDIATE, JOP_LESS_THAN_IMMEDIATE,
JOP_LESS_THAN_REAL,
JOP_LESS_THAN_EQUAL_REAL,
JOP_EQUALS, JOP_EQUALS,
JOP_EQUALS_INTEGER,
JOP_EQUALS_IMMEDIATE, JOP_EQUALS_IMMEDIATE,
JOP_EQUALS_REAL,
JOP_COMPARE, JOP_COMPARE,
JOP_LOAD_NIL, JOP_LOAD_NIL,
JOP_LOAD_TRUE, JOP_LOAD_TRUE,
@ -934,9 +915,8 @@ JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len,
JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out); JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);
/* Number scanning */ /* Number scanning */
JANET_API Janet janet_scan_number(const uint8_t *src, int32_t len);
JANET_API int32_t janet_scan_integer(const uint8_t *str, int32_t len, int *err); JANET_API int32_t janet_scan_integer(const uint8_t *str, int32_t len, int *err);
JANET_API double janet_scan_real(const uint8_t *str, int32_t len, int *err); JANET_API double janet_scan_number(const uint8_t *str, int32_t len, int *err);
/* Debugging */ /* Debugging */
JANET_API int janet_debug_break(JanetFuncDef *def, int32_t pc); JANET_API int janet_debug_break(JanetFuncDef *def, int32_t pc);
@ -1102,6 +1082,11 @@ JANET_API int32_t janet_hash(Janet x);
JANET_API int janet_compare(Janet x, Janet y); JANET_API int janet_compare(Janet x, Janet y);
JANET_API int janet_cstrcmp(const uint8_t *str, const char *other); JANET_API int janet_cstrcmp(const uint8_t *str, const char *other);
JANET_API JanetBuffer *janet_pretty(JanetBuffer *buffer, int depth, Janet x); JANET_API JanetBuffer *janet_pretty(JanetBuffer *buffer, int depth, Janet x);
JANET_API int janet_get(Janet ds, Janet key, Janet *out);
JANET_API int janet_getindex(Janet ds, int32_t index, Janet *out);
JANET_API int janet_length(Janet x, int32_t *out);
JANET_API int janet_put(Janet ds, Janet key, Janet value);
JANET_API int janet_putindex(Janet ds, int32_t index, Janet value);
/* VM functions */ /* VM functions */
JANET_API int janet_init(void); JANET_API int janet_init(void);
@ -1176,19 +1161,6 @@ JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstr
}\ }\
} while (0) } while (0)
#define JANET_ARG_NUMBER(DEST, A, N) do { \
if ((A).n <= (N)) return janet_typemany_err(A, N, JANET_TFLAG_NUMBER); \
Janet _val_ = (A).v[(N)];\
JanetType _type_ = janet_type(_val_); \
if (_type_ == JANET_REAL) { \
DEST = janet_unwrap_real(_val_); \
} else if (_type_ == JANET_INTEGER) {\
DEST = (double) janet_unwrap_integer(_val_);\
} else { \
return janet_typemany_err(A, N, JANET_TFLAG_NUMBER); \
} \
} while (0)
#define JANET_ARG_BOOLEAN(DEST, A, N) do { \ #define JANET_ARG_BOOLEAN(DEST, A, N) do { \
JANET_CHECKMANY(A, N, JANET_TFLAG_TRUE | JANET_TFLAG_FALSE);\ JANET_CHECKMANY(A, N, JANET_TFLAG_TRUE | JANET_TFLAG_FALSE);\
DEST = janet_unwrap_boolean((A).v[(N)]); \ DEST = janet_unwrap_boolean((A).v[(N)]); \
@ -1214,8 +1186,7 @@ JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstr
} while (0) } while (0)
#define JANET_ARG_FIBER(DEST, A, N) _JANET_ARG(JANET_FIBER, fiber, DEST, A, N) #define JANET_ARG_FIBER(DEST, A, N) _JANET_ARG(JANET_FIBER, fiber, DEST, A, N)
#define JANET_ARG_INTEGER(DEST, A, N) _JANET_ARG(JANET_INTEGER, integer, DEST, A, N) #define JANET_ARG_NUMBER(DEST, A, N) _JANET_ARG(JANET_NUMBER, number, DEST, A, N)
#define JANET_ARG_REAL(DEST, A, N) _JANET_ARG(JANET_REAL, real, DEST, A, N)
#define JANET_ARG_STRING(DEST, A, N) _JANET_ARG(JANET_STRING, string, DEST, A, N) #define JANET_ARG_STRING(DEST, A, N) _JANET_ARG(JANET_STRING, string, DEST, A, N)
#define JANET_ARG_SYMBOL(DEST, A, N) _JANET_ARG(JANET_SYMBOL, symbol, DEST, A, N) #define JANET_ARG_SYMBOL(DEST, A, N) _JANET_ARG(JANET_SYMBOL, symbol, DEST, A, N)
#define JANET_ARG_ARRAY(DEST, A, N) _JANET_ARG(JANET_ARRAY, array, DEST, A, N) #define JANET_ARG_ARRAY(DEST, A, N) _JANET_ARG(JANET_ARRAY, array, DEST, A, N)
@ -1226,6 +1197,30 @@ JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstr
#define JANET_ARG_FUNCTION(DEST, A, N) _JANET_ARG(JANET_FUNCTION, function, DEST, A, N) #define JANET_ARG_FUNCTION(DEST, A, N) _JANET_ARG(JANET_FUNCTION, function, DEST, A, N)
#define JANET_ARG_CFUNCTION(DEST, A, N) _JANET_ARG(JANET_CFUNCTION, cfunction, DEST, A, N) #define JANET_ARG_CFUNCTION(DEST, A, N) _JANET_ARG(JANET_CFUNCTION, cfunction, DEST, A, N)
#define JANET_ARG_INTEGER(DEST, A, N) do { \
if ((A).n <= (N) || !janet_checktype((A).v[(N)], JANET_NUMBER)) { \
JANET_THROW(A, "expected integer"); \
} \
double _x_ = janet_unwrap_number((A).v[(N)]); \
if (janet_checkintrange(_x_)) { \
DEST = (int32_t) _x_; \
} else { \
JANET_THROW(A, "expected integer representable by 32 bits"); \
} \
} while (0)
#define JANET_ARG_INTEGER64(DEST, A, N) do { \
if ((A).n <= (N) || !janet_checktype((A).v[(N)], JANET_NUMBER)) { \
JANET_THROW(A, "expected integer"); \
} \
double _x_ = janet_unwrap_number((A).v[(N)]); \
if (janet_checkintrange64(_x_)) { \
DEST = (int64_t) _x_; \
} else { \
JANET_THROW(A, "expected integer representable by 64 bits"); \
} \
} while (0)
#define JANET_ARG_ABSTRACT(DEST, A, N, AT) do { \ #define JANET_ARG_ABSTRACT(DEST, A, N, AT) do { \
JANET_CHECKABSTRACT(A, N, AT); \ JANET_CHECKABSTRACT(A, N, AT); \
DEST = janet_unwrap_abstract((A).v[(N)]); \ DEST = janet_unwrap_abstract((A).v[(N)]); \
@ -1236,8 +1231,7 @@ JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstr
#define JANET_RETURN_TRUE(A) JANET_RETURN(A, janet_wrap_true()) #define JANET_RETURN_TRUE(A) JANET_RETURN(A, janet_wrap_true())
#define JANET_RETURN_BOOLEAN(A, X) JANET_RETURN(A, janet_wrap_boolean(X)) #define JANET_RETURN_BOOLEAN(A, X) JANET_RETURN(A, janet_wrap_boolean(X))
#define JANET_RETURN_FIBER(A, X) JANET_RETURN(A, janet_wrap_fiber(X)) #define JANET_RETURN_FIBER(A, X) JANET_RETURN(A, janet_wrap_fiber(X))
#define JANET_RETURN_INTEGER(A, X) JANET_RETURN(A, janet_wrap_integer(X)) #define JANET_RETURN_NUMBER(A, X) JANET_RETURN(A, janet_wrap_number(X))
#define JANET_RETURN_REAL(A, X) JANET_RETURN(A, janet_wrap_real(X))
#define JANET_RETURN_STRING(A, X) JANET_RETURN(A, janet_wrap_string(X)) #define JANET_RETURN_STRING(A, X) JANET_RETURN(A, janet_wrap_string(X))
#define JANET_RETURN_SYMBOL(A, X) JANET_RETURN(A, janet_wrap_symbol(X)) #define JANET_RETURN_SYMBOL(A, X) JANET_RETURN(A, janet_wrap_symbol(X))
#define JANET_RETURN_ARRAY(A, X) JANET_RETURN(A, janet_wrap_array(X)) #define JANET_RETURN_ARRAY(A, X) JANET_RETURN(A, janet_wrap_array(X))
@ -1252,6 +1246,8 @@ JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstr
#define JANET_RETURN_CSTRING(A, X) JANET_RETURN(A, janet_cstringv(X)) #define JANET_RETURN_CSTRING(A, X) JANET_RETURN(A, janet_cstringv(X))
#define JANET_RETURN_CSYMBOL(A, X) JANET_RETURN(A, janet_csymbolv(X)) #define JANET_RETURN_CSYMBOL(A, X) JANET_RETURN(A, janet_csymbolv(X))
#define JANET_RETURN_INTEGER(A, X) JANET_RETURN(A, janet_wrap_number((double) (X)))
/**** END SECTION MACROS *****/ /**** END SECTION MACROS *****/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -39,7 +39,7 @@
(assert (order< nil false true (assert (order< nil false true
(fiber/new (fn [] 1)) (fiber/new (fn [] 1))
1 1.0 "hi" 1.0 "hi"
(quote hello) (quote hello)
(array 1 2 3) (array 1 2 3)
(tuple 1 2 3) (tuple 1 2 3)

View File

@ -21,8 +21,7 @@
(import test/helper :prefix "" :exit true) (import test/helper :prefix "" :exit true)
(start-suite 1) (start-suite 1)
(assert (= 400.0 (math/sqrt 160000)) "sqrt(160000)=400") (assert (= 400 (math/sqrt 160000)) "sqrt(160000)=400")
(assert (= (real 400) (math/sqrt 160000)) "sqrt(160000)=400")
(def test-struct {'def 1 'bork 2 'sam 3 'a 'b 'het @[1 2 3 4 5]}) (def test-struct {'def 1 'bork 2 'sam 3 'a 'b 'het @[1 2 3 4 5]})
(assert (= (get test-struct 'def) 1) "struct get") (assert (= (get test-struct 'def) 1) "struct get")
@ -188,7 +187,7 @@
(assert (= 14 (sum (map inc @[1 2 3 4]))) "sum map") (assert (= 14 (sum (map inc @[1 2 3 4]))) "sum map")
(def myfun (juxt + - * /)) (def myfun (juxt + - * /))
(assert (= '[2 -2 2 0] (myfun 2)) "juxt") (assert (= '[2 -2 2 0.5] (myfun 2)) "juxt")
# Case statements # Case statements
(assert (assert