From cccbdc164c532393d5af91c656d1a564b97eaa7c Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 19 Sep 2021 13:02:16 -0500 Subject: [PATCH] Add (number combinator to peg). This allows using Janet's number parser without creating intermediate strings. --- CHANGELOG.md | 4 ++++ Makefile | 2 +- meson.build | 2 +- src/conf/janetconf.h | 8 ++++---- src/core/peg.c | 23 +++++++++++++++++++++++ src/core/strtod.c | 2 +- src/include/janet.h | 3 ++- test/suite0008.janet | 4 ++++ 8 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e088f259..95e951c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. +## Unreleased - ??? +- Add `(number ...)` pattern to peg for more efficient number parsing using Janet's + scan-number function without immediate string creation. + ## 1.17.2 - 2021-09-18 - Remove include of windows.h from janet.h. This caused issues on certain projects. - Fix formatting in doc-format to better handle special characters in signatures. diff --git a/Makefile b/Makefile index 3b331383..dec653e4 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ build/c/janet.c: build/janet_boot src/boot/boot.janet ##### Amalgamation ##### ######################## -SONAME=libjanet.so.1.17 +SONAME=libjanet.so.1.18 build/c/shell.c: src/mainclient/shell.c cp $< $@ diff --git a/meson.build b/meson.build index b7780d4c..03b0d567 100644 --- a/meson.build +++ b/meson.build @@ -20,7 +20,7 @@ project('janet', 'c', default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'], - version : '1.17.2') + version : '1.18.0') # Global settings janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet') diff --git a/src/conf/janetconf.h b/src/conf/janetconf.h index 46e259cc..d78e3257 100644 --- a/src/conf/janetconf.h +++ b/src/conf/janetconf.h @@ -4,10 +4,10 @@ #define JANETCONF_H #define JANET_VERSION_MAJOR 1 -#define JANET_VERSION_MINOR 17 -#define JANET_VERSION_PATCH 2 -#define JANET_VERSION_EXTRA "" -#define JANET_VERSION "1.17.2" +#define JANET_VERSION_MINOR 18 +#define JANET_VERSION_PATCH 0 +#define JANET_VERSION_EXTRA "-dev" +#define JANET_VERSION "1.18.0-dev" /* #define JANET_BUILD "local" */ diff --git a/src/core/peg.c b/src/core/peg.c index 48a3dc70..61c6b4a3 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -387,6 +387,24 @@ tail: return result; } + case RULE_CAPTURE_NUM: { + down1(s); + const uint8_t *result = peg_rule(s, s->bytecode + rule[1], text); + up1(s); + if (!result) return NULL; + /* check number parsing */ + double x = 0.0; + if (janet_scan_number(text, (int32_t)(result - text), &x)) return NULL; + /* Specialized pushcap - avoid intermediate string creation */ + if (!s->has_backref && s->mode == PEG_MODE_ACCUMULATE) { + janet_buffer_push_bytes(s->scratch, text, (int32_t)(result - text)); + } else { + uint32_t tag = rule[2]; + pushcap(s, janet_wrap_number(x), tag); + } + return result; + } + case RULE_ACCUMULATE: { uint32_t tag = rule[2]; int oldmode = s->mode; @@ -965,6 +983,9 @@ static void spec_cap1(Builder *b, int32_t argc, const Janet *argv, uint32_t op) static void spec_capture(Builder *b, int32_t argc, const Janet *argv) { spec_cap1(b, argc, argv, RULE_CAPTURE); } +static void spec_capture_number(Builder *b, int32_t argc, const Janet *argv) { + spec_cap1(b, argc, argv, RULE_CAPTURE_NUM); +} static void spec_accumulate(Builder *b, int32_t argc, const Janet *argv) { spec_cap1(b, argc, argv, RULE_ACCUMULATE); } @@ -1118,6 +1139,7 @@ static const SpecialPair peg_specials[] = { {"line", spec_line}, {"look", spec_look}, {"not", spec_not}, + {"number", spec_capture_number}, {"opt", spec_opt}, {"position", spec_position}, {"quote", spec_capture}, @@ -1422,6 +1444,7 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) { case RULE_ACCUMULATE: case RULE_GROUP: case RULE_CAPTURE: + case RULE_CAPTURE_NUM: case RULE_UNREF: /* [rule, tag] */ if (rule[1] >= blen) goto bad; diff --git a/src/core/strtod.c b/src/core/strtod.c index 0b85c8d8..2acc1be8 100644 --- a/src/core/strtod.c +++ b/src/core/strtod.c @@ -246,7 +246,7 @@ static double convert( } /* 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, return 0. */ int janet_scan_number( const uint8_t *str, int32_t len, diff --git a/src/include/janet.h b/src/include/janet.h index 9c741b0f..a718efae 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -2040,7 +2040,8 @@ typedef enum { RULE_READINT, /* [(signedness << 4) | (endianess << 5) | bytewidth, tag] */ RULE_LINE, /* [tag] */ RULE_COLUMN, /* [tag] */ - RULE_UNREF /* [rule, tag] */ + RULE_UNREF, /* [rule, tag] */ + RULE_CAPTURE_NUM /* [rule, tag] */ } JanetPegOpcod; typedef struct { diff --git a/test/suite0008.janet b/test/suite0008.janet index 03570a16..3f91ace7 100644 --- a/test/suite0008.janet +++ b/test/suite0008.janet @@ -344,4 +344,8 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02 (assert (deep= @[] (peg/match '(* "test" (any 1)) @"test")) "peg empty pattern 5") (assert (deep= @[] (peg/match '(* "test" (any 1)) (buffer "test"))) "peg empty pattern 6") +# number pattern +(assert (deep= @[111] (peg/match '(number :d+) "111")) "simple number capture 1") +(assert (deep= @[255] (peg/match '(number :w+) "0xff")) "simple number capture 2") + (end-suite)