Skip to content

Commit

Permalink
Merge branch 'main' into debian
Browse files Browse the repository at this point in the history
  • Loading branch information
keith-packard committed Oct 10, 2021
2 parents 5ea9275 + b5307df commit 455f851
Show file tree
Hide file tree
Showing 26 changed files with 214 additions and 106 deletions.
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -87,6 +87,12 @@ described below.

Here's some places that have seen recent work

* Fix NaN comparisons and make dicts containing NaN keys work.
[Jake Edge's article, “Revisiting NaNs in Python”](https://lwn.net/Articles/869231/)
led to the discovery that Snek had several bugs in NaN
comparisons. Snek now computes the right value for comparisons with
Nan, as well as permitting NaN to be used as a key in dictionaries.

* Support explicit serial synchronization using ENQ/ACK so that
applications sending lots of data do not require OS flow control
support. With many devices connecting via USB/serial adapters that
Expand Down
1 change: 1 addition & 0 deletions build-snek
Expand Up @@ -2,6 +2,7 @@
export SNEKMAC=imac.keithp.com:build/snek
export SNEK_RISCV_TEST=1
export SNEK_ESP32=1
export SNEK_NANO_EVERY=1
export SNEK_OTHEROS=1
export ESP_IDF=$HOME/src/esp/esp-idf
wakeonlan 58:40:4e:ee:39:1a
Expand Down
2 changes: 1 addition & 1 deletion chips/atmega/snek-atmega.defs
Expand Up @@ -32,7 +32,7 @@ SNEK_ATMEGA_MATH_SRC = \
SNEK_ATMEGA_SRC = \
snek-atmega-eeprom.c \
snek-io.c \
snek-strtof.c \
snek-atof.c \
snek-atmega-serial.c \
snek-atmega-time.c

Expand Down
6 changes: 4 additions & 2 deletions chips/atmega/snek-atmega.h
Expand Up @@ -21,7 +21,8 @@
#include <avr/interrupt.h>

#define SNEK_DEBUG 0
#define strtof(a,b) strtod(a,b)
float atoff(const char *);
#define strtof(s, n) atoff(s)
#define PARSE_TABLE_DECLARATION(t) PROGMEM t
#define PARSE_TABLE_FETCH_TOKEN(a) ((token_key_t) pgm_read_byte(a))
#define PARSE_TABLE_FETCH_INDEX(a) ((uint8_t) pgm_read_byte(a))
Expand Down Expand Up @@ -51,7 +52,8 @@
static const char PROGMEM __fmt__[] = (fmt); \
sprintf_P(dst, __fmt__, ##args); \
})
#define strfromf(dst, len, fmt, val) sprintf_const(dst, fmt, val)
#define strfromf_const(dst, len, fmt, val) sprintf_const(dst, fmt, val)
#define strfromf(dst, len, fmt, val) sprintf(dst, fmt, val)

#define SNEK_BUILTIN_NAMES_DECLARE(n) PROGMEM n
#define SNEK_BUILTIN_NAMES(a) ((uint8_t) pgm_read_byte(&snek_builtin_names[a]))
Expand Down
2 changes: 1 addition & 1 deletion chips/avr/snek-avr.defs
Expand Up @@ -26,7 +26,7 @@ SNEK_AVR_SRC = \
ao-usb-avr.c \
ao-notask.c \
ao-product.c \
snek-strtof.c
snek-atof.c

SNEK_AVR_INC = \
ao.h \
Expand Down
6 changes: 4 additions & 2 deletions chips/avr/snek-avr.h
Expand Up @@ -29,7 +29,8 @@ sqrtf(float x) {
}

