1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-25 07:50:27 +00:00

Move strtod to core, and rename parse-number, parse-integer, and

parse-real functions to scan-number, scan-integer, and scan-real.
Add very basic format function for formatting strings for printing.
This commit is contained in:
Calvin Rose 2018-05-01 11:06:31 -04:00
parent e4434f74b6
commit 1e4f221170
10 changed files with 114 additions and 64 deletions

View File

@ -57,6 +57,7 @@ src/core/math.c
src/core/native.c
src/core/os.c
src/core/string.c
src/core/strtod.c
src/core/struct.c
src/core/symcache.c
src/core/table.c
@ -83,7 +84,6 @@ src/mainclient/line.h
set(PARSER_SOURCES
src/parser/ast.c
src/parser/parse.c
src/parser/strtod.c
)
set(TESTLIB_SOURCES

View File

@ -37,8 +37,12 @@ static const DstReg cfuns[] = {
{"string", dst_core_string},
{"symbol", dst_core_symbol},
{"buffer", dst_core_buffer},
{"format", dst_core_format},
{"table", dst_core_table},
{"array", dst_core_array},
{"scan-number", dst_core_scannumber},
{"scan-integer", dst_core_scaninteger},
{"scan-real", dst_core_scanreal},
{"tuple", dst_core_tuple},
{"struct", dst_core_struct},
{"buffer", dst_core_buffer},

View File

@ -218,15 +218,20 @@ static int cfun_concat(DstArgs args) {
return dst_return(args, args.v[0]);
}
static const DstReg cfuns[] = {
{"array-pop", cfun_pop},
{"array-peek", cfun_peek},
{"array-push", cfun_push},
{"array-setcount", cfun_setcount},
{"array-ensure", cfun_ensure},
{"array-slice", cfun_slice},
{"array-concat", cfun_concat},
{NULL, NULL}
};
/* Load the array module */
int dst_lib_array(DstArgs args) {
DstTable *env = dst_env_arg(args);
dst_env_def(env, "array-pop", dst_wrap_cfunction(cfun_pop));
dst_env_def(env, "array-peek", dst_wrap_cfunction(cfun_peek));
dst_env_def(env, "array-push", dst_wrap_cfunction(cfun_push));
dst_env_def(env, "array-setcount", dst_wrap_cfunction(cfun_setcount));
dst_env_def(env, "array-ensure", dst_wrap_cfunction(cfun_ensure));
dst_env_def(env, "array-slice", dst_wrap_cfunction(cfun_slice));
dst_env_def(env, "array-concat", dst_wrap_cfunction(cfun_concat));
dst_env_cfuns(env, cfuns);
return 0;
}

View File

@ -95,6 +95,82 @@ int dst_core_buffer(DstArgs args) {
return dst_return(args, dst_wrap_buffer(b));
}
int dst_core_format(DstArgs args) {
const uint8_t *format;
int32_t i, len, n;
DstBuffer buf;
dst_minarity(args, 1);
dst_arg_bytes(format, len, args, 0);
n = 1;
dst_buffer_init(&buf, len);
for (i = 0; i < len; i++) {
uint8_t c = format[i];
if (c != '%') {
dst_buffer_push_u8(&buf, c);
} else {
if (++i == len) break;
c = format[i];
switch (c) {
default:
dst_buffer_push_u8(&buf, c);
break;
case 's':
{
if (n >= args.n) goto noarg;
dst_buffer_push_string(&buf, dst_to_string(args.v[n++]));
break;
}
}
}
}
*args.ret = dst_wrap_string(dst_string(buf.data, buf.count));
dst_buffer_deinit(&buf);
return 0;
noarg:
dst_buffer_deinit(&buf);
return dst_throw(args, "not enough arguments to format");
}
int dst_core_scannumber(DstArgs args) {
const uint8_t *data;
Dst x;
int32_t len;
dst_fixarity(args, 1);
dst_arg_bytes(data, len, args, 0);
x = dst_scan_number(data, len);
if (!dst_checktype(x, DST_INTEGER) && !dst_checktype(x, DST_REAL)) {
return dst_throw(args, "error parsing number");
}
return dst_return(args, x);
}
int dst_core_scaninteger(DstArgs args) {
const uint8_t *data;
int32_t len, ret;
int err = 0;
dst_fixarity(args, 1);
dst_arg_bytes(data, len, args, 0);
ret = dst_scan_integer(data, len, &err);
if (err) {
return dst_throw(args, "error parsing integer");
}
return dst_return(args, dst_wrap_integer(ret));
}
int dst_core_scanreal(DstArgs args) {
const uint8_t *data;
int32_t len;
double ret;
int err = 0;
dst_fixarity(args, 1);
dst_arg_bytes(data, len, args, 0);
ret = dst_scan_real(data, len, &err);
if (err) {
return dst_throw(args, "error parsing real");
}
return dst_return(args, dst_wrap_real(ret));
}
int dst_core_tuple(DstArgs args) {
return dst_return(args, dst_wrap_tuple(dst_tuple_n(args.v, args.n)));
}
@ -137,7 +213,7 @@ int dst_core_gensym(DstArgs args) {
}
int dst_core_length(DstArgs args) {
dst_checkmany(args, 0, DST_TFLAG_LENGTHABLE);
dst_fixarity(args, 1);
return dst_return(args, dst_wrap_integer(dst_length(args.v[0])));
}

View File

@ -211,7 +211,7 @@ static struct DstScanRes dst_scan_impl(
/* underscores are ignored - can be used for separator */
} else {
int digit = digit_lookup[*str & 0x7F];
if (digit >= res.base) goto error;
if (*str > 127 || digit >= res.base) goto error;
if (res.seenpoint) res.ex--;
if (res.mant > 0x00ffffffffffffff)
res.ex++;
@ -242,7 +242,7 @@ static struct DstScanRes dst_scan_impl(
while (str < end && *str == '0') str++;
while (str < end && ee < (INT32_MAX / 40)) {
int digit = digit_lookup[*str & 0x7F];
if (digit >= res.base) goto error;
if (*str > 127 || digit >= res.base) goto error;
ee = res.base * ee + digit;
str++;
seenadigit = 1;

View File

@ -36,6 +36,11 @@ extern "C" {
#include "dsttypes.h"
/* Number scanning */
Dst dst_scan_number(const uint8_t *src, int32_t len);
int32_t dst_scan_integer(const uint8_t *str, int32_t len, int *err);
double dst_scan_real(const uint8_t *str, int32_t len, int *err);
/* Array functions */
DstArray *dst_array(int32_t capacity);
DstArray *dst_array_init(DstArray *array, int32_t capacity);
@ -250,6 +255,13 @@ int dst_typeabstract_err(DstArgs args, int32_t n, DstAbstractType *at);
dst_check(A, N, TYPE);\
DEST = dst_unwrap_##NAME((A).v[(N)]); } while (0)
#define dst_arg_bytes(DESTBYTES, DESTLEN, A, N) do {\
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_BYTES);\
if (dst_chararray_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\
dst_typemany_err(A, N, DST_TFLAG_BYTES);\
}\
} while (0)
#define dst_arg_fiber(DEST, A, N) _dst_arg(DST_FIBER, fiber, DEST, A, N)
#define dst_arg_integer(DEST, A, N) _dst_arg(DST_INTEGER, integer, DEST, A, N)
#define dst_arg_real(DEST, A, N) _dst_arg(DST_REAL, real, DEST, A, N)

View File

@ -84,6 +84,10 @@ int dst_core_describe(DstArgs args);
int dst_core_string(DstArgs args);
int dst_core_symbol(DstArgs args);
int dst_core_buffer(DstArgs args);
int dst_core_format(DstArgs args);
int dst_core_scannumber(DstArgs args);
int dst_core_scaninteger(DstArgs args);
int dst_core_scanreal(DstArgs args);
int dst_core_tuple(DstArgs args);
int dst_core_array(DstArgs args);
int dst_core_table(DstArgs args);

View File

@ -38,11 +38,6 @@ Dst dst_ast_unwrap(Dst x);
typedef struct DstParseState DstParseState;
typedef struct DstParser DstParser;
/* Number scanning */
Dst dst_scan_number(const uint8_t *src, int32_t len);
int32_t dst_scan_integer(const uint8_t *str, int32_t len, int *err);
double dst_scan_real(const uint8_t *str, int32_t len, int *err);
enum DstParserStatus {
DST_PARSE_ROOT,
DST_PARSE_ERROR,

View File

@ -102,7 +102,7 @@ typedef enum DstType {
#define DST_TFLAG_BOOLEAN (DST_TFLAG_TRUE | DST_TFLAG_FALSE)
#define DST_TFLAG_NUMBER (DST_TFLAG_REAL | DST_TFLAG_INTEGER)
#define DST_TFLAG_CALLABLE (DST_TFLAG_FUNCTION | DST_TFLAG_CFUNCTION)
#define DST_TFLAG_CHARS (DST_TFLAG_STRING | DST_TFLAG_SYMBOL | DST_TFLAG_BUFFER)
#define DST_TFLAG_BYTES (DST_TFLAG_STRING | DST_TFLAG_SYMBOL | DST_TFLAG_BUFFER)
#define DST_TFLAG_INDEXED (DST_TFLAG_ARRAY | DST_TFLAG_TUPLE)
#define DST_TFLAG_DICTIONARY (DST_TFLAG_TABLE | DST_TFLAG_STRUCT)
#define DST_TFLAG_LENGTHABLE (DST_TFLAG_CHARS | DST_TFLAG_INDEXED | DST_TFLAG_DICTIONARY)

View File

@ -86,7 +86,7 @@ The table contains 256 bits, where each bit is 1
if the corresponding ascci code is a symbol char, and 0
if not. The upper characters are also considered symbol
chars and are then checked for utf-8 compliance. */
static uint32_t symchars[8] = {
static const uint32_t symchars[8] = {
0x00000000, 0xF7ffec72, 0xd7ffffff, 0x57fffffe,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
};
@ -703,49 +703,6 @@ static int cfun_node(DstArgs args) {
return dst_return(args, dst_wrap_tuple(dst_tuple_end(tup)));
}
static int cfun_parsenumber(DstArgs args) {
const uint8_t *data;
Dst x;
int32_t len;
if (args.n != 1) return dst_throw(args, "expected string or buffer");
if (!dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected string or buffer");
x = dst_scan_number(data, len);
if (!dst_checktype(x, DST_INTEGER) && !dst_checktype(x, DST_REAL)) {
return dst_throw(args, "error parsing number");
}
return dst_return(args, x);
}
static int cfun_parseint(DstArgs args) {
const uint8_t *data;
int32_t len, ret;
int err = 0;
if (args.n != 1) return dst_throw(args, "expected string or buffer");
if (!dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected string or buffer");
ret = dst_scan_integer(data, len, &err);
if (err) {
return dst_throw(args, "error parsing integer");
}
return dst_return(args, dst_wrap_integer(ret));
}
static int cfun_parsereal(DstArgs args) {
const uint8_t *data;
int32_t len;
double ret;
int err = 0;
if (args.n != 1) return dst_throw(args, "expected string or buffer");
if (!dst_chararray_view(args.v[0], &data, &len))
return dst_throw(args, "expected string or buffer");
ret = dst_scan_real(data, len, &err);
if (err) {
return dst_throw(args, "error parsing real");
}
return dst_return(args, dst_wrap_real(ret));
}
static const DstReg cfuns[] = {
{"parser", cfun_parser},
{"parser-produce", cfun_produce},
@ -757,9 +714,6 @@ static const DstReg cfuns[] = {
{"ast-unwrap1", cfun_unwrap1},
{"ast-wrap", cfun_wrap},
{"ast-node", cfun_node},
{"parse-number", cfun_parsenumber},
{"parse-int", cfun_parseint},
{"parse-real", cfun_parsereal},
{NULL, NULL}
};