#define SNEK_DEBUG 0
#define strtof(a,b) strtod(a,b)
float atoff(const char *);
#define strtof(s, n) atoff(s)
#define SNEK_POOL 1024
#define SNEK_MAX_TOKEN 63
#define VALUE_STACK_SIZE 16
Expand Down Expand Up @@ -64,7 +65,8 @@ sqrtf(float x) {
static const char PROGMEM __fmt__[] = (fmt); \
sprintf_P(dst, __fmt__, ##args); \
})
#define strfromf(dst, len, fmt, val) sprintf_const(dst, fmt, val)
#define strfromf_const(dst, len, fmt, val) sprintf_const(dst, fmt, val)
#define strfromf(dst, len, fmt, val) sprintf(dst, fmt, val)

#define SNEK_BUILTIN_NAMES_DECLARE(n) PROGMEM n
#define SNEK_BUILTIN_NAMES(a) ((uint8_t) pgm_read_byte(&snek_builtin_names[a]))
Expand Down
13 changes: 13 additions & 0 deletions chips/samd21/ao-stdio.c
Expand Up @@ -22,4 +22,17 @@

static FILE __stdio = FDEV_SETUP_STREAM(ao_usb_putc, snek_io_getc, ao_usb_flush, _FDEV_SETUP_RW);

#ifdef PICOLIBC_STDIO_GLOBALS
#ifdef __strong_reference
#define STDIO_ALIAS(x) __strong_reference(stdin, x);
#else
#define STDIO_ALIAS(x) FILE *const x = &__stdio;
#endif

FILE *const stdin = &__stdio;
STDIO_ALIAS(stdout);
STDIO_ALIAS(stderr);

#else
FILE *const __iob[3] = { &__stdio, &__stdio, &__stdio };
#endif
6 changes: 3 additions & 3 deletions chips/samd21/snek-eeprom.c
Expand Up @@ -73,8 +73,8 @@ snek_eeprom_load(void)
{
snek_interactive = false;
ao_flash_read_init();
save_getc = __iob[0]->get;
__iob[0]->get = snek_eeprom_getchar;
save_getc = stdin->get;
stdin->get = snek_eeprom_getchar;
}

int
Expand All @@ -87,6 +87,6 @@ snek_eeprom_getchar(FILE *stream)
return c;
}
snek_interactive = true;
__iob[0]->get = save_getc;
stdin->get = save_getc;
return EOF;
}
1 change: 1 addition & 0 deletions ports/duemilanove/Makefile
Expand Up @@ -56,6 +56,7 @@ OPT=-Os -frename-registers -funsigned-char -fno-jump-tables -mcall-prologues
CFLAGS=$(OPT) -DF_CPU=16000000UL -mmcu=atmega328p -I. -I$(SNEK_LOCAL_VPATH) -g $(SNEK_CFLAGS) -Waddr-space-convert
LDFLAGS=$(SNEK_LDFLAGS) \
-Wl,-uvfprintf -lprintf_flt -lm \
-Wl,--defsym -Wl,__TEXT_REGION_LENGTH__=0x7e00 \
-Wl,-Map=$(MAP)

all:: $(HEX) snek-$(BOARD)-install snek-$(BOARD)-install.1
Expand Down
3 changes: 1 addition & 2 deletions ports/ev3/snekserver.c
Expand Up @@ -12,8 +12,7 @@
* General Public License for more details.
*/

#define _GNU_SOURCE

#include <snek.h>
#include "utils.h"
#include <errno.h>
#include <getopt.h>
Expand Down
1 change: 1 addition & 0 deletions ports/grove/Makefile
Expand Up @@ -54,6 +54,7 @@ OPT=-Os -frename-registers -funsigned-char -fno-jump-tables -mcall-prologues
CFLAGS=$(OPT) -DF_CPU=16000000UL -mmcu=atmega328p -I. -I$(SNEK_LOCAL_VPATH) -g $(SNEK_CFLAGS) -Waddr-space-convert
LDFLAGS=$(SNEK_LDFLAGS) \
-Wl,-uvfprintf -lprintf_flt -lm \
-Wl,--defsym -Wl,__TEXT_REGION_LENGTH__=0x7e00 \
-Wl,-Map=$(MAP)

all: $(HEX) snek-grove-install
Expand Down
7 changes: 6 additions & 1 deletion ports/nano-every/Makefile
Expand Up @@ -26,13 +26,18 @@ SNEK_LOCAL_VPATH = $(SNEK_ATMEGA)
SNEK_LOCAL_SRC = \
snek-pow.c \
snek-nano-every.c \
snek-input.c \
$(SNEK_ATMEGA_MATH_SRC) \
$(SNEK_ATMEGA_SRC)

SNEK_LOCAL_INC = \
$(SNEK_ATMEGA_INC)
$(SNEK_ATMEGA_INC) \
$(SNEK_ATMEGA_MATH_INC)

SNEK_LOCAL_BUILTINS = \
$(SNEK_ATMEGA_BUILTINS) \
snek-input.builtin \
snek-math.builtin \
snek-nano-every.builtin

include $(SNEK_ROOT)/snek-install.defs
Expand Down
1 change: 1 addition & 0 deletions ports/nano-every/snek-nano-every.builtin
Expand Up @@ -34,5 +34,6 @@ A5, -2, 19
A6, -2, 20
A7, -2, 21
#include <snek-atmega.h>
#include <snek-atmega-math.h>
#define SNEK_POOL 3584
#define SNEK_MAX_TOKEN 63
4 changes: 2 additions & 2 deletions ports/xiao/Makefile
Expand Up @@ -18,8 +18,8 @@ SNEK_SAMD21 = $(SNEK_ROOT)/chips/samd21

PROGNAME=snek-xiao
PRODUCT_NAME=SnekXiao
IDPRODUCT=0x8057
IDVENDOR=0x2341
IDPRODUCT=0x002e
IDVENDOR=0x2886

include $(SNEK_SAMD21)/snek-samd21.defs

Expand Down
64 changes: 29 additions & 35 deletions snek-strtof.c → snek-atof.c
Expand Up @@ -28,8 +28,6 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */

/* $Id: strtod.c 2191 2010-11-05 13:45:57Z arcanum $ */


#include <ctype.h>
#include <errno.h>
Expand All @@ -38,27 +36,27 @@
#include <stdlib.h>

#ifdef AVR
#define strtof strtod
#define float double
#include <avr/pgmspace.h>
#else
#define PROGMEM
#define __flash
#define pgm_read_dword(x) (*x)
#endif
#include <snek.h>

/* Only GCC 4.2 calls the library function to convert an unsigned long
to float. Other GCC-es (including 4.3) use a signed long to float
conversion along with a large inline code to correct the result. */
extern float __floatunsisf (unsigned long);

PROGMEM static const float pwr_p10 [6] = {
1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32
static const __flash float pwr_p10 [6] = {
1e+32, 1e+16, 1e+8, 1e+4, 1e+2, 1e+1,
};
PROGMEM static const float pwr_m10 [6] = {
1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32
static const __flash float pwr_m10 [6] = {
1e-32, 1e-16, 1e-8, 1e-4, 1e-2, 1e-1,
};

/** The strtof() function converts the initial portion of the string pointed
/** The atof() function converts the initial portion of the string pointed
to by \a nptr to float representation.
The expected form of the string is an optional plus ( \c '+' ) or minus
Expand All @@ -69,11 +67,7 @@ PROGMEM static const float pwr_m10 [6] = {
Leading white-space characters in the string are not skipped.
The strtod() function returns the converted value, if any.
If \a endptr is not \c NULL, a pointer to the character after the last
character used in the conversion is stored in the location referenced by
\a endptr.
The atof() function returns the converted value, if any.
If no conversion is performed, zero is returned and the value of
\a nptr is stored in the location referenced by \a endptr.
Expand All @@ -83,8 +77,12 @@ PROGMEM static const float pwr_m10 [6] = {
in \c errno. If the correct value would cause underflow, zero is
returned and \c ERANGE is stored in \c errno.
*/

#define CASE_CONVERT ('a' - 'A')
#define TOLOWER(c) ((c) | CASE_CONVERT)

float
strtof (const char * nptr, char ** endptr)
atoff (const char * nptr)
{
union {
unsigned long u32;
Expand All @@ -99,11 +97,15 @@ strtof (const char * nptr, char ** endptr)
#define FL_DOT 0x04 /* decimal '.' was */
#define FL_MEXP 0x08 /* exponent 'e' is neg. */

if (endptr)
*endptr = (char *)nptr;

c = *nptr++;

#if defined(SNEK_BUILTIN_float)
if (TOLOWER(c) == 'n')
return NAN;
if (TOLOWER(c) == 'i')
return INFINITY;
#endif

flag = 0;

x.u32 = 0;
Expand All @@ -120,8 +122,7 @@ strtof (const char * nptr, char ** endptr)
} else {
if (flag & FL_DOT)
exp -= 1;
/* x.u32 = x.u32 * 10 + c */
x.u32 = (((x.u32 << 2) + x.u32) << 1) + c;
x.u32 = x.u32 * 10 + c;
if (x.u32 >= (ULONG_MAX - 9) / 10)
flag |= FL_OVFL;
}
Expand All @@ -134,7 +135,7 @@ strtof (const char * nptr, char ** endptr)
c = *nptr++;
}

if (c == (('e'-'0') & 0xff) || c == (('E'-'0') & 0xff))
if (TOLOWER(c) == 'e' - '0')
{
int i;
c = *nptr++;
Expand Down Expand Up @@ -163,29 +164,22 @@ strtof (const char * nptr, char ** endptr)
}
}

if ((flag & FL_ANY) && endptr)
*endptr = (char *)nptr - 1;

x.flt = __floatunsisf (x.u32); /* manually */

if (x.flt != 0) {
int pwr;
const __flash float *fptr;

if (exp < 0) {
nptr = (void *)(pwr_m10 + 5);
fptr = pwr_m10;
exp = -exp;
} else {
nptr = (void *)(pwr_p10 + 5);
fptr = pwr_p10;
}
for (pwr = 32; pwr; pwr >>= 1) {
for (; exp >= pwr; exp -= pwr) {
union {
unsigned long u32;
float flt;
} y;
y.u32 = pgm_read_dword ((float *)nptr);
x.flt *= y.flt;
}
nptr -= sizeof(float);
for (; exp >= pwr; exp -= pwr)
x.flt *= *fptr;
fptr++;
}
}

Expand Down
51 changes: 28 additions & 23 deletions snek-exec.c
Expand Up @@ -290,30 +290,35 @@ snek_binary(snek_poly_t a, snek_op_t op, snek_poly_t b, bool inplace)
* in snek, so no type checking needed here.
*/
if (op <= snek_op_is_not) {
int8_t cmp = snek_poly_cmp(a, b, op >= snek_op_is);
bool v;
switch (op) {
case snek_op_eq:
case snek_op_is:
v = cmp == 0;
break;
case snek_op_ne:
case snek_op_is_not:
v = cmp != 0;
break;
case snek_op_gt:
v = cmp > 0;
break;
case snek_op_lt:
v = cmp < 0;
break;
case snek_op_ge:
v = cmp >= 0;
break;
case snek_op_le:
default:
v = cmp <= 0;
break;
if (op < snek_op_is && (snek_is_nan(a) || snek_is_nan(b)))
v = (op == snek_op_ne);
else
{
int8_t cmp = snek_poly_cmp(a, b, op >= snek_op_is);
switch (op) {
case snek_op_eq:
case snek_op_is:
v = cmp == 0;
break;
case snek_op_ne:
case snek_op_is_not:
v = cmp != 0;
break;
case snek_op_gt:
v = cmp > 0;
break;
case snek_op_lt:
v = cmp < 0;
break;
case snek_op_ge:
v = cmp >= 0;
break;
case snek_op_le:
default:
v = cmp <= 0;
break;
}
}
return snek_bool_to_poly(v);
}
Expand Down

0 comments on commit 455f851

Please sign in to comment.