diff --git a/lib/libesp32/Berry/LICENSE b/lib/libesp32/Berry/LICENSE
deleted file mode 100644
index 609969272cbf..000000000000
--- a/lib/libesp32/Berry/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018-2020 Guan Wenliang
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/lib/libesp32/Berry/Makefile b/lib/libesp32/Berry/Makefile
deleted file mode 100755
index 2d33069fbbef..000000000000
--- a/lib/libesp32/Berry/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-CFLAGS = -Wall -Wextra -std=c99 -O2 -Wno-zero-length-array -Wno-empty-translation-unit -DUSE_BERRY_INT64
-DEBUG_FLAGS = -O0 -g -DBE_DEBUG
-TEST_FLAGS = $(DEBUG_FLAGS) --coverage -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined
-LIBS = -lm
-TARGET = berry
-CC = gcc
-MKDIR = mkdir
-LFLAGS =
-
-INCPATH = src default ../re1.5 ../berry_mapping/src ../berry_int64/src generate
-SRCPATH = src default ../re1.5 ../berry_mapping/src ../berry_int64/src
-GENERATE = generate
-CONFIG = default/berry_conf.h
-COC = tools/coc/coc
-CONST_TAB = $(GENERATE)/be_const_strtab.h
-
-ifeq ($(OS), Windows_NT) # Windows
- CFLAGS += -Wno-format # for "%I64d" warning
- LFLAGS += -Wl,--out-implib,berry.lib # export symbols lib for dll linked
- TARGET := $(TARGET).exe
- PYTHON ?= python # only for windows and need python3
- COC := $(PYTHON) $(COC)
-else
- CFLAGS += -DUSE_READLINE_LIB
- LIBS += -lreadline -ldl
- OS := $(shell uname)
- ifeq ($(OS), Linux)
- LFLAGS += -Wl,--export-dynamic
- endif
-endif
-
-ifneq ($(V), 1)
- Q=@
- MSG=@echo
-else
- MSG=@true
-endif
-
-SRCS = $(foreach dir, $(SRCPATH), $(wildcard $(dir)/*.c))
-OBJS = $(patsubst %.c, %.o, $(SRCS))
-DEPS = $(patsubst %.c, %.d, $(SRCS))
-INCFLAGS = $(foreach dir, $(INCPATH), -I"$(dir)")
-
-.PHONY : clean
-
-all: $(TARGET)
-
-debug: CFLAGS += $(DEBUG_FLAGS)
-debug: all
-
-test: CFLAGS += $(TEST_FLAGS)
-test: LFLAGS += $(TEST_FLAGS)
-test: all
- $(MSG) [Run Testcases...]
- $(Q) ./testall.be
- $(Q) $(RM) */*.gcno */*.gcda
-
-$(TARGET): $(OBJS)
- $(MSG) [Linking...]
- $(Q) $(CC) $(OBJS) $(LFLAGS) $(LIBS) -o $@
- $(MSG) done
-
-$(OBJS): %.o: %.c
- $(MSG) [Compile] $<
- $(Q) $(CC) -MM $(CFLAGS) $(INCFLAGS) -MT"$*.d" -MT"$(<:.c=.o)" $< > $*.d
- $(Q) $(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $@
-
-sinclude $(DEPS)
-
-$(OBJS): $(CONST_TAB)
-
-$(CONST_TAB): $(GENERATE) $(SRCS) $(CONFIG)
- $(MSG) [Prebuild] generate resources
- $(Q) $(COC) -o $(GENERATE) $(SRCPATH) -c $(CONFIG)
-
-$(GENERATE):
- $(Q) $(MKDIR) $(GENERATE)
-
-install:
- cp $(TARGET) /usr/local/bin
-
-uninstall:
- $(RM) /usr/local/bin/$(TARGET)
-
-prebuild: $(GENERATE)
- $(MSG) [Prebuild] generate resources
- $(Q) $(COC) -o $(GENERATE) $(SRCPATH) -c $(CONFIG)
- $(MSG) done
-
-clean:
- $(MSG) [Clean...]
- $(Q) $(RM) $(OBJS) $(DEPS) $(GENERATE)/* berry.lib
- $(MSG) done
diff --git a/lib/libesp32/Berry/README.md b/lib/libesp32/Berry/README.md
deleted file mode 100644
index aef02a192c73..000000000000
--- a/lib/libesp32/Berry/README.md
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
- The Berry Script Language.
-
-
-## Introduction
-
-Berry is a ultra-lightweight dynamically typed embedded scripting language. It is designed for lower-performance embedded devices. The Berry interpreter-core's code size is less than 40KiB and can run on less than 4KiB heap (on ARM Cortex M4 CPU, Thumb ISA and ARMCC compiler).
-
-The interpreter of Berry include a one-pass compiler and register-based VM, all the code is written in ANSI C99. In Berry not every type is a class object. Some simple value types, such as int, real, boolean and string are not class object, but list, map and range are class object. This is a consideration about performance.
-Register-based VM is the same meaning as above.
-
-Berry has the following advantages:
-
-* Lightweight: A well-optimized interpreter with very little resources. Ideal for use in microprocessors.
-* Fast: optimized one-pass bytecode compiler and register-based virtual machine.
-* Powerful: supports imperative programming, object-oriented programming, functional programming.
-* Flexible: Berry is a dynamic type script, and it's intended for embedding in applications. It can provide good dynamic scalability for the host system.
-* Simple: simple and natural syntax, support garbage collection, and easy to use FFI (foreign function interface).
-* RAM saving: With compile-time object construction, most of the constant objects are stored in read-only code data segments, so the RAM usage of the interpreter is very low when it starts.
-
-## Documents
-
-Reference Manual: [Wiki](https://github.com/berry-lang/berry/wiki/Reference)
-
-Short Manual (slightly outdated): [berry_short_manual.pdf](https://github.com/Skiars/berry_doc/releases/download/latest/berry_short_manual.pdf).
-
-Berry's EBNF grammar definition: [tools/grammar/berry.ebnf](./tools/grammar/berry.ebnf)
-
-## Features
-
-* Base Type
- * Nil: `nil`
- * Boolean: `true` and `false`
- * Numerical: Integer (`int`) and Real (`real`)
- * String: Single quotation-mark string and double quotation-mark string
- * Class: Instance template, read only
- * Instance: Object constructed by class
- * Module: Read-write key-value pair table
- * List: Ordered container, like `[1, 2, 3]`
- * Map: Hash Map container, like `{ 'a': 1, 2: 3, 'map': {} }`
- * Range: include a lower and a upper integer value, like `0..5`
-* Operator and Expression
- * Assign operator: `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `<<=`, `>>=`
- * Relational operator: `<`, `<=`, `==`, `!=`, `>`, `>=`
- * Logic operator: `&&`, `||`, `!`
- * Arithmetic operator: `+`, `-`, `*`, `/`, `%`
- * Bitwise operator: `&`, `|`, `~`, `^`, `<<`, `>>`
- * Field operator: `.`
- * Subscript operator: `[]`
- * Connect string operator: `+`
- * Conditional operator: `? :`
- * Brackets: `()`
-* Control Structure
- * Conditional statement: `if-else`
- * Iteration statement: `while` and `for`
- * Jump statement: `break` and `continue`
-* Function
- * Local variable and block scope
- * Return statement
- * Nested functions definition
- * Closure based on Upvalue
- * Anonymous function
- * Lambda expression
-* Class
- * Inheritance (only public single inheritance)
- * Method and Operator Overload
- * Constructor method
- * Destructive method
-* Module Management
- * Built-in module that takes almost no RAM
- * Extension module support: script module, bytecode file module and shared library (like *.so, *.dll) module
-* GC (Garbage collection)
- * Mark-Sweep GC
-* Exceptional Handling
- * Throw any exception value using the `raise` statement
- * Multiple catch mode
-* Bytecode file support
- * Export function to bytecode file
- * Load the bytecode file and execute
-
-## Build and Run
-
-1. Install the readline library (Windows does not need):
-
- ``` bash
- sudo apt install libreadline-dev # Ubuntu
- brew install readline # MacOS
- ```
-
-2. Build (The default compiler is GCC):
-
- ```
- make
- ```
-
-3. Run:
-
- ``` bash
- ./berry # Bash or PowerShell
- berry # Windows CMD
- ```
-
-4. Install (Only Unix-like):
-
- ``` bash
- make install
- ```
-
-## Editor plugins
-
-[Visual Studio Code](https://code.visualstudio.com/) plugin are in this directory: [./tools/plugins/vscode](./tools/plugins/vscode).
-
-## Examples
-
-After compiling successfully, use the `berry` command with no parameters to enter the REPL environment:
-```
-Berry 0.0.1 (build in Dec 24 2018, 18:12:49)
-[GCC 8.2.0] on Linux (default)
->
-```
-
-Now enter this code:
-
-``` lua
-print("Hello world!")
-```
-
-You will see this output:
-
-```
-Hello world!
-```
-
-You can copy this code to the REPL:
-
-``` ruby
-def fib(x)
- if x <= 1
- return x
- end
- return fib(x - 1) + fib(x - 2)
-end
-fib(10)
-```
-
-This example code will output the result `55` and you can save the above code to a plain text file (eg test.be) and run this command:
-
-``` bash
-./berry test.be
-```
-
-This will also get the correct output.
-
-## License
-
-Berry is free software distributed under the [MIT license](./LICENSE).
-
-The Berry interpreter partly referred to [Lua](http://www.lua.org/)'s design. View Lua's license here: http://www.lua.org/license.html.
diff --git a/lib/libesp32/Berry/berry-logo.png b/lib/libesp32/Berry/berry-logo.png
deleted file mode 100644
index 1eb41908963a..000000000000
Binary files a/lib/libesp32/Berry/berry-logo.png and /dev/null differ
diff --git a/lib/libesp32/Berry/default/be_modtab.c b/lib/libesp32/Berry/default/be_modtab.c
deleted file mode 100644
index e4f60edcc939..000000000000
--- a/lib/libesp32/Berry/default/be_modtab.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "berry.h"
-#include "../../berry_custom/src/modules.h"
-
-/* this file contains the declaration of the module table. */
-
-/* default modules declare */
-be_extern_native_module(string);
-be_extern_native_module(json);
-be_extern_native_module(math);
-be_extern_native_module(time);
-be_extern_native_module(os);
-be_extern_native_module(global);
-be_extern_native_module(sys);
-be_extern_native_module(debug);
-be_extern_native_module(gc);
-be_extern_native_module(solidify);
-be_extern_native_module(introspect);
-be_extern_native_module(strict);
-be_extern_native_module(undefined);
-
-/* Berry extensions */
-be_extern_native_module(cb);
-
-/* Tasmota specific */
-be_extern_native_module(python_compat);
-be_extern_native_module(re);
-be_extern_native_module(mqtt);
-be_extern_native_module(persist);
-be_extern_native_module(autoconf);
-be_extern_native_module(tapp);
-be_extern_native_module(light);
-be_extern_native_module(gpio);
-be_extern_native_module(display);
-be_extern_native_module(energy);
-be_extern_native_module(webserver);
-be_extern_native_module(flash);
-be_extern_native_module(path);
-be_extern_native_module(unishox);
-be_extern_native_module(hue_ntv);
-be_extern_native_module(hue_bridge);
-be_extern_native_module(uuid);
-be_extern_native_module(animate);
-be_extern_native_module(partition_core);
-be_extern_native_module(crc);
-be_extern_native_module(crypto);
-be_extern_native_module(ULP);
-be_extern_native_module(TFL);
-be_extern_native_module(mdns);
-#ifdef USE_ZIGBEE
-be_extern_native_module(zigbee);
-be_extern_native_module(matter_zigbee);
-#endif // USE_ZIGBEE
-#ifdef USE_BERRY_CAM
-be_extern_native_module(cam);
-#endif // USE_BERRY_CAM
-// BLE
-be_extern_native_module(MI32);
-be_extern_native_module(BLE);
-#ifdef USE_LVGL
-be_extern_native_module(lv);
-be_extern_native_module(lv_extra);
-be_extern_native_module(lv_tasmota);
-#ifdef USE_LVGL_HASPMOTA
-be_extern_native_module(haspmota);
-#endif // USE_LVGL_HASPMOTA
-#endif // USE_LVGL
-#ifdef USE_MATTER_DEVICE
-be_extern_native_module(matter);
-#endif // USE_MATTER_DEVICE
-
-/* user-defined modules declare start */
-
-/* user-defined modules declare end */
-
-/* module list declaration */
-BERRY_LOCAL const bntvmodule_t* const be_module_table[] = {
-/* default modules register */
-#if BE_USE_STRING_MODULE
- &be_native_module(string),
-#endif
-#if BE_USE_JSON_MODULE
- &be_native_module(json),
-#endif
-#if BE_USE_MATH_MODULE
- &be_native_module(math),
-#endif
-#if BE_USE_TIME_MODULE
- &be_native_module(time),
-#endif
-#if BE_USE_OS_MODULE
- &be_native_module(os),
-#endif
-#if BE_USE_GLOBAL_MODULE
- &be_native_module(global),
-#endif
-#if BE_USE_SYS_MODULE
- &be_native_module(sys),
-#endif
-#if BE_USE_DEBUG_MODULE
- &be_native_module(debug),
-#endif
-#if BE_USE_GC_MODULE
- &be_native_module(gc),
-#endif
-#if BE_USE_SOLIDIFY_MODULE
- &be_native_module(solidify),
-#endif
-#if BE_USE_INTROSPECT_MODULE
- &be_native_module(introspect),
-#endif
-#if BE_USE_STRICT_MODULE
- &be_native_module(strict),
-#endif
- &be_native_module(undefined),
-
- &be_native_module(re),
-#ifdef TASMOTA
- /* Berry extensions */
- &be_native_module(cb),
-
- /* user-defined modules register start */
-
- &be_native_module(python_compat),
- &be_native_module(path),
- &be_native_module(mqtt),
- &be_native_module(persist),
-#ifdef USE_AUTOCONF
- &be_native_module(autoconf),
-#endif // USE_AUTOCONF
- &be_native_module(tapp),
- &be_native_module(gpio),
-#ifdef USE_DISPLAY
- &be_native_module(display),
-#endif // USE_DISPLAY
-#ifdef USE_LIGHT
- &be_native_module(light),
-#endif
-#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
- &be_native_module(hue_ntv),
- &be_native_module(hue_bridge),
-#endif
-
- &be_native_module(uuid),
-#ifdef USE_UNISHOX_COMPRESSION
- &be_native_module(unishox),
-#endif // USE_UNISHOX_COMPRESSION
-
-#ifdef USE_WS2812
- &be_native_module(animate),
-#endif // USE_WS2812
-
-#ifdef USE_LVGL
- &be_native_module(lv),
- &be_native_module(lv_extra),
- &be_native_module(lv_tasmota),
-#ifdef USE_LVGL_HASPMOTA
- &be_native_module(haspmota),
-#endif // USE_LVGL_HASPMOTA
-#endif // USE_LVGL
-#ifdef USE_ENERGY_SENSOR
- &be_native_module(energy),
-#endif // USE_ENERGY_SENSOR
-#ifdef USE_WEBSERVER
- &be_native_module(webserver),
-#endif // USE_WEBSERVER
-#ifdef USE_ZIGBEE
- &be_native_module(zigbee),
- &be_native_module(matter_zigbee),
-#endif // USE_ZIGBEE
- &be_native_module(flash),
- &be_native_module(partition_core),
- &be_native_module(crc),
- &be_native_module(crypto),
-#if defined(USE_BERRY_ULP) && ((CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
- &be_native_module(ULP),
-#endif // USE_BERRY_ULP
-#if defined(USE_BERRY_TF_LITE)
- &be_native_module(TFL),
-#endif //USE_BERRY_TF_LITE
-#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
- &be_native_module(MI32),
- &be_native_module(BLE),
-#endif //USE_MI_ESP32
-#ifdef USE_BERRY_CAM
- &be_native_module(cam),
-#endif
-#ifdef USE_DISCOVERY
- &be_native_module(mdns),
-#endif // USE_DISCOVERY
-#ifdef USE_MATTER_DEVICE
- &be_native_module(matter),
-#endif // USE_MATTER_DEVICE
-#endif // TASMOTA
- CUSTOM_NATIVE_MODULES
- /* user-defined modules register end */
- NULL /* do not remove */
-};
-
-be_extern_native_class(dyn);
-be_extern_native_class(tasmota);
-be_extern_native_class(Trigger);
-be_extern_native_class(Driver);
-be_extern_native_class(ctypes_bytes);
-be_extern_native_class(ctypes_bytes_dyn);
-be_extern_native_class(serial);
-be_extern_native_class(ccronexpr);
-be_extern_native_class(tasmota_log_reader);
-be_extern_native_class(light_state);
-be_extern_native_class(Wire);
-be_extern_native_class(I2C_Driver);
-be_extern_native_class(AXP192);
-be_extern_native_class(AXP202);
-be_extern_native_class(OneWire);
-be_extern_native_class(Leds_ntv);
-be_extern_native_class(Leds);
-be_extern_native_class(AudioGenerator);
-be_extern_native_class(AudioFileSource);
-be_extern_native_class(AudioOutputI2S);
-be_extern_native_class(AudioGeneratorWAV);
-be_extern_native_class(AudioGeneratorMP3);
-be_extern_native_class(AudioFileSourceFS);
-be_extern_native_class(AudioOpusDecoder);
-be_extern_native_class(AudioInputI2S);
-be_extern_native_class(md5);
-be_extern_native_class(udp);
-be_extern_native_class(webclient);
-be_extern_native_class(tcpclient);
-be_extern_native_class(tcpclientasync);
-be_extern_native_class(webserver_async);
-be_extern_native_class(tcpserver);
-be_extern_native_class(energy_struct);
-// LVGL core classes
-be_extern_native_class(lv_color);
-be_extern_native_class(lv_font);
-be_extern_native_class(LVGL_glob);
-// LVGL custom classes
-be_extern_native_class(lv_signal_bars);
-be_extern_native_class(lv_wifi_bars);
-be_extern_native_class(lv_wifi_bars_icon);
-be_extern_native_class(lv_signal_arcs);
-be_extern_native_class(lv_wifi_arcs);
-be_extern_native_class(lv_wifi_arcs_icon);
-be_extern_native_class(lv_clock);
-be_extern_native_class(lv_clock_icon);
-
-be_extern_native_class(int64);
-
-#ifdef USE_BERRY_IMAGE
-be_extern_native_class(img);
-#endif // USE_BERRY_IMAGE
-
-BERRY_LOCAL bclass_array be_class_table = {
-#ifdef TASMOTA
- /* first list are direct classes */
- &be_native_class(dyn),
- &be_native_class(tasmota),
- &be_native_class(Trigger),
- &be_native_class(Driver),
- &be_native_class(serial),
- &be_native_class(ccronexpr),
- &be_native_class(ctypes_bytes),
- &be_native_class(ctypes_bytes_dyn),
- &be_native_class(tasmota_log_reader),
-#ifdef USE_LIGHT
- &be_native_class(light_state),
-#endif
-#if defined(USE_ONEWIRE) || defined(USE_DS18x20)
- &be_native_class(OneWire),
-#endif
-#ifdef USE_I2C
- &be_native_class(Wire),
- &be_native_class(I2C_Driver),
- &be_native_class(AXP192),
- &be_native_class(AXP202),
-#endif // USE_I2C
- &be_native_class(md5),
-#ifdef USE_WEBCLIENT
- &be_native_class(udp),
- &be_native_class(webclient),
- &be_native_class(tcpclient),
- &be_native_class(tcpclientasync),
-#ifdef USE_BERRY_DEBUG
- &be_native_class(webserver_async), // include only when USE_BERRY_DEBUG is enabled
-#endif // USE_BERRY_DEBUG
-#endif // USE_WEBCLIENT
-#ifdef USE_BERRY_TCPSERVER
- &be_native_class(tcpserver),
-#endif // USE_BERRY_TCPSERVER
-#ifdef USE_WS2812
- &be_native_class(Leds_ntv),
- &be_native_class(Leds),
-#endif // USE_WS2812
-#ifdef USE_ENERGY_SENSOR
- &be_native_class(energy_struct),
-#endif // USE_ENERGY_SENSOR
-
-#ifdef USE_LVGL
- &be_native_class(LVGL_glob),
-
- &be_native_class(lv_signal_bars),
- &be_native_class(lv_wifi_bars),
- &be_native_class(lv_wifi_bars_icon),
- &be_native_class(lv_signal_arcs),
- &be_native_class(lv_wifi_arcs),
- &be_native_class(lv_wifi_arcs_icon),
- &be_native_class(lv_clock),
- &be_native_class(lv_clock_icon),
-#endif // USE_LVGL
-
-#ifdef USE_BERRY_IMAGE
- &be_native_class(img),
-#endif // USE_BERRY_IMAGE
-
-#if defined(USE_I2S_AUDIO_BERRY) && (ESP_IDF_VERSION_MAJOR >= 5)
- &be_native_class(AudioGenerator),
- &be_native_class(AudioFileSource),
- &be_native_class(AudioOutputI2S),
- &be_native_class(AudioGeneratorWAV),
- &be_native_class(AudioGeneratorMP3),
-#ifdef USE_UFILESYS
- &be_native_class(AudioFileSourceFS),
-#endif // USE_UFILESYS
- &be_native_class(AudioOpusDecoder),
- &be_native_class(AudioInputI2S),
-#endif // defined(USE_I2S_AUDIO_BERRY) && (ESP_IDF_VERSION_MAJOR >= 5)
-#endif // TASMOTA
-
-#if defined(USE_BERRY_INT64) || defined(USE_MATTER_DEVICE)
- &be_native_class(int64),
-#endif
- CUSTOM_NATIVE_CLASSES
- NULL, /* do not remove */
-};
-
-extern void be_load_ctypes_energy_definitions_lib(bvm *vm);
-
-/* this code loads the native class definitions */
-BERRY_API void be_load_custom_libs(bvm *vm)
-{
- (void)vm; /* prevent a compiler warning */
-
- /* add here custom libs */
-#if !BE_USE_PRECOMPILED_OBJECT
- /* be_load_xxxlib(vm); */
-#endif
-}
diff --git a/lib/libesp32/Berry/default/berry_conf.h b/lib/libesp32/Berry/default/berry_conf.h
deleted file mode 100644
index 13200f530993..000000000000
--- a/lib/libesp32/Berry/default/berry_conf.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BERRY_CONF_H
-#define BERRY_CONF_H
-
-#include
-
-#ifdef COMPILE_BERRY_LIB
- #include "my_user_config.h"
- #include "include/tasmota_configurations.h"
-#endif
-
-/* Macro: BE_DEBUG
- * Berry interpreter debug switch.
- * Default: 0
- **/
-#ifndef BE_DEBUG
-#define BE_DEBUG 0
-#endif
-
-/* Macro: BE_LONGLONG_INT
- * Select integer length.
- * If the value is 0, use an integer of type int, use a long
- * integer type when the value is 1, and use a long long integer
- * type when the value is 2.
- * Default: 2
- */
-#ifdef TASMOTA
-#define BE_INTGER_TYPE 1 // use long int = uint32_t
-#else
-#define BE_INTGER_TYPE 0
-#endif
-
-/* Macro: BE_USE_SINGLE_FLOAT
- * Select floating point precision.
- * Use double-precision floating-point numbers when the value
- * is 0 (default), otherwise use single-precision floating-point
- * numbers.
- * Default: 0
- **/
-#define BE_USE_SINGLE_FLOAT 1 // use `float` not `double`
-
-/* Macro: BE_BYTES_MAX_SIZE
- * Maximum size in bytes of a `bytes()` object.
- * Putting too much pressure on the memory allocator can do
- * harm, so we limit the maximum size.
- * Default: 32kb
- **/
-#define BE_BYTES_MAX_SIZE (32*1024) /* 32 kb default value */
-
-/* Macro: BE_USE_PRECOMPILED_OBJECT
- * Use precompiled objects to avoid creating these objects at
- * runtime. Enable this macro can greatly optimize RAM usage.
- * Default: 1
- **/
-#define BE_USE_PRECOMPILED_OBJECT 1
-
-/* Macro: BE_DEBUG_SOURCE_FILE
- * Indicate if each function remembers its source file name
- * 0: do not keep the file name (saves 4 bytes per function)
- * 1: keep the source file name
- * Default: 1
- **/
-#define BE_DEBUG_SOURCE_FILE 0
-
-/* Macro: BE_DEBUG_RUNTIME_INFO
- * Set runtime error debugging information.
- * 0: unable to output source file and line number at runtime.
- * 1: output source file and line number information at runtime.
- * 2: the information use uint16_t type (save space).
- * Default: 1
- **/
-#define BE_DEBUG_RUNTIME_INFO 0
-
-/* Macro: BE_DEBUG_VAR_INFO
- * Set variable debugging tracking information.
- * 0: disable variable debugging tracking information at runtime.
- * 1: enable variable debugging tracking information at runtime.
- * Default: 1
- **/
-#define BE_DEBUG_VAR_INFO 0
-
-/* Macro: BE_USE_PERF_COUNTERS
- * Use the obshook function to report low-level actions.
- * Default: 0
- **/
-#define BE_USE_PERF_COUNTERS 1
-
-/* Macro: BE_VM_OBSERVABILITY_SAMPLING
- * If BE_USE_PERF_COUNTERS == 1
- * then the observability hook is called regularly in the VM loop
- * allowing to stop infinite loops or too-long running code.
- * The value is a power of 2.
- * Default: 20 - which translates to 2^20 or ~1 million instructions
- **/
-#define BE_VM_OBSERVABILITY_SAMPLING 20
-
-/* Macro: BE_STACK_TOTAL_MAX
- * Set the maximum total stack size.
- * Default: 20000
- **/
-#define BE_STACK_TOTAL_MAX 8000
-
-/* Macro: BE_STACK_FREE_MIN
- * Set the minimum free count of the stack. The stack idles will
- * be checked when a function is called, and the stack will be
- * expanded if the number of free is less than BE_STACK_FREE_MIN.
- * Default: 10
- **/
-#define BE_STACK_FREE_MIN 20
-
-/* Macro: BE_STACK_START
- * Set the starting size of the stack at VM creation.
- * Default: 50
- **/
-#define BE_STACK_START 100
-
-/* Macro: BE_CONST_SEARCH_SIZE
- * Constants in function are limited to 255. However the compiler
- * will look for a maximum of pre-existing constants to avoid
- * performance degradation. This may cause the number of constants
- * to be higher than required.
- * Increase is you need to solidify functions.
- * Default: 50
- **/
-#define BE_CONST_SEARCH_SIZE 150
-
-/* Macro: BE_STACK_FREE_MIN
- * The short string will hold the hash value when the value is
- * true. It may be faster but requires more RAM.
- * Default: 0
- **/
-#define BE_USE_STR_HASH_CACHE 0
-
-/* Macro: BE_USE_FILE_SYSTEM
- * The file system interface will be used when this macro is true
- * or when using the OS module. Otherwise the file system interface
- * will not be used.
- * Default: 0
- **/
-#ifdef TASMOTA
-#define BE_USE_FILE_SYSTEM 0
-#else
-#define BE_USE_FILE_SYSTEM 1
-#endif
-
-/* Macro: BE_USE_SCRIPT_COMPILER
- * Enable compiler when BE_USE_SCRIPT_COMPILER is not 0, otherwise
- * disable the compiler.
- * Default: 1
- **/
-#define BE_USE_SCRIPT_COMPILER 1
-
-/* Macro: BE_USE_BYTECODE_SAVER
- * Enable save bytecode to file when BE_USE_BYTECODE_SAVER is not 0,
- * otherwise disable the feature.
- * Default: 1
- **/
-#define BE_USE_BYTECODE_SAVER 1
-
-/* Macro: BE_USE_BYTECODE_LOADER
- * Enable load bytecode from file when BE_USE_BYTECODE_LOADER is not 0,
- * otherwise disable the feature.
- * Default: 1
- **/
-#define BE_USE_BYTECODE_LOADER 1
-
-/* Macro: BE_USE_SHARED_LIB
- * Enable shared library when BE_USE_SHARED_LIB is not 0,
- * otherwise disable the feature.
- * Default: 1
- **/
-#define BE_USE_SHARED_LIB 0
-
-/* Macro: BE_USE_OVERLOAD_HASH
- * Allows instances to overload hash methods for use in the
- * built-in Map class. Disable this feature to crop the code
- * size.
- * Default: 1
- **/
-#define BE_USE_OVERLOAD_HASH 1
-
-/* Macro: BE_USE_DEBUG_HOOK
- * Berry debug hook switch.
- * Default: 0
- **/
-#define BE_USE_DEBUG_HOOK 0
-
-/* Macro: BE_USE_DEBUG_GC
- * Enable GC debug mode. This causes an actual gc after each
- * allocation. It's much slower and should not be used
- * in production code.
- * Default: 0
- **/
-#define BE_USE_DEBUG_GC 0
-
-/* Macro: BE_USE_DEBUG_STACK
- * Enable Stack Resize debug mode. At each function call
- * the stack is reallocated at a different memory location
- * and the previous location is cleared with toxic data.
- * Default: 0
- **/
-#define BE_USE_DEBUG_STACK 0
-
-/* Macro: BE_USE_MEM_ALIGNED
- * Some embedded processors have special memory areas
- * with read/write constraints of being aligned to 32 bits boundaries.
- * This options tries to move such memory areas to this region.
- * Default: 0
- **/
-#ifdef TASMOTA
-#define BE_USE_MEM_ALIGNED 1
-#else
-#define BE_USE_MEM_ALIGNED 0
-#endif
-
-/* Macro: BE_USE_XXX_MODULE
- * These macros control whether the related module is compiled.
- * When they are true, they will enable related modules. At this
- * point you can use the import statement to import the module.
- * They will not compile related modules when they are false.
- **/
-
-#ifdef TASMOTA
- #define BE_USE_STRING_MODULE 1
- #define BE_USE_JSON_MODULE 1
- #define BE_USE_MATH_MODULE 1
- #define BE_USE_TIME_MODULE 0
- #define BE_USE_OS_MODULE 0
- #define BE_USE_GLOBAL_MODULE 1
- #define BE_USE_SYS_MODULE 1
- #define BE_USE_DEBUG_MODULE 0
- #define BE_USE_GC_MODULE 1
- #define BE_USE_SOLIDIFY_MODULE 0
- #define BE_USE_INTROSPECT_MODULE 1
- #define BE_USE_STRICT_MODULE 1
-#else
- #define BE_USE_STRING_MODULE 1
- #define BE_USE_JSON_MODULE 1
- #define BE_USE_MATH_MODULE 1
- #define BE_USE_TIME_MODULE 1
- #define BE_USE_OS_MODULE 1
- #define BE_USE_GLOBAL_MODULE 1
- #define BE_USE_SYS_MODULE 1
- #define BE_USE_DEBUG_MODULE 1
- #define BE_USE_GC_MODULE 1
- #define BE_USE_SOLIDIFY_MODULE 1
- #define BE_USE_INTROSPECT_MODULE 1
- #define BE_USE_STRICT_MODULE 1
-#endif
-
-#if defined(USE_BERRY_DEBUG) || !defined(TASMOTA)
- #undef BE_USE_DEBUG_MODULE
- #undef BE_USE_SOLIDIFY_MODULE
- #define BE_USE_DEBUG_MODULE 1
- #define BE_USE_SOLIDIFY_MODULE 1
-#endif // USE_BERRY_DEBUG
-
-/* Macro: BE_EXPLICIT_XXX
- * If these macros are defined, the corresponding function will
- * use the version defined by these macros. These macro definitions
- * are not required.
- * The default is to use the functions in the standard library.
- **/
-#ifdef __cplusplus
-extern "C" {
-#endif
- extern void *berry_malloc(size_t size);
- extern void berry_free(void *ptr);
- extern void *berry_realloc(void *ptr, size_t size);
- extern void *berry_malloc32(size_t size);
-#ifdef __cplusplus
-}
-#endif
-#ifdef USE_BERRY_PSRAM
- #define BE_EXPLICIT_MALLOC berry_malloc
- #define BE_EXPLICIT_FREE berry_free
- #define BE_EXPLICIT_REALLOC berry_realloc
-#else
- #define BE_EXPLICIT_MALLOC malloc
- #define BE_EXPLICIT_FREE free
- #define BE_EXPLICIT_REALLOC realloc
-#endif // USE_BERRY_PSRAM
-
-#define BE_EXPLICIT_ABORT abort
-#define BE_EXPLICIT_EXIT exit
-// #define BE_EXPLICIT_MALLOC malloc
-// #define BE_EXPLICIT_FREE free
-// #define BE_EXPLICIT_REALLOC realloc
-
-/* Macro: be_assert
- * Berry debug assertion. Only enabled when BE_DEBUG is active.
- * Default: use the assert() function of the standard library.
- **/
-#define be_assert(expr) assert(expr)
-
-/* Tasmota debug specific */
-#ifdef USE_BERRY_DEBUG
- #undef BE_DEBUG_RUNTIME_INFO
- #define BE_DEBUG_RUNTIME_INFO 1 /* record line information in 32 bits to be places in IRAM */
- #undef BE_DEBUG
- #define BE_DEBUG 1
- #undef be_assert
- #define be_assert(expr) \
- ((expr) \
- ? (0) \
- : serial_debug("BRY: ASSERT '%s', %s - %i\n", #expr, __FILE__, __LINE__))
- #ifdef USE_LVGL
- #undef BE_STACK_START
- #define BE_STACK_START 200
- #endif // USE_LVGL
- #ifdef USE_MATTER_DEVICE
- #undef BE_STACK_START
- #define BE_STACK_START 256
- #endif // USE_MATTER_DEVICE
-#endif // USE_BERRY_DEBUG
-
-#endif
diff --git a/lib/libesp32/Berry/examples/anon_func.be b/lib/libesp32/Berry/examples/anon_func.be
deleted file mode 100644
index 78854ce64a37..000000000000
--- a/lib/libesp32/Berry/examples/anon_func.be
+++ /dev/null
@@ -1,20 +0,0 @@
-# anonymous function and closure
-def count(x)
- var arr = []
- for i : 0 .. x
- arr.push(
- def (n) # loop variable cannot be used directly as free variable
- return def ()
- return n * n
- end
- end (i) # define and call anonymous function
- )
- end
- return arr
-end
-
-for xx : count(6)
- print(xx()) # 0, 1, 4 ... n * n
-end
-
-return count
diff --git a/lib/libesp32/Berry/examples/bigloop.be b/lib/libesp32/Berry/examples/bigloop.be
deleted file mode 100644
index a3a77768b232..000000000000
--- a/lib/libesp32/Berry/examples/bigloop.be
+++ /dev/null
@@ -1,15 +0,0 @@
-import time
-
-c = time.clock()
-do
- i = 0
- while i < 100000000
- i += 1
- end
-end
-print('while iteration 100000000 times', time.clock() - c, 's')
-
-c = time.clock()
-for i : 1 .. 100000000
-end
-print('for iteration 100000000 times', time.clock() - c, 's')
diff --git a/lib/libesp32/Berry/examples/bintree.be b/lib/libesp32/Berry/examples/bintree.be
deleted file mode 100644
index 81936f8a0306..000000000000
--- a/lib/libesp32/Berry/examples/bintree.be
+++ /dev/null
@@ -1,60 +0,0 @@
-# Reference from https://github.com/BerryMathDevelopmentTeam/BerryMath/blob/master/testscript/BinaryTree.bm
-
-class node
- var v, l, r
- def init(v, l, r)
- self.v = v
- self.l = l
- self.r = r
- end
- def insert(v)
- if v < self.v
- if self.l
- self.l.insert(v)
- else
- self.l = node(v)
- end
- else
- if self.r
- self.r.insert(v)
- else
- self.r = node (v)
- end
- end
- end
- def sort(l)
- if (self.l) self.l.sort(l) end
- l.push(self.v)
- if (self.r) self.r.sort(l) end
- end
-end
-
-class btree
- var root
- def insert(v)
- if self.root
- self.root.insert(v)
- else
- self.root = node(v)
- end
- end
- def sort()
- var l = []
- if self.root
- self.root.sort(l)
- end
- return l
- end
-end
-
-var tree = btree()
-tree.insert(-100)
-tree.insert(5);
-tree.insert(3);
-tree.insert(9);
-tree.insert(10);
-tree.insert(10000000);
-tree.insert(1);
-tree.insert(-1);
-tree.insert(-10);
-print(tree.sort());
diff --git a/lib/libesp32/Berry/examples/calcpi.be b/lib/libesp32/Berry/examples/calcpi.be
deleted file mode 100644
index 053f878753de..000000000000
--- a/lib/libesp32/Berry/examples/calcpi.be
+++ /dev/null
@@ -1,16 +0,0 @@
-def cpi(n)
- i = 2
- pi = 3
- while i <= n
- term = 4.0 / (i * (i + 1) * (i + 2))
- if i % 4
- pi = pi + term
- else
- pi = pi - term
- end
- i = i + 2
- end
- return pi
-end
-
-print("pi =", cpi(100))
diff --git a/lib/libesp32/Berry/examples/exception.be b/lib/libesp32/Berry/examples/exception.be
deleted file mode 100644
index 3a3098dcefc5..000000000000
--- a/lib/libesp32/Berry/examples/exception.be
+++ /dev/null
@@ -1,12 +0,0 @@
-import debug
-
-def test_func()
- try
- compile('def +() end')()
- except .. as e, v
- print('catch execption:', str(e) + ' >>>\n ' + str(v))
- debug.traceback()
- end
-end
-
-test_func()
diff --git a/lib/libesp32/Berry/examples/fib_rec.be b/lib/libesp32/Berry/examples/fib_rec.be
deleted file mode 100644
index 31ed3817bfae..000000000000
--- a/lib/libesp32/Berry/examples/fib_rec.be
+++ /dev/null
@@ -1,12 +0,0 @@
-import time
-
-def fib(x)
- if x <= 2
- return 1
- end
- return fib(x - 1) + fib(x - 2)
-end
-
-c = time.clock()
-print("fib:", fib(38)) # minimum stack size: 78!!
-print("time:", time.clock() - c, 's')
diff --git a/lib/libesp32/Berry/examples/guess_number.be b/lib/libesp32/Berry/examples/guess_number.be
deleted file mode 100644
index 6cbd07e7c0db..000000000000
--- a/lib/libesp32/Berry/examples/guess_number.be
+++ /dev/null
@@ -1,26 +0,0 @@
-import time
-import math
-
-math.srand(time.time())
-res = math.rand() % 100
-max_test = 7
-test = -1
-idx = 1
-print('Guess a number between 0 and 99. You have', max_test, 'chances.')
-while test != res && idx <= max_test
- test = number(input(str(idx) + ': enter the number you guessed: '))
- if type(test) != 'int'
- print('This is not an integer. Continue!')
- continue
- elif test > res
- print('This number is too large.')
- elif test < res
- print('This number is too small.')
- end
- idx = idx + 1
-end
-if test == res
- print('You win!')
-else
- print('You failed, the correct answer is', res)
-end
diff --git a/lib/libesp32/Berry/examples/json.be b/lib/libesp32/Berry/examples/json.be
deleted file mode 100644
index d98dff8bb4f7..000000000000
--- a/lib/libesp32/Berry/examples/json.be
+++ /dev/null
@@ -1,4 +0,0 @@
-import json
-print(json.load('{"key": "value"}'))
-print(json.dump({'test key': nil}))
-print(json.dump({'key1': nil, 45: true}, 'format'))
diff --git a/lib/libesp32/Berry/examples/lambda.be b/lib/libesp32/Berry/examples/lambda.be
deleted file mode 100644
index 1d0b709bb2ee..000000000000
--- a/lib/libesp32/Berry/examples/lambda.be
+++ /dev/null
@@ -1,8 +0,0 @@
-# simple lambda example
-print((/a b c-> a * b + c)(2, 3, 4))
-
-# Y-Combinator and factorial functions
-Y = /f-> (/x-> f(/n-> x(x)(n)))(/x-> f(/n-> x(x)(n)))
-F = /f-> /x-> x ? f(x - 1) * x : 1
-fact = Y(F)
-print('fact(10) == ' .. fact(10))
diff --git a/lib/libesp32/Berry/examples/listdir.be b/lib/libesp32/Berry/examples/listdir.be
deleted file mode 100644
index 2dd880118fb7..000000000000
--- a/lib/libesp32/Berry/examples/listdir.be
+++ /dev/null
@@ -1,16 +0,0 @@
-import os
-
-def scandir(path)
- print('path: ' + path)
- for name : os.listdir(path)
- var fullname = os.path.join(path, name)
- if os.path.isfile(fullname)
- print('file: ' + fullname)
- else
- print('path: ' + fullname)
- scandir(fullname)
- end
- end
-end
-
-scandir('.')
diff --git a/lib/libesp32/Berry/examples/qsort.be b/lib/libesp32/Berry/examples/qsort.be
deleted file mode 100644
index b09b65672ee0..000000000000
--- a/lib/libesp32/Berry/examples/qsort.be
+++ /dev/null
@@ -1,42 +0,0 @@
-def qsort(data)
- # do once sort
- def once(left, right)
- var pivot = data[left] # use the 0th value as the pivot
- while left < right # check if sort is complete
- # put the value less than the pivot to the left
- while left < right && data[right] >= pivot
- right -= 1 # skip values greater than pivot
- end
- data[left] = data[right]
- # put the value greater than the pivot on the right
- while left < right && data[left] <= pivot
- left += 1 # skip values less than pivot
- end
- data[right] = data[left]
- end
- # now we have the index of the pivot, store it
- data[left] = pivot
- return left # return the index of the pivot
- end
- # recursive quick sort algorithm
- def _sort(left, right)
- if left < right # executed when the array is not empty
- var index = once(left, right) # get index of pivot for divide and conquer
- _sort(left, index - 1) # sort the data on the left
- _sort(index + 1, right) # sort the data on the right
- end
- end
- # start quick sort
- _sort(0, data.size() - 1)
- return data
-end
-
-import time, math
-math.srand(time.time()) # sse system time as a random seed
-data = []
-# put 20 random numbers into the array
-for i : 1 .. 20
- data.push(math.rand() % 100)
-end
-# sort and print
-print(qsort(data))
diff --git a/lib/libesp32/Berry/examples/repl.be b/lib/libesp32/Berry/examples/repl.be
deleted file mode 100644
index aac26b0a1b2f..000000000000
--- a/lib/libesp32/Berry/examples/repl.be
+++ /dev/null
@@ -1,61 +0,0 @@
-do
- def ismult(msg)
- import string
- return string.split(msg, -5)[1] == '\'EOS\''
- end
-
- def multline(src, msg)
- if !ismult(msg)
- print('syntax_error: ' + msg)
- return
- end
- while true
- try
- src += '\n' + input('>> ')
- return compile(src)
- except 'syntax_error' as e, m
- if !ismult(m)
- print('syntax_error: ' + m)
- return
- end
- end
- end
- end
-
- def parse()
- var fun, src = input('> ')
- try
- fun = compile('return (' + src + ')')
- except 'syntax_error' as e, m
- try
- fun = compile(src)
- except 'syntax_error' as e, m
- fun = multline(src, m)
- end
- end
- return fun
- end
-
- def run(fun)
- try
- var res = fun()
- if res print(res) end
- except .. as e, m
- import debug
- print(e .. ': ' .. m)
- debug.traceback()
- end
- end
-
- def repl()
- while true
- var fun = parse()
- if fun != nil
- run(fun)
- end
- end
- end
-
- print("Berry Berry REPL!")
- repl()
-end
diff --git a/lib/libesp32/Berry/examples/string.be b/lib/libesp32/Berry/examples/string.be
deleted file mode 100644
index 299834e21c2d..000000000000
--- a/lib/libesp32/Berry/examples/string.be
+++ /dev/null
@@ -1,32 +0,0 @@
-s = "This is a long string test. 0123456789 abcdefg ABCDEFG"
-print(s)
-
-a = .5
-print(a)
-
-import string as s
-
-print(s.hex(0x45678ABCD, 16))
-
-def bin(x, num)
- assert(type(x) == 'int', 'the type of \'x\' must be integer')
- # test the 'x' bits
- var bits = 1
- for i : 0 .. 62
- if x & (1 << 63 - i)
- bits = 64 - i
- break
- end
- end
- if type(num) == 'int' && num > 0 && num <= 64
- bits = bits < num ? num : bits
- end
- var result = ''
- bits -= 1
- for i : 0 .. bits
- result += x & (1 << (bits - i)) ? '1' : '0'
- end
- return result
-end
-
-print(bin(33))
diff --git a/lib/libesp32/Berry/examples/strmod.be b/lib/libesp32/Berry/examples/strmod.be
deleted file mode 100644
index 8660f5b4ec7d..000000000000
--- a/lib/libesp32/Berry/examples/strmod.be
+++ /dev/null
@@ -1,7 +0,0 @@
-import string
-
-print(string.format('%.3d', 12))
-print(string.format('%.3f', 12))
-print(string.format('%20.7f', 14.5))
-print(string.format('-- %-40s ---', 'this is a string format test'))
-print(string.format('-- %40s ---', 'this is a string format test'))
diff --git a/lib/libesp32/Berry/gen.sh b/lib/libesp32/Berry/gen.sh
deleted file mode 100755
index e248a977f1d9..000000000000
--- a/lib/libesp32/Berry/gen.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-#
-# generate all precompiled Berry structures from multiple modules
-#
-# Included in the Platformio build process with `pio-tools/gen-berry-structures.py
-#
-rm -Rf ./generate/be_*.h
-python3 tools/coc/coc -o generate src default ../berry_tasmota/src ../berry_mapping/src ../berry_int64/src ../../libesp32_lvgl/lv_binding_berry/src ../../libesp32_lvgl/lv_haspmota/src/solidify ../berry_matter/src/solidify ../berry_matter/src ../berry_animate/src/solidify ../berry_animate/src ../../libesp32_lvgl/lv_binding_berry/src/solidify ../../libesp32_lvgl/lv_binding_berry/generate -c default/berry_conf.h
diff --git a/lib/libesp32/Berry/library.json b/lib/libesp32/Berry/library.json
deleted file mode 100644
index e5b08a1de0d6..000000000000
--- a/lib/libesp32/Berry/library.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name":"Berry",
- "description":"Berry scripting language for Tasmota32",
- "keywords":"berry, script",
- "authors":
- {
- "name": "Guan Wenliang , ",
- "maintainer": true
- },
- "repository":
- {
- "type": "git",
- "url": "https://github.com/Skiars/berry"
- },
- "version": "7.0",
- "license": "MIT License",
- "frameworks": "arduino",
- "platforms": "espressif32",
- "build": {
- "includeDir": "generate",
- "srcFilter": [
- "+<*.c>",
- "+<../default/*.c>",
- "+<../default/*.cpp>",
- "+<../default/*.hpp>",
- "+<../generate/*.h>",
- "+<*.cpp>",
- "+<*.h>"
- ],
- "flags": [ "-I$PROJECT_DIR/tasmota", "-DCOMPILE_BERRY_LIB", "-includeesp_idf_version.h" ]
- }
-}
diff --git a/lib/libesp32/Berry/src/be_api.c b/lib/libesp32/Berry/src/be_api.c
deleted file mode 100644
index 6ccb65c5accb..000000000000
--- a/lib/libesp32/Berry/src/be_api.c
+++ /dev/null
@@ -1,1179 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_vm.h"
-#include "be_func.h"
-#include "be_class.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_var.h"
-#include "be_list.h"
-#include "be_map.h"
-#include "be_parser.h"
-#include "be_debug.h"
-#include "be_exec.h"
-#include "be_strlib.h"
-#include "be_module.h"
-#include "be_gc.h"
-#include
-
-#define retreg(vm) ((vm)->cf->func)
-
-struct solidfuncinfo {
- const char *name;
- bclosure *function;
-};
-
-static void class_init(bvm *vm, bclass *c, const bnfuncinfo *lib)
-{
- if (lib) {
- while (lib->name) {
- bstring *s = be_newstr(vm, lib->name);
- if (lib->function) { /* method */
- be_class_native_method_bind(vm, c, s, lib->function);
- } else {
- be_class_member_bind(vm, c, s, btrue); /* member */
- }
- ++lib;
- }
- if (lib->function == (bntvfunc)BE_CLOSURE) {
- /* next section is closures */
- struct solidfuncinfo *slib = (struct solidfuncinfo*)++lib;
- while (slib->name) {
- if (slib->function) { /* method */
- bstring *s = be_newstr(vm, slib->name);
- be_class_closure_method_bind(vm, c, s, slib->function);
- }
- ++slib;
- }
- }
- be_map_compact(vm, c->members); /* clear space */
- }
-}
-
-static bclass* class_auto_make(bvm *vm, bstring *name, const bnfuncinfo *lib)
-{
- bvalue key, *res;
- var_setobj(&key, BE_COMPTR, (void*)lib);
- if (vm->ntvclass == NULL) {
- vm->ntvclass = be_map_new(vm);
- }
- res = be_map_find(vm, vm->ntvclass, &key);
- if (res == NULL || !var_isclass(res)) {
- bclass *c;
- /* insert class to native class table */
- res = be_map_insert(vm, vm->ntvclass, &key, NULL);
- var_setnil(res); /* must be initialized to ensure correct GC */
- c = be_newclass(vm, name, NULL);
- var_setclass(res, c);
- class_init(vm, c, lib); /* bind members */
- return c;
- }
- return var_toobj(res);
-}
-
-BERRY_API void be_regfunc(bvm *vm, const char *name, bntvfunc f)
-{
- bvalue *var;
- bstring *s = be_newstr(vm, name);
-#if !BE_USE_PRECOMPILED_OBJECT
- int idx = be_builtin_find(vm, s);
- be_assert(idx == -1);
- if (idx == -1) { /* new function */
- idx = be_builtin_new(vm, s);
-#else
- int idx = be_global_find(vm, s);
- be_assert(idx < be_builtin_count(vm));
- if (idx < be_builtin_count(vm)) { /* new function */
- idx = be_global_new(vm, s);
-#endif
- var = be_global_var(vm, idx);
- var_setntvfunc(var, f);
- } /* error case, do nothing */
-}
-
-BERRY_API void be_regclass(bvm *vm, const char *name, const bnfuncinfo *lib)
-{
- bvalue *var;
- bstring *s = be_newstr(vm, name);
-#if !BE_USE_PRECOMPILED_OBJECT
- int idx = be_builtin_find(vm, s);
- be_assert(idx == -1);
- if (idx == -1) { /* new function */
- idx = be_builtin_new(vm, s);
-#else
- int idx = be_global_find(vm, s);
- be_assert(idx < be_builtin_count(vm));
- if (idx < be_builtin_count(vm)) { /* new function */
- idx = be_global_new(vm, s);
-#endif
- var = be_global_var(vm, idx);
- var_setclass(var, class_auto_make(vm, s, lib));
- } /* error case, do nothing */
-}
-
-BERRY_API int be_top(bvm *vm)
-{
- return cast_int(vm->top - vm->reg);
-}
-
-BERRY_API void be_pop(bvm *vm, int n)
-{
- be_assert(n <= vm->top - vm->reg);
- be_stackpop(vm, n);
-}
-
-BERRY_API int be_absindex(bvm *vm, int index)
-{
- if (index > 0) {
- return index;
- }
- be_assert(vm->reg <= vm->top + index);
- return cast_int(vm->top + index - vm->reg + 1);
-}
-
-BERRY_API bbool be_isnil(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isnil(v);
-}
-
-BERRY_API bbool be_isbool(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isbool(v);
-}
-
-BERRY_API bbool be_isint(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isint(v);
-}
-
-BERRY_API bbool be_isreal(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isreal(v);
-}
-
-BERRY_API bbool be_isnumber(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isnumber(v);
-}
-
-BERRY_API bbool be_isstring(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isstr(v);
-}
-
-BERRY_API bbool be_isclosure(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isclosure(v);
-}
-
-BERRY_API bbool be_isntvclos(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isntvclos(v);
-}
-
-BERRY_API bbool be_isfunction(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isfunction(v);
-}
-
-BERRY_API bbool be_isproto(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isproto(v);
-}
-
-BERRY_API bbool be_isclass(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isclass(v);
-}
-
-BERRY_API bbool be_isinstance(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_isinstance(v);
-}
-
-static bbool be_isinstanceofbuiltin(bvm *vm, int rel_index, const char *classname)
-{
- bbool ret = bfalse;
- int index = be_absindex(vm, rel_index);
- if (be_isinstance(vm, index)) {
- be_getbuiltin(vm, classname);
- if (be_isderived(vm, index)) {
- ret = btrue;
- }
- be_pop(vm, 1);
- }
- return ret;
-}
-
-BERRY_API bbool be_ismapinstance(bvm *vm, int index)
-{
- return be_isinstanceofbuiltin(vm, index, "map");
-}
-
-BERRY_API bbool be_islistinstance(bvm *vm, int index)
-{
- return be_isinstanceofbuiltin(vm, index, "list");
-}
-
-
-BERRY_API bbool be_ismodule(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_ismodule(v);
-}
-
-BERRY_API bbool be_islist(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_islist(v);
-}
-
-BERRY_API bbool be_ismap(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_ismap(v);
-}
-
-BERRY_API bbool be_iscomptr(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_istype(v, BE_COMPTR);
-}
-
-BERRY_API bbool be_iscomobj(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_istype(v, BE_COMOBJ);
-}
-
-BERRY_API bint be_toint(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_toint(v);
-}
-
-BERRY_API breal be_toreal(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_isreal(v)) {
- return var_toreal(v);
- }
- if (var_isint(v)) {
- return cast(breal, var_toint(v));
- }
- return cast(breal, 0.0);
-}
-
-BERRY_API int be_toindex(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return var_toidx(v);
-}
-
-BERRY_API bbool be_tobool(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return be_value2bool(vm, v);
-}
-
-BERRY_API const char* be_tostring(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (!var_isstr(v)) {
- be_val2str(vm, index);
- v = be_indexof(vm, index);
- }
- return str(var_tostr(v));
-}
-
-BERRY_API void* be_tocomptr(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_istype(v, BE_COMPTR)) {
- return var_toobj(v);
- }
- if (var_istype(v, BE_COMOBJ)) {
- bcommomobj *obj = var_toobj(v);
- return obj->data;
- }
- return NULL;
-}
-
-BERRY_API void be_moveto(bvm *vm, int from, int to)
-{
- bvalue *src = be_indexof(vm, from);
- bvalue *dst = be_indexof(vm, to);
- var_setval(dst, src);
-}
-
-BERRY_API void be_pushnil(bvm *vm)
-{
- bvalue *reg = be_incrtop(vm);
- var_setnil(reg);
-}
-
-BERRY_API void be_pushbool(bvm *vm, int b)
-{
- bvalue *reg = be_incrtop(vm);
- var_setbool(reg, b != bfalse);
-}
-
-BERRY_API void be_pushint(bvm *vm, bint i)
-{
- bvalue *reg = be_incrtop(vm);
- var_setint(reg, i);
-}
-
-BERRY_API void be_pushreal(bvm *vm, breal r)
-{
- bvalue *reg = be_incrtop(vm);
- var_setreal(reg, r);
-}
-
-BERRY_API void be_pushstring(bvm *vm, const char *str)
-{
- /* to create a string and then push the top registor,
- * otherwise the GC may crash due to uninitialized values.
- **/
- bstring *s = be_newstr(vm, str);
- bvalue *reg = be_incrtop(vm);
- be_assert(reg < vm->stacktop);
- var_setstr(reg, s);
-}
-
-BERRY_API void be_pushnstring(bvm *vm, const char *str, size_t n)
-{
- /* to create a string and then push the top registor,
- * otherwise the GC may crash due to uninitialized values.
- **/
- bstring *s = be_newstrn(vm, str, n);
- bvalue *reg = be_incrtop(vm);
- var_setstr(reg, s);
-}
-
-BERRY_API const char* be_pushfstring(bvm *vm, const char *format, ...)
-{
- const char* s;
- va_list arg_ptr;
- va_start(arg_ptr, format);
- s = be_pushvfstr(vm, format, arg_ptr);
- va_end(arg_ptr);
- return s;
-}
-
-BERRY_API void* be_pushbuffer(bvm *vm, size_t size)
-{
- bstring *s = be_newlongstr(vm, NULL, size);
- bvalue *reg = be_incrtop(vm);
- var_setstr(reg, s);
- return (void*)str(s);
-}
-
-BERRY_API void be_pushvalue(bvm *vm, int index)
-{
- bvalue *reg = vm->top;
- var_setval(reg, be_indexof(vm, index));
- be_incrtop(vm);
-}
-
-BERRY_API void be_pushclosure(bvm *vm, void *cl)
-{
- bvalue *reg = be_incrtop(vm);
- bclosure * closure = (bclosure*) cl;
- var_setclosure(reg, closure);
-}
-
-BERRY_API void be_pushntvclosure(bvm *vm, bntvfunc f, int nupvals)
-{
- /* to create a native closure and then push the top registor,
- * otherwise the GC may crash due to uninitialized values.
- **/
- bntvclos *cl = be_newntvclosure(vm, f, nupvals);
- bvalue *top = be_incrtop(vm);
- var_setntvclos(top, cl);
-}
-
-BERRY_API void be_pushntvfunction(bvm *vm, bntvfunc f)
-{
- bvalue *top = be_incrtop(vm);
- var_setntvfunc(top, f);
-}
-
-BERRY_API void be_pushclass(bvm *vm, const char *name, const bnfuncinfo *lib)
-{
- bclass *c;
- bstring *s = be_newstr(vm, name);
- bvalue *dst = be_incrtop(vm);
- var_setstr(dst, s);
- c = class_auto_make(vm, s, lib);
- var_setclass(vm->top - 1, c);
-}
-
-BERRY_API void be_pushntvclass(bvm *vm, const struct bclass * c)
-{
- bvalue *top = be_incrtop(vm);
- var_setclass(top, (bclass *) c);
-}
-
-BERRY_API void be_pushcomptr(bvm *vm, void *ptr)
-{
- bvalue *top = be_incrtop(vm);
- var_setobj(top, BE_COMPTR, ptr);
-}
-
-BERRY_API void be_remove(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- bvalue *top = --vm->top;
- while (v < top) {
- *v = v[1];
- ++v;
- }
-}
-
-BERRY_API void be_strconcat(bvm *vm, int index)
-{
- bstring *s;
- bvalue *dst = be_indexof(vm, index);
- bvalue *src = be_indexof(vm, -1);
- be_assert(var_isstr(src) && var_isstr(dst));
- s = be_strcat(vm, var_tostr(dst), var_tostr(src));
- var_setstr(dst, s);
-}
-
-BERRY_API bbool be_setsuper(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- bvalue *top = be_indexof(vm, -1);
- if (var_isclass(v) && var_isclass(top)) {
- bclass *c = var_toobj(v);
- if (!gc_isconst(c)) {
- bclass *super = var_toobj(top);
- be_class_setsuper(c, super);
- return btrue;
- }
- }
- return bfalse;
-}
-
-BERRY_API void be_getsuper(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- bvalue *top = be_incrtop(vm);
- if (var_isclass(v)) {
- bclass *c = var_toobj(v);
- c = be_class_super(c);
- if (c) {
- var_setclass(top, c);
- return;
- }
- } else if (var_isinstance(v)) {
- binstance *o = var_toobj(v);
- o = be_instance_super(o);
- if (o) {
- var_setinstance(top, o);
- return;
- }
- }
- var_setnil(top);
-}
-
-static bclass* _getclass(bvalue *v)
-{
- if (var_isinstance(v)) {
- binstance *ins = var_toobj(v);
- return be_instance_class(ins);
- }
- return var_isclass(v) ? var_toobj(v) : NULL;
-}
-
-BERRY_API bbool be_isderived(bvm *vm, int index)
-{
- bclass *sup = _getclass(be_indexof(vm, -1));
- if (sup) {
- bclass *c = _getclass(be_indexof(vm, index));
- while (c && c != sup)
- c = be_class_super(c);
- return c != NULL;
- }
- return bfalse;
-}
-
-BERRY_API const char *be_typename(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- return be_vtype2str(v);
-}
-
-BERRY_API const char *be_classname(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_isclass(v)) {
- bclass *c = var_toobj(v);
- return str(be_class_name(c));
- }
- if (var_isinstance(v)) {
- binstance *i = var_toobj(v);
- return str(be_instance_name(i));
- }
- return NULL;
-}
-
-BERRY_API bbool be_classof(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_isinstance(v)) {
- bvalue *top = be_incrtop(vm);
- binstance *ins = var_toobj(v);
- var_setclass(top, be_instance_class(ins));
- return btrue;
- }
- return bfalse;
-}
-
-BERRY_API int be_strlen(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_isstr(v)) {
- return str_len(var_tostr(v));
- }
- return 0;
-}
-
-BERRY_API void be_newlist(bvm *vm)
-{
- blist *list = be_list_new(vm);
- bvalue *top = be_incrtop(vm);
- var_setlist(top, list);
-}
-
-BERRY_API void be_newmap(bvm *vm)
-{
- bmap *map = be_map_new(vm);
- bvalue *top = be_incrtop(vm);
- var_setobj(top, BE_MAP, map);
-}
-
-BERRY_API void be_newmodule(bvm *vm)
-{
- bmodule *mod = be_module_new(vm);
- bvalue *top = be_incrtop(vm);
- var_setobj(top, BE_MODULE, mod);
-}
-
-BERRY_API void be_newobject(bvm *vm, const char *name)
-{
- be_getbuiltin(vm, name);
- be_call(vm, 0);
- be_getmember(vm, -1, ".p");
-}
-
-BERRY_API bbool be_setname(bvm *vm, int index, const char *name)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_ismodule(v)) {
- bmodule *module = var_toobj(v);
- return be_module_setname(module, be_newstr(vm, name));
- }
- return bfalse;
-}
-
-BERRY_API bbool be_getglobal(bvm *vm, const char *name)
-{
- int idx = be_global_find(vm, be_newstr(vm, name));
- bvalue *top = be_incrtop(vm);
- if (idx > -1) {
- *top = *be_global_var(vm, idx);
- return btrue;
- }
- var_setnil(top);
- return bfalse;
-}
-
-BERRY_API void be_setglobal(bvm *vm, const char *name)
-{
- int idx;
- bstring *s = be_newstr(vm, name);
- bvalue *v = be_incrtop(vm);
- var_setstr(v, s);
- idx = be_global_new(vm, s);
- v = be_global_var(vm, idx);
- *v = *be_indexof(vm, -2);
- be_stackpop(vm, 1);
-}
-
-BERRY_API bbool be_getbuiltin(bvm *vm, const char *name)
-{
- int idx = be_builtin_find(vm, be_newstr(vm, name));
- bvalue *top = be_incrtop(vm);
- if (idx > -1) {
- *top = *be_global_var(vm, idx);
- return btrue;
- }
- var_setnil(top);
- return bfalse;
-}
-
-BERRY_API bbool be_setmember(bvm *vm, int index, const char *k)
-{
- bvalue *o = be_indexof(vm, index);
- bvalue *v = be_indexof(vm, -1);
- if (var_isinstance(o)) {
- bstring *key = be_newstr(vm, k);
- binstance *obj = var_toobj(o);
- return be_instance_setmember(vm, obj, key, v);
- } else if (var_ismodule(o)) {
- bstring *key = be_newstr(vm, k);
- bmodule *mod = var_toobj(o);
- return be_module_setmember(vm, mod, key, v);
- } else if (var_isclass(o)) {
- bstring *key = be_newstr(vm, k);
- bclass *cl = var_toobj(o);
- return be_class_setmember(vm, cl, key, v);
- }
- return bfalse;
-}
-
-BERRY_API bbool be_copy(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- bvalue *top = be_incrtop(vm);
- if (var_type(v) == BE_LIST) {
- blist *list = be_list_copy(vm, var_toobj(v));
- var_setlist(top, list)
- return btrue;
- }
- var_setnil(top);
- return bfalse;
-}
-
-/* `onlyins` limits the search to instance, and discards module. Makes sure getmethod does not return anything for module. */
-/* may return BE_NONE */
-static int ins_member(bvm *vm, int index, const char *k, bbool onlyins)
-{
- int type = BE_NIL;
- bvalue *o = be_indexof(vm, index);
- bvalue *top = be_incrtop(vm);
- var_setnil(top);
- if (var_isinstance(o)) {
- binstance *obj = var_toobj(o);
- type = be_instance_member(vm, obj, be_newstr(vm, k), top);
- } else if (var_isclass(o) && !onlyins) {
- bclass *cl = var_toobj(o);
- type = be_class_member(vm, cl, be_newstr(vm, k), top);
- } else if (var_ismodule(o) && !onlyins) {
- bmodule *module = var_toobj(o);
- type = be_module_attr(vm, module, be_newstr(vm, k), top);
- }
- return type;
-}
-
-BERRY_API bbool be_getmember(bvm *vm, int index, const char *k)
-{
- return ins_member(vm, index, k, bfalse) != BE_NONE;
-}
-
-BERRY_API bbool be_getmethod(bvm *vm, int index, const char *k)
-{
- return basetype(ins_member(vm, index, k, btrue)) == BE_FUNCTION;
-}
-
-BERRY_API bbool be_getindex(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- bvalue *k = be_indexof(vm, -1);
- bvalue *dst = be_incrtop(vm);
- switch (var_type(o)) {
- case BE_LIST:
- if (var_isint(k)) {
- blist *list = cast(blist*, var_toobj(o));
- int idx = var_toidx(k);
- bvalue *src = be_list_index(list, idx);
- if (src) {
- var_setval(dst, src);
- return btrue;
- }
- }
- break;
- case BE_MAP:
- if (!var_isnil(k)) {
- bmap *map = cast(bmap*, var_toobj(o));
- bvalue *src = be_map_find(vm, map, k);
- if (src) {
- var_setval(dst, src);
- return btrue;
- }
- }
- break;
- default:
- break;
- }
- var_setnil(dst);
- return bfalse;
-}
-
-static bvalue* list_setindex(blist *list, bvalue *key)
-{
- int idx = var_toidx(key);
- if (idx < 0) {
- idx = list->count + idx;
- }
- if (idx < 0 || idx >= list->count) {
- return NULL;
- }
- return be_list_at(list, idx);
-}
-
-BERRY_API bbool be_setindex(bvm *vm, int index)
-{
- bvalue *dst = NULL;
- bvalue *o = be_indexof(vm, index);
- bvalue *k = be_indexof(vm, -2);
- bvalue *v = be_indexof(vm, -1);
- switch (var_type(o)) {
- case BE_LIST:
- if (var_isint(k)) {
- blist *list = var_toobj(o);
- dst = list_setindex(list, k);
- }
- break;
- case BE_MAP:
- if (!var_isnil(k)) {
- bmap *map = var_toobj(o);
- dst = be_map_insert(vm, map, k, NULL);
- }
- break;
- default:
- break;
- }
- if (dst) {
- var_setval(dst, v);
- return btrue;
- }
- return bfalse;
-}
-
-BERRY_API void be_getupval(bvm *vm, int index, int pos)
-{
- bvalue *f = index ? be_indexof(vm, index) : vm->cf->func;
- bvalue *uv, *top = be_incrtop(vm);
- be_assert(var_istype(f, BE_NTVCLOS));
- if (var_istype(f, BE_NTVCLOS)) {
- bntvclos *nf = var_toobj(f);
- be_assert(pos >= 0 && pos < nf->nupvals);
- uv = be_ntvclos_upval(nf, pos)->value;
- var_setval(top, uv);
- } else {
- var_setnil(top);
- }
-}
-
-BERRY_API bbool be_setupval(bvm *vm, int index, int pos)
-{
- bvalue *f = index ? be_indexof(vm, index) : vm->cf->func;
- bvalue *uv, *v = be_indexof(vm, -1);
- be_assert(var_istype(f, BE_NTVCLOS));
- if (var_istype(f, BE_NTVCLOS)) {
- bntvclos *nf = var_toobj(f);
- be_assert(pos >= 0 && pos < nf->nupvals);
- uv = be_ntvclos_upval(nf, pos)->value;
- var_setval(uv, v);
- return btrue;
- }
- return bfalse;
-}
-
-BERRY_API int be_data_size(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_islist(v)) {
- blist *list = var_toobj(v);
- return be_list_count(list);
- } else if (var_ismap(v)) {
- bmap *map = cast(bmap*, var_toobj(v));
- return be_map_count(map);
- }
- return -1;
-}
-
-BERRY_API void be_data_push(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- bvalue *v = be_indexof(vm, -1);
- if (var_islist(o)) {
- blist *list = var_toobj(o);
- be_list_push(vm, list, v);
- }
-}
-
-BERRY_API bbool be_data_insert(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- bvalue *k = be_indexof(vm, -2);
- bvalue *v = be_indexof(vm, -1);
- switch (var_type(o)) {
- case BE_MAP:
- if (!var_isnil(k)) {
- bmap *map = cast(bmap*, var_toobj(o));
- bvalue *dst = be_map_find(vm, map, k);
- if (dst == NULL) {
- return be_map_insert(vm, map, k, v) != NULL;
- }
- }
- break;
- case BE_LIST:
- if (var_isint(k)) {
- blist *list = cast(blist*, var_toobj(o));
- return be_list_insert(vm, list, var_toidx(k), v) != NULL;
- }
- break;
- default:
- break;
- }
- return bfalse;
-}
-
-BERRY_API bbool be_data_remove(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- bvalue *k = be_indexof(vm, -1);
- switch (var_type(o)) {
- case BE_MAP:
- if (!var_isnil(k)) {
- bmap *map = cast(bmap*, var_toobj(o));
- return be_map_remove(vm, map, k);
- }
- break;
- case BE_LIST:
- if (var_isint(k)) {
- blist *list = cast(blist*, var_toobj(o));
- return be_list_remove(vm, list, var_toidx(k));
- }
- break;
- default:
- break;
- }
- return bfalse;
-}
-
-BERRY_API bbool be_data_merge(bvm *vm, int index)
-{
- bvalue *a = be_indexof(vm, index);
- bvalue *b = be_indexof(vm, -1);
- if (var_islist(a) && var_islist(b)) {
- blist *dst = var_toobj(a), *src = var_toobj(b);
- be_list_merge(vm, dst, src);
- return btrue;
- }
- return bfalse;
-}
-
-BERRY_API void be_data_resize(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- bvalue *v = be_indexof(vm, -1);
- if (var_islist(o)) {
- blist *list = var_toobj(o);
- if (var_isint(v)) {
- be_list_resize(vm, list, var_toidx(v));
- }
- }
-}
-
-BERRY_API void be_data_reverse(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_type(v) == BE_LIST) {
- be_list_reverse(var_toobj(v));
- }
-}
-
-BERRY_API bbool be_pushiter(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- if (var_ismap(v)) {
- bvalue *iter = be_incrtop(vm);
- var_setobj(iter, BE_COMPTR, NULL);
- return btrue;
- } else if (var_islist(v)) {
- blist *list = var_toobj(v);
- bvalue *iter = be_incrtop(vm);
- var_setobj(iter, BE_COMPTR, be_list_data(list) - 1);
- return btrue;
- }
- return bfalse;
-}
-
-static int list_next(bvm *vm)
-{
- bvalue *iter = be_indexof(vm, -1);
- bvalue *next, *dst = be_incrtop(vm);
- next = cast(bvalue*, var_toobj(iter)) + 1;
- var_setobj(iter, BE_COMPTR, next);
- var_setval(dst, next);
- return 1;
-}
-
-static bbool list_hasnext(bvm *vm, bvalue *v)
-{
- bvalue *next;
- bvalue *iter = be_indexof(vm, -1);
- blist *obj = var_toobj(v);
- next = cast(bvalue*, var_toobj(iter)) + 1;
- return next >= be_list_data(obj) && next < be_list_end(obj);
-}
-
-static int map_next(bvm *vm, bvalue *v)
-{
- bmapiter iter;
- bmapnode *entry;
- bvalue *dst = vm->top;
- bvalue *itvar = be_indexof(vm, -1);
- iter = var_toobj(itvar);
- entry = be_map_next(var_toobj(v), &iter);
- var_setobj(itvar, BE_COMPTR, iter);
- if (entry) {
- be_map_key2value(dst, entry);
- var_setval(dst + 1, &entry->value);
- vm->top += 2;
- return 2;
- }
- return 0;
-}
-
-static bbool map_hasnext(bvm *vm, bvalue *v)
-{
- bvalue *node = be_indexof(vm, -1);
- bmapiter iter = var_toobj(node);
- return be_map_next(var_toobj(v), &iter) != NULL;
-}
-
-BERRY_API int be_iter_next(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- if (var_islist(o)) {
- return list_next(vm);
- } else if (var_ismap(o)) {
- return map_next(vm, o);
- }
- return 0;
-}
-
-BERRY_API bbool be_iter_hasnext(bvm *vm, int index)
-{
- bvalue *o = be_indexof(vm, index);
- if (var_islist(o)) {
- return list_hasnext(vm, o);
- } else if (var_ismap(o)) {
- return map_hasnext(vm, o);
- }
- return bfalse;
-}
-
-BERRY_API bbool be_refcontains(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- binstance **ref = be_stack_base(&vm->refstack);
- binstance **top = be_stack_top(&vm->refstack);
- binstance *ins = var_toobj(v);
- be_assert(var_isinstance(v));
- if (ref) {
- while (ref <= top && *ref != ins) {
- ++ref;
- }
- return ref <= top;
- }
- return bfalse;
-}
-
-BERRY_API void be_refpush(bvm *vm, int index)
-{
- bvalue *v = be_indexof(vm, index);
- binstance *ins = var_toobj(v);
- be_assert(var_isinstance(v));
- be_stack_push(vm, &vm->refstack, &ins);
-}
-
-BERRY_API void be_refpop(bvm *vm)
-{
- be_stack_pop(&vm->refstack);
- if (be_stack_isempty(&vm->refstack)) {
- be_vector_release(vm, &vm->refstack);
- }
-}
-
-BERRY_API int be_returnvalue(bvm *vm)
-{
- bvalue *src = vm->top - 1;
- bvalue *ret = retreg(vm);
- var_setval(ret, src);
- return 0;
-}
-
-BERRY_API int be_returnnilvalue(bvm *vm)
-{
- bvalue *ret = retreg(vm);
- var_setnil(ret);
- return 0;
-}
-
-BERRY_API void be_call(bvm *vm, int argc)
-{
- bvalue *fval = vm->top - argc - 1;
- be_dofunc(vm, fval, argc);
-}
-
-BERRY_API int be_pcall(bvm *vm, int argc)
-{
- bvalue *f = vm->top - argc - 1;
- return be_protectedcall(vm, f, argc);
-}
-
-#ifdef __GNUC__
-__attribute__((noreturn))
-#endif
-BERRY_API void be_raise(bvm *vm, const char *except, const char *msg)
-{
- be_pushstring(vm, except);
- if (msg) {
- be_pushstring(vm, msg);
- } else {
- be_pushnil(vm);
- }
- be_pop(vm, 2);
- be_save_stacktrace(vm);
- be_throw(vm, BE_EXCEPTION);
-#ifdef __GNUC__
- __builtin_unreachable();
-#endif
-}
-
-BERRY_API void be_stop_iteration(bvm *vm)
-{
- be_raise(vm, "stop_iteration", NULL);
-}
-
-BERRY_API int be_getexcept(bvm *vm, int code)
-{
- if (code == BE_EXCEPTION) {
- if (be_isstring(vm, -2)) {
- const char *except = be_tostring(vm, -2);
- if (!strcmp(except, "syntax_error")) {
- return BE_SYNTAX_ERROR;
- }
- if (!strcmp(except, "io_error")) {
- return BE_IO_ERROR;
- }
- }
- return BE_EXEC_ERROR;
- }
- return code;
-}
-
-static int _dvfunc(bvm *vm, bbool esc)
-{
- const char* s = esc ?
- be_toescape(vm, 1, 'x') : be_tostring(vm, 1);
- be_writestring(s);
- be_return_nil(vm);
-}
-
-static int _dumpesc(bvm *vm)
-{
- return _dvfunc(vm, btrue);
-}
-
-static int _dumpdir(bvm *vm)
-{
- return _dvfunc(vm, bfalse);
-}
-
-static int dump_value(bvm *vm, int index, bbool esc)
-{
- int res, top = be_top(vm) + 1;
- index = be_absindex(vm, index);
- be_pushntvfunction(vm, esc ? _dumpesc : _dumpdir);
- be_pushvalue(vm, index);
- res = be_pcall(vm, 1); /* using index to store result */
- be_remove(vm, top); /* remove '_dumpvalue' function */
- be_remove(vm, top); /* remove the value */
- if (res == BE_EXCEPTION) {
- be_dumpexcept(vm);
- }
- return res;
-}
-
-BERRY_API void be_dumpvalue(bvm *vm, int index)
-{
- if (dump_value(vm, index, btrue) == BE_OK) {
- be_writenewline();
- }
-}
-
-BERRY_API void be_dumpexcept(bvm *vm)
-{
- do {
- /* print exception value */
- if (dump_value(vm, -2, bfalse)) break;
- be_writestring(": ");
- /* print exception argument */
- if (dump_value(vm, -1, bfalse)) break;
- be_writenewline();
- /* print stack traceback */
- be_tracestack(vm);
- } while (0);
- be_pop(vm, 2); /* pop the exception value & argument */
-}
-
-BERRY_API bbool be_iseq(bvm *vm)
-{
- be_assert(vm->reg + 2 <= vm->top);
- return be_vm_iseq(vm, vm->top - 2, vm->top - 1);
-}
-
-BERRY_API bbool be_isneq(bvm *vm)
-{
- be_assert(vm->reg + 2 <= vm->top);
- return be_vm_isneq(vm, vm->top - 2, vm->top - 1);
-}
-
-BERRY_API bbool be_islt(bvm *vm)
-{
- be_assert(vm->reg + 2 <= vm->top);
- return be_vm_islt(vm, vm->top - 2, vm->top - 1);
-}
-
-BERRY_API bbool be_isle(bvm *vm)
-{
- be_assert(vm->reg + 2 <= vm->top);
- return be_vm_isle(vm, vm->top - 2, vm->top - 1);
-}
-
-BERRY_API bbool be_isgt(bvm *vm)
-{
- be_assert(vm->reg + 2 <= vm->top);
- return be_vm_isgt(vm, vm->top - 2, vm->top - 1);
-}
-
-BERRY_API bbool be_isge(bvm *vm)
-{
- be_assert(vm->reg + 2 <= vm->top);
- return be_vm_isge(vm, vm->top - 2, vm->top - 1);
-}
diff --git a/lib/libesp32/Berry/src/be_baselib.c b/lib/libesp32/Berry/src/be_baselib.c
deleted file mode 100644
index 3cc2e9f2c5f7..000000000000
--- a/lib/libesp32/Berry/src/be_baselib.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_vm.h"
-#include "be_exec.h"
-#include "be_mem.h"
-#include "be_gc.h"
-#include "be_class.h"
-#include "be_vector.h"
-#include "be_string.h"
-#include "be_map.h"
-#include "be_strlib.h"
-#include
-
-#define READLINE_STEP 100
-
-int be_baselib_assert(bvm *vm)
-{
- int argc = be_top(vm);
- /* assertion fails when there is no argument
- * or the first argument is nil or false. */
- if (!argc || !be_tobool(vm, 1)) {
- const char *msg = "assert failed!";
- if (argc >= 2 && be_isstring(vm, 2)) {
- msg = be_tostring(vm, 2);
- }
- be_raise(vm, "assert_failed", msg);
- }
- be_return_nil(vm);
-}
-
-int be_baselib_print(bvm *vm)
-{
- int i, argc = be_top(vm);
- for (i = 1; i <= argc; ++i) {
- const char *str = be_tostring(vm, i);
- size_t len = be_strlen(vm, i);
- be_writebuffer(str, len);
- if (i < argc) {
- be_writebuffer(" ", 1);
- }
- }
- be_writenewline();
- be_return_nil(vm);
-}
-
-static int m_readline(bvm *vm)
-{
- size_t pos = 0, size = READLINE_STEP;
- char *buffer = be_malloc(vm, size);
- char *res = be_readstring(buffer, (int)size);
- while (res) {
- pos += strlen(buffer + pos) - 1;
- if (!pos || buffer[pos] == '\n') {
- buffer[pos] = '\0'; /* trim \n */
- break;
- }
- buffer = be_realloc(vm, buffer, size, size + READLINE_STEP);
- res = be_readstring(buffer + pos + 1, READLINE_STEP);
- size += READLINE_STEP;
- }
- be_pushstring(vm, buffer);
- be_free(vm, buffer, size);
- be_return(vm);
-}
-
-int be_baselib_input(bvm *vm)
-{
- if (be_top(vm) && be_isstring(vm, 1)) { /* echo prompt */
- be_writestring(be_tostring(vm, 1));
- }
- return m_readline(vm);
-}
-
-/* Look in the current class and all super classes for a method corresponding to a specific closure pointer */
-static bclass *find_class_closure(bclass *cl, bclosure *needle)
-{
- while (cl) {
- bmapnode *node; /* iterate on members of the class */
- bmap *members = be_class_members(cl);
- if (members) { /* only iterate if there are members */
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(members, &iter)) != NULL) {
- if (var_primetype(&node->value) == BE_CLOSURE) { /* only native functions are considered */
- bclosure *clos_iter = var_toobj(&node->value); /* retrieve the method's closure */
- if (clos_iter == needle) {
- /* we found the closure, we now know its class */
- return cl;
- }
- }
- }
- }
- cl = be_class_super(cl); /* move to super class */
- }
- return NULL; /* not found */
-}
-
-static bbool obj2int(bvm *vm, bvalue *var, bint *val)
-{
- binstance *obj = var_toobj(var);
- bstring *toint = str_literal(vm, "toint");
- /* get operator method */
- // TODO what if `tobool` is static
- int type = be_instance_member(vm, obj, toint, vm->top);
- if (type != BE_NONE && type != BE_NIL) {
- vm->top[1] = *var; /* move self to argv[0] */
- be_dofunc(vm, vm->top, 1); /* call method 'tobool' */
- /* check the return value */
- if (var_isint(vm->top)) {
- *val = var_toint(vm->top);
- return btrue;
- }
- }
- return bfalse;
-}
-
-int be_baselib_super(bvm *vm)
-{
- int argc = be_top(vm);
-
- /* if no argument, or arg 1 is nil, return nil */
- if (argc == 0 || be_isnil(vm, 1)) {
- be_return_nil(vm);
- }
-
- /* if arg 1 is a class, simply return super */
- if (be_isclass(vm, 1)) {
- be_getsuper(vm, 1);
- be_return(vm);
- }
-
- /* arg 1 is an instance */
- if (be_isinstance(vm, 1)) {
- binstance *o = var_toobj(be_indexof(vm, 1));
- bclass *target_class = NULL; /* the minimal class expected, or any super class */
- bclass *base_class = NULL; /* current class of the caller, if any */
-
- /* if arg 2 is present, it must be a class */
- if (argc >= 2) {
- if (be_isclass(vm, 2)) {
- target_class = var_toobj(be_indexof(vm, 2));
- } else if (be_isnil(vm, 2)) {
- // ignore, revert to standard super() behavior if second arg is explicit nil
- } else {
- be_raise(vm, "type_error", "leveled super() requires 'instance' and 'class' arguments");
- }
- }
-
- /* now the more complex part, if arg 1 is an instance */
- /* if instance is the sole argument, try to find if it comes from a method of a class and set 'base_class' accordinly */
- /* later it will be equivalent to passing this class as second argument */
- if (argc == 1) {
- /* we look in the callstack for the caller's closure */
- int size = be_stack_count(&vm->callstack);
- if (size >= 2) { /* need at least 2 stackframes: current (for super() native) and caller (the one we are interested in) */
- bcallframe *caller = be_vector_at(&vm->callstack, size - 2); /* get the callframe of caller */
- bvalue *func = caller->func; /* function object of caller */
- if (var_primetype(func) == BE_CLOSURE) { /* only useful if the caller is a Berry closure (i.e. not native) */
- bclosure *clos_ctx = var_toobj(func); /* this is the closure we look for in the class chain */
- base_class = find_class_closure(o->_class, clos_ctx); /* iterate on current and super classes to find where the closure belongs */
- }
- }
- }
-
- if (base_class || target_class) {
- if (base_class) {
- target_class = base_class->super;
- if (!target_class) be_return_nil(vm); /* fast exit if top class */
- }
- /* leveled super, i.e. fix the parenthood class level */
- if (o) {
- o = be_instance_super(o); /* always skip the current class and move to super */
- }
- while (o) {
- bclass *c = be_instance_class(o);
- if (c == target_class) break; /* found */
- o = be_instance_super(o);
- }
- bvalue *top = be_incrtop(vm);
- if (o) {
- var_setinstance(top, o); /* return the instance with the specified parent class */
- } else {
- var_setnil(top); /* not found, return nil */
- }
- be_return(vm);
- } else {
- be_getsuper(vm, 1);
- be_return(vm);
- }
- }
-
- /* fall through, return nil if we don't know what to do */
- be_return_nil(vm);
-}
-
-int be_baselib_type(bvm *vm)
-{
- if (be_top(vm)) {
- be_pushstring(vm, be_typename(vm, 1));
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-int be_baselib_classname(bvm *vm)
-{
- if (be_top(vm)) {
- const char *t = be_classname(vm, 1);
- if (t) {
- be_pushstring(vm, t);
- be_return(vm);
- }
- }
- be_return_nil(vm);
-}
-
-int be_baselib_classof(bvm *vm)
-{
- if (be_top(vm) && be_classof(vm, 1)) {
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-int be_baselib_number(bvm *vm)
-{
- if (be_top(vm)) {
- if (be_isstring(vm, 1)) {
- be_str2num(vm, be_tostring(vm, 1));
- be_return(vm);
- } else if (be_isnumber(vm, 1)) {
- be_pushvalue(vm, 1);
- be_return(vm);
- }
- }
- be_return_nil(vm);
-}
-
-int be_baselib_int(bvm *vm)
-{
- if (be_top(vm)) {
- if (be_isstring(vm, 1)) {
- const char *s = be_tostring(vm, 1);
- be_pushint(vm, be_str2int(s, NULL));
- } else if (be_isreal(vm, 1)) {
- be_pushint(vm, (bint)be_toreal(vm, 1));
- } else if (be_isint(vm, 1)) {
- be_pushvalue(vm, 1);
- } else if (be_isbool(vm, 1)) {
- be_pushint(vm, be_tobool(vm, 1) ? 1 : 0);
- } else if (be_iscomptr(vm, 1)) {
- intptr_t p = (intptr_t) be_tocomptr(vm, 1);
- be_pushint(vm, (int) p);
- } else if (be_isinstance(vm, 1)) {
- /* try to call `toint` method */
- bvalue *v = be_indexof(vm, 1);
- bint val;
- if (obj2int(vm, v, &val)) {
- be_pushint(vm, val);
- } else {
- be_return_nil(vm);
- }
- } else {
- be_return_nil(vm);
- }
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-int be_baselib_real(bvm *vm)
-{
- if (be_top(vm)) {
- if (be_isstring(vm, 1)) {
- const char *s = be_tostring(vm, 1);
- be_pushreal(vm, be_str2real(s, NULL));
- } else if (be_isint(vm, 1)) {
- be_pushreal(vm, (breal)be_toint(vm, 1));
- } else if (be_isreal(vm, 1)) {
- be_pushvalue(vm, 1);
- } else {
- be_return_nil(vm);
- }
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int check_method(bvm *vm, const char *attr)
-{
- return be_top(vm) &&
- be_isinstance(vm, 1) && be_getmethod(vm, 1, attr);
-}
-
-int be_baselib_iterator(bvm *vm)
-{
- if (be_top(vm) && be_isfunction(vm, 1)) {
- be_return(vm); /* return the argument[0]::function */
- }
- if (check_method(vm, "iter")) {
- be_pushvalue(vm, 1);
- be_call(vm, 1);
- be_pop(vm, 1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-/* call a function with variable number of arguments */
-/* first argument is a callable object (function, closure, native function, native closure) */
-/* then all subsequent arguments are pushed except the last one */
-/* If the last argument is a 'list', then all elements are pushed as arguments */
-/* otherwise the last argument is pushed as well */
-static int l_call(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1 && be_isfunction(vm, 1)) {
- size_t arg_count = top - 1; /* we have at least 'top - 1' arguments */
- /* test if last argument is a list */
-
- if (top > 1 && be_isinstance(vm, top) && be_getmember(vm, top, ".p") && be_islist(vm, top + 1)) {
- int32_t list_size = be_data_size(vm, top + 1);
-
- if (list_size > 0) {
- be_stack_require(vm, list_size + 3); /* make sure we don't overflow the stack */
- for (int i = 0; i < list_size; i++) {
- be_pushnil(vm);
- }
- be_moveto(vm, top + 1, top + 1 + list_size);
- be_moveto(vm, top, top + list_size);
-
- be_pushiter(vm, -1);
- while (be_iter_hasnext(vm, -2)) {
- be_iter_next(vm, -2);
- be_moveto(vm, -1, top);
- top++;
- be_pop(vm, 1);
- }
- be_pop(vm, 1); /* remove iterator */
- }
- be_pop(vm, 2);
- arg_count = arg_count - 1 + list_size;
- }
- /* actual call */
- be_call(vm, arg_count);
- /* remove args */
- be_pop(vm, arg_count);
- /* return value */
-
- be_return(vm);
- }
- be_raise(vm, "value_error", "first argument must be a function");
- be_return_nil(vm);
-}
-
-int be_baselib_str(bvm *vm)
-{
- if (be_top(vm)) {
- be_tostring(vm, 1);
- } else {
- be_pushstring(vm, "");
- }
- be_return(vm);
-}
-
-static int l_bool(bvm *vm)
-{
- if (be_top(vm)) {
- be_pushbool(vm, be_tobool(vm, 1));
- } else {
- be_pushbool(vm, bfalse);
- }
- be_return(vm);
-}
-
-
-int be_baselib_size(bvm *vm)
-{
- if (be_top(vm) && be_isstring(vm, 1)) {
- be_pushint(vm, be_strlen(vm, 1));
- be_return(vm);
- }
- if (check_method(vm, "size")) {
- be_pushvalue(vm, 1);
- be_call(vm, 1);
- be_pop(vm, 1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-int be_baselib_module(bvm *vm)
-{
- int argc = be_top(vm);
- be_newmodule(vm);
- if (argc > 0 && be_isstring(vm, 1)) {
- be_setname(vm, -1, be_tostring(vm, 1));
- }
- be_return(vm);
-}
-
-#if BE_USE_SCRIPT_COMPILER
-static int raise_compile_error(bvm *vm)
-{
- be_pop(vm, 2); /* pop the exception value and message */
- be_throw(vm, BE_EXCEPTION);
- return 0;
-}
-
-static int m_compile_str(bvm *vm)
-{
- int len = be_strlen(vm, 1);
- const char *src = be_tostring(vm, 1);
- int res = be_loadbuffer(vm, "string", src, len);
- if (res == BE_OK) {
- be_return(vm);
- }
- return raise_compile_error(vm);
-}
-
-static int m_compile_file(bvm *vm)
-{
- const char *fname = be_tostring(vm, 1);
- int res = be_loadfile(vm, fname);
- if (res == BE_OK) {
- be_return(vm);
- } else if (res == BE_IO_ERROR) {
- be_pushstring(vm, "io_error");
- be_pushvalue(vm, -2);
- }
- return raise_compile_error(vm);
-}
-#endif
-
-int be_baselib_compile(bvm *vm)
-{
-#if BE_USE_SCRIPT_COMPILER
- if (be_top(vm) && be_isstring(vm, 1)) {
- if (be_top(vm) >= 2 && be_isstring(vm, 2)) {
- const char *s = be_tostring(vm, 2);
- if (!strcmp(s, "string")) {
- return m_compile_str(vm);
- }
- if (!strcmp(s, "file")) {
- return m_compile_file(vm);
- }
- } else {
- return m_compile_str(vm);
- }
- }
-#endif
- be_return_nil(vm);
-}
-
-static int _issubv(bvm *vm, bbool (*filter)(bvm*, int))
-{
- bbool status = bfalse;
- if (be_top(vm) >= 2 && filter(vm, 1)) {
- be_pushvalue(vm, 2);
- status = be_isderived(vm, 1);
- }
- be_pushbool(vm, status);
- be_return(vm);
-}
-
-int be_baselib_issubclass(bvm *vm)
-{
- return _issubv(vm, be_isclass);
-}
-
-int be_baselib_isinstance(bvm *vm)
-{
- return _issubv(vm, be_isinstance);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-void be_load_baselib(bvm *vm)
-{
- be_regfunc(vm, "assert", be_baselib_assert);
- be_regfunc(vm, "print", be_baselib_print);
- be_regfunc(vm, "input", be_baselib_input);
- be_regfunc(vm, "super", be_baselib_super);
- be_regfunc(vm, "type", be_baselib_type);
- be_regfunc(vm, "classname", be_baselib_classname);
- be_regfunc(vm, "classof", be_baselib_classof);
- be_regfunc(vm, "number", be_baselib_number);
- be_regfunc(vm, "str", be_baselib_str);
- be_regfunc(vm, "int", be_baselib_int);
- be_regfunc(vm, "real", be_baselib_real);
- be_regfunc(vm, "module", be_baselib_module);
- be_regfunc(vm, "size", be_baselib_size);
- be_regfunc(vm, "compile", be_baselib_compile);
- be_regfunc(vm, "issubclass", be_baselib_issubclass);
- be_regfunc(vm, "isinstance", be_baselib_isinstance);
- be_regfunc(vm, "__iterator__", be_baselib_iterator);
-}
-
-/* call must be added later to respect order of builtins */
-void be_load_baselib_next(bvm *vm)
-{
- be_regfunc(vm, "call", l_call);
- be_regfunc(vm, "bool", l_bool);
- be_regfunc(vm, "format", be_str_format);
-}
-#else
-extern const bclass be_class_list;
-extern const bclass be_class_map;
-extern const bclass be_class_range;
-extern const bclass be_class_bytes;
-extern int be_nfunc_open(bvm *vm);
-/* @const_object_info_begin
-vartab m_builtin (scope: local) {
- assert, func(be_baselib_assert)
- print, func(be_baselib_print)
- input, func(be_baselib_input)
- super, func(be_baselib_super)
- type, func(be_baselib_type)
- classname, func(be_baselib_classname)
- classof, func(be_baselib_classof)
- number, func(be_baselib_number)
- str, func(be_baselib_str)
- int, func(be_baselib_int)
- real, func(be_baselib_real)
- module, func(be_baselib_module)
- size, func(be_baselib_size)
- compile, func(be_baselib_compile)
- issubclass, func(be_baselib_issubclass)
- isinstance, func(be_baselib_isinstance)
- __iterator__, func(be_baselib_iterator)
- open, func(be_nfunc_open)
- list, class(be_class_list)
- map, class(be_class_map)
- range, class(be_class_range)
- bytes, class(be_class_bytes)
- call, func(l_call)
- bool, func(l_bool)
- format, func(be_str_format)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_m_builtin.h"
-#include "be_var.h"
-
-void be_load_baselib(bvm *vm)
-{
- be_const_builtin_set(vm, &m_builtin_map, &m_builtin_vector);
-}
-#endif
diff --git a/lib/libesp32/Berry/src/be_bytecode.c b/lib/libesp32/Berry/src/be_bytecode.c
deleted file mode 100644
index 79ed503bd95d..000000000000
--- a/lib/libesp32/Berry/src/be_bytecode.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_bytecode.h"
-#include "be_decoder.h"
-#include "be_vector.h"
-#include "be_string.h"
-#include "be_class.h"
-#include "be_func.h"
-#include "be_exec.h"
-#include "be_list.h"
-#include "be_map.h"
-#include "be_mem.h"
-#include "be_sys.h"
-#include "be_var.h"
-#include "be_vm.h"
-#include
-
-#define MAGIC_NUMBER1 0xBE
-#define MAGIC_NUMBER2 0xCD
-#define MAGIC_NUMBER3 0xFE
-#define BYTECODE_VERSION 4
-
-#define USE_64BIT_INT (BE_INTGER_TYPE == 2 \
- || BE_INTGER_TYPE == 1 && LONG_MAX == 9223372036854775807L)
-
-#if !BE_USE_SCRIPT_COMPILER && BE_USE_BYTECODE_SAVER
-#error bytecode generation dependent compiler (require BE_USE_SCRIPT_COMPILER != 0)
-#endif
-
-#if BE_USE_BYTECODE_SAVER || BE_USE_BYTECODE_LOADER
-static void bytecode_error(bvm *vm, const char *msg)
-{
- be_raise(vm, "io_error", msg);
-}
-
-static uint8_t vm_sizeinfo(void)
-{
- uint8_t res = sizeof(bint) == 8;
- res |= (sizeof(breal) == 8) << 1;
- return res;
-}
-#endif
-
-#if BE_USE_BYTECODE_SAVER
-static void save_proto(bvm *vm, void *fp, bproto *proto);
-
-static void save_byte(void *fp, uint8_t value)
-{
- be_fwrite(fp, &value, 1);
-}
-
-static void save_word(void *fp, uint16_t value)
-{
- uint8_t buffer[2];
- buffer[0] = value & 0xff;
- buffer[1] = value >> 8;
- be_fwrite(fp, buffer, sizeof(buffer));
-}
-
-static void save_long(void *fp, uint32_t value)
-{
- uint8_t buffer[4];
- buffer[0] = value & 0xff;
- buffer[1] = (value >> 8) & 0xff;
- buffer[2] = (value >> 16) & 0xff;
- buffer[3] = (value >> 24) & 0xff;
- be_fwrite(fp, buffer, sizeof(buffer));
-}
-
-static void save_header(void *fp)
-{
- uint8_t buffer[8] = { 0 };
- buffer[0] = MAGIC_NUMBER1;
- buffer[1] = MAGIC_NUMBER2;
- buffer[2] = MAGIC_NUMBER3;
- buffer[3] = BYTECODE_VERSION;
- buffer[4] = vm_sizeinfo();
- be_fwrite(fp, buffer, sizeof(buffer));
-}
-
-static void save_int(void *fp, bint i)
-{
-#if USE_64BIT_INT
- save_long(fp, i & 0xffffffff);
- save_long(fp, (i >> 32) & 0xffffffff);
-#else
- save_long(fp, (uint32_t)i);
-#endif
-}
-
-static void save_real(void *fp, breal r)
-{
-#if BE_USE_SINGLE_FLOAT
- union { breal r; uint32_t i; } u;
- u.r = r;
- save_long(fp, u.i);
-#else
- union { breal r; uint64_t i; } u;
- u.r = r;
- save_long(fp, u.i & 0xffffffff);
- save_long(fp, (u.i >> 32) & 0xffffffff);
-#endif
-}
-
-static void save_string(void *fp, bstring *s)
-{
- if (s) {
- uint16_t length = (uint16_t)str_len(s);
- const char *data = str(s);
- save_word(fp, length);
- be_fwrite(fp, data, length);
- } else {
- save_word(fp, 0);
- }
-}
-
-static bstring** save_members(bvm *vm, void *fp, bclass *c, int nvar)
-{
- bmapnode *node;
- bstring **vars = NULL;
- bmap *members = c->members;
- bmapiter iter = be_map_iter();
- if (nvar) {
- /* allocate the member-variable name cache */
- vars = be_malloc(vm, sizeof(bstring *) * nvar);
- }
- while ((node = be_map_next(members, &iter)) != NULL) {
- be_assert(var_isstr(&node->key));
- if (var_isindex(&node->value)) { /* cache member name */
- if (vars == NULL) {
- return NULL; /* should never be executed */
- }
- vars[var_toidx(&node->value)] = var_tostr(&node->key);
- } else { /* save method's name and function */
- bproto *proto;
- bvalue *value = &node->value;
- be_assert(var_isclosure(value) || var_isproto(value) || var_isnil(value));
- save_string(fp, var_tostr(&node->key)); /* save method name */
- if (var_isproto(value)) { /* the method is a prototype */
- proto = var_toobj(value);
- save_proto(vm, fp, proto); /* only save prototype */
- } else if (var_isclosure(value)) { /* the method is a closure */
- proto = cast(bclosure *, var_toobj(value))->proto;
- save_proto(vm, fp, proto); /* only save prototype */
- } else if (var_isnil(value)) {
- /* this is a static member (nil default) */
- save_word(fp, 0); /* store a zero byte that will be seen as a zero length method name which is invalid */
- } else {
- be_raise(vm, "internal_error", "unsupported member in class");
- return NULL; /* should never be executed */
- }
- }
- }
- return vars;
-}
-
-static void save_class(bvm *vm, void *fp, bclass *c)
-{
- bstring **vars;
- int i, count = c->members ? be_map_count(c->members) : 0;
- int nvar = c->nvar - be_class_closure_count(c);
- save_string(fp, c->name);
- save_long(fp, nvar); /* member variables count */
- save_long(fp, count - nvar); /* method count */
- if (count > 0) {
- vars = save_members(vm, fp, c, nvar);
- if (vars != NULL) {
- for (i = 0; i < nvar; ++i) {
- save_string(fp, vars[i]);
- }
- be_free(vm, vars, sizeof(bstring *) * nvar);
- }
- }
-}
-
-static void save_value(bvm *vm, void *fp, bvalue *v)
-{
- save_byte(fp, (uint8_t)var_primetype(v)); /* type */
- switch (var_primetype(v)) {
- case BE_INT: save_int(fp, var_toint(v)); break;
- case BE_REAL: save_real(fp, var_toreal(v)); break;
- case BE_STRING: save_string(fp, var_tostr(v)); break;
- case BE_CLASS: save_class(vm, fp, var_toobj(v)); break;
- default: break;
- }
-}
-
-static void save_bytecode(bvm *vm, void *fp, bproto *proto)
-{
- int forbid_gbl = comp_is_named_gbl(vm);
- binstruction *code = proto->code, *end;
- save_long(fp, (uint32_t)proto->codesize);
- for (end = code + proto->codesize; code < end; ++code) {
- save_long(fp, (uint32_t)*code);
- if (forbid_gbl) { /* we are saving only named globals, so make sure we don't save OP_GETGBL or OP_SETGBL */
- if ((uint32_t)*code == OP_GETGBL || (uint32_t)*code == OP_SETGBL) {
- be_raise(vm, "internal_error", "GETGBL/SETGBL found when saving with named globals");
- }
- }
- }
-}
-
-static void save_constants(bvm *vm, void *fp, bproto *proto)
-{
- bvalue *v = proto->ktab, *end;
- save_long(fp, proto->nconst); /* constants count */
- for (end = v + proto->nconst; v < end; ++v) {
- if ((v == proto->ktab) && (proto->varg & BE_VA_STATICMETHOD) && (v->type == BE_CLASS)) {
- /* implicit `_class` parameter, output nil */
- bvalue v_nil;
- v_nil.v.i = 0;
- v_nil.type = BE_NIL;
- save_value(vm, fp, &v_nil);
- } else {
- save_value(vm, fp, v);
- }
- }
-}
-
-static void save_proto_table(bvm *vm, void *fp, bproto *proto)
-{
- bproto **p = proto->ptab, **end;
- save_long(fp, proto->nproto); /* proto count */
- if (p) {
- for (end = p + proto->nproto; p < end; ++p) {
- save_proto(vm, fp, *p);
- }
- }
-}
-
-static void save_upvals(void *fp, bproto *proto)
-{
- bupvaldesc *uv = proto->upvals, *end;
- save_byte(fp, proto->nupvals); /* upvals count */
- if (uv) {
- for (end = uv + proto->nupvals; uv < end; ++uv) {
- save_byte(fp, uv->instack);
- save_byte(fp, uv->idx);
- }
- }
-}
-
-static void save_proto(bvm *vm, void *fp, bproto *proto)
-{
- if (proto) {
- save_string(fp, proto->name); /* name */
-#if BE_DEBUG_SOURCE_FILE
- save_string(fp, proto->source); /* source */
-#else
- save_string(fp, NULL); /* source */
-#endif
- save_byte(fp, proto->argc); /* argc */
- save_byte(fp, proto->nstack); /* nstack */
- save_byte(fp, proto->varg); /* varg */
- save_byte(fp, 0x00); /* reserved */
- save_bytecode(vm, fp, proto); /* bytecode */
- save_constants(vm, fp, proto); /* constant */
- save_proto_table(vm, fp, proto); /* proto table */
- save_upvals(fp, proto); /* upvals description table */
- }
-}
-
-static void save_globals(bvm *vm, void *fp)
-{
- bmapnode *node;
- bmapiter iter = be_map_iter();
- bmap *map = vm->gbldesc.global.vtab;
- int i, count = be_global_count(vm);
- bstring **list = be_malloc(vm, sizeof(bstring*) * count);
- while ((node = be_map_next(map, &iter)) != NULL) {
- if (var_isstr(&node->key)) {
- int idx = var_toidx(&node->value);
- be_assert(idx < count);
- list[idx] = var_tostr(&node->key);
- }
- }
- for (i = 0; i < count; ++i) {
- save_string(fp, list[i]);
- }
- be_free(vm, list, sizeof(bstring*) * count);
-}
-
-static void save_global_info(bvm *vm, void *fp)
-{
- save_long(fp, be_builtin_count(vm));
- if (comp_is_named_gbl(vm)) {
- /* named globals only so no need to save current globals */
- save_long(fp, 0);
- } else {
- save_long(fp, be_global_count(vm));
- save_globals(vm, fp);
- }
-}
-
-void be_bytecode_save_to_fs(bvm *vm, void *fp, bproto *proto)
-{
- save_header(fp);
- save_global_info(vm, fp);
- save_proto(vm, fp, proto);
-}
-
-void be_bytecode_save(bvm *vm, const char *filename, bproto *proto)
-{
- void *fp = be_fopen(filename, "wb");
- if (fp == NULL) {
- bytecode_error(vm, be_pushfstring(vm,
- "can not open file '%s'.", filename));
- } else {
- be_bytecode_save_to_fs(vm, fp, proto);
- be_fclose(fp);
- }
-}
-#endif /* BE_USE_BYTECODE_SAVER */
-
-#if BE_USE_BYTECODE_LOADER
-static bbool load_proto(bvm *vm, void *fp, bproto **proto, int info, int version);
-
-static uint8_t load_byte(void *fp)
-{
- uint8_t buffer[1];
- if (be_fread(fp, buffer, sizeof(buffer)) == sizeof(buffer)) {
- return buffer[0];
- }
- return 0;
-}
-
-static uint16_t load_word(void *fp)
-{
- uint8_t buffer[2];
- if (be_fread(fp, buffer, sizeof(buffer)) == sizeof(buffer)) {
- return ((uint16_t)buffer[1] << 8) | buffer[0];
- }
- return 0;
-}
-
-static uint32_t load_long(void *fp)
-{
- uint8_t buffer[4];
- if (be_fread(fp, buffer, sizeof(buffer)) == sizeof(buffer)) {
- return ((uint32_t)buffer[3] << 24)
- | ((uint32_t)buffer[2] << 16)
- | ((uint32_t)buffer[1] << 8)
- | buffer[0];
- }
- return 0;
-}
-
-static int load_head(void *fp)
-{
- int res;
- uint8_t buffer[8] = { 0 };
- be_fread(fp, buffer, sizeof(buffer));
- res = buffer[0] == MAGIC_NUMBER1 &&
- buffer[1] == MAGIC_NUMBER2 &&
- buffer[2] == MAGIC_NUMBER3 &&
- buffer[4] == vm_sizeinfo();
- if (res) {
- return buffer[3];
- } else {
- return 0;
- }
-}
-
-bbool be_bytecode_check(const char *path)
-{
- void *fp = be_fopen(path, "r");
- if (fp) {
- uint8_t buffer[3], rb;
- rb = (uint8_t)be_fread(fp, buffer, 3);
- be_fclose(fp);
- /* check magic number */
- return rb == 3 &&
- buffer[0] == MAGIC_NUMBER1 &&
- buffer[1] == MAGIC_NUMBER2 &&
- buffer[2] == MAGIC_NUMBER3;
- }
- return bfalse;
-}
-
-static bint load_int(void *fp)
-{
-#if USE_64BIT_INT
- bint i;
- i = load_long(fp);
- i |= (bint)load_long(fp) << 32;
- return i;
-#else
- return load_long(fp);
-#endif
-}
-
-static breal load_real(void *fp)
-{
-#if BE_USE_SINGLE_FLOAT
- union { breal r; uint32_t i; } u;
- u.i = load_long(fp);
- return u.r;
-#else
- union {
- breal r;
- uint64_t i;
- } u;
- u.i = load_long(fp);
- u.i |= (uint64_t)load_long(fp) << 32;
- return u.r;
-#endif
-}
-
-static bstring* load_string(bvm *vm, void *fp)
-{
- uint16_t len = load_word(fp);
- if (len > 0) {
- bstring *str;
- char *buf = be_malloc(vm, len);
- be_fread(fp, buf, len);
- str = be_newstrn(vm, buf, len);
- be_free(vm, buf, len);
- return str;
- }
- return str_literal(vm, "");
-}
-
-static bstring* cache_string(bvm *vm, void *fp)
-{
- bstring *str = load_string(vm, fp);
- var_setstr(vm->top, str);
- be_incrtop(vm);
- return str;
-}
-
-static void load_class(bvm *vm, void *fp, bvalue *v, int version)
-{
- int nvar, count;
- bclass *c = be_newclass(vm, NULL, NULL);
- var_setclass(v, c);
- c->name = load_string(vm, fp);
- nvar = load_long(fp);
- count = load_long(fp);
- while (count--) { /* load method table */
- bvalue *value;
- bstring *name = cache_string(vm, fp);
- value = vm->top;
- var_setproto(value, NULL);
- be_incrtop(vm);
- if (load_proto(vm, fp, (bproto**)&var_toobj(value), -3, version)) {
- /* actual method */
- bproto *proto = (bproto*)var_toobj(value);
- bbool is_method = proto->varg & BE_VA_METHOD;
- if (!is_method) {
- if ((proto->nconst > 0) && (proto->ktab->type == BE_NIL)) {
- /* The first argument is nil so we replace with the class as implicit '_class' */
- proto->ktab->type = BE_CLASS;
- proto->ktab->v.p = c;
- }
- }
- be_class_method_bind(vm, c, name, var_toobj(value), !is_method);
- } else {
- /* no proto, static member set to nil */
- be_class_member_bind(vm, c, name, bfalse);
- }
- be_stackpop(vm, 2); /* pop the cached string and proto */
- }
- for (count = 0; count < nvar; ++count) { /* load member-variable table */
- bstring *name = cache_string(vm, fp);
- be_class_member_bind(vm, c, name, btrue);
- be_stackpop(vm, 1); /* pop the cached string */
- }
-}
-
-static void load_value(bvm *vm, void *fp, bvalue *v, int version)
-{
- switch (load_byte(fp)) {
- case BE_INT: var_setint(v, load_int(fp)); break;
- case BE_REAL: var_setreal(v, load_real(fp)); break;
- case BE_STRING: var_setstr(v, load_string(vm, fp)); break;
- case BE_CLASS: load_class(vm, fp, v, version); break;
- default: break;
- }
-}
-
-static void load_bytecode(bvm *vm, void *fp, bproto *proto, int info)
-{
- int size = (int)load_long(fp);
- if (size) {
- binstruction *code, *end;
- int bcnt = be_builtin_count(vm);
- blist *list = var_toobj(be_indexof(vm, info));
- be_assert(be_islist(vm, info));
- proto->code = be_malloc(vm, sizeof(binstruction) * size);
- proto->codesize = size;
- code = proto->code;
- for (end = code + size; code < end; ++code) {
- binstruction ins = (binstruction)load_long(fp);
- binstruction op = IGET_OP(ins);
- /* fix global variable index */
- if (op == OP_GETGBL || op == OP_SETGBL) {
- int idx = IGET_Bx(ins);
- if (idx >= bcnt) { /* does not fix builtin index */
- bvalue *name = be_list_at(list, idx - bcnt);
- idx = be_global_find(vm, var_tostr(name));
- ins = (ins & ~IBx_MASK) | ISET_Bx(idx);
- }
- }
- *code = ins;
- }
- }
-}
-
-static void load_constant(bvm *vm, void *fp, bproto *proto, int version)
-{
- int size = (int)load_long(fp); /* nconst */
- if (size) {
- bvalue *end, *v = be_malloc(vm, sizeof(bvalue) * size);
- memset(v, 0, sizeof(bvalue) * size);
- proto->ktab = v;
- proto->nconst = size;
- for (end = v + size; v < end; ++v) {
- load_value(vm, fp, v, version);
- }
- }
-}
-
-static void load_proto_table(bvm *vm, void *fp, bproto *proto, int info, int version)
-{
- int size = (int)load_long(fp); /* proto count */
- if (size) {
- bproto **p = be_malloc(vm, sizeof(bproto *) * size);
- memset(p, 0, sizeof(bproto *) * size);
- proto->ptab = p;
- proto->nproto = size;
- while (size--) {
- load_proto(vm, fp, p++, info, version);
- }
- }
-}
-
-static void load_upvals(bvm *vm, void *fp, bproto *proto)
-{
- int size = (int)load_byte(fp);
- if (size) {
- bupvaldesc *uv, *end;
- proto->upvals = be_malloc(vm, sizeof(bupvaldesc) * size);
- proto->nupvals = (bbyte)size;
- uv = proto->upvals;
- for (end = uv + size; uv < end; ++uv) {
- uv->instack = load_byte(fp);
- uv->idx = load_byte(fp);
- }
- }
-}
-
-static bbool load_proto(bvm *vm, void *fp, bproto **proto, int info, int version)
-{
- /* first load the name */
- /* if empty, it's a static member so don't allocate an actual proto */
- bstring *name = load_string(vm, fp);
- if (str_len(name)) {
- *proto = be_newproto(vm);
- (*proto)->name = name;
-#if BE_DEBUG_SOURCE_FILE
- (*proto)->source = load_string(vm, fp);
-#else
- load_string(vm, fp); /* discard name */
-#endif
- (*proto)->argc = load_byte(fp);
- (*proto)->nstack = load_byte(fp);
- if (version > 1) {
- (*proto)->varg = load_byte(fp);
- load_byte(fp); /* discard reserved byte */
- }
- load_bytecode(vm, fp, *proto, info);
- load_constant(vm, fp, *proto, version);
- load_proto_table(vm, fp, *proto, info, version);
- load_upvals(vm, fp, *proto);
- return btrue;
- }
- return bfalse; /* no proto read */
-}
-
-void load_global_info(bvm *vm, void *fp)
-{
- int i;
- int bcnt = (int)load_long(fp); /* builtin count */
- int gcnt = (int)load_long(fp); /* global count */
- if (bcnt > be_builtin_count(vm)) {
- bytecode_error(vm, be_pushfstring(vm,
- "inconsistent number of builtin objects."));
- }
- be_newlist(vm);
- for (i = 0; i < gcnt; ++i) {
- bstring *name = cache_string(vm, fp);
- be_global_new(vm, name);
- be_data_push(vm, -2); /* push the variable name to list */
- be_stackpop(vm, 1); /* pop the cached string */
- }
- be_global_release_space(vm);
-}
-
-bclosure* be_bytecode_load_from_fs(bvm *vm, void *fp)
-{
- int version = load_head(fp);
- if (version == BYTECODE_VERSION) {
- bclosure *cl = be_newclosure(vm, 0);
- var_setclosure(vm->top, cl);
- be_stackpush(vm);
- load_global_info(vm, fp);
- load_proto(vm, fp, &cl->proto, -1, version);
- be_stackpop(vm, 2); /* pop the closure and list */
- be_fclose(fp);
- return cl;
- }
- bytecode_error(vm, be_pushfstring(vm,
- "invalid bytecode version."));
- return NULL;
-}
-
-bclosure* be_bytecode_load(bvm *vm, const char *filename)
-{
- void *fp = be_fopen(filename, "rb");
- if (fp == NULL) {
- bytecode_error(vm, be_pushfstring(vm,
- "can not open file '%s'.", filename));
- } else {
- return be_bytecode_load_from_fs(vm, fp);
- }
- return NULL;
-}
-
-#endif /* BE_USE_BYTECODE_LOADER */
diff --git a/lib/libesp32/Berry/src/be_bytecode.h b/lib/libesp32/Berry/src/be_bytecode.h
deleted file mode 100644
index 4e1d54a3b58c..000000000000
--- a/lib/libesp32/Berry/src/be_bytecode.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef __BE_BYTECODE_H
-#define __BE_BYTECODE_H
-
-#include "be_object.h"
-
-void be_bytecode_save(bvm *vm, const char *filename, bproto *proto);
-void be_bytecode_save_to_fs(bvm *vm, void *fp, bproto *proto);
-bclosure* be_bytecode_load(bvm *vm, const char *filename);
-bclosure* be_bytecode_load_from_fs(bvm *vm, void *fp);
-bbool be_bytecode_check(const char *path);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_byteslib.c b/lib/libesp32/Berry/src/be_byteslib.c
deleted file mode 100644
index 460de413e6eb..000000000000
--- a/lib/libesp32/Berry/src/be_byteslib.c
+++ /dev/null
@@ -1,1907 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang - Stephan Hadinger
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_string.h"
-#include "be_strlib.h"
-#include "be_list.h"
-#include "be_func.h"
-#include "be_exec.h"
-#include "be_vm.h"
-#include "be_mem.h"
-#include "be_constobj.h"
-#include
-#include
-#include "be_byteslib.h"
-
-/********************************************************************
-** Base64 lib from https://github.com/Densaugeo/base64_arduino
-**
-********************************************************************/
-
-/* binary_to_base64:
- * Description:
- * Converts a single byte from a binary value to the corresponding base64 character
- * Parameters:
- * v - Byte to convert
- * Returns:
- * ascii code of base64 character. If byte is >= 64, then there is not corresponding base64 character
- * and 255 is returned
- */
-static unsigned char binary_to_base64(unsigned char v);
-
-/* base64_to_binary:
- * Description:
- * Converts a single byte from a base64 character to the corresponding binary value
- * Parameters:
- * c - Base64 character (as ascii code)
- * Returns:
- * 6-bit binary value
- */
-static unsigned char base64_to_binary(unsigned char c);
-
-/* encode_base64_length:
- * Description:
- * Calculates length of base64 string needed for a given number of binary bytes
- * Parameters:
- * input_length - Amount of binary data in bytes
- * Returns:
- * Number of base64 characters needed to encode input_length bytes of binary data
- */
-static unsigned int encode_base64_length(unsigned int input_length);
-
-/* decode_base64_length:
- * Description:
- * Calculates number of bytes of binary data in a base64 string
- * Parameters:
- * input - Base64-encoded null-terminated string
- * Returns:
- * Number of bytes of binary data in input
- */
-static unsigned int decode_base64_length(unsigned char input[]);
-
-/* encode_base64:
- * Description:
- * Converts an array of bytes to a base64 null-terminated string
- * Parameters:
- * input - Pointer to input data
- * input_length - Number of bytes to read from input pointer
- * output - Pointer to output string. Null terminator will be added automatically
- * Returns:
- * Length of encoded string in bytes (not including null terminator)
- */
-static unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[]);
-
-/* decode_base64:
- * Description:
- * Converts a base64 null-terminated string to an array of bytes
- * Parameters:
- * input - Pointer to input string
- * output - Pointer to output array
- * Returns:
- * Number of bytes in the decoded binary
- */
-static unsigned int decode_base64(unsigned char input[], unsigned char output[]);
-
-static unsigned char binary_to_base64(unsigned char v) {
- // Capital letters - 'A' is ascii 65 and base64 0
- if(v < 26) return v + 'A';
-
- // Lowercase letters - 'a' is ascii 97 and base64 26
- if(v < 52) return v + 71;
-
- // Digits - '0' is ascii 48 and base64 52
- if(v < 62) return v - 4;
-
- // '+' is ascii 43 and base64 62
- if(v == 62) return '+';
-
- // '/' is ascii 47 and base64 63
- if(v == 63) return '/';
-
- return 64;
-}
-
-static unsigned char base64_to_binary(unsigned char c) {
- // Capital letters - 'A' is ascii 65 and base64 0
- if('A' <= c && c <= 'Z') return c - 'A';
-
- // Lowercase letters - 'a' is ascii 97 and base64 26
- if('a' <= c && c <= 'z') return c - 71;
-
- // Digits - '0' is ascii 48 and base64 52
- if('0' <= c && c <= '9') return c + 4;
-
- // '+' is ascii 43 and base64 62
- if(c == '+') return 62;
-
- // '/' is ascii 47 and base64 63
- if(c == '/') return 63;
-
- return 255;
-}
-
-static unsigned int encode_base64_length(unsigned int input_length) {
- return (input_length + 2)/3*4;
-}
-
-static unsigned int decode_base64_length(unsigned char input[]) {
- unsigned char *start = input;
-
- while(base64_to_binary(input[0]) < 64) {
- ++input;
- }
-
- unsigned int input_length = input - start;
-
- unsigned int output_length = input_length/4*3;
-
- switch(input_length % 4) {
- default: return output_length;
- case 2: return output_length + 1;
- case 3: return output_length + 2;
- }
-}
-
-static unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[]) {
- unsigned int full_sets = input_length/3;
-
- // While there are still full sets of 24 bits...
- for(unsigned int i = 0; i < full_sets; ++i) {
- output[0] = binary_to_base64( input[0] >> 2);
- output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
- output[2] = binary_to_base64((input[1] & 0x0F) << 2 | input[2] >> 6);
- output[3] = binary_to_base64( input[2] & 0x3F);
-
- input += 3;
- output += 4;
- }
-
- switch(input_length % 3) {
- case 0:
- output[0] = '\0';
- break;
- case 1:
- output[0] = binary_to_base64( input[0] >> 2);
- output[1] = binary_to_base64((input[0] & 0x03) << 4);
- output[2] = '=';
- output[3] = '=';
- output[4] = '\0';
- break;
- case 2:
- output[0] = binary_to_base64( input[0] >> 2);
- output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
- output[2] = binary_to_base64((input[1] & 0x0F) << 2);
- output[3] = '=';
- output[4] = '\0';
- break;
- }
-
- return encode_base64_length(input_length);
-}
-
-static unsigned int decode_base64(unsigned char input[], unsigned char output[]) {
- unsigned int output_length = decode_base64_length(input);
-
- // While there are still full sets of 24 bits...
- for(unsigned int i = 2; i < output_length; i += 3) {
- output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
- output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
- output[2] = base64_to_binary(input[2]) << 6 | base64_to_binary(input[3]);
-
- input += 4;
- output += 3;
- }
-
- switch(output_length % 3) {
- case 1:
- output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
- break;
- case 2:
- output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
- output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
- break;
- }
-
- return output_length;
-}
-
-/********************************************************************
-** Buffer low-level implementation
-**
-** Extracted from Tasmota SBuffer lib
-********************************************************************/
-// static inline uint8_t* buf_get_buf(buf_impl* attr)
-// {
-// return &attr->bufptr[0];
-// }
-
-// shrink or increase. If increase, fill with zeores. Cannot go beyond `size`
-static void buf_set_len(buf_impl* attr, const size_t len)
-{
- int32_t old_len = attr->len;
- attr->len = ((int32_t)len <= attr->size) ? (int32_t)len : attr->size;
- if (old_len < attr->len) {
- memset((void*) &attr->bufptr[old_len], 0, attr->len - old_len);
- }
-}
-
-static size_t buf_add1(buf_impl* attr, const uint8_t data) // append 8 bits value
-{
- if (attr->len < attr->size) { // do we have room for 1 byte
- attr->bufptr[attr->len++] = data;
- }
- return attr->len;
-}
-
-static size_t buf_add2_le(buf_impl* attr, const uint16_t data) // append 16 bits value
-{
- if (attr->len < attr->size - 1) { // do we have room for 2 bytes
- attr->bufptr[attr->len++] = data;
- attr->bufptr[attr->len++] = data >> 8;
- }
- return attr->len;
-}
-
-static size_t buf_add2_be(buf_impl* attr, const uint16_t data) // append 16 bits value
-{
- if (attr->len < attr->size - 1) { // do we have room for 2 bytes
- attr->bufptr[attr->len++] = data >> 8;
- attr->bufptr[attr->len++] = data;
- }
- return attr->len;
-}
-
-static size_t buf_add4_le(buf_impl* attr, const uint32_t data) // append 32 bits value
-{
- if (attr->len < attr->size - 3) { // do we have room for 4 bytes
- attr->bufptr[attr->len++] = data;
- attr->bufptr[attr->len++] = data >> 8;
- attr->bufptr[attr->len++] = data >> 16;
- attr->bufptr[attr->len++] = data >> 24;
- }
- return attr->len;
-}
-
-size_t buf_add4_be(buf_impl* attr, const uint32_t data) // append 32 bits value
-{
- if (attr->len < attr->size - 3) { // do we have room for 4 bytes
- attr->bufptr[attr->len++] = data >> 24;
- attr->bufptr[attr->len++] = data >> 16;
- attr->bufptr[attr->len++] = data >> 8;
- attr->bufptr[attr->len++] = data;
- }
- return attr->len;
-}
-
-static size_t buf_add_buf(buf_impl* attr, buf_impl* attr2)
-{
- if (attr->len + attr2->len <= attr->size) {
- for (int32_t i = 0; i < attr2->len; i++) {
- attr->bufptr[attr->len++] = attr2->bufptr[i];
- }
- }
- return attr->len;
-}
-
-static size_t buf_add_raw(buf_impl* attr, const void* buf_raw, int32_t len)
-{
- uint8_t *buf = (uint8_t*) buf_raw;
- if ((len > 0) && (attr->len + len <= attr->size)) {
- for (int32_t i = 0; i < len; i++) {
- attr->bufptr[attr->len++] = buf[i];
- }
- }
- return attr->len;
-}
-
-static uint8_t buf_get1(buf_impl* attr, int offset)
-{
- if ((offset >= 0) && (offset < attr->len)) {
- return attr->bufptr[offset];
- }
- return 0;
-}
-
-static void buf_set1(buf_impl* attr, size_t offset, uint8_t data)
-{
- if ((int32_t)offset < attr->len) {
- attr->bufptr[offset] = data;
- }
-}
-
-static void buf_set2_le(buf_impl* attr, size_t offset, uint16_t data)
-{
- if ((int32_t)offset + 1 < attr->len) {
- attr->bufptr[offset] = data & 0xFF;
- attr->bufptr[offset+1] = data >> 8;
- }
-}
-
-static void buf_set2_be(buf_impl* attr, size_t offset, uint16_t data)
-{
- if ((int32_t)offset + 1 < attr->len) {
- attr->bufptr[offset+1] = data & 0xFF;
- attr->bufptr[offset] = data >> 8;
- }
-}
-
-static uint16_t buf_get2_le(buf_impl* attr, size_t offset)
-{
- if ((int32_t)offset + 1 < attr->len) {
- return attr->bufptr[offset] | (attr->bufptr[offset+1] << 8);
- }
- return 0;
-}
-
-static uint16_t buf_get2_be(buf_impl* attr, size_t offset)
-{
- if ((int32_t)offset + 1 < attr->len) {
- return attr->bufptr[offset+1] | (attr->bufptr[offset] << 8);
- }
- return 0;
-}
-
-static uint32_t buf_get3_le(buf_impl* attr, size_t offset)
-{
- if ((int32_t)offset + 2 < attr->len) {
- return attr->bufptr[offset] | (attr->bufptr[offset+1] << 8) | (attr->bufptr[offset+2] << 16);
- }
- return 0;
-}
-
-static uint32_t buf_get3_be(buf_impl* attr, size_t offset)
-{
- if ((int32_t)offset + 2 < attr->len) {
- return attr->bufptr[offset+2] | (attr->bufptr[offset+1] << 8) | (attr->bufptr[offset] << 16);
- }
- return 0;
-}
-
-static void buf_set3_le(buf_impl* attr, size_t offset, uint32_t data)
-{
- if ((int32_t)offset + 2 < attr->len) {
- attr->bufptr[offset] = data & 0xFF;
- attr->bufptr[offset+1] = (data >> 8) & 0xFF;
- attr->bufptr[offset+2] = (data >> 16) & 0xFF;
- }
-}
-
-static void buf_set3_be(buf_impl* attr, size_t offset, uint32_t data)
-{
- if ((int32_t)offset + 2 < attr->len) {
- attr->bufptr[offset+2] = data & 0xFF;
- attr->bufptr[offset+1] = (data >> 8) & 0xFF;
- attr->bufptr[offset] = (data >> 16) & 0xFF;
- }
-}
-
-static void buf_set4_le(buf_impl* attr, size_t offset, uint32_t data)
-{
- if ((int32_t)offset + 3 < attr->len) {
- attr->bufptr[offset] = data & 0xFF;
- attr->bufptr[offset+1] = (data >> 8) & 0xFF;
- attr->bufptr[offset+2] = (data >> 16) & 0xFF;
- attr->bufptr[offset+3] = data >> 24;
- }
-}
-
-static void buf_set4_be(buf_impl* attr, size_t offset, uint32_t data)
-{
- if ((int32_t)offset + 3 < attr->len) {
- attr->bufptr[offset+3] = data & 0xFF;
- attr->bufptr[offset+2] = (data >> 8) & 0xFF;
- attr->bufptr[offset+1] = (data >> 16) & 0xFF;
- attr->bufptr[offset] = data >> 24;
- }
-}
-
-static uint32_t buf_get4_le(buf_impl* attr, size_t offset)
-{
- if ((int32_t)offset + 3 < attr->len) {
- return attr->bufptr[offset] | (attr->bufptr[offset+1] << 8) |
- (attr->bufptr[offset+2] << 16) | (attr->bufptr[offset+3] << 24);
- }
- return 0;
-}
-
-static uint32_t buf_get4_be(buf_impl* attr, size_t offset)
-{
- if ((int32_t)offset + 3 < attr->len) {
- return attr->bufptr[offset+3] | (attr->bufptr[offset+2] << 8) |
- (attr->bufptr[offset+1] << 16) | (attr->bufptr[offset] << 24);
- }
- return 0;
-}
-
-// nullptr accepted
-static bbool buf_equals(buf_impl* buf1, buf_impl* buf2)
-{
- if (buf1 == buf2) { return btrue; }
- if (!buf1 || !buf2) { return bfalse; } // at least one attr is not empty
- // we know that both buf1 and buf2 are non-null
- if (buf1->len != buf2->len) { return bfalse; }
- size_t len = buf1->len;
- if (!buf1->bufptr && !buf2->bufptr) { return btrue; } /* if both are null then considered equal */
- if (!buf1->bufptr || !buf2->bufptr) { return bfalse; } /* if only one is null, then not equal */
- /* here none of the pointer are null */
- for (uint32_t i=0; i= 'A' && chr <= 'F') { rVal = chr + 10 - 'A'; }
- else if (chr >= 'a' && chr <= 'f') { rVal = chr + 10 - 'a'; }
- return rVal;
-}
-
-// does not check if there is enough room before hand, truncated if buffer too small
-static void buf_add_hex(buf_impl* attr, const char *hex, size_t len)
-{
- uint8_t val;
- for (; len > 1; len -= 2) {
- val = asc2byte(*hex++) << 4;
- val |= asc2byte(*hex++);
- buf_add1(attr, val);
- }
-}
-
-/********************************************************************
-** Wrapping into lib
-********************************************************************/
-
-/* if the bufptr is null, don't try to dereference and raise an exception instead */
-static void check_ptr(bvm *vm, const buf_impl* attr) {
- if (!attr->bufptr) {
- be_raise(vm, "value_error", "operation not allowed on pointer");
- }
-}
-
-static void check_ptr_modifiable(bvm *vm, const buf_impl* attr) {
- if (attr->solidified) {
- be_raise(vm, "value_error", BYTES_READ_ONLY_MESSAGE);
- }
- if (!attr->bufptr) {
- be_raise(vm, "value_error", "operation not allowed on pointer");
- }
-}
-
-/* load instance attribute into a single structure, and store 'previous' values in order to later update only the changed ones */
-/* stack item 1 must contain the instance */
-buf_impl m_read_attributes(bvm *vm, int idx)
-{
- buf_impl attr;
- be_getmember(vm, idx, ".p");
- attr.bufptr = attr.prev_bufptr = be_tocomptr(vm, -1);
- be_pop(vm, 1);
-
- be_getmember(vm, idx, ".len");
- attr.len = attr.prev_len = be_toint(vm, -1);
- be_pop(vm, 1);
-
- be_getmember(vm, idx, ".size");
- int32_t signed_size = be_toint(vm, -1);
- attr.fixed = bfalse;
- attr.mapped = bfalse;
- attr.solidified = bfalse;
- if (signed_size < 0) {
- if (signed_size == BYTES_SIZE_MAPPED) {
- attr.mapped = btrue;
- }
- if (signed_size == BYTES_SIZE_SOLIDIFIED) {
- attr.solidified = btrue;
- }
- signed_size = attr.len;
- attr.fixed = btrue;
- }
- attr.size = attr.prev_size = signed_size;
- be_pop(vm, 1);
- return attr;
-}
-
-static void m_assert_not_readlonly(bvm *vm, const buf_impl* attr)
-{
- if (attr->solidified) {
- be_raise(vm, "value_error", BYTES_READ_ONLY_MESSAGE);
- }
-}
-
-/* Write back attributes to the bytes instance, only if values changed after loading */
-/* stack item 1 must contain the instance */
-void m_write_attributes(bvm *vm, int rel_idx, const buf_impl * attr)
-{
- m_assert_not_readlonly(vm, attr);
- int idx = be_absindex(vm, rel_idx);
- if (attr->bufptr != attr->prev_bufptr) {
- be_pushcomptr(vm, attr->bufptr);
- be_setmember(vm, idx, ".p");
- be_pop(vm, 1);
- }
-
- if (attr->len != attr->prev_len) {
- be_pushint(vm, attr->len);
- be_setmember(vm, idx, ".len");
- be_pop(vm, 1);
- }
-
- int32_t new_size = attr->size;
- if (attr->mapped) {
- new_size = BYTES_SIZE_MAPPED;
- } else if (attr->fixed) {
- new_size = BYTES_SIZE_FIXED;
- }
- if (new_size != attr->prev_size) {
- be_pushint(vm, new_size);
- be_setmember(vm, idx, ".size");
- be_pop(vm, 1);
- }
-}
-
-// buf_impl * bytes_realloc(bvm *vm, buf_impl *oldbuf, int32_t size)
-void bytes_realloc(bvm *vm, buf_impl * attr, size_t size)
-{
- m_assert_not_readlonly(vm, attr);
- if (!attr->fixed && size < 4) { size = 4; }
- if (size > vm->bytesmaxsize) { size = vm->bytesmaxsize; }
- size_t oldsize = attr->bufptr ? attr->size : 0;
- attr->bufptr = (uint8_t*) be_realloc(vm, attr->bufptr, oldsize, size); /* malloc */
- attr->size = size;
- if (!attr->bufptr) {
- attr->len = 0; /* allocate a new buffer */
- }
-}
-
-/* allocate a new `bytes` object with pre-allocated size */
-static void bytes_new_object(bvm *vm, size_t size)
-{
- be_getbuiltin(vm, "bytes");
- be_pushint(vm, size);
- be_call(vm, 1);
- be_pop(vm, 1);
-}
-
-/*
- * constructor for bytes()
- * Arg0 is always self
- *
- * Option 1: main use
- * Arg1: string - a string representing the bytes in HEX
- *
- * Option 2:
- * Arg1: string - a string representing the bytes in HEX
- * Arg2: int - pre-reserved buffer size. If negative, size is fixed and cannot be later changed
- *
- * Option 3: used by subclasses like ctypes
- * Arg1: int - pre-reserved buffer size. If negative, size is fixed and cannot be later changed
- *
- * Option 4: mapped buffer
- * Arg1: comptr - buffer address of the mapped buffer
- * Arg2: int - buffer size. Always fixed (negative or positive)
- *
- * */
-static int m_init(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = { 0, 0, NULL, 0, -1, NULL, bfalse, bfalse, bfalse }; /* initialize prev_values to invalid to force a write at the end */
- /* size cannot be 0, len cannot be negative */
- const char * hex_in = NULL;
-
- int32_t size_arg = 0;
- if (argc > 1 && be_isint(vm, 2)) {
- size_arg = be_toint(vm, 2); /* raw size arg, can be positive or negative */
- } else if (argc > 2 && be_isint(vm, 3)) {
- size_arg = be_toint(vm, 3); /* raw size arg, can be positive or negative */
- }
-
- if (argc > 1 && be_iscomptr(vm, 2)) {
- if (size_arg) {
- attr.len = (size_arg < 0) ? -size_arg : size_arg;
- attr.bufptr = be_tocomptr(vm, 2);
- attr.fixed = btrue;
- attr.mapped = btrue;
- m_write_attributes(vm, 1, &attr); /* write attributes back to instance */
- be_return_nil(vm);
- } else {
- be_raise(vm, "value_error", "size is required");
- }
- }
- if (size_arg == 0) { size_arg = BYTES_DEFAULT_SIZE; } /* if not specified, use default size */
-
- /* compute actual size to be reserved */
- if (size_arg >= 0) {
- size_arg += BYTES_HEADROOM; /* add automatic headroom to slightly overallocate */
- if (size_arg > attr.size) {
- attr.size = size_arg;
- }
- } else {
- attr.size = -size_arg; /* set the size to a fixed negative value */
- attr.fixed = btrue;
- }
- size_arg = attr.size;
-
- /* if arg1 is string, we convert hex */
- if (argc > 1 && be_isstring(vm, 2)) {
- hex_in = be_tostring(vm, 2);
- if (hex_in) {
- size_arg = strlen(hex_in) / 2; /* allocate headroom */
- }
- /* check if fixed size that we have the right size */
- if (size_arg > attr.size) {
- if (attr.fixed) {
- be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
- } else {
- attr.size = size_arg;
- }
- }
- }
-
- /* allocate */
- bytes_realloc(vm, &attr, attr.size); /* allocate new buffer */
- if (!attr.bufptr) {
- be_throw(vm, BE_MALLOC_FAIL);
- }
-
- if (hex_in) {
- buf_add_hex(&attr, hex_in, strlen(hex_in));
- }
-
- /* if fixed size, set len to size */
- if (attr.fixed) {
- buf_set_len(&attr, attr.size);
- }
-
- m_write_attributes(vm, 1, &attr); /* write attributes back to instance */
- be_return_nil(vm);
-}
-
-/* deallocate buffer */
-static int m_deinit(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- if (attr.bufptr != NULL && !attr.mapped) {
- be_realloc(vm, attr.bufptr, attr.size, 0);
- }
- attr.size = 0;
- attr.len = 0;
- attr.bufptr = NULL;
- m_write_attributes(vm, 1, &attr);
- be_return_nil(vm);
-}
-
-/* grow or shrink to the exact value */
-/* stack item 1 must contain the instance */
-void _bytes_resize(bvm *vm, buf_impl * attr, size_t new_size) {
- bytes_realloc(vm, attr, new_size);
- if (!attr->bufptr) {
- be_throw(vm, BE_MALLOC_FAIL);
- }
-}
-
-/* grow if needed but don't shrink */
-/* if grow, then add some headroom */
-/* stack item 1 must contain the instance */
-void bytes_resize(bvm *vm, buf_impl * attr, size_t new_size) {
- if (attr->mapped) { return; } /* if mapped, don't bother with allocation */
- /* when resized to smaller, we introduce a new heurstic */
- /* If the buffer is 64 bytes or smaller, don't shrink */
- /* Shrink buffer only if target size is smaller than half the original size */
- if (attr->size >= (int32_t)new_size) { /* enough room, consider if need to shrink */
- if (attr->size <= 64) { return; } /* don't shrink if below 64 bytes */
- if (attr->size < (int32_t)new_size * 2) { return; }
- }
- _bytes_resize(vm, attr, new_size);
-}
-
-buf_impl bytes_check_data(bvm *vm, size_t add_size) {
- buf_impl attr = m_read_attributes(vm, 1);
- /* check if the `size` is big enough */
- if (attr.len + (int32_t)add_size > attr.size) {
- if (attr.fixed) {
- be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
- }
- /* it does not fit so we need to realocate the buffer */
- bytes_resize(vm, &attr, attr.len + add_size);
- }
- return attr;
-}
-
-size_t be_bytes_tohex(char * out, size_t outsz, const uint8_t * in, size_t insz) {
- static const char * hex = "0123456789ABCDEF";
- const uint8_t * pin = in;
- char * pout = out;
- for (; pin < in + insz; pout += 2, pin++) {
- pout[0] = hex[((*pin)>>4) & 0xF];
- pout[1] = hex[ (*pin) & 0xF];
- if (pout + 3 > out + outsz) { break; } /* check overflow */
- }
- pout[0] = 0; /* terminating Nul char */
- return pout - out;
-}
-
-static int m_tostring(bvm *vm)
-{
- int argc = be_top(vm);
- int32_t max_len = 32; /* limit to 32 bytes by default */
- int truncated = 0;
- if (argc > 1 && be_isint(vm, 2)) {
- max_len = be_toint(vm, 2); /* you can specify the len as second argument, or 0 for unlimited */
- }
- buf_impl attr = m_read_attributes(vm, 1);
- if (attr.bufptr) { /* pointer looks valid */
- int32_t len = attr.len;
- if (max_len > 0 && len > max_len) {
- len = max_len; /* limit output size */
- truncated = 1;
- }
- size_t hex_len = len * 2 + 5 + 2 + 2 + 1 + truncated * 3; /* reserve size for `bytes("")\0` - 9 chars */
-
- char * hex_out = be_pushbuffer(vm, hex_len);
- size_t l = be_strlcpy(hex_out, "bytes('", hex_len);
- l += be_bytes_tohex(&hex_out[l], hex_len - l, attr.bufptr, len);
- if (truncated) {
- l += be_strlcpy(&hex_out[l], "...", hex_len - l);
- }
- l += be_strlcpy(&hex_out[l], "')", hex_len - l);
-
- be_pushnstring(vm, hex_out, l); /* make escape string from buffer */
- be_remove(vm, -2); /* remove buffer */
- } else { /* pointer is null, don't try to dereference it as it would crash */
- be_pushstring(vm, "bytes()");
- }
- be_return(vm);
-}
-
-static int m_tohex(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- if (attr.bufptr) { /* pointer looks valid */
- int32_t len = attr.len;
- size_t hex_len = len * 2 + 1;
-
- char * hex_out = be_pushbuffer(vm, hex_len);
- size_t l = be_bytes_tohex(hex_out, hex_len, attr.bufptr, len);
-
- be_pushnstring(vm, hex_out, l); /* make escape string from buffer */
- be_remove(vm, -2); /* remove buffer */
- } else { /* pointer is null, don't try to dereference it as it would crash */
- be_pushstring(vm, "");
- }
- be_return(vm);
-}
-
-/*
- * Copy the buffer into a string without any changes
- */
-static int m_asstring(bvm *vm)
-{
- buf_impl attr = bytes_check_data(vm, 0);
- check_ptr(vm, &attr);
- be_pushnstring(vm, (const char*) attr.bufptr, attr.len);
- be_return(vm);
-}
-
-static int m_fromstring(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2 && be_isstring(vm, 2)) {
- const char *s = be_tostring(vm, 2);
- int32_t len = be_strlen(vm, 2); /* calling be_strlen to support null chars in string */
- buf_impl attr = bytes_check_data(vm, 0);
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed && attr.len != len) {
- be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
- }
- bytes_resize(vm, &attr, len); /* resize if needed */
- if (len > attr.size) { len = attr.size; } /* avoid overflow */
- memmove(attr.bufptr, s, len);
- attr.len = len;
- be_pop(vm, 1); /* remove arg to leave instance */
- m_write_attributes(vm, 1, &attr); /* update attributes */
- be_return(vm);
- }
- be_raise(vm, "type_error", "operand must be a string");
- be_return_nil(vm);
-}
-
-/*
- * Add an int made of 1, 2 or 4 bytes, in little or big endian
- * `add(value:int[, size:int = 1]) -> instance`
- *
- * size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
- * obvisouly -1 is idntical to 1
- * size==0 does nothing
- */
-static int m_add(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 4); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed) { be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE); }
- if (argc >= 2 && be_isint(vm, 2)) {
- int32_t v = be_toint(vm, 2);
- int vsize = 1;
- if (argc >= 3 && be_isint(vm, 3)) {
- vsize = be_toint(vm, 3);
- }
- switch (vsize) {
- case 0: break;
- case -1: /* fallback below */
- case 1: buf_add1(&attr, v); break;
- case 2: buf_add2_le(&attr, v); break;
- case 4: buf_add4_le(&attr, v); break;
- case -2: buf_add2_be(&attr, v); break;
- case -4: buf_add4_be(&attr, v); break;
- default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4.");
- }
- be_pop(vm, argc - 1);
- m_write_attributes(vm, 1, &attr); /* update attributes */
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-/*
- * Get an int made of 1, 2 or 4 bytes, in little or big endian
- * `get(index:int[, size:int = 1]) -> int`
- *
- * size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
- * obvisouly -1 is identical to 1
- * 0 returns nil
- */
-static int m_get(bvm *vm, bbool sign)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr(vm, &attr);
- if (argc >=2 && be_isint(vm, 2)) {
- int32_t idx = be_toint(vm, 2);
- int vsize = 1;
- if (argc >= 3 && be_isint(vm, 3)) {
- vsize = be_toint(vm, 3);
- }
- if (idx < 0) {
- idx = attr.len + idx; /* if index is negative, count from end */
- }
- if (idx < 0) {
- vsize = 0; /* if still negative, then invalid, return 0 */
- }
- int ret = 0;
- switch (vsize) {
- case 0: break;
- case -1: /* fallback below */
- case 1: ret = buf_get1(&attr, idx);
- if (sign) { ret = (int8_t)(uint8_t) ret; }
- break;
- case 2: ret = buf_get2_le(&attr, idx);
- if (sign) { ret = (int16_t)(uint16_t) ret; }
- break;
- case 3: ret = buf_get3_le(&attr, idx);
- if (sign & (ret & 0x800000)) { ret = ret | 0xFF000000; }
- break;
- case 4: ret = buf_get4_le(&attr, idx); break;
- case -2: ret = buf_get2_be(&attr, idx);
- if (sign) { ret = (int16_t)(uint16_t) ret; }
- break;
- case -3: ret = buf_get3_be(&attr, idx);
- if (sign & (ret & 0x800000)) { ret = ret | 0xFF000000; }
- break;
- case -4: ret = buf_get4_be(&attr, idx); break;
- default: be_raise(vm, "type_error", "size must be -4, -3, -2, -1, 0, 1, 2, 3 or 4.");
- }
- be_pop(vm, argc - 1);
- be_pushint(vm, ret);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-/*
- * Get a float (32 bits)
- * `getfloat(index:int [, big_endian:bool]) -> real`
- */
-static int m_getfloat(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr(vm, &attr);
- if (argc >=2 && be_isint(vm, 2)) {
- int32_t idx = be_toint(vm, 2);
- float ret_f = 0;
- if (idx < 0) {
- idx = attr.len + idx; /* if index is negative, count from end */
- }
- if (idx >= 0) {
- bbool be = bfalse; /* little endian? */
- if (argc >= 3) {
- be = be_tobool(vm, 3);
- }
- int32_t ret_i = be ? buf_get4_be(&attr, idx) : buf_get4_le(&attr, idx);
- ret_f = *(float*) &ret_i;
- }
- be_pop(vm, argc - 1);
- be_pushreal(vm, ret_f);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-/* signed int */
-static int m_geti(bvm *vm)
-{
- return m_get(vm, 1);
-}
-
-/* unsigned int */
-static int m_getu(bvm *vm)
-{
- return m_get(vm, 0);
-}
-
-/*
- * Set an int made of 1, 2 or 4 bytes, in little or big endian
- * `set(index:int, value:int[, size:int = 1]) -> nil`
- *
- * size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
- * obvisouly -1 is identical to 1
- * 0 returns nil
- */
-static int m_set(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
- if (argc >=3 && be_isint(vm, 2) && be_isint(vm, 3)) {
- int32_t idx = be_toint(vm, 2);
- int32_t value = be_toint(vm, 3);
- int vsize = 1;
- if (argc >= 4 && be_isint(vm, 4)) {
- vsize = be_toint(vm, 4);
- }
- if (idx < 0) {
- idx = attr.len + idx; /* if index is negative, count from end */
- }
- if (idx < 0) {
- vsize = 0; /* if still negative, then invalid, do nothing */
- }
- switch (vsize) {
- case 0: break;
- case -1: /* fallback below */
- case 1: buf_set1(&attr, idx, value); break;
- case 2: buf_set2_le(&attr, idx, value); break;
- case 3: buf_set3_le(&attr, idx, value); break;
- case 4: buf_set4_le(&attr, idx, value); break;
- case -2: buf_set2_be(&attr, idx, value); break;
- case -3: buf_set3_be(&attr, idx, value); break;
- case -4: buf_set4_be(&attr, idx, value); break;
- default: be_raise(vm, "type_error", "size must be -4, -3, -2, -1, 0, 1, 2, 3 or 4.");
- }
- be_pop(vm, argc - 1);
- // m_write_attributes(vm, 1, &attr); /* update attributes */
- be_return_nil(vm);
- }
- be_return_nil(vm);
-}
-
-/*
- * Set a 32 bits float
- * `setfloat(index:int, value:real or int [, big_endian:bool]) -> nil`
- *
- */
-static int m_setfloat(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
- if (argc >=3 && be_isint(vm, 2) && (be_isint(vm, 3) || be_isreal(vm, 3))) {
- int32_t idx = be_toint(vm, 2);
- if (idx < 0) {
- idx = attr.len + idx; /* if index is negative, count from end */
- }
- if (idx >= 0) {
- float val_f = (float) be_toreal(vm, 3);
- int32_t* val_i = (int32_t*) &val_f;
- bbool be = bfalse;
- if (argc >= 4) {
- be = be_tobool(vm, 4);
- }
- if (be) { buf_set4_be(&attr, idx, *val_i); } else { buf_set4_le(&attr, idx, *val_i); }
- be_pop(vm, argc - 1);
- // m_write_attributes(vm, 1, &attr); /* update attributes */
- }
- be_return_nil(vm);
- }
- be_return_nil(vm);
-}
-
-/*
- * Add a 32 bits float
- * `addfloat(value:real or int [, big_endian:bool]) -> instance`
- *
- */
-static int m_addfloat(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 4); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed) { be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE); }
- if (argc >=2 && (be_isint(vm, 2) || be_isreal(vm, 2))) {
- float val_f = (float) be_toreal(vm, 2);
- int32_t* val_i = (int32_t*) &val_f;
- bbool be = bfalse;
- if (argc >= 3) {
- be = be_tobool(vm, 3);
- }
- if (be) { buf_add4_be(&attr, *val_i); } else { buf_add4_le(&attr, *val_i); }
- be_pop(vm, argc - 1);
- m_write_attributes(vm, 1, &attr); /* update attributes */
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-/*
- * Fills a buffer with another buffer.
- *
- * This is meant to be very flexible and avoid loops
- *
- * `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
- *
- */
-static int m_setbytes(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
- if (argc >=3 && be_isint(vm, 2) && (be_isbytes(vm, 3))) {
- int32_t idx = be_toint(vm, 2);
- size_t from_len_total;
- const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
- if (idx < 0) {
- idx = attr.len + idx; /* if index is negative, count from end */
- }
- if (idx < 0) { idx = 0; } /* if still negative, start from offset 0 */
- if (idx >= attr.len) { idx = attr.len; }
-
- int32_t from_byte = 0;
- if (argc >= 4 && be_isint(vm, 4)) {
- from_byte = be_toint(vm, 4);
- if (from_byte < 0) { from_byte = 0; }
- if ((size_t)from_byte >= from_len_total) { from_byte = from_len_total; }
- }
-
- int32_t from_len = from_len_total - from_byte;
- if (argc >= 5 && be_isint(vm, 5)) {
- from_len = be_toint(vm, 5);
- if (from_len < 0) { from_len = 0; }
- if (from_len >= (int32_t)from_len_total) { from_len = from_len_total; }
- }
- if (idx + from_len >= attr.len) { from_len = attr.len - idx; }
-
- // all parameters ok
- if (from_len > 0) {
- memmove(attr.bufptr + idx, buf_ptr + from_byte, from_len);
- }
- }
- be_return_nil(vm);
-}
-
-
-/*
- * Reverses in-place a sub-buffer composed of groups of n-bytes packets
- *
- * This is useful for pixel manipulation when displaying RGB pixels
- *
- * `reverse([index:int, len:int, grouplen:int]) -> self`
- *
- */
-static int m_reverse(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
-
- int32_t idx = 0; /* start from index 0 */
- int32_t len = attr.len; /* entire len */
- int32_t grouplen = 1; /* default to 1-byte group */
-
- if (argc >= 2 && be_isint(vm, 2)) {
- idx = be_toint(vm, 2);
- if (idx < 0) { idx = attr.len + idx; } /* if negative, count from end */
- if (idx < 0) { idx = 0; } /* railguards */
- if (idx > attr.len) { idx = attr.len; }
- }
- if (argc >= 3 && be_isint(vm, 3)) {
- len = be_toint(vm, 3);
- if (len < 0) { len = attr.len - idx; } /* negative len means */
- }
- if (idx + len >= attr.len) { len = attr.len - idx; }
-
- // truncate len to multiple of grouplen
- if (argc >= 4 && be_isint(vm, 4)) {
- grouplen = be_toint(vm, 4);
- if (grouplen <= 0) { grouplen = 1; }
- }
- len = len - (len % grouplen);
-
- // apply reverse
- if (len > 0) {
- if (grouplen == 1) {
- /* fast version if simple byte inversion */
- for (int32_t i = idx, j = idx + len -1; i < j; i++, j--) {
- uint8_t temp = attr.bufptr[i];
- attr.bufptr[i] = attr.bufptr[j];
- attr.bufptr[j] = temp;
- }
- } else {
- for (int32_t i = idx, j = idx + len - grouplen; i < j; i += grouplen, j -= grouplen) {
- for (int32_t k = 0; k < grouplen; k++) {
- uint8_t temp = attr.bufptr[i+k];
- attr.bufptr[i+k] = attr.bufptr[j+k];
- attr.bufptr[j+k] = temp;
- }
- }
- }
- }
- be_pushvalue(vm, 1); /* push bytes object */
- be_return(vm);
-}
-
-static int m_setitem(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr_modifiable(vm, &attr);
- if (argc >=3 && be_isint(vm, 2) && be_isint(vm, 3)) {
- int index = be_toint(vm, 2);
- int val = be_toint(vm, 3);
- if (index < 0) {
- index += attr.len; /* if index is negative, count from end */
- }
- if (index >= 0 && index < attr.len) {
- buf_set1(&attr, index, val);
- // m_write_attributes(vm, 1, &attr); /* update attributes */
- be_return_nil(vm);
- }
- }
- be_raise(vm, "index_error", "bytes index out of range or value non int");
- be_return_nil(vm);
-}
-
-static int m_item(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
- check_ptr(vm, &attr);
- if (argc >=2 && be_isint(vm, 2)) { /* single byte */
- int index = be_toint(vm,2);
- if (index < 0) {
- index += attr.len;
- }
- if (index >= 0 && index < attr.len) {
- be_pushint(vm, buf_get1(&attr, index));
- be_return(vm);
- }
- }
- if (argc >= 2 && be_isinstance(vm, 2)) {
- const char *cname = be_classname(vm, 2);
- if (!strcmp(cname, "range")) {
- bint lower, upper;
- bint size = attr.len;
- /* get index range */
- be_getmember(vm, 2, "__lower__");
- lower = be_toint(vm, -1);
- be_pop(vm, 1);
- be_getmember(vm, 2, "__upper__");
- upper = be_toint(vm, -1);
- be_pop(vm, 1);
- /* handle negative limits */
- if (upper < 0) { upper += attr.len; }
- if (lower < 0) { lower += attr.len; }
- /* protection scope */
- upper = upper < size ? upper : size - 1;
- lower = lower < 0 ? 0 : lower;
- /* construction result list instance */
- bytes_new_object(vm, upper > lower ? upper-lower : 0);
- buf_impl attr2 = m_read_attributes(vm, -1);
-
- for (; lower <= upper; ++lower) {
- buf_add1(&attr2, attr.bufptr[lower]);
- }
- m_write_attributes(vm, -1, &attr2); /* update instance */
- be_return(vm);
- }
- }
- be_raise(vm, "index_error", "bytes index out of range");
- be_return_nil(vm);
-}
-
-static int m_size(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- be_pushint(vm, attr.len);
- be_return(vm);
-}
-
-static int m_tobool(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- be_pushbool(vm, attr.len > 0 ? 1 : 0);
- be_return(vm);
-}
-
-static int m_resize(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr_modifiable(vm, &attr);
-
- if (argc <= 1 || !be_isint(vm, 2)) {
- be_raise(vm, "type_error", "size must be of type 'int'");
- }
- int new_len = be_toint(vm, 2);
- if (new_len < 0) {
- new_len = 0;
- }
- if (attr.fixed && attr.len != new_len) {
- be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
- }
-
- bytes_resize(vm, &attr, new_len);
- buf_set_len(&attr, new_len);
- be_pop(vm, 1);
- m_write_attributes(vm, 1, &attr); /* update instance */
- be_return(vm);
-}
-
-static int m_clear(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed) { be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE); }
- attr.len = 0;
- m_write_attributes(vm, 1, &attr); /* update instance */
- be_return_nil(vm);
-}
-
-static int m_merge(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = m_read_attributes(vm, 1); /* no resize yet */
- check_ptr(vm, &attr);
- if (argc >= 2 && (be_isbytes(vm, 2) || be_isstring(vm, 2))) {
- const uint8_t * buf;
- int32_t buf_len;
- if (be_isbytes(vm, 2)) {
- buf_impl attr2 = m_read_attributes(vm, 2);
- check_ptr(vm, &attr2);
- buf = attr2.bufptr;
- buf_len = attr2.len;
- } else {
- buf = (const uint8_t *)be_tostring(vm, 2);
- buf_len = strlen((const char *)buf);
- }
-
- /* allocate new object */
- bytes_new_object(vm, attr.len + buf_len);
- buf_impl attr3 = m_read_attributes(vm, -1);
- check_ptr(vm, &attr3);
-
- buf_add_buf(&attr3, &attr);
- buf_add_raw(&attr3, buf, buf_len);
-
- m_write_attributes(vm, -1, &attr3); /* update instance */
- be_return(vm); /* return self */
- }
- be_raise(vm, "type_error", "operand must be bytes");
- be_return_nil(vm); /* return self */
-}
-
-static int m_copy(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr(vm, &attr);
- bytes_new_object(vm, attr.len);
- buf_impl attr2 = m_read_attributes(vm, -1);
- check_ptr(vm, &attr2);
- buf_add_buf(&attr2, &attr);
- m_write_attributes(vm, -1, &attr2); /* update instance */
- be_return(vm); /* return self */
-}
-
-/* accept bytes or int as operand */
-static int m_connect(bvm *vm)
-{
- int argc = be_top(vm);
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed) { be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE); }
- if (argc >= 2 && (be_isbytes(vm, 2) || be_isint(vm, 2) || be_isstring(vm, 2))) {
- if (be_isint(vm, 2)) {
- bytes_resize(vm, &attr, attr.len + 1); /* resize */
- buf_add1(&attr, be_toint(vm, 2));
- m_write_attributes(vm, 1, &attr); /* update instance */
- be_pushvalue(vm, 1);
- be_return(vm); /* return self */
- } else if (be_isstring(vm, 2)) {
- const char *str = be_tostring(vm, 2);
- size_t str_len = strlen(str);
- if (str_len > 0) {
- bytes_resize(vm, &attr, attr.len + str_len); /* resize */
- buf_add_raw(&attr, str, str_len);
- m_write_attributes(vm, 1, &attr); /* update instance */
- }
- be_pushvalue(vm, 1);
- be_return(vm); /* return self */
- } else {
- buf_impl attr2 = m_read_attributes(vm, 2);
- check_ptr(vm, &attr2);
- bytes_resize(vm, &attr, attr.len + attr2.len); /* resize buf1 for total size */
- buf_add_buf(&attr, &attr2);
- m_write_attributes(vm, 1, &attr); /* update instance */
- be_pushvalue(vm, 1);
- be_return(vm); /* return self */
- }
- }
- be_raise(vm, "type_error", "operand must be bytes or int or string");
- be_return_nil(vm); /* return self */
-}
-
-static int bytes_equal(bvm *vm, bbool iseq)
-{
- bbool ret;
- buf_impl attr1 = m_read_attributes(vm, 1);
- if (!be_isbytes(vm, 2)) {
- ret = !iseq;
- } else {
- buf_impl attr2 = m_read_attributes(vm, 2);
-
- if (buf_equals(&attr1, &attr2)) {
- ret = iseq;
- } else {
- ret = !iseq;
- }
- }
- be_pushbool(vm, ret);
- be_return(vm);
-}
-
-static int m_equal(bvm *vm)
-{
- return bytes_equal(vm, btrue);
-}
-
-static int m_nequal(bvm *vm)
-{
- return bytes_equal(vm, bfalse);
-}
-
-/*
- * Converts bytes() to a base64 string
- *
- * Note: there are no line breaks inserted
- *
- * `b.tob64() -> string`
- */
-static int m_tob64(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr(vm, &attr);
- int32_t len = attr.len;
- int32_t b64_len = encode_base64_length(len) + 1; /* size of base64 encoded string for this binary length, add NULL terminator */
-
- char * b64_out = be_pushbuffer(vm, b64_len);
- size_t converted = encode_base64(attr.bufptr, len, (unsigned char*)b64_out);
-
- be_pushnstring(vm, b64_out, converted); /* make string from buffer */
- be_remove(vm, -2); /* remove buffer */
- be_return(vm);
-}
-
-/*
- * Converts base63 to bytes()
- *
- * `bytes().fromb64() -> bytes()`
- */
-static int m_fromb64(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2 && be_isstring(vm, 2)) {
- const char *s = be_tostring(vm, 2);
- int32_t bin_len = decode_base64_length((unsigned char*)s); /* do a first pass to calculate the buffer size */
-
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed && attr.len != bin_len) {
- be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
- }
- bytes_resize(vm, &attr, bin_len); /* resize if needed */
- if (bin_len > attr.size) { /* avoid overflow */
- be_raise(vm, "memory_error", "cannot allocate buffer");
- }
-
- int32_t bin_len_final = decode_base64((unsigned char*)s, attr.bufptr); /* decode */
- attr.len = bin_len_final;
- be_pop(vm, 1); /* remove arg to leave instance */
- m_write_attributes(vm, 1, &attr); /* update instance */
- be_return(vm);
- }
- be_raise(vm, "type_error", "operand must be a string");
- be_return_nil(vm);
-}
-
-/*
- * Converts hex to bytes()
- *
- * `bytes().fromhexx() -> bytes()`
- */
-static int m_fromhex(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2 && be_isstring(vm, 2)) {
- int32_t from = 0; // skip x chars
- if (argc >= 3 && be_isint(vm, 3)) {
- from = be_toint(vm, 3);
- }
- const char *s = be_tostring(vm, 2);
- int32_t s_len = strlen(s);
- if (from < 0) { from = 0; }
- if (from > s_len) { from = s_len; }
- int32_t bin_len = (s_len - from) / 2;
-
- buf_impl attr = m_read_attributes(vm, 1);
- check_ptr_modifiable(vm, &attr);
- if (attr.fixed && attr.len != bin_len) {
- be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
- }
- bytes_resize(vm, &attr, bin_len); /* resize if needed */
- if (bin_len > attr.size) { /* avoid overflow */
- be_raise(vm, "memory_error", "cannot allocate buffer");
- }
- attr.len = 0;
- buf_add_hex(&attr, s + from, s_len - from);
-
- be_pop(vm, 1); /* remove arg to leave instance */
- m_write_attributes(vm, 1, &attr); /* update instance */
- be_pop(vm, be_top(vm) - 1); /* leave instance on stack */
- be_return(vm);
- }
- be_raise(vm, "type_error", "operand must be a string");
- be_return_nil(vm);
-}
-
-/*
- * Advanced API
- */
-
-/*
- * Retrieve the memory address of the raw buffer
- * to be used in C functions.
- *
- * Note: the address is guaranteed not to move unless you
- * resize the buffer
- *
- * `_buffer() -> comptr`
- */
-static int m_buffer(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- be_pushcomptr(vm, attr.bufptr);
- be_return(vm);
-}
-
-/*
- * Returns `btrue` if the buffer is mapped to memory
- * or `bfalse` if memory was allocated by us.
- *
- * `ismapped() -> bool`
- */
-static int m_is_mapped(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- bbool mapped = (attr.mapped || (attr.bufptr == NULL));
- be_pushbool(vm, mapped);
- be_return(vm);
-}
-
-/*
- * Returns `btrue` if the buffer is solidified and read only
- *
- * `isreadonly() -> bool`
- */
-static int m_is_readonly(bvm *vm)
-{
- buf_impl attr = m_read_attributes(vm, 1);
- be_pushbool(vm, attr.solidified);
- be_return(vm);
-}
-
-/*
- * Change the pointer to a mapped buffer.
- *
- * This call does nothing if the buffer is not mapped (i.e. memory is managed externally)
- *
- * It is typically used to reuse existing Berry object and avoid a complete reallocation
- *
- * `_change_buffer(comptr) -> comptr`
- */
-static int m_change_buffer(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2 && be_iscomptr(vm, 2)) {
- buf_impl attr = m_read_attributes(vm, 1);
- if (attr.solidified) {
- be_raise(vm, "value_error", BYTES_READ_ONLY_MESSAGE);
- }
- if (!attr.mapped) {
- be_raise(vm, "type_error", "bytes() object must be mapped");
- }
- attr.bufptr = be_tocomptr(vm, 2);
- m_write_attributes(vm, 1, &attr); /* write attributes back to instance */
- be_pushcomptr(vm, attr.bufptr);
- be_return(vm);
- }
- be_raise(vm, "type_error", "operand must be a comptr");
- be_return_nil(vm);
-}
-
-/*
- * External API
- */
-BERRY_API void * be_pushbytes(bvm *vm, const void * bytes, size_t len)
-{
- bytes_new_object(vm, len);
- buf_impl attr = m_read_attributes(vm, -1);
- check_ptr(vm, &attr);
- if ((int32_t)len > attr.size) { len = attr.size; } /* double check if the buffer allocated was smaller */
- if (bytes) { /* if bytes is null, buffer is filled with zeros */
- memmove((void*)attr.bufptr, bytes, len);
- } else {
- memset((void*)attr.bufptr, 0, len);
- }
- attr.len = len;
- m_write_attributes(vm, -1, &attr); /* update instance */
- /* bytes instance is on top of stack */
- return (void*)attr.bufptr;
-}
-
-BERRY_API const void *be_tobytes(bvm *vm, int rel_index, size_t *len)
-{
- int index = be_absindex(vm, rel_index);
- if (be_isbytes(vm, index)) {
- buf_impl attr = m_read_attributes(vm, index);
- check_ptr(vm, &attr);
- if (len) { *len = attr.len; }
- return (void*) attr.bufptr;
- }
- if (len) { *len = 0; }
- return NULL;
-}
-
-BERRY_API bbool be_isbytes(bvm *vm, int rel_index)
-{
- bbool ret = bfalse;
- int index = be_absindex(vm, rel_index);
- if (be_isinstance(vm, index)) {
- be_getbuiltin(vm, "bytes");
- if (be_isderived(vm, index)) {
- ret = btrue;
- }
- be_pop(vm, 1);
- }
- return ret;
-}
-
-/* Helper code to compile bytecode
-
-
-class Bytes : bytes
-#-------------------------------------------------------------
-#- 'getbits' function
-#-
-#- Reads a bit-field in a `bytes()` object
-#-
-#- Input:
-#- offset_bits (int): bit number to start reading from (0 = LSB)
-#- len_bits (int): how many bits to read
-#- Output:
-#- valuer (int)
-#-------------------------------------------------------------#
- def getbits(offset_bits, len_bits)
- if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
- var ret = 0
-
- var offset_bytes = offset_bits >> 3
- offset_bits = offset_bits % 8
-
- var bit_shift = 0 #- bit number to write to -#
-
- while (len_bits > 0)
- var block_bits = 8 - offset_bits # how many bits to read in the current block (block = byte) -#
- if block_bits > len_bits block_bits = len_bits end
-
- var mask = ( (1<> offset_bits) << bit_shift)
-
- #- move the input window -#
- bit_shift += block_bits
- len_bits -= block_bits
- offset_bits = 0 #- start at full next byte -#
- offset_bytes += 1
- end
-
- return ret
- end
-
- #-------------------------------------------------------------
- #- 'setbits' function
- #-
- #- Writes a bit-field in a `bytes()` object
- #-
- #- Input:
- #- offset_bits (int): bit number to start writing to (0 = LSB)
- #- len_bits (int): how many bits to write
- #- val (int): value to set
- #-------------------------------------------------------------#
- def setbits(offset_bits, len_bits, val)
- if len_bits < 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
-
- val = int(val) #- convert bool or others to int -#
- var offset_bytes = offset_bits >> 3
- offset_bits = offset_bits % 8
-
- while (len_bits > 0)
- var block_bits = 8 - offset_bits #- how many bits to write in the current block (block = byte) -#
- if block_bits > len_bits block_bits = len_bits end
-
- var mask_val = (1<>= block_bits
- len_bits -= block_bits
- offset_bits = 0 #- start at full next byte -#
- offset_bytes += 1
- end
- return self
- end
-end
-
-*/
-
-/********************************************************************
-** Solidified function: getbits
-********************************************************************/
-be_local_closure(getbits, /* name */
- be_nested_proto(
- 9, /* nstack */
- 3, /* argc */
- 0, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 5]) { /* constants */
- /* K0 */ be_const_int(0),
- /* K1 */ be_nested_str(value_error),
- /* K2 */ be_nested_str(length_X20in_X20bits_X20must_X20be_X20between_X200_X20and_X2032),
- /* K3 */ be_const_int(3),
- /* K4 */ be_const_int(1),
- }),
- &be_const_str_getbits,
- &be_const_str_solidified,
- ( &(const binstruction[32]) { /* code */
- 0x180C0500, // 0000 LE R3 R2 K0
- 0x740E0002, // 0001 JMPT R3 #0005
- 0x540E001F, // 0002 LDINT R3 32
- 0x240C0403, // 0003 GT R3 R2 R3
- 0x780E0000, // 0004 JMPF R3 #0006
- 0xB0060302, // 0005 RAISE 1 K1 K2
- 0x580C0000, // 0006 LDCONST R3 K0
- 0x3C100303, // 0007 SHR R4 R1 K3
- 0x54160007, // 0008 LDINT R5 8
- 0x10040205, // 0009 MOD R1 R1 R5
- 0x58140000, // 000A LDCONST R5 K0
- 0x24180500, // 000B GT R6 R2 K0
- 0x781A0011, // 000C JMPF R6 #001F
- 0x541A0007, // 000D LDINT R6 8
- 0x04180C01, // 000E SUB R6 R6 R1
- 0x241C0C02, // 000F GT R7 R6 R2
- 0x781E0000, // 0010 JMPF R7 #0012
- 0x5C180400, // 0011 MOVE R6 R2
- 0x381E0806, // 0012 SHL R7 K4 R6
- 0x041C0F04, // 0013 SUB R7 R7 K4
- 0x381C0E01, // 0014 SHL R7 R7 R1
- 0x94200004, // 0015 GETIDX R8 R0 R4
- 0x2C201007, // 0016 AND R8 R8 R7
- 0x3C201001, // 0017 SHR R8 R8 R1
- 0x38201005, // 0018 SHL R8 R8 R5
- 0x300C0608, // 0019 OR R3 R3 R8
- 0x00140A06, // 001A ADD R5 R5 R6
- 0x04080406, // 001B SUB R2 R2 R6
- 0x58040000, // 001C LDCONST R1 K0
- 0x00100904, // 001D ADD R4 R4 K4
- 0x7001FFEB, // 001E JMP #000B
- 0x80040600, // 001F RET 1 R3
- })
- )
-);
-/*******************************************************************/
-
-/********************************************************************
-** Solidified function: setbits
-********************************************************************/
-be_local_closure(setbits, /* name */
- be_nested_proto(
- 10, /* nstack */
- 4, /* argc */
- 0, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 5]) { /* constants */
- /* K0 */ be_const_int(0),
- /* K1 */ be_nested_str(value_error),
- /* K2 */ be_nested_str(length_X20in_X20bits_X20must_X20be_X20between_X200_X20and_X2032),
- /* K3 */ be_const_int(3),
- /* K4 */ be_const_int(1),
- }),
- &be_const_str_setbits,
- &be_const_str_solidified,
- ( &(const binstruction[37]) { /* code */
- 0x14100500, // 0000 LT R4 R2 K0
- 0x74120002, // 0001 JMPT R4 #0005
- 0x5412001F, // 0002 LDINT R4 32
- 0x24100404, // 0003 GT R4 R2 R4
- 0x78120000, // 0004 JMPF R4 #0006
- 0xB0060302, // 0005 RAISE 1 K1 K2
- 0x60100009, // 0006 GETGBL R4 G9
- 0x5C140600, // 0007 MOVE R5 R3
- 0x7C100200, // 0008 CALL R4 1
- 0x5C0C0800, // 0009 MOVE R3 R4
- 0x3C100303, // 000A SHR R4 R1 K3
- 0x54160007, // 000B LDINT R5 8
- 0x10040205, // 000C MOD R1 R1 R5
- 0x24140500, // 000D GT R5 R2 K0
- 0x78160014, // 000E JMPF R5 #0024
- 0x54160007, // 000F LDINT R5 8
- 0x04140A01, // 0010 SUB R5 R5 R1
- 0x24180A02, // 0011 GT R6 R5 R2
- 0x781A0000, // 0012 JMPF R6 #0014
- 0x5C140400, // 0013 MOVE R5 R2
- 0x381A0805, // 0014 SHL R6 K4 R5
- 0x04180D04, // 0015 SUB R6 R6 K4
- 0x541E00FE, // 0016 LDINT R7 255
- 0x38200C01, // 0017 SHL R8 R6 R1
- 0x041C0E08, // 0018 SUB R7 R7 R8
- 0x94200004, // 0019 GETIDX R8 R0 R4
- 0x2C201007, // 001A AND R8 R8 R7
- 0x2C240606, // 001B AND R9 R3 R6
- 0x38241201, // 001C SHL R9 R9 R1
- 0x30201009, // 001D OR R8 R8 R9
- 0x98000808, // 001E SETIDX R0 R4 R8
- 0x3C0C0605, // 001F SHR R3 R3 R5
- 0x04080405, // 0020 SUB R2 R2 R5
- 0x58040000, // 0021 LDCONST R1 K0
- 0x00100904, // 0022 ADD R4 R4 K4
- 0x7001FFE8, // 0023 JMP #000D
- 0x80040000, // 0024 RET 1 R0
- })
- )
-);
-/*******************************************************************/
-
-#if !BE_USE_PRECOMPILED_OBJECT
-void be_load_byteslib(bvm *vm)
-{
- static const bnfuncinfo members[] = {
- { ".p", NULL },
- { ".len", NULL },
- { ".size", NULL },
- { "_buffer", m_buffer },
- { "_change_buffer", m_change_buffer },
- { "ismapped", m_is_mapped },
- { "isreadonly", m_is_readonly },
- { "init", m_init },
- { "deinit", m_deinit },
- { "tostring", m_tostring },
- { "asstring", m_asstring },
- { "tobool", m_tobool },
- { "fromstring", m_fromstring },
- { "tob64", m_tob64 },
- { "fromb64", m_fromb64 },
- { "fromhex", m_fromhex },
- { "tohex", m_tohex },
- { "add", m_add },
- { "get", m_getu },
- { "geti", m_geti },
- { "set", m_set },
- { "seti", m_set }, // setters for signed and unsigned are identical
- { "setbytes", m_setbytes },
- { "getfloat", m_getfloat },
- { "setfloat", m_setfloat },
- { "addfloat", m_addfloat },
- { "item", m_item },
- { "setitem", m_setitem },
- { "size", m_size },
- { "resize", m_resize },
- { "clear", m_clear },
- { "reverse", m_reverse },
- { "copy", m_copy },
- { "append", m_connect },
- { "+", m_merge },
- { "..", m_connect },
- { "==", m_equal },
- { "!=", m_nequal },
-
- { NULL, (bntvfunc) BE_CLOSURE }, /* mark section for berry closures */
- { "getbits", (bntvfunc) &getbits_closure },
- { "setbits", (bntvfunc) &setbits_closure },
-
- { NULL, NULL }
- };
- be_regclass(vm, "bytes", members);
-}
-#else
-
-#include "../generate/be_const_bytes_def.h"
-
-/* @const_object_info_begin
-class be_class_bytes (scope: global, name: bytes) {
- .p, var
- .len, var
- .size, var
- _buffer, func(m_buffer)
- _change_buffer, func(m_change_buffer)
- ismapped, func(m_is_mapped)
- isreadonly, func(m_is_readonly)
- init, func(m_init)
- deinit, func(m_deinit)
- tostring, func(m_tostring)
- asstring, func(m_asstring)
- tobool, func(m_tobool)
- fromstring, func(m_fromstring)
- tob64, func(m_tob64)
- fromb64, func(m_fromb64)
- fromhex, func(m_fromhex)
- tohex, func(m_tohex)
- add, func(m_add)
- get, func(m_getu)
- geti, func(m_geti)
- getfloat, func(m_getfloat)
- setfloat, func(m_setfloat)
- addfloat, func(m_addfloat)
- set, func(m_set)
- seti, func(m_set)
- setbytes, func(m_setbytes)
- item, func(m_item)
- setitem, func(m_setitem)
- size, func(m_size)
- resize, func(m_resize)
- clear, func(m_clear)
- reverse, func(m_reverse)
- copy, func(m_copy)
- append, func(m_connect)
- +, func(m_merge)
- .., func(m_connect)
- ==, func(m_equal)
- !=, func(m_nequal)
-
- getbits, closure(getbits_closure)
- setbits, closure(setbits_closure)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_be_class_bytes.h"
-#endif
diff --git a/lib/libesp32/Berry/src/be_class.c b/lib/libesp32/Berry/src/be_class.c
deleted file mode 100644
index 90c7b5599caf..000000000000
--- a/lib/libesp32/Berry/src/be_class.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_class.h"
-#include "be_string.h"
-#include "be_map.h"
-#include "be_exec.h"
-#include "be_gc.h"
-#include "be_vm.h"
-#include "be_func.h"
-#include "be_module.h"
-#include
-
-#define check_members(vm, c) \
- if (!(c)->members) { \
- (c)->members = be_map_new(vm); \
- }
-
-bclass* be_newclass(bvm *vm, bstring *name, bclass *super)
-{
- bgcobject *gco = be_gcnew(vm, BE_CLASS, bclass);
- bclass *obj = cast_class(gco);
- bvalue *buf = be_incrtop(vm); /* protect new objects from GC */
- var_setclass(buf, obj);
- if (obj) {
- obj->super = super;
- obj->members = NULL; /* gc protection */
- obj->nvar = 0;
- obj->name = name;
- }
- be_stackpop(vm, 1);
- return obj;
-}
-
-void be_class_compress(bvm *vm, bclass *c)
-{
- if (!gc_isconst(c) && c->members) {
- be_map_compact(vm, c->members); /* clear space */
- }
-}
-
-/* Return the type of the class attribute, only used to check if the attribute already exists */
-int be_class_attribute(bvm *vm, bclass *c, bstring *attr)
-{
- for (; c; c = c->super) {
- if (c->members) {
- bvalue *v = be_map_findstr(vm, c->members, attr);
- if (v) {
- return var_type(v);
- }
- }
- }
- return BE_NONE;
-}
-
-void be_class_member_bind(bvm *vm, bclass *c, bstring *name, bbool var)
-{
- bvalue *attr;
- set_fixed(name);
- check_members(vm, c);
- attr = be_map_insertstr(vm, c->members, name, NULL);
- restore_fixed(name);
- if (var) {
- /* this is an instance variable so we set it as MT_VARIABLE */
- attr->v.i = c->nvar++;
- attr->type = MT_VARIABLE;
- } else {
- /* this is a static class constant, leave it as BE_NIL */
- attr->v.i = 0;
- attr->type = BE_NIL;
- }
-}
-
-void be_class_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_static)
-{
- bclosure *cl;
- bvalue *attr;
- set_fixed(name);
- check_members(vm, c);
- attr = be_map_insertstr(vm, c->members, name, NULL);
- restore_fixed(name);
- var_setnil(attr);
- cl = be_newclosure(vm, p->nupvals);
- cl->proto = p;
- var_setclosure(attr, cl);
- if (is_static) {
- var_markstatic(attr);
- }
-}
-
-void be_class_native_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f)
-{
- bvalue *attr;
- set_fixed(name);
- check_members(vm, c);
- attr = be_map_insertstr(vm, c->members, name, NULL);
- restore_fixed(name);
- attr->v.nf = f;
- attr->type = MT_PRIMMETHOD;
-}
-
-void be_class_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl)
-{
- bvalue *attr;
- check_members(vm, c);
- attr = be_map_insertstr(vm, c->members, name, NULL);
- attr->v.gc = (bgcobject*) cl;
- attr->type = MT_METHOD;
-}
-
-/* get the closure method count that need upvalues */
-int be_class_closure_count(bclass *c)
-{
- int count = 0;
- if (c->members) {
- bmapnode *node;
- bmap *members = c->members;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(members, &iter)) != NULL) {
- if (var_isproto(&node->value)) {
- ++count;
- }
- }
- }
- return count;
-}
-
-static binstance* instance_member(bvm *vm,
- binstance *obj, bstring *name, bvalue *dst)
-{
- for (; obj; obj = obj->super) {
- bmap *members = obj->_class->members;
- if (members) {
- bvalue *v = be_map_findstr(vm, members, name);
- if (v) {
- *dst = *v;
- return obj;
- }
- }
- }
- var_setnil(dst);
- return NULL;
-}
-
-static bclass* class_member(bvm *vm,
- bclass *obj, bstring *name, bvalue *dst)
-{
- for (; obj; obj = obj->super) {
- bmap *members = obj->members;
- if (members) {
- bvalue *v = be_map_findstr(vm, members, name);
- if (v) {
- *dst = *v;
- return obj;
- }
- }
- }
- var_setnil(dst);
- return NULL;
-}
-
-void be_class_upvalue_init(bvm *vm, bclass *c)
-{
- bmap *mbr = c->members;
- if (mbr != NULL) {
- bmapnode *node;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(mbr, &iter)) != NULL) {
- if (var_isclosure(&node->value)) {
- bclosure *cl = var_toobj(&node->value);
- if (cl->proto->nupvals) {
- /* initialize the closure's upvalues */
- be_release_upvalues(vm, cl);
- be_initupvals(vm, cl);
- }
- }
- }
- }
-}
-
-/* (internal) Instanciate an instance for a single class and initialize variables to nil */
-static binstance* newobjself(bvm *vm, bclass *c)
-{
- size_t size = sizeof(binstance) + sizeof(bvalue) * (c->nvar - 1);
- bgcobject *gco = be_newgcobj(vm, BE_INSTANCE, size);
- binstance *obj = cast_instance(gco);
- be_assert(obj != NULL);
- if (obj) { /* initialize members */
- bvalue *v = obj->members, *end = v + c->nvar; /* instance variables is a simple array of pointers at obj->members of size c->nvar */
- while (v < end) { var_setnil(v); ++v; } /* Initialize all instance variables to `nil` */
- obj->_class = c; /* set its class object */
- obj->super = NULL; /* no super class instance for now */
- obj->sub = NULL; /* no subclass instance for now */
- }
- return obj;
-}
-
-/* (internal) Instanciate the whole chain of instances when there is a class hierarchy */
-/* All variables set to nil, constructors are not called here */
-static binstance* newobject(bvm *vm, bclass *c)
-{
- binstance *obj, *prev;
- be_assert(c != NULL);
- obj = prev = newobjself(vm, c);
- var_setinstance(vm->top, obj);
- be_incrtop(vm); /* protect new objects from GC */
- for (c = c->super; c; c = c->super) { /* initialize one instance object per class and per superclass */
- prev->super = newobjself(vm, c);
- prev->super->sub = prev; /* link the super/sub classes instances */
- prev = prev->super;
- }
- be_stackpop(vm, 1);
- return obj;
-}
-
-/* Instanciate new instance from stack with argc parameters */
-/* Pushes the constructor on the stack to be executed if a construtor is found */
-/* Returns true if a constructor is found */
-bbool be_class_newobj(bvm *vm, bclass *c, int pos, int argc, int mode)
-{
- bvalue init;
- binstance *obj = newobject(vm, c); /* create empty object hierarchy from class hierarchy */
- // reg = vm->reg + pos - mode; /* the stack may have changed, mode=1 when class is instanciated from module #104 */
- var_setinstance(vm->reg + pos, obj);
- var_setinstance(vm->reg + pos - mode, obj); /* copy to reg and reg+1 if mode==1 */
- /* find constructor */
- obj = instance_member(vm, obj, str_literal(vm, "init"), &init);
- if (obj && var_type(&init) != MT_VARIABLE) {
- /* copy argv */
- bvalue * reg;
- for (reg = vm->reg + pos + 1; argc > 0; --argc) {
- reg[argc] = reg[argc - 2];
- }
- *reg = init; /* set constructor */
- return btrue;
- }
- return bfalse;
-}
-
-/* Find instance member by name and copy value to `dst` */
-/* Do not look into virtual members */
-int be_instance_member_simple(bvm *vm, binstance *instance, bstring *name, bvalue *dst)
-{
- int type;
- be_assert(name != NULL);
- binstance * obj = instance_member(vm, instance, name, dst);
- if (obj && var_type(dst) == MT_VARIABLE) {
- *dst = obj->members[dst->v.i];
- }
- type = var_type(dst);
- var_clearstatic(dst);
- return type;
-}
-
-/* Find instance member by name and copy value to `dst` */
-/* Input: none of `obj`, `name` and `dst` may not be NULL */
-/* Returns the type of the member or BE_NONE if member not found */
-/* TODO need to support synthetic members */
-int be_instance_member(bvm *vm, binstance *instance, bstring *name, bvalue *dst)
-{
- int type;
- be_assert(name != NULL);
- binstance *obj = instance_member(vm, instance, name, dst);
- if (obj && var_type(dst) == MT_VARIABLE) {
- *dst = obj->members[dst->v.i];
- }
- type = var_type(dst);
- if (obj) {
- var_clearstatic(dst);
- return type;
- } else { /* if no method found, try virtual */
- /* if 'init' does not exist, create a virtual empty constructor */
- if (strcmp(str(name), "init") == 0) {
- var_setntvfunc(dst, be_default_init_native_function);
- return var_primetype(dst);
- } else {
- /* get method 'member' */
- obj = instance_member(vm, instance, str_literal(vm, "member"), vm->top);
- if (obj && basetype(var_type(vm->top)) == BE_FUNCTION) {
- bvalue *top = vm->top;
- var_setinstance(&top[1], instance);
- var_setstr(&top[2], name);
- vm->top += 3; /* prevent gc collection results */
- be_dofunc(vm, top, 2); /* call method 'member' */
- vm->top -= 3;
- *dst = *vm->top; /* copy result to R(A) */
- if (obj && var_type(dst) == MT_VARIABLE) {
- *dst = obj->members[dst->v.i];
- }
- type = var_type(dst);
- if (type == BE_MODULE) {
- /* check if the module is named `undefined` */
- bmodule *mod = var_toobj(dst);
- if (strcmp(be_module_name(mod), "undefined") == 0) {
- return BE_NONE; /* if the return value is module `undefined`, consider it is an error */
- }
- }
- var_clearstatic(dst);
- return type;
- }
- }
- }
- return BE_NONE;
-}
-
-int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst)
-{
- int type;
- be_assert(name != NULL);
- obj = class_member(vm, obj, name, dst);
- type = var_type(dst);
- var_clearstatic(dst);
- return obj ? type : BE_NONE;
-}
-
-bbool be_instance_setmember(bvm *vm, binstance *o, bstring *name, bvalue *src)
-{
- bvalue v;
- be_assert(name != NULL);
- binstance * obj = instance_member(vm, o, name, &v);
- if (obj && var_istype(&v, MT_VARIABLE)) {
- obj->members[var_toint(&v)] = *src;
- return btrue;
- } else {
- obj = instance_member(vm, o, str_literal(vm, "setmember"), &v);
- if (obj && var_type(&v) == MT_VARIABLE) {
- v = obj->members[v.v.i];
- }
- if (var_basetype(&v) == BE_FUNCTION) {
- bvalue *top = vm->top;
- var_setval(top, &v);
- var_setinstance(top + 1, o); /* move instance to argv[0] */
- var_setstr(top + 2, name); /* move method name to argv[1] */
- var_setval(top + 3, src); /* move method name to argv[1] */
- vm->top += 4; /* prevent collection results */
- be_dofunc(vm, top, 3); /* call method 'member' */
- vm->top -= 4;
- /* if return value is `false` or `undefined` signal an unknown attribute */
- int type = var_type(vm->top);
- if (type == BE_BOOL) {
- bbool ret = var_tobool(vm->top);
- if (!ret) {
- return bfalse;
- }
- } else if (type == BE_MODULE) {
- /* check if the module is named `undefined` */
- bmodule *mod = var_toobj(vm->top);
- if (strcmp(be_module_name(mod), "undefined") == 0) {
- return bfalse; /* if the return value is module `undefined`, consider it is an error */
- }
- }
- return btrue;
- }
- }
- return bfalse;
-}
-
-bbool be_class_setmember(bvm *vm, bclass *o, bstring *name, bvalue *src)
-{
- bvalue v;
- be_assert(name != NULL);
- if (!gc_isconst(o)) {
- bclass * obj = class_member(vm, o, name, &v);
- if (obj && !var_istype(&v, MT_VARIABLE)) {
- be_map_insertstr(vm, obj->members, name, src);
- return btrue;
- }
- }
- return bfalse;
-}
diff --git a/lib/libesp32/Berry/src/be_class.h b/lib/libesp32/Berry/src/be_class.h
deleted file mode 100644
index 12f317b5ff40..000000000000
--- a/lib/libesp32/Berry/src/be_class.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_CLASS_H
-#define BE_CLASS_H
-
-#include "be_object.h"
-
-#define MT_VARIABLE BE_INDEX
-#define MT_METHOD BE_CLOSURE
-#define MT_PRIMMETHOD BE_NTVFUNC
-
-#define be_class_name(cl) ((cl)->name)
-#define be_class_members(cl) ((cl)->members)
-#define be_class_super(cl) ((cl)->super)
-#define be_class_setsuper(self, sup) ((self)->super = (sup))
-#define be_class_setsub(self, sub) ((self)->sub = (sub))
-#define be_instance_name(obj) ((obj)->_class->name)
-#define be_instance_class(obj) ((obj)->_class)
-#define be_instance_members(obj) ((obj)->members)
-#define be_instance_member_count(obj) ((obj)->_class->nvar)
-#define be_instance_super(obj) ((obj)->super)
-#define be_instance_sub(obj) ((obj)->sub)
-
-struct bclass {
- bcommon_header;
- uint16_t nvar; /* members variable data field count */
- struct bclass *super;
- bmap *members;
- bstring *name;
- bgcobject *gray; /* for gc gray list */
-#ifdef __cplusplus
- BE_CONSTEXPR bclass(uint16_t nv, bclass *sup, bmap *mem, bstring *s) :
- next(0), type(BE_CLASS), marked(GC_CONST), nvar(nv),
- super(sup), members(mem), name(s), gray(0) {}
-#endif
-};
-
-struct binstance {
- bcommon_header;
- struct binstance *super;
- struct binstance *sub;
- bclass *_class;
- bgcobject *gray; /* for gc gray list */
- bvalue members[1]; /* members variable data field */
-};
-
-/* special structure accepting 3 instance variables used only for bytes() solidification */
-struct binstance_arg3 {
- bcommon_header;
- struct binstance *super;
- struct binstance *sub;
- bclass *_class;
- bgcobject *gray; /* for gc gray list */
- bvalue members[3]; /* members variable data field */
-};
-
-bclass* be_newclass(bvm *vm, bstring *name, bclass *super);
-void be_class_compress(bvm *vm, bclass *c);
-int be_class_attribute(bvm *vm, bclass *c, bstring *attr);
-void be_class_member_bind(bvm *vm, bclass *c, bstring *name, bbool var);
-void be_class_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_static);
-void be_class_native_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f);
-void be_class_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl);
-int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst);
-bbool be_class_setmember(bvm *vm, bclass *obj, bstring *name, bvalue *src);
-int be_class_closure_count(bclass *c);
-void be_class_upvalue_init(bvm *vm, bclass *c);
-bbool be_class_newobj(bvm *vm, bclass *c, int pos, int argc, int mode);
-int be_instance_member_simple(bvm *vm, binstance *obj, bstring *name, bvalue *dst);
-int be_instance_member(bvm *vm, binstance *obj, bstring *name, bvalue *dst);
-bbool be_instance_setmember(bvm *vm, binstance *obj, bstring *name, bvalue *src);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_code.c b/lib/libesp32/Berry/src/be_code.c
deleted file mode 100644
index 9f7cf1300fd3..000000000000
--- a/lib/libesp32/Berry/src/be_code.c
+++ /dev/null
@@ -1,976 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_code.h"
-#include "be_decoder.h"
-#include "be_parser.h"
-#include "be_lexer.h"
-#include "be_vector.h"
-#include "be_list.h"
-#include "be_var.h"
-#include "be_exec.h"
-#include "be_vm.h"
-
-#define NOT_MASK (1 << 0)
-#define NOT_EXPR (1 << 1)
-#define FUNC_RET_FLAG (1 << 0)
-
-#define isset(v, mask) (((v) & (mask)) != 0)
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#define notexpr(e) isset((e)->not, NOT_EXPR)
-#define notmask(e) isset((e)->not, NOT_MASK)
-#define exp2anyreg(f, e) exp2reg(f, e, -1) /* -1 means allocate a new register if needed */
-#define var2anyreg(f, e) var2reg(f, e, -1) /* -1 means allocate a new register if needed */
-#define hasjump(e) ((e)->t != (e)->f || notexpr(e))
-#define code_bool(f, r, b, j) codeABC(f, OP_LDBOOL, r, b, j)
-#define code_call(f, a, b) codeABC(f, OP_CALL, a, b, 0)
-#define code_getmbr(f, a, b, c) codeABC(f, OP_GETMBR, a, b, c)
-#define jumpboolop(e, b) ((b) != notmask(e) ? OP_JMPT : OP_JMPF)
-
-#if BE_USE_SCRIPT_COMPILER
-
-static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst);
-
-#if BE_DEBUG_RUNTIME_INFO
-static void codelineinfo(bfuncinfo *finfo)
-{
- bvector *vec = &finfo->linevec;
- int line = finfo->lexer->lastline;
- blineinfo *li = be_vector_end(vec);
- if (be_vector_isempty(vec) || li->linenumber != line) {
- be_vector_push(finfo->lexer->vm, vec, NULL);
- li = be_vector_end(vec);
- li->endpc = finfo->pc;
- li->linenumber = line;
- finfo->proto->lineinfo = be_vector_data(vec);
- finfo->proto->nlineinfo = be_vector_capacity(vec);
- } else {
- li->endpc = finfo->pc;
- }
-}
-#else
- #define codelineinfo(finfo)
-#endif
-
-/* Add new instruction in the code vector */
-static int codeinst(bfuncinfo *finfo, binstruction ins)
-{
- /* put new instruction in code array */
- be_vector_push_c(finfo->lexer->vm, &finfo->code, &ins);
- finfo->proto->code = be_vector_data(&finfo->code);
- finfo->proto->codesize = be_vector_capacity(&finfo->code);
- codelineinfo(finfo);
- return finfo->pc++;
-}
-
-static int codeABC(bfuncinfo *finfo, bopcode op, int a, int b, int c)
-{
- return codeinst(finfo, ISET_OP(op)
- | ISET_RA(a) | ISET_RKB(b) | ISET_RKC(c));
-}
-
-static int codeABx(bfuncinfo *finfo, bopcode op, int a, int bx)
-{
- return codeinst(finfo, ISET_OP(op) | ISET_RA(a) | ISET_Bx(bx));
-}
-
-/* Move value from register b to register a */
-/* Check the previous instruction to compact both instruction as one if possible */
-/* If b is a constant, add LDCONST or add MOVE otherwise */
-/* returns false if the move operation happened, or true if there was a register optimization and `b` should be replaced by `a` */
-static bbool code_move(bfuncinfo *finfo, int a, int b)
-{
- if (finfo->pc > finfo->binfo->lastjmp) { /* If not the first instruction of the function */
- binstruction *i = be_vector_end(&finfo->code); /* get the last instruction */
- bopcode op = IGET_OP(*i);
- if (op <= OP_LDNIL) { /* binop or unop */
- /* remove redundant MOVE instruction */
- int x = IGET_RA(*i), y = IGET_RKB(*i), z = IGET_RKC(*i);
- if (b == x && (a == y || (op < OP_NEG && a == z))) {
- *i = (*i & ~IRA_MASK) | ISET_RA(a);
- return btrue;
- }
- }
- if (!isK(b)) { /* OP_MOVE */
- /* check if the previous OP_MOVE is not identical */
- binstruction mov = ISET_OP(OP_MOVE) | ISET_RA(a) | ISET_RKB(b) | ISET_RKC(0);
- if (mov == *i) {
- return btrue; /* previous instruction is the same move, remove duplicate */
- }
- }
- }
- if (isK(b)) {
- codeABx(finfo, OP_LDCONST, a, b & 0xFF);
- } else {
- codeABC(finfo, OP_MOVE, a, b, 0);
- }
- return bfalse;
-}
-
-/* Free register at top (checks that it´s a register) */
-/* Warning: the register must be at top of stack */
-static void free_expreg(bfuncinfo *finfo, bexpdesc *e)
-{
- /* release temporary register */
- if (e && e->type == ETREG && e->v.idx == finfo->freereg - 1) { /* free ETREG only if it's top of stack */
- be_code_freeregs(finfo, 1);
- }
-}
-
-/* Privat. Allocate `count` new registers on the stack and uptade proto´s max nstack accordingly */
-/* Note: deallocate is simpler and handled by a macro */
-static void allocstack(bfuncinfo *finfo, int count)
-{
- int nstack = finfo->freereg + count;
- if (nstack > finfo->proto->nstack) {
- if (nstack >= 255) {
- be_lexerror(finfo->lexer, "register overflow (more than 255)");
- }
- finfo->proto->nstack = (bbyte)nstack;
- }
-}
-
-/* Allocate `count` registers at top of stack, update stack accordingly */
-int be_code_allocregs(bfuncinfo *finfo, int count)
-{
- int base = finfo->freereg;
- allocstack(finfo, count);
- finfo->freereg += (char)count;
- return base;
-}
-
-static void setjump(bfuncinfo *finfo, int pc, int dst)
-{
- binstruction *p = be_vector_at(&finfo->code, pc);
- int offset = dst - (pc + 1);
- /* instruction edit jump destination */
- *p = (*p & ~IBx_MASK) | ISET_sBx(offset);
-}
-
-static int isjumpbool(bfuncinfo *finfo, int pc)
-{
- binstruction *p = be_vector_at(&finfo->code, pc);
- bopcode op = IGET_OP(*p);
-
- if (op == OP_JMPT || op == OP_JMPF) {
- return 1;
- }
- return 0;
-}
-
-static int get_jump(bfuncinfo *finfo, int pc)
-{
- binstruction *i = be_vector_at(&finfo->code, pc);
- int offset = IGET_sBx(*i);
- return offset == NO_JUMP ? NO_JUMP : pc + 1 + offset;
-}
-
-static void patchlistaux(bfuncinfo *finfo, int list, int vtarget, int dtarget)
-{
- /* mark the last destination point of a jump to avoid false register optimization */
- if (vtarget > finfo->binfo->lastjmp) {
- finfo->binfo->lastjmp = vtarget;
- }
- if (dtarget > finfo->binfo->lastjmp) {
- finfo->binfo->lastjmp = dtarget;
- }
- while (list != NO_JUMP) {
- int next = get_jump(finfo, list);
- if (isjumpbool(finfo, list)) {
- setjump(finfo, list, dtarget); /* jump to default target */
- } else {
- setjump(finfo, list, vtarget);
- }
- list = next;
- }
-}
-
-static int appendjump(bfuncinfo *finfo, bopcode op, bexpdesc *e)
-{
- int reg = e ? var2anyreg(finfo, e) : 0;
- if (isK(reg)) {
- reg = be_code_allocregs(finfo, 1);
- code_move(finfo, reg, e->v.idx);
- e->v.idx = reg;
- e->type = ETREG;
- }
- return codeABx(finfo, op, reg, NO_JUMP + IsBx_MAX);
-}
-
-int be_code_jump(bfuncinfo *finfo)
-{
- return appendjump(finfo, OP_JMP, NULL);
-}
-
-void be_code_jumpto(bfuncinfo *finfo, int dst)
-{
- be_code_patchlist(finfo, be_code_jump(finfo), dst);
-}
-
-void be_code_jumpbool(bfuncinfo *finfo, bexpdesc *e, int jture)
-{
- int pc = appendjump(finfo, jumpboolop(e, jture), e);
- be_code_conjump(finfo, jture ? &e->t : &e->f, pc);
- be_code_patchjump(finfo, jture ? e->f : e->t);
- free_expreg(finfo, e);
- jture ? (e->f = NO_JUMP) : (e->t = NO_JUMP);
- e->not = 0;
-}
-
-/* connect jump */
-void be_code_conjump(bfuncinfo *finfo, int *list, int jmp)
-{
- if (jmp == NO_JUMP) {
- return;
- }
- if (*list == NO_JUMP) {
- *list = jmp;
- } else {
- int next, l = *list;
- while ((next = (get_jump(finfo, l))) != NO_JUMP) {
- l = next;
- }
- setjump(finfo, l, jmp);
- }
-}
-
-void be_code_patchlist(bfuncinfo *finfo, int list, int dst)
-{
- if (dst == finfo->pc) {
- be_code_patchjump(finfo, list);
- } else {
- patchlistaux(finfo, list, dst, dst);
- }
-}
-
-void be_code_patchjump(bfuncinfo *finfo, int jmp)
-{
- patchlistaux(finfo, jmp, finfo->pc, finfo->pc);
-}
-
-/* Allocate new constant for value k */
-/* If k is NULL then push `nil` value */
-static int newconst(bfuncinfo *finfo, bvalue *k)
-{
- int idx = be_vector_count(&finfo->kvec);
- be_vector_push_c(finfo->lexer->vm, &finfo->kvec, k);
- finfo->proto->ktab = be_vector_data(&finfo->kvec);
- finfo->proto->nconst = be_vector_capacity(&finfo->kvec);
- if (k == NULL) {
- var_setnil(&finfo->proto->ktab[idx]);
- }
- return idx;
-}
-
-/* Find constant by value and return constant number, or -1 if constant does not exist */
-/* The search is linear and limited to BE_CONST_SEARCH_SIZE elements for performance reasons */
-static int findconst(bfuncinfo *finfo, bexpdesc *e)
-{
- int i, count = be_vector_count(&finfo->kvec);
- /* if the constant table is too large, the lookup
- * operation will become very time consuming.
- * so only search the constant table for the
- * previous value.
- **/
- count = count < BE_CONST_SEARCH_SIZE ? count : BE_CONST_SEARCH_SIZE;
- for (i = 0; i < count; ++i) {
- bvalue *k = be_vector_at(&finfo->kvec, i);
- switch (e->type) {
- case ETINT:
- if (var_isint(k) && k->v.i == e->v.i) {
- return i;
- }
- break;
- case ETREAL:
- if (var_isreal(k) && k->v.r == e->v.r) {
- return i;
- }
- break;
- case ETSTRING:
- if (var_isstr(k) && be_eqstr(k->v.p, e->v.s)) {
- return i;
- }
- break;
- default:
- break;
- }
- }
- return -1;
-}
-
-/* convert expdesc to constant and return kreg index (either constant kindex or register number) */
-static int exp2const(bfuncinfo *finfo, bexpdesc *e)
-{
- int idx = findconst(finfo, e); /* does the constant already exist? */
- if (idx == -1) { /* if not add it */
- bvalue k = {0};
- switch (e->type) {
- case ETINT:
- k.type = BE_INT;
- k.v.i = e->v.i;
- break;
- case ETREAL:
- k.type = BE_REAL;
- k.v.r = e->v.r;
- break;
- case ETSTRING:
- k.type = BE_STRING;
- k.v.s = e->v.s;
- break;
- default: /* all other values are filled later */
- break;
- }
- idx = newconst(finfo, &k); /* create new constant */
- }
- if (idx < 256) { /* if constant number fits in KB or KC */
- e->type = ETCONST; /* new type is constant by index */
- e->v.idx = setK(idx);
- } else { /* index value is too large */
- e->type = ETREG; /* does not fit in compact mode, allocate an explicit register and emit LDCONTS */
- e->v.idx = be_code_allocregs(finfo, 1);
- codeABx(finfo, OP_LDCONST, e->v.idx, idx);
- }
- return e->v.idx;
-}
-
-static void free_suffix(bfuncinfo *finfo, bexpdesc *e)
-{
- int idx = e->v.ss.idx;
- int nlocal = be_list_count(finfo->local);
- /* release suffix register */
- if (!isK(idx) && idx >= nlocal) {
- be_code_freeregs(finfo, 1);
- }
- /* release object register */
- if (e->v.ss.tt == ETREG && (int)e->v.ss.obj >= nlocal && (e->v.ss.obj + 1 >= finfo->freereg)) {
- be_code_freeregs(finfo, 1);
- }
-}
-
-static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst, bbool no_reg_reuse)
-{
- int cand_dst = dst; /* candidate for new dst */
- int nlocal = be_list_count(finfo->local);
- int reg1 = (e1->v.ss.tt == ETREG) ? e1->v.ss.obj : -1; /* check if obj is ETREG or -1 */
- int reg2 = (!isK(e1->v.ss.idx) && e1->v.ss.idx >= nlocal) ? e1->v.ss.idx : -1; /* check if idx is ETREG or -1 */
- if (no_reg_reuse) { /* if no_reg_reuse flag, then don't reuse any register, this is useful for compound assignments */
- reg1 = reg2 = -1;
- }
-
- if (reg1 >= 0 && reg2 >= 0) {
- /* both are ETREG, we keep the lowest and discard the other */
- if (reg1 != reg2) {
- cand_dst = min(reg1, reg2);
- be_code_freeregs(finfo, finfo->freereg - cand_dst); /* and free the other one */
- } else {
- cand_dst = reg1; /* both ETREG are equal, we return its value */
- }
- } else if (reg1 >= 0) {
- cand_dst = reg1;
- } else if (reg2 >= 0) {
- cand_dst = reg2;
- } else {
- // dst unchanged
- }
-
- if (dst >= finfo->freereg) {
- dst = cand_dst; /* if dst was allocating a new register, use the more precise candidate */
- }
- return dst;
-}
-
-static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst, bbool no_reg_reuse)
-{
- dst = suffix_destreg(finfo, e, dst, no_reg_reuse);
- if (dst > finfo->freereg) {
- dst = finfo->freereg;
- }
- codeABC(finfo, op, dst, e->v.ss.obj, e->v.ss.idx);
- return dst;
-}
-
-/* idx: the proto index in proto_table
- * dst: the destination register
- **/
-static void code_closure(bfuncinfo *finfo, int idx, int dst)
-{
- codeABx(finfo, OP_CLOSURE, dst, idx); /* load closure to register */
-}
-
-/* Given an integer, check if we should create a constant */
-/* True for values 0..3 and if there is room for kindex */
-/* This optimization makes code more compact for commonly used ints */
-static bbool constint(bfuncinfo *finfo, bint i)
-{
- /* cache common numbers */
- if ((i < IsBx_MIN || i > IsBx_MAX) ||
- (i >= 0 && i <= 3 && be_vector_count(&finfo->kvec) < 256)) {
- return btrue;
- }
- return bfalse;
-}
-
-/* Compute variable from an expdesc */
-/* Return constant index, or existing register or fallback to dst */
-/* At exit, If dst is `freereg`, the register is allocated */
-static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
-{
- bbool no_reg_reuse = (dst >= 0); /* if dst reg is explicitly specified, do not optimize register allocation */
- if (dst < 0) { /* if unspecified, allocate a new register if needed */
- dst = finfo->freereg;
- }
- be_assert(e != NULL);
- switch (e->type) {
- case ETINT:
- if (constint(finfo, e->v.i)) {
- return exp2const(finfo, e);
- } else {
- codeABx(finfo, OP_LDINT, dst, var_toidx(e) + IsBx_MAX);
- }
- break;
- case ETBOOL:
- code_bool(finfo, dst, e->v.i != 0, 0);
- break;
- case ETNIL:
- codeABx(finfo, OP_LDNIL, dst, 0);
- break;
- case ETREAL:
- case ETSTRING:
- return exp2const(finfo, e);
- case ETPROTO:
- code_closure(finfo, e->v.idx, dst);
- break;
- case ETGLOBAL:
- codeABx(finfo, OP_GETGBL, dst, e->v.idx);
- break;
- case ETNGLOBAL:
- codeABC(finfo, OP_GETNGBL, dst, e->v.ss.idx, 0);
- break;
- case ETUPVAL:
- codeABx(finfo, OP_GETUPV, dst, e->v.idx);
- break;
- case ETMEMBER:
- dst = code_suffix(finfo, OP_GETMBR, e, dst, no_reg_reuse);
- break;
- case ETINDEX:
- dst = code_suffix(finfo, OP_GETIDX, e, dst, no_reg_reuse);
- break;
- case ETLOCAL: case ETREG: case ETCONST:
- return e->v.idx;
- default:
- return dst; /* error */
- }
- if (dst == finfo->freereg) { /* use a new register */
- be_code_allocregs(finfo, 1);
- }
- e->type = ETREG;
- e->v.idx = dst;
- return dst;
-}
-
-static int exp2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
-{
- int reg = var2reg(finfo, e, dst);
- if (hasjump(e)) { /* if conditional expression */
- int pcf = NO_JUMP; /* position of an eventual LOAD false */
- int pct = NO_JUMP; /* position of an eventual LOAD true */
- int jpt = appendjump(finfo, jumpboolop(e, 1), e);
- /* below is a simplified version of `codedestreg` for a single bexpdesc */
- if (e->type == ETREG) {
- /* if e is already ETREG from local calculation, we reuse the register */
- reg = e->v.idx;
- } else {
- /* otherwise, we allocate a new register or use the target provided */
- reg = (dst < 0) ? be_code_allocregs(finfo, 1) : dst;
- }
- be_code_conjump(finfo, &e->t, jpt);
- pcf = code_bool(finfo, reg, 0, 1);
- pct = code_bool(finfo, reg, 1, 0);
- patchlistaux(finfo, e->f, finfo->pc, pcf);
- patchlistaux(finfo, e->t, finfo->pc, pct);
- e->t = NO_JUMP;
- e->f = NO_JUMP;
- e->not = 0;
- }
- return reg;
-}
-
-/* Select dest registers from both expressions */
-/* If one of them is already a register, keep it */
-/* If e1 or e2 are registers, we keep the lowest and free the highest (that must be at top) */
-/* If none is a register, allocate a new one */
-/* Returns the destination register, guaranteed to be ETREG */
-static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst)
-{
- if (dst < 0) { dst = finfo->freereg; }
- int cand_dst = dst;
- int con1 = e1->type == ETREG, con2 = e2->type == ETREG;
-
- if (con1 && con2) {
- cand_dst = min(e1->v.idx, e2->v.idx);
- be_code_freeregs(finfo, 1);
- } else if (con1) {
- cand_dst = e1->v.idx;
- } else if (con2) {
- cand_dst = e2->v.idx;
- } else {
- if (dst >= finfo->freereg) {
- cand_dst = be_code_allocregs(finfo, 1);
- return cand_dst;
- }
- }
- if (dst >= finfo->freereg) {
- return cand_dst;
- } else {
- return dst;
- }
-}
-
-/* compute binary expression and update e1 as result */
-/* On exit, e1 is guaranteed to be ETREG, which may have been allocated */
-static void binaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e1, bexpdesc *e2, int dst)
-{
- int src1 = exp2reg(finfo, e1, dst); /* potentially force the target for src1 reg */
- int src2 = exp2anyreg(finfo, e2);
- dst = codedestreg(finfo, e1, e2, dst);
- codeABC(finfo, op, dst, src1, src2);
- e1->type = ETREG;
- e1->v.idx = dst; /* update register as output */
-}
-
-void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e)
-{
- switch (op) {
- case OptAnd:
- be_code_jumpbool(finfo, e, bfalse);
- break;
- case OptOr:
- be_code_jumpbool(finfo, e, btrue);
- break;
- default:
- exp2anyreg(finfo, e);
- break;
- }
-}
-
-/* Apply binary operator `op` to e1 and e2, result in e1 */
-void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2, int dst)
-{
- switch (op) {
- case OptAnd:
- var2anyreg(finfo, e2);
- be_code_conjump(finfo, &e2->f, e1->f);
- *e1 = *e2;
- break;
- case OptOr:
- var2anyreg(finfo, e2);
- be_code_conjump(finfo, &e2->t, e1->t);
- *e1 = *e2;
- break;
- case OptAdd: case OptSub: case OptMul: case OptDiv:
- case OptMod: case OptLT: case OptLE: case OptEQ:
- case OptNE: case OptGT: case OptGE: case OptConnect:
- case OptBitAnd: case OptBitOr: case OptBitXor:
- case OptShiftL: case OptShiftR:
- binaryexp(finfo, (bopcode)(op - OptAdd), e1, e2, dst);
- break;
- default: break;
- }
-}
-
-/* Apply unary operator and return register number */
-/* If input is register, change in place or allocate new register */
-static void unaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e)
-{
- int src = exp2anyreg(finfo, e);
- int dst = e->type == ETREG ? src : be_code_allocregs(finfo, 1);
- if (!(op == OP_MOVE && src == dst)) {
- /* skip if MOVE from same src / dst */
- codeABC(finfo, op, dst, src, 0);
- }
- e->type = ETREG;
- e->v.idx = dst;
-}
-
-/* Apply not to conditional expression */
-/* If literal compute the value */
-/* Or invert t/f subexpressions */
-static void code_not(bfuncinfo *finfo, bexpdesc *e)
-{
- switch (e->type) {
- case ETINT: e->v.i = e->v.i == 0; break;
- case ETREAL: e->v.i = e->v.r == cast(breal, 0); break;
- case ETNIL: e->v.i = 1; break;
- case ETBOOL: e->v.i = !e->v.i; break;
- case ETSTRING: e->v.i = 0; break;
- default: {
- unaryexp(finfo, OP_MOVE, e);
- int temp = e->t;
- e->t = e->f;
- e->f = temp;
- e->not = NOT_EXPR | (e->not ^ NOT_MASK);
- return;
- }
- }
- e->type = ETBOOL;
-}
-
-/* Negative value of literal or emit NEG opcode */
-static int code_neg(bfuncinfo *finfo, bexpdesc *e)
-{
- switch (e->type) {
- case ETINT: e->v.i = -e->v.i; break;
- case ETREAL: e->v.r = -e->v.r; break;
- case ETNIL: case ETBOOL: case ETSTRING:
- return 1; /* error */
- default:
- unaryexp(finfo, OP_NEG, e);
- }
- return 0;
-}
-
-/* Bit flip of literal or emit FLIP opcode */
-static int code_flip(bfuncinfo *finfo, bexpdesc *e)
-{
- switch (e->type) {
- case ETINT: e->v.i = ~e->v.i; break;
- case ETREAL: case ETNIL: case ETBOOL: case ETSTRING:
- return 2; /* error */
- default:
- unaryexp(finfo, OP_FLIP, e);
- }
- return 0;
-}
-
-/* Apply unary operator: not, neg or bitflip */
-int be_code_unop(bfuncinfo *finfo, int op, bexpdesc *e)
-{
- switch (op) {
- case OptNot:
- code_not(finfo, e); break;
- case OptFlip: /* do nothing */
- return code_flip(finfo, e);
- case OptSub:
- return code_neg(finfo, e);
- default:
- break;
- }
- return 0;
-}
-
-static void setbgblvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
-{
- if (isK(src)) { /* move const to register */
- code_move(finfo, finfo->freereg, src);
- src = finfo->freereg;
- }
- codeABC(finfo, op, src, e1->v.idx, 0);
-}
-
-static void setsupvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
-{
- if (isK(src)) { /* move const to register */
- code_move(finfo, finfo->freereg, src);
- src = finfo->freereg;
- }
- codeABx(finfo, op, src, e1->v.idx);
-}
-
-static void setsfxvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
-{
- int obj = e1->v.ss.obj;
- free_suffix(finfo, e1);
- if (isK(obj)) { /* move const to register */
- code_move(finfo, finfo->freereg, obj);
- obj = finfo->freereg;
- }
- codeABC(finfo, op, obj, e1->v.ss.idx, src);
-}
-
-/* Assign expr e2 to e1 */
-/* e1 must be in a register and have a valid idx */
-/* if `keep_reg` is true, do not release register */
-/* return 1 if assignment was possible, 0 if type is not compatible */
-int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg)
-{
- /* free_e2 indicates special case where ETINDEX or ETMEMBER need to be freed if top of registers */
- bbool free_e2 = (e2->type == ETINDEX || e2->type == ETMEMBER) && (e2->v.ss.idx != e1->v.idx) && (e2->v.ss.idx == finfo->freereg - 1);
- int src = exp2reg(finfo, e2,
- e1->type == ETLOCAL ? e1->v.idx : -1); /* Convert e2 to kreg */
- /* If e1 is a local variable, use the register */
-
- if (!keep_reg && (e1->type != ETLOCAL || e1->v.idx != src)) {
- free_expreg(finfo, e2); /* free source (checks only ETREG) */ /* TODO e2 is at top */
- } else if (!keep_reg && free_e2) {
- be_code_freeregs(finfo, 1);
- }
- switch (e1->type) {
- case ETLOCAL: /* It can't be ETREG. */
- if (e1->v.idx != src) {
- bbool reg_optimized = code_move(finfo, e1->v.idx, src); /* do explicit move only if needed */
- if (reg_optimized) {
- free_expreg(finfo, e2); /* free source (checks only ETREG) */
- *e2 = *e1; /* now e2 is e1 ETLOCAL */
- }
- }
- break;
- case ETGLOBAL: /* store to grobal R(A) -> G(Bx) by global index */
- setsupvar(finfo, OP_SETGBL, e1, src);
- break;
- case ETNGLOBAL: /* store to global R(A) -> G(Bx) by name */
- setbgblvar(finfo, OP_SETNGBL, e1, src);
- break;
- case ETUPVAL:
- setsupvar(finfo, OP_SETUPV, e1, src);
- break;
- case ETMEMBER: /* store to member R(A).RK(B) <- RK(C) */
- case ETINDEX: /* store to member R(A)[RK(B)] <- RK(C) */
- setsfxvar(finfo, (e1->type == ETMEMBER) ? OP_SETMBR : OP_SETIDX, e1, src);
- if (keep_reg && e2->type == ETREG && e1->v.ss.obj >= be_list_count(finfo->local)) {
- /* special case of walrus assignemnt when we need to recreate an ETREG */
- code_move(finfo, e1->v.ss.obj, src); /* move from ETREG to MEMBER instance*/
- free_expreg(finfo, e2); /* free source (checks only ETREG) */
- e2->v.idx = e1->v.ss.obj; /* update to new register */
- }
- break;
- default:
- return 1;
- }
- return 0;
-}
-
-/* Get the expdesc as a register */
-/* if already in a register, use the existing register */
-/* if local or const, allocate a new register and copy value */
-int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e)
-{
- int src = exp2anyreg(finfo, e); /* get variable register index */
- int dst = finfo->freereg;
- if ((e->type != ETREG) || (src < dst - 1)) { /* move local and const to new register, don't move if already top of stack */
- code_move(finfo, dst, src);
- be_code_allocregs(finfo, 1);
- } else {
- dst = src;
- }
- return dst;
-}
-
-int be_code_getmethod(bfuncinfo *finfo, bexpdesc *e)
-{
- int dst = finfo->freereg;
- be_assert(e->type == ETMEMBER);
- dst = code_suffix(finfo, OP_GETMET, e, dst, bfalse);
- /* method [object] args */
- be_code_allocregs(finfo, dst == finfo->freereg ? 2 : 1);
- return dst;
-}
-
-/* Generate a CALL instruction at base register with argc consecutive values */
-/* i.e. arg1 is base+1... */
-/* Important: argc registers are freed upon call, which are supposed to be registers above base */
-void be_code_call(bfuncinfo *finfo, int base, int argc)
-{
- codeABC(finfo, OP_CALL, base, argc, 0);
- be_code_freeregs(finfo, argc);
-}
-
-int be_code_proto(bfuncinfo *finfo, bproto *proto)
-{
- int idx = be_vector_count(&finfo->pvec);
- /* append proto to current function proto table */
- be_vector_push_c(finfo->lexer->vm, &finfo->pvec, &proto);
- finfo->proto->ptab = be_vector_data(&finfo->pvec);
- finfo->proto->nproto = be_vector_capacity(&finfo->pvec);
- return idx;
-}
-
-void be_code_closure(bfuncinfo *finfo, bexpdesc *e, int idx)
-{
- int reg = (e->type == ETGLOBAL || e->type == ETNGLOBAL) ? finfo->freereg: e->v.idx;
- code_closure(finfo, idx, reg);
- if (e->type == ETGLOBAL) { /* store to global R(A) -> G(Bx) */
- codeABx(finfo, OP_SETGBL, reg, e->v.idx);
- } else if (e->type == ETNGLOBAL) { /* store R(A) -> GLOBAL[RK(B)] */
- codeABC(finfo, OP_SETNGBL, reg, e->v.idx, 0);
- }
-}
-
-void be_code_close(bfuncinfo *finfo, int isret)
-{
- bblockinfo *binfo = finfo->binfo;
- if (isret) { /* in 'return' */
- while (binfo && !binfo->hasupval) {
- binfo = binfo->prev;
- }
- if (binfo) {
- codeABC(finfo, OP_CLOSE, 0, 0, 0);
- }
- } else if (binfo->prev) { /* leave block */
- if (binfo->hasupval) {
- codeABC(finfo, OP_CLOSE, binfo->nactlocals, 0, 0);
- }
- }
-}
-
-static void leave_function(bfuncinfo *finfo)
-{
- int try_depth = 0; /* count of exception catch blocks */
- bblockinfo *binfo = finfo->binfo;
- for (; binfo; binfo = binfo->prev) {
- if (binfo->type & BLOCK_EXCEPT) {
- ++try_depth; /* leave the exception catch block */
- }
- }
- if (try_depth) { /* exception catch blocks that needs to leave */
- be_code_exblk(finfo, try_depth);
- }
-}
-
-void be_code_ret(bfuncinfo *finfo, bexpdesc *e)
-{
- if (finfo->binfo->prev == NULL) {
- if (finfo->flags & FUNC_RET_FLAG) {
- return;
- }
- finfo->flags |= FUNC_RET_FLAG;
- }
- if (e) {
- int reg = exp2anyreg(finfo, e);
- be_code_close(finfo, 1);
- leave_function(finfo);
- codeABC(finfo, OP_RET, e->type != ETVOID, reg, 0);
- free_expreg(finfo, e);
- } else {
- be_code_close(finfo, 1);
- codeABC(finfo, OP_RET, 0, 0, 0);
- }
-}
-
-/* Package a suffix object from `c` with key `k` */
-/* Both expdesc are materialized in kregs */
-static void package_suffix(bfuncinfo *finfo, bexpdesc *c, bexpdesc *k)
-{
- c->v.ss.obj = exp2anyreg(finfo, c);
- int key = exp2anyreg(finfo, k);
- c->v.ss.tt = c->type;
- c->v.ss.idx = key;
-}
-
-int be_code_nglobal(bfuncinfo *finfo, bexpdesc *k)
-{
- return exp2anyreg(finfo, k);
-}
-
-/* Package a MEMBER suffix object from `c` with key `k` */
-void be_code_member(bfuncinfo *finfo, bexpdesc *c, bexpdesc *k)
-{
- package_suffix(finfo, c, k);
- c->type = ETMEMBER;
-}
-
-/* Package a INDEX suffix object from `c` with key `k` */
-void be_code_index(bfuncinfo *finfo, bexpdesc *c, bexpdesc *k)
-{
- package_suffix(finfo, c, k);
- c->type = ETINDEX;
-}
-
-void be_code_class(bfuncinfo *finfo, bexpdesc *dst, bclass *c)
-{
- int src;
- bvalue var = {0};
- var_setclass(&var, c); /* new var of CLASS type */
- src = newconst(finfo, &var); /* allocate a new constant and return kreg */
- if (dst->type == ETLOCAL) { /* if target is a local variable, just assign */
- codeABx(finfo, OP_LDCONST, dst->v.idx, src);
- } else if (dst->type == ETGLOBAL) { /* otherwise set as global with same name as class name */
- codeABx(finfo, OP_LDCONST, finfo->freereg, src);
- codeABx(finfo, OP_SETGBL, finfo->freereg, dst->v.idx);
- } else if (dst->type == ETNGLOBAL) {
- codeABx(finfo, OP_LDCONST, finfo->freereg, src);
- codeABC(finfo, OP_SETNGBL, finfo->freereg, dst->v.idx, 0);
- }
- codeABx(finfo, OP_CLASS, 0, src); /* emit CLASS opcode to register class */
-}
-
-void be_code_setsuper(bfuncinfo *finfo, bexpdesc *c, bexpdesc *s)
-{
- int self = exp2anyreg(finfo, c);
- int super = exp2anyreg(finfo, s);
- codeABC(finfo, OP_SETSUPER, self, super, 0);
- free_expreg(finfo, c);
- free_expreg(finfo, s);
-}
-
-/* Emit IMPORT opcode for import module */
-/* `m` is module name, is copied to register if not already */
-/* `v` is destination where the imported module is stored */
-/* If destination is a local variable, it is the destination of the IMPORT opcode */
-/* otherwise the value is copied to a temporary register and stored to the destination */
-/* TODO is this optilization useful, isn´t it done anyways by be_code_move optim? */
-void be_code_import(bfuncinfo *finfo, bexpdesc *m, bexpdesc *v)
-{
- int dst, src = exp2anyreg(finfo, m);
- if (v->type == ETLOCAL) {
- dst = v->v.idx;
- codeABC(finfo, OP_IMPORT, dst, src, 0);
- } else {
- dst = be_code_allocregs(finfo, 1);
- codeABC(finfo, OP_IMPORT, dst, src, 0);
- m->type = ETREG;
- m->v.idx = dst;
- be_code_setvar(finfo, v, m, bfalse);
- }
-}
-
-int be_code_exblk(bfuncinfo *finfo, int depth)
-{
- if (depth == 0) {
- return appendjump(finfo, OP_EXBLK, NULL);
- }
- codeABx(finfo, OP_EXBLK, 1, depth);
- return 0;
-}
-
-void be_code_catch(bfuncinfo *finfo, int base, int ecnt, int vcnt, int *jmp)
-{
- codeABC(finfo, OP_CATCH, base, ecnt, vcnt);
- if (jmp) {
- *jmp = NO_JUMP; /* reset jump point */
- be_code_conjump(finfo, jmp, be_code_jump(finfo));
- }
-}
-
-/* Emit RAISE opcode */
-/* e1 is the exception code */
-/* e2 is the exception description */
-/* both are materialized to a temp register (if not null) */
-void be_code_raise(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2)
-{
- if (e1) {
- int src1 = exp2anyreg(finfo, e1);
- int src2 = e2 ? exp2anyreg(finfo, e2) : 0;
- codeABC(finfo, OP_RAISE, e2 != NULL, src1, src2);
- } else {
- codeABC(finfo, OP_RAISE, 2, 0, 0); /* rethrow the current exception with parameters already on top of stack */
- }
- /* release the register occupied by the expression */
- free_expreg(finfo, e1);
- free_expreg(finfo, e2);
-}
-
-void be_code_implicit_class(bfuncinfo *finfo, bexpdesc *e, bclass *c)
-{
- bvalue k = {0};
- k.type = BE_CLASS;
- k.v.p = c;
- int idx = newconst(finfo, &k); /* create new constant */
- e->type = ETCONST; /* new type is constant by index */
- e->v.idx = setK(idx);
-}
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_code.h b/lib/libesp32/Berry/src/be_code.h
deleted file mode 100644
index f0ef2e1943c8..000000000000
--- a/lib/libesp32/Berry/src/be_code.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_CODE_H
-#define BE_CODE_H
-
-#include "be_parser.h"
-
-#define be_code_freeregs(f, n) ((f)->freereg -= (bbyte)(n))
-
-int be_code_allocregs(bfuncinfo *finfo, int count);
-void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e);
-void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2, int dst);
-int be_code_unop(bfuncinfo *finfo, int op, bexpdesc *e);
-int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg);
-int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e);
-int be_code_jump(bfuncinfo *finfo);
-void be_code_jumpto(bfuncinfo *finfo, int dst);
-void be_code_jumpbool(bfuncinfo *finfo, bexpdesc *e, int jumptrue);
-void be_code_conjump(bfuncinfo *finfo, int *list, int jmp);
-void be_code_patchlist(bfuncinfo *finfo, int list, int dst);
-void be_code_patchjump(bfuncinfo *finfo, int jmp);
-int be_code_getmethod(bfuncinfo *finfo, bexpdesc *e);
-void be_code_call(bfuncinfo *finfo, int base, int argc);
-int be_code_proto(bfuncinfo *finfo, bproto *proto);
-void be_code_closure(bfuncinfo *finfo, bexpdesc *e, int idx);
-void be_code_close(bfuncinfo *finfo, int isret);
-void be_code_class(bfuncinfo *finfo, bexpdesc *dst, bclass *c);
-void be_code_ret(bfuncinfo *finfo, bexpdesc *e);
-int be_code_nglobal(bfuncinfo *finfo, bexpdesc *k);
-void be_code_member(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2);
-void be_code_index(bfuncinfo *finfo, bexpdesc *c, bexpdesc *k);
-void be_code_setsuper(bfuncinfo *finfo, bexpdesc *c, bexpdesc *s);
-void be_code_import(bfuncinfo *finfo, bexpdesc *m, bexpdesc *v);
-int be_code_exblk(bfuncinfo *finfo, int depth);
-void be_code_catch(bfuncinfo *finfo, int base, int ecnt, int vcnt, int *jmp);
-void be_code_raise(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2);
-void be_code_implicit_class(bfuncinfo *finfo, bexpdesc *e, bclass *c);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_constobj.h b/lib/libesp32/Berry/src/be_constobj.h
deleted file mode 100644
index 86a871563110..000000000000
--- a/lib/libesp32/Berry/src/be_constobj.h
+++ /dev/null
@@ -1,508 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_CONSTOBJ_H
-#define BE_CONSTOBJ_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "be_object.h"
-#include "be_gc.h"
-#include "be_map.h"
-#include "be_list.h"
-#include "be_class.h"
-#include "be_string.h"
-#include "be_module.h"
-#include "be_byteslib.h"
-
-#ifndef __cplusplus
-
-#define be_const_header(_t) \
- .next = NULL, \
- .type = (_t), \
- .marked = GC_CONST
-
-#define be_define_const_bytes(_name, ...) \
- const binstance_arg3 be_const_instance_##_name = { \
- be_const_header(BE_INSTANCE), \
- .super = NULL, \
- .sub = NULL, \
- ._class = (bclass*) &be_class_bytes, \
- .members = { \
- {.v.c = (const void*) & (const uint8_t[]) { __VA_ARGS__ }, \
- .type = BE_COMPTR }, \
- be_const_int(sizeof(#_name) / 2), \
- be_const_int(BYTES_SIZE_SOLIDIFIED) \
- } \
- }
-
-/* special version to define a default empty bytes */
-#define be_define_const_bytes_empty() \
- const binstance_arg3 be_const_instance_ = { \
- be_const_header(BE_INSTANCE), \
- .super = NULL, \
- .sub = NULL, \
- ._class = (bclass*) &be_class_bytes, \
- .members = { \
- {.v.c = (const void*) & (const uint8_t[]) { 0x00 }, \
- .type = BE_COMPTR }, \
- be_const_int(0), \
- be_const_int(BYTES_SIZE_SOLIDIFIED) \
- } \
- }
-
-#define be_const_bytes_instance(_bytes) { \
- .v.c = &be_const_instance_##_bytes, \
- .type = BE_INSTANCE \
-}
-
-#define be_define_const_str_weak(_name, _s, _len) \
- const bcstring be_const_str_##_name = { \
- .next = NULL, \
- .type = BE_STRING, \
- .marked = GC_CONST, \
- .extra = 0, \
- .slen = _len, \
- .hash = 0, \
- .s = _s \
- }
-
-#define be_const_key(_str, _next) { \
- .v.c = &be_const_str_##_str, \
- .type = BE_STRING, \
- .next = (uint32_t)(_next) & 0xFFFFFF \
-}
-
-/* try to use the predefined string in strtab, but don't create an instance if none is present */
-/* the behavior is exactly the same as `be_const_key()` but it not detected by coc */
-#define be_const_key_weak(_str, _next) { \
- .v.c = &be_const_str_##_str, \
- .type = BE_STRING, \
- .next = (uint32_t)(_next) & 0xFFFFFF \
-}
-
-#define be_const_key_literal(_str, _next) { \
- .v.c = be_str_literal(#_str), \
- .type = BE_STRING, \
- .next = (uint32_t)(_next) & 0xFFFFFF \
-}
-
-#define be_const_key_int(_i, _next) { \
- .v.i = _i, \
- .type = BE_INT, \
- .next = (uint32_t)(_next) & 0xFFFFFF \
-}
-
-#define be_const_func(_func) { \
- .v.nf = (_func), \
- .type = BE_NTVFUNC \
-}
-
-#define be_const_static_func(_func) { \
- .v.nf = (_func), \
- .type = BE_NTVFUNC | BE_STATIC \
-}
-
-#define be_const_nil() { \
- .v.i = 0, \
- .type = BE_NIL \
-}
-
-#define be_const_int(_val) { \
- .v.i = (bint)(_val), \
- .type = BE_INT \
-}
-
-#define be_const_var(_val) { \
- .v.i = (bint)(_val), \
- .type = BE_INDEX \
-}
-
-#define be_const_real(_val) { \
- .v.r = (breal)(_val), \
- .type = BE_REAL \
-}
-
-#define be_const_real_hex(_val) { \
- .v.p = (void*)(_val), \
- .type = BE_REAL \
-}
-
-#define be_const_bool(_val) { \
- .v.b = (bbool)(_val), \
- .type = BE_BOOL \
-}
-
-#define be_const_str(_str) { \
- .v.s = (bstring*)(_str), \
- .type = BE_STRING \
-}
-
-#define be_const_comptr(_val) { \
- .v.c = (const void*)(_val), \
- .type = BE_COMPTR \
-}
-
-#define be_const_class(_class) { \
- .v.c = &(_class), \
- .type = BE_CLASS \
-}
-
-#define be_const_closure(_closure) { \
- .v.c = &(_closure), \
- .type = BE_CLOSURE \
-}
-
-#define be_const_static_closure(_closure) { \
- .v.c = &(_closure), \
- .type = BE_CLOSURE | BE_STATIC \
-}
-
-#define be_const_module(_module) { \
- .v.c = &(_module), \
- .type = BE_MODULE \
-}
-
-#define be_const_simple_instance(_instance) { \
- .v.c = (_instance), \
- .type = BE_INSTANCE \
-}
-
-#define be_const_map(_map) { \
- .v.c = &(_map), \
- .type = BE_MAP \
-}
-
-#define be_const_list(_list) { \
- .v.c = &(_list), \
- .type = BE_LIST \
-}
-
-#define be_define_const_map_slots(_name) \
-const bmapnode _name##_slots[] =
-
-#define be_define_const_map(_name, _size) \
-const bmap _name = { \
- be_const_header(BE_MAP), \
- .slots = (bmapnode*)_name##_slots, \
- .lastfree = NULL, \
- .size = _size, \
- .count = _size \
-}
-
-#define be_define_const_class(_name, _nvar, _super, _name_) \
-const bclass _name = { \
- be_const_header(BE_CLASS), \
- .nvar = _nvar, \
- .super = _super, \
- .members = (bmap*)&_name##_map, \
- .name = (bstring*)&be_const_str_##_name_ \
-}
-
-#define be_define_const_empty_class(_name, _super, _name_) \
-const bclass _name = { \
- be_const_header(BE_CLASS), \
- .nvar = 0, \
- .super = (bclass*)_super, \
- .members = NULL, \
- .name = (bstring*)&be_const_str_##_name_ \
-}
-
-#define be_define_const_module(_name, _name_) \
-const bmodule _name = { \
- be_const_header(BE_MODULE), \
- .table = (bmap*)&_name##_map, \
- .info.name = _name_, \
-}
-
-#define be_define_const_vector(_name, _data, _size) \
-const bvector _name = { \
- .capacity = _size, \
- .size = sizeof(bvalue), \
- .count = _size, \
- .data = (void*)_data, \
- .end = (void*)(_data + (_size) - 1) \
-}
-
-#define be_define_const_native_module(_module) \
-const bntvmodule_t be_native_module(_module) = { \
- .name = #_module, \
- .attrs = NULL, \
- .size = 0, \
- .module = (bmodule*)&(m_lib##_module) \
-}
-
-/* defines needed for solidified classes */
-#define be_local_class(_name, _nvar, _super, _map, _cname) \
- const bclass be_class_##_name = { \
- be_const_header(BE_CLASS), \
- .nvar = _nvar, \
- .super = (bclass*)_super, \
- .members = (bmap*)_map, \
- .name = _cname \
-}
-
-/* defines needed for solidified modules */
-#define be_local_module(_c_name, _module_name, _map) \
- static const bmodule m_lib##_c_name = { \
- be_const_header(BE_MODULE), \
- .table = (bmap*)_map, \
- .info.name = _module_name \
-}
-
-/* only instances with no super and no sub instance are supported */
-/* primarily for `list` and `map`*/
-#define be_nested_simple_instance(_class_ptr, _members) \
- & (const binstance) { \
- be_const_header(BE_INSTANCE), \
- .super = NULL, \
- .sub = NULL, \
- ._class = (bclass*) _class_ptr, \
- .members = _members \
- }
-
-#define be_nested_simple_instance_1_arg(_class_ptr, arg0) \
- & (const binstance) { \
- be_const_header(BE_INSTANCE), \
- .super = NULL, \
- .sub = NULL, \
- ._class = (bclass*) _class_ptr, \
- .members = { arg0 } \
- }
-
-
-/* only instances with no super and no sub instance are supported */
-/* primarily for `list` and `map`*/
-#define be_nested_simple_instance_3_args(_class_ptr, arg0, arg1, arg2) \
- & (const binstance_arg3) { \
- be_const_header(BE_INSTANCE), \
- .super = NULL, \
- .sub = NULL, \
- ._class = (bclass*) _class_ptr, \
- .members = { arg0, arg1, arg2 } \
- }
-
-#define be_nested_map(_size, _slots) \
- & (const bmap) { \
- be_const_header(BE_MAP), \
- .slots = _slots, \
- .lastfree = NULL, \
- .size = _size, \
- .count = _size \
- }
-
-#define be_nested_list(_size, _items) \
- & (const blist) { \
- be_const_header(BE_LIST), \
- .count = _size, \
- .capacity = _size, \
- .data = _items \
- }
-
-#define be_nested_str(_name_) \
- { \
- { .s=((bstring*)&be_const_str_##_name_) }, \
- BE_STRING \
- }
-
-/* variant that does not trigger strtab */
-#define be_nested_str_weak(_name_) \
- { \
- { .s=((bstring*)&be_const_str_##_name_) }, \
- BE_STRING \
- }
-
-/* variant for long strings that does not trigger strtab */
-#define be_nested_str_long(_name_) \
- { \
- { .s=((bstring*)&be_const_str_##_name_) }, \
- BE_STRING \
- }
-
-#define be_nested_str_literal(_name_) \
- { \
- { .s=(be_nested_const_str(_name_, _hash, sizeof(_name_)-1 ))\
- }, \
- BE_STRING \
- }
-
-#define be_str_literal(_str) \
- be_nested_const_str(_str, 0, sizeof(_str)-1 )
-
-#define be_str_weak(_str) \
- (bstring*) &be_const_str_##_str
-
-#define be_nested_string(_str, _hash, _len) \
- { \
- { .s=(be_nested_const_str(_str, _hash, _len )) \
- }, \
- BE_STRING \
- }
-
-#define be_nested_key(_str, _hash, _len, _next) \
- { \
- { .s=(be_nested_const_str(_str, _hash, _len )) }, \
- BE_STRING, \
- (uint32_t)(_next) & 0xFFFFFF \
- }
-
-#else
-
-// #define be_define_const_bytes(_name, ...) \
-// const uint8_t be_const_bin_##_name[] = { __VA_ARGS__ }
-
-#define be_define_const_str_weak(_name, _s, _len) \
-const bcstring be_const_str_##_name = { \
- NULL, \
- BE_STRING, \
- GC_CONST, \
- 0, \
- _len, \
- 0, \
- _s \
-}
-
-#define be_const_key(_str, _next) { \
- bvaldata(&be_const_str_##_str), \
- BE_STRING, \
- uint32_t((_next)&0xFFFFFF) \
-}
-
-/* try to use the predefined string in strtab, but don't create an instance if none is present */
-/* the behavior is exactly the same as `be_const_key()` but it not detected by coc */
-#define be_const_key_weak(_str, _next) { \
- bvaldata(&be_const_str_##_str), \
- BE_STRING, \
- uint32_t((_next)&0xFFFFFF) \
-}
-
-#define be_const_key_int(_i, _next) { \
- bvaldata(i), \
- BE_INT, \
- uint32_t((_next)&0xFFFFFF) \
-}
-
-#define be_const_func(_func) { \
- bvaldata(_func), \
- BE_NTVFUNC \
-}
-
-#define be_const_static_func(_func) { \
- bvaldata(_func), \
- BE_NTVFUNC | BE_STATIC \
-}
-
-#define be_const_nil() { \
- bvaldata(0), \
- BE_NIL \
-}
-
-#define be_const_int(_val) { \
- bvaldata(bint(_val)), \
- BE_INT \
-}
-
-#define be_const_bool(_val) { \
- bvaldata(bbool(_val)), \
- BE_BOOL \
-}
-
-#define be_const_var(_val) { \
- bvaldata(bint(_val)), \
- BE_INDEX \
-}
-
-#define be_const_real(_val) { \
- bvaldata(breal(_val)), \
- BE_REAL \
-}
-
-#define be_const_real_hex(_val) { \
- bvaldata((void*)(_val)), \
- BE_REAL \
-}
-
-#define be_const_comptr(_val) { \
- bvaldata((void*)(_val)), \
- BE_COMPTR \
-}
-
-#define be_const_str(_string) { \
- bvaldata(bstring(_string)), \
- BE_STRING \
-}
-
-#define be_const_class(_class) { \
- bvaldata(&(_class)), \
- BE_CLASS \
-}
-
-#define be_const_closure(_closure) { \
- bvaldata(&(_closure)), \
- BE_CLOSURE \
-}
-
-#define be_const_static_closure(_closure) { \
- bvaldata(&(_closure)), \
- BE_CLOSURE | BE_STATIC \
-}
-
-#define be_const_module(_module) { \
- bvaldata(&(_module)), \
- BE_MODULE \
-}
-
-#define be_define_const_map_slots(_name) \
-const bmapnode _name##_slots[] =
-
-#define be_define_const_map(_name, _size) \
-const bmap _name( \
- (bmapnode*)_name##_slots, _size \
-)
-
-#define be_define_const_class(_name, _nvar, _super, _name_) \
-const bclass _name( \
- _nvar, (bclass*)_super, (bmap*)&_name##_map, \
- (bstring*)&be_const_str_##_name_ \
-)
-
-#define be_define_const_empty_class(_name, _super, _name_) \
-const bclass _name( \
- 0, (bclass*)_super, NULL, \
- (bstring*)&be_const_str_##_name_ \
-)
-
-#define be_define_const_module(_name, _name_) \
-const bmodule _name((bmap*)&_name##_map, _name_)
-
-#define be_define_const_vector(_name, _data, _size) \
-const bvector _name = { \
- _size, sizeof(bvalue), _size, \
- (void*)_data, (void*)(_data + (_size) - 1) \
-}
-
-#define be_define_const_native_module(_module) \
-const bntvmodule_t be_native_module_##_module = { \
- #_module, \
- 0, 0, \
- (bmodule*)&(m_lib##_module) \
-}
-
-#endif
-
-/* provide pointers to map and list classes for solidified code */
-extern const bclass be_class_list;
-extern const bclass be_class_map;
-extern const bclass be_class_bytes;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_debug.c b/lib/libesp32/Berry/src/be_debug.c
deleted file mode 100644
index 142c4ea5eab4..000000000000
--- a/lib/libesp32/Berry/src/be_debug.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_debug.h"
-#include "be_func.h"
-#include "be_decoder.h"
-#include "be_string.h"
-#include "be_class.h"
-#include "be_vm.h"
-#include "be_vector.h"
-#include "be_strlib.h"
-#include "be_exec.h"
-#include "be_mem.h"
-#include "be_sys.h"
-#include
-#include
-
-#if BE_USE_DEBUG_HOOK && !BE_DEBUG_RUNTIME_INFO
- #error This macro BE_USE_DEBUG_HOOK requires BE_DEBUG_RUNTIME_INFO != 0
-#endif
-
-#ifndef INST_BUF_SIZE
-#define INST_BUF_SIZE 96
-#endif
-
-#define logbuf(...) snprintf(__lbuf, sizeof(__lbuf), __VA_ARGS__)
-
-#define logfmt(...) \
- do { \
- char __lbuf[INST_BUF_SIZE]; \
- logbuf(__VA_ARGS__); \
- be_writestring(__lbuf); \
- } while (0)
-
-#if BE_USE_DEBUG_MODULE
-static const char* opc2str(bopcode op)
-{
- static const char* const opc_tab[] = {
- #define OPCODE(opc) #opc
- #include "be_opcodes.h"
- #undef OPCODE
- };
- return op < array_count(opc_tab) ? opc_tab[op] : "ERROP";
-}
-
-void be_print_inst(binstruction ins, int pc, void* fout)
-{
- char __lbuf[INST_BUF_SIZE + 1], __lbuf_tmp[INST_BUF_SIZE];
- bopcode op = IGET_OP(ins);
-
- logbuf(" %.4X ", pc);
- if (fout) {
- be_fwrite(fout, __lbuf, strlen(__lbuf));
- } else {
- be_writestring(__lbuf);
- }
- switch (op) {
- case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
- case OP_MOD: case OP_LT: case OP_LE: case OP_EQ:
- case OP_NE: case OP_GT: case OP_GE: case OP_CONNECT:
- case OP_GETMBR: case OP_SETMBR: case OP_GETMET:
- case OP_GETIDX: case OP_SETIDX: case OP_AND:
- case OP_OR: case OP_XOR: case OP_SHL: case OP_SHR:
- logbuf("%s\tR%d\t%c%d\t%c%d", opc2str(op), IGET_RA(ins),
- isKB(ins) ? 'K' : 'R', IGET_RKB(ins) & KR_MASK,
- isKC(ins) ? 'K' : 'R', IGET_RKC(ins) & KR_MASK);
- break;
- case OP_GETNGBL: case OP_SETNGBL:
- logbuf("%s\tR%d\t%c%d", opc2str(op), IGET_RA(ins),
- isKB(ins) ? 'K' : 'R', IGET_RKB(ins) & KR_MASK);
- break;
- case OP_GETGBL: case OP_SETGBL:
- logbuf("%s\tR%d\tG%d", opc2str(op), IGET_RA(ins), IGET_Bx(ins));
- break;
- case OP_MOVE: case OP_SETSUPER: case OP_NEG: case OP_FLIP: case OP_IMPORT:
- logbuf("%s\tR%d\t%c%d", opc2str(op), IGET_RA(ins),
- isKB(ins) ? 'K' : 'R', IGET_RKB(ins) & KR_MASK);
- break;
- case OP_JMP:
- logbuf("%s\t\t#%.4X", opc2str(op), IGET_sBx(ins) + pc + 1);
- break;
- case OP_JMPT: case OP_JMPF:
- logbuf("%s\tR%d\t#%.4X", opc2str(op), IGET_RA(ins), IGET_sBx(ins) + pc + 1);
- break;
- case OP_LDINT:
- logbuf("%s\tR%d\t%d", opc2str(op), IGET_RA(ins), IGET_sBx(ins));
- break;
- case OP_LDBOOL:
- logbuf("%s\tR%d\t%d\t%d", opc2str(op), IGET_RA(ins), IGET_RKB(ins), IGET_RKC(ins));
- break;
- case OP_RET:
- if (IGET_RA(ins)) {
- logbuf("%s\t%d\t%c%d", opc2str(op), IGET_RA(ins),
- isKB(ins) ? 'K' : 'R', IGET_RKB(ins) & KR_MASK);
- } else {
- logbuf("%s\t%d", opc2str(op), IGET_RA(ins)); /* RET 0 does not take an additional parameter */
- }
- break;
- case OP_GETUPV: case OP_SETUPV:
- logbuf("%s\tR%d\tU%d", opc2str(op), IGET_RA(ins), IGET_Bx(ins));
- break;
- case OP_LDCONST:
- logbuf("%s\tR%d\tK%d", opc2str(op), IGET_RA(ins), IGET_Bx(ins));
- break;
- case OP_CALL:
- logbuf("%s\tR%d\t%d", opc2str(op), IGET_RA(ins), IGET_RKB(ins));
- break;
- case OP_CLOSURE:
- logbuf("%s\tR%d\tP%d", opc2str(op), IGET_RA(ins), IGET_Bx(ins));
- break;
- case OP_CLASS:
- logbuf("%s\tK%d", opc2str(op), IGET_Bx(ins));
- break;
- case OP_CLOSE: case OP_LDNIL:
- logbuf("%s\tR%d", opc2str(op), IGET_RA(ins));
- break;
- case OP_RAISE:
- logbuf("%s\t%d\t%c%d\t%c%d", opc2str(op), IGET_RA(ins),
- isKB(ins) ? 'K' : 'R', IGET_RKB(ins) & KR_MASK,
- isKC(ins) ? 'K' : 'R', IGET_RKC(ins) & KR_MASK);
- break;
- case OP_EXBLK:
- if (IGET_RA(ins)) {
- logbuf("%s\t%d\t%d", opc2str(op), IGET_RA(ins), IGET_Bx(ins));
- } else {
- logbuf("%s\t%d\t#%.4X", opc2str(op), IGET_RA(ins), IGET_sBx(ins) + pc + 1);
- }
- break;
- case OP_CATCH:
- logbuf("%s\tR%d\t%d\t%d", opc2str(op), IGET_RA(ins), IGET_RKB(ins), IGET_RKC(ins));
- break;
- default:
- logbuf("%s", opc2str(op));
- break;
- }
- memcpy(__lbuf_tmp, __lbuf, strlen(__lbuf) + 1);
- logbuf("%s\n", __lbuf_tmp);
- if (fout) {
- be_fwrite(fout, __lbuf, strlen(__lbuf));
- } else {
- be_writestring(__lbuf);
- }
-}
-#endif
-
-#if BE_USE_DEBUG_MODULE
-void be_dumpclosure(bclosure *cl)
-{
- int pc;
- bproto *proto = cl->proto;
- binstruction *code = proto->code;
-#if BE_DEBUG_RUNTIME_INFO
- blineinfo *lineinfo = proto->lineinfo;
-#endif
-#if BE_DEBUG_SOURCE_FILE
- logfmt("source '%s', ", str(proto->source));
-#endif
- logfmt("function '%s':\n", str(proto->name));
-#if BE_DEBUG_RUNTIME_INFO
- if (lineinfo) { /* first line */
- logfmt("; line %d\n", lineinfo->linenumber);
- }
-#endif
- for (pc = 0; pc < proto->codesize; pc++) {
-#if BE_DEBUG_RUNTIME_INFO
- if (lineinfo && pc > lineinfo->endpc) {
- logfmt("; line %d\n", (++lineinfo)->linenumber);
- }
-#endif
- be_print_inst(*code++, pc, NULL);
- }
-}
-#endif
-
-static void sourceinfo(bproto *proto, binstruction *ip)
-{
-#if BE_DEBUG_RUNTIME_INFO
- char buf[24];
- be_assert(proto != NULL);
- if (proto->lineinfo && proto->nlineinfo) {
- blineinfo *it = proto->lineinfo;
- blineinfo *end = it + proto->nlineinfo;
- int pc = cast_int(ip - proto->code - 1); /* now vm->ip has been increased */
- for (; it < end && pc > it->endpc; ++it);
- snprintf(buf, sizeof(buf), ":%d:", it->linenumber);
-#if BE_DEBUG_SOURCE_FILE
- be_writestring(str(proto->source));
-#endif
- be_writestring(buf);
- } else {
- be_writestring(":");
- }
-#else
- (void)proto; (void)ip;
- be_writestring(":");
-#endif
-}
-
-static void tracestack(bvm *vm)
-{
- bcallsnapshot *cf;
- bcallsnapshot *base = be_stack_base(&vm->tracestack);
- bcallsnapshot *top = be_stack_top(&vm->tracestack);
- be_writestring("stack traceback:\n");
- for (cf = top; cf >= base; --cf) {
- if (cf <= top - 10 && cf >= base + 10) {
- if (cf == top - 10)
- be_writestring("\t...\n");
- continue;
- }
- if (var_isclosure(&cf->func)) {
- bclosure *cl = var_toobj(&cf->func);
- be_writestring("\t");
- sourceinfo(cl->proto, cf->ip);
- be_writestring(" in function `");
- be_writestring(str(cl->proto->name));
- be_writestring("`\n");
- } else {
- be_writestring("\t: in native function\n");
- }
- }
-}
-
-static void repair_stack(bvm *vm)
-{
- bcallsnapshot *cf;
- bcallsnapshot *base = be_stack_base(&vm->tracestack);
- bcallsnapshot *top = be_stack_top(&vm->tracestack);
- /* Because the native function does not push `ip` to the
- * stack, the ip on the native function frame corresponds
- * to the previous Berry closure. */
- for (cf = top; cf >= base; --cf) {
- if (!var_isclosure(&cf->func)) {
- /* the last native function stack frame has the `ip` of
- * the previous Berry frame */
- binstruction *ip = cf->ip;
- /* skip native function stack frames */
- for (; cf >= base && !var_isclosure(&cf->func); --cf);
- /* fixed `ip` of Berry closure frame near native function frame */
- if (cf >= base) cf->ip = ip;
- }
- }
-}
-
-void be_tracestack(bvm *vm)
-{
- if (be_stack_count(&vm->tracestack)) {
- repair_stack(vm);
- tracestack(vm);
- }
-}
-
-#if BE_USE_DEBUG_HOOK
-
-static void hook_callnative(bvm *vm, int mask)
-{
- bhookinfo_t info;
- int top = be_top(vm);
- bcallframe *cf = vm->cf;
- bclosure *cl = var_toobj(cf->func);
- struct bhookblock *hb = var_toobj(&vm->hook);
- be_stack_require(vm, BE_STACK_FREE_MIN + 2);
- info.type = mask;
- info.line = cf->lineinfo->linenumber;
-#if BE_DEBUG_SOURCE_FILE
- info.source = str(cl->proto->source);
-#endif
- info.func_name = str(cl->proto->name);
- info.data = hb->data;
- hb->hook(vm, &info);
- vm->top += 2;
- be_pop(vm, be_top(vm) - top);
-}
-
-static int hook_pushargs(bvm *vm, int mask)
-{
- bcallframe *cf = vm->cf;
- if (mask == BE_HOOK_LINE) {
- be_pushstring(vm, "line");
- be_pushint(vm, cf->lineinfo->linenumber);
- return 2;
- }
- if (mask == BE_HOOK_CALL) {
- bclosure *cl = var_toobj(cf->func);
- be_pushstring(vm, "call");
- var_setstr(vm->top, cl->proto->name);
- vm->top++;
- return 2;
- }
- if (mask == BE_HOOK_RET) {
- be_pushstring(vm, "return");
- return 1;
- }
- return 0;
-}
-
-static void hook_call(bvm *vm, int mask)
-{
- int argc;
- vm->top[2] = vm->hook;
- be_stack_require(vm, 5);
- vm->top += 3;
- argc = hook_pushargs(vm, mask);
- be_call(vm, argc);
- be_pop(vm, 3 + argc);
-}
-
-void be_callhook(bvm *vm, int mask)
-{
- if (vm->hookmask & mask) {
- int hookmask = vm->hookmask;
- vm->hookmask = 0;
- if (var_istype(&vm->hook, BE_COMPTR)) {
- hook_callnative(vm, mask);
- } else {
- hook_call(vm, mask);
- }
- vm->hookmask = (bbyte)hookmask;
- }
-}
-
-static bbyte parse_hookmask(const char *mask)
-{
- int c, res = 0;
- if (mask) {
- while ((c = *mask++) != '\0') {
- switch (c) {
- case 'l': res |= BE_HOOK_LINE; break;
- case 'c': res |= BE_HOOK_CALL; break;
- case 'r': res |= BE_HOOK_RET; break;
- default: break;
- }
- }
- }
- return (bbyte)res;
-}
-
-BERRY_API void be_sethook(bvm *vm, const char *mask)
-{
- vm->hookmask = parse_hookmask(mask);
- if (vm->hookmask && var_istype(&vm->hook, BE_COMPTR)) /* free native hook */
- be_free(vm, var_toobj(&vm->hook), sizeof(struct bhookblock));
- if (vm->hookmask) {
- vm->hook = *be_indexof(vm, -1);
- } else if (!var_istype(&vm->hook, BE_COMPTR)) {
- var_setnil(&vm->hook);
- }
-}
-
-BERRY_API void be_setntvhook(bvm *vm, bntvhook hook, void *data, int mask)
-{
- struct bhookblock *hb;
- if (mask) {
- if (!var_istype(&vm->hook, BE_COMPTR)) {
- var_setobj(&vm->hook, BE_COMPTR,
- be_malloc(vm, sizeof(struct bhookblock)));
- }
- hb = var_toobj(&vm->hook);
- be_assert(hb != NULL);
- hb->hook = hook;
- hb->data = data;
- } else if (!var_istype(&vm->hook, BE_COMPTR)) {
- var_setnil(&vm->hook);
- }
- vm->hookmask = (bbyte)mask;
-}
-
-#endif
-
-#if BE_DEBUG_VAR_INFO
-static binstruction* callstack_fixip(bvm *vm, int level)
-{
- bcallframe *top = (bcallframe*)be_stack_top(&vm->callstack);
- bcallframe *cf = top - level + 2;
- for (; cf <= top && cf->status & PRIM_FUNC; ++cf);
- return cf <= top ? cf->ip : vm->ip;
-}
-
-bbool be_debug_varname(bvm *vm, int level, int index)
-{
- int depth = be_stack_count(&vm->callstack);
- if (level > 0 && level <= depth) {
- bcallframe *cf = be_vector_at(&vm->callstack, depth - level);
- if ((cf->status & PRIM_FUNC) == 0) {
- bproto *proto = cast(bclosure*, var_toobj(cf->func))->proto;
- int pc = (int)(callstack_fixip(vm, level) - proto->code);
- bstring *name = be_func_varname(proto, index, pc);
- if (name) {
- bvalue *reg = be_incrtop(vm);
- var_setstr(reg, name);
- return btrue;
- }
- }
- }
- return bfalse;
-}
-
-bbool be_debug_upvname(bvm *vm, int level, int index)
-{
- int depth = be_stack_count(&vm->callstack);
- if (level > 0 && level <= depth) {
- bcallframe *cf = be_vector_at(&vm->callstack, depth - level);
- if ((cf->status & PRIM_FUNC) == 0) {
- bproto *proto = cast(bclosure*, var_toobj(cf->func))->proto;
- if (index >= 0 && index < proto->nupvals) {
- bvalue *reg = be_incrtop(vm);
- var_setstr(reg, proto->upvals[index].name);
- return btrue;
- }
- }
- }
- return bfalse;
-}
-#endif
diff --git a/lib/libesp32/Berry/src/be_debug.h b/lib/libesp32/Berry/src/be_debug.h
deleted file mode 100644
index b8e2edf4b641..000000000000
--- a/lib/libesp32/Berry/src/be_debug.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_DEBUG_H
-#define BE_DEBUG_H
-
-#include "be_object.h"
-
-struct bhookblock {
- void *data;
- bntvhook hook;
-};
-
-void be_dumpclosure(bclosure *cl);
-void be_tracestack(bvm *vm);
-void be_callhook(bvm *vm, int mask);
-bbool be_debug_varname(bvm *vm, int level, int index);
-bbool be_debug_upvname(bvm *vm, int level, int index);
-
-#if BE_USE_DEBUG_MODULE
-void be_print_inst(binstruction ins, int pc, void* fout);
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_debuglib.c b/lib/libesp32/Berry/src/be_debuglib.c
deleted file mode 100644
index 2e4ee9bf41a7..000000000000
--- a/lib/libesp32/Berry/src/be_debuglib.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_module.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_class.h"
-#include "be_debug.h"
-#include "be_map.h"
-#include "be_vm.h"
-#include "be_exec.h"
-#include
-
-#if BE_USE_DEBUG_MODULE
-
-static void dump_map(bmap *map)
-{
- bmapnode *node;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(map, &iter)) != NULL) {
- if (var_isstr(&node->key)) {
- bstring *s = var_tostr(&node->key);
- be_writestring("\t");
- be_writebuffer(str(s), str_len(s));
- be_writestring(": <");
- be_writestring(be_vtype2str(&node->value));
- be_writestring(">\n");
- }
- }
-}
-
-static void dump_module(bmodule *module)
-{
- dump_map(module->table);
-}
-
-static void dump_class(bclass *class)
-{
- if (class->members) {
- dump_map(class->members);
- }
-}
-
-static void dump_instanse(binstance *ins)
-{
- dump_class(ins->_class);
-}
-
-static void dump_value(bvalue *value)
-{
- be_writestring("value type <");
- be_writestring(be_vtype2str(value));
- be_writestring(">, attributes:\n");
-}
-
-static int m_attrdump(bvm *vm)
-{
- if (be_top(vm) >= 1) {
- bvalue *v = be_indexof(vm, 1);
- void *obj = var_toobj(v);
- dump_value(v);
- switch (var_type(v)) {
- case BE_MODULE: dump_module(obj); break;
- case BE_CLASS: dump_class(obj); break;
- case BE_INSTANCE: dump_instanse(obj); break;
- default: break;
- }
- }
- be_return_nil(vm);
-}
-
-static int m_codedump(bvm *vm)
-{
- if (be_top(vm) >= 1) {
- bvalue *v = be_indexof(vm, 1);
- if (var_isclosure(v)) {
- be_dumpclosure(var_toobj(v));
- }
- }
- be_return_nil(vm);
-}
-
-static int m_gcdebug(bvm *vm) {
- int argc = be_top(vm);
- if (argc >= 1 && be_isbool(vm, 1)) {
- if (be_tobool(vm, 1)) {
- comp_set_gc_debug(vm);
- } else {
- comp_clear_gc_debug(vm);
- }
- }
- be_pushbool(vm, comp_is_gc_debug(vm));
- be_return(vm);
-}
-
-static int m_traceback(bvm *vm)
-{
- be_tracestack(vm);
- be_return_nil(vm);
-}
-
-static int m_caller(bvm *vm)
-{
- int depth = 1;
- if (be_top(vm) >= 1 && be_isint(vm, 1)) {
- depth = be_toint(vm, 1);
- if (depth < 0) {
- depth = -depth; /* take absolute value */
- }
- }
- bcallframe *cf = (bcallframe*)be_stack_top(&vm->callstack) - depth;
- bcallframe *base = be_stack_base(&vm->callstack);
- if (cf >= base) {
- bvalue *reg = be_incrtop(vm);
- var_setval(reg, cf->func);
- be_return(vm);
- } else {
- be_return_nil(vm);
- }
-}
-
-#if BE_USE_DEBUG_HOOK
-static int m_sethook(bvm *vm)
-{
- if (be_top(vm) >= 2) {
- be_pushvalue(vm, 1);
- be_sethook(vm, be_tostring(vm, 2));
- } else {
- be_sethook(vm, NULL);
- }
- be_return_nil(vm);
-}
-#endif
-
-static int m_top(bvm *vm)
-{
- bint top = vm->top - vm->stack + 1;
- be_pushint(vm, top);
- be_return(vm);
-}
-
-static int m_calldepth(bvm *vm)
-{
- bint depth = be_stack_count(&vm->callstack);
- be_pushint(vm, depth);
- be_return(vm);
-}
-
-#if BE_DEBUG_VAR_INFO
-static int v_getname(bvm *vm, bbool(*getter)(bvm *vm, int, int))
-{
- int index, level = 1;
- if (be_top(vm) < 1)
- be_raise(vm, "value_error", "too few arguments");
- if (!be_isint(vm, 1) || (be_top(vm) >= 2 && !be_isint(vm, 2)))
- be_raise(vm, "value_error", "invalid argument(s) value");
- if (be_top(vm) >= 2)
- level = be_toindex(vm, 2);
- index = be_toindex(vm, 1);
- if (index < 0)
- be_raise(vm, "value_error", "variable index cannot be less than 0");
- if (level < 1 || level >= be_stack_count(&vm->callstack))
- be_raise(vm, "value_error", "invalid call depth level");
- if (getter(vm, level + 1, index)) {
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_varname(bvm *vm)
-{
- return v_getname(vm, be_debug_varname);
-}
-
-static int m_upvname(bvm *vm)
-{
- return v_getname(vm, be_debug_upvname);
-}
-#endif
-
-
-#if BE_USE_PERF_COUNTERS
-static void map_insert(bvm *vm, const char *key, int value)
-{
- be_pushstring(vm, key);
- be_pushint(vm, value);
- be_data_insert(vm, -3);
- be_pop(vm, 2);
-}
-
-static int m_counters(bvm *vm)
-{
- be_newobject(vm, "map");
- map_insert(vm, "instruction", vm->counter_ins);
- map_insert(vm, "vmenter", vm->counter_enter);
- map_insert(vm, "call", vm->counter_call);
- map_insert(vm, "get", vm->counter_get);
- map_insert(vm, "set", vm->counter_set);
- map_insert(vm, "getgbl", vm->counter_get_global);
- map_insert(vm, "try", vm->counter_try);
- map_insert(vm, "raise", vm->counter_exc);
- map_insert(vm, "objects", vm->counter_gc_kept);
- map_insert(vm, "mem_alloc", vm->counter_mem_alloc);
- map_insert(vm, "mem_free", vm->counter_mem_free);
- map_insert(vm, "mem_realloc", vm->counter_mem_realloc);
- be_pop(vm, 1);
- be_return(vm);
-}
-#endif
-
-static int m_allocs(bvm *vm) {
-#if BE_USE_PERF_COUNTERS
- be_pushint(vm, vm->counter_mem_alloc);
- be_return(vm);
-#else
- be_return_nil(vm);
-#endif
-}
-
-static int m_frees(bvm *vm) {
-#if BE_USE_PERF_COUNTERS
- be_pushint(vm, vm->counter_mem_free);
- be_return(vm);
-#else
- be_return_nil(vm);
-#endif
-}
-
-static int m_reallocs(bvm *vm) {
-#if BE_USE_PERF_COUNTERS
- be_pushint(vm, vm->counter_mem_realloc);
- be_return(vm);
-#else
- be_return_nil(vm);
-#endif
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(debug) {
- be_native_module_function("attrdump", m_attrdump),
- be_native_module_function("codedump", m_codedump),
- be_native_module_function("traceback", m_traceback),
-#if BE_USE_DEBUG_HOOK
- be_native_module_function("sethook", m_sethook),
-#endif
-#if BE_USE_PERF_COUNTERS
- be_native_module_function("counters", m_counters),
-#endif
- be_native_module_function("calldepth", m_calldepth),
- be_native_module_function("top", m_top),
-#if BE_DEBUG_VAR_INFO
- be_native_module_function("varname", m_varname),
- be_native_module_function("upvname", m_upvname)
-#endif
- be_native_module_function("caller", m_caller),
- be_native_module_function("gcdebug", m_gcdebug)
-};
-
-be_define_native_module(debug, NULL);
-#else
-/* @const_object_info_begin
-module debug (scope: global, depend: BE_USE_DEBUG_MODULE) {
- attrdump, func(m_attrdump)
- codedump, func(m_codedump)
- traceback, func(m_traceback)
- sethook, func(m_sethook), BE_USE_DEBUG_HOOK
- counters, func(m_counters), BE_USE_PERF_COUNTERS
- calldepth, func(m_calldepth)
- top, func(m_top)
- varname, func(m_varname), BE_DEBUG_VAR_INFO
- upvname, func(m_upvname), BE_DEBUG_VAR_INFO
- caller, func(m_caller)
- // individual counters
- allocs, func(m_allocs)
- frees, func(m_frees)
- reallocs, func(m_reallocs)
- // GC debug mode
- gcdebug, func(m_gcdebug)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_debug.h"
-#endif
-
-#endif /* BE_USE_DEBUG_MODULE */
diff --git a/lib/libesp32/Berry/src/be_decoder.h b/lib/libesp32/Berry/src/be_decoder.h
deleted file mode 100644
index c6cfd7ade636..000000000000
--- a/lib/libesp32/Berry/src/be_decoder.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_OPCODE_H
-#define BE_OPCODE_H
-
-#define NO_JUMP -1
-
-/* define field's bit-width */
-#define IOP_BITS 6u
-#define IRA_BITS 8u
-#define IRKB_BITS 9u
-#define IRKC_BITS 9u
-
-/* define field's bit-width and positions */
-#define IRKC_POS 0u
-#define IRKB_POS (IRKC_POS + IRKC_BITS)
-#define IRA_POS (IRKB_POS + IRKB_BITS)
-#define IOP_POS (IRA_POS + IRA_BITS)
-#define IAx_BITS (IRA_BITS + IRKB_BITS + IRKC_BITS)
-#define IBx_BITS (IRKC_BITS + IRKB_BITS)
-
-/* basic field operation */
-#define INS_MASK(pos, bits) ((binstruction)((1 << (bits)) - 1) << (pos))
-#define INS_GETx(i, mask, pos) cast_int(((binstruction)(i) & (mask)) >> (pos))
-#define INS_SETx(v, mask, pos) (((binstruction)(v) << (pos)) & (mask))
-
-/* instruction operation */
-#define isK(v) (((v) & (1 << (IRKB_BITS - 1))) != 0)
-#define setK(v) ((v) | (1 << (IRKB_BITS - 1)))
-#define KR2idx(v) ((v) & 0xFF)
-#define isKB(v) (((v) & (1 << (IRA_POS - 1))) != 0)
-#define isKC(v) (((v) & (1 << (IRKB_POS - 1))) != 0)
-
-/* define masks and limit values */
-#define IOP_MASK INS_MASK(IOP_POS, IOP_BITS)
-#define IRA_MASK INS_MASK(IRA_POS, IRA_BITS)
-#define IRKB_MASK INS_MASK(IRKB_POS, IRKB_BITS)
-#define IRKC_MASK INS_MASK(IRKC_POS, IRKC_BITS)
-#define IAx_MASK INS_MASK(0, IAx_BITS)
-#define IBx_MASK INS_MASK(0, IBx_BITS)
-#define IsBx_MAX cast_int(IBx_MASK >> 1)
-#define IsBx_MIN cast_int(-IsBx_MAX - 1)
-
-/* mask for K/R values */
-#define KR_MASK ((1 << (IRKB_BITS-1)) - 1)
-
-/* get field */
-#define IGET_OP(i) cast(bopcode, INS_GETx(i, IOP_MASK, IOP_POS))
-#define IGET_RA(i) INS_GETx(i, IRA_MASK, IRA_POS)
-#define IGET_RKB(i) INS_GETx(i, IRKB_MASK, IRKB_POS)
-#define IGET_RKC(i) INS_GETx(i, IRKC_MASK, IRKC_POS)
-#define IGET_Bx(i) INS_GETx(i, IBx_MASK, 0)
-#define IGET_sBx(i) (IGET_Bx(i) - IsBx_MAX)
-
-/* set field */
-#define ISET_OP(i) INS_SETx(i, IOP_MASK, IOP_POS)
-#define ISET_RA(i) INS_SETx(i, IRA_MASK, IRA_POS)
-#define ISET_RKB(i) INS_SETx(i, IRKB_MASK, IRKB_POS)
-#define ISET_RKC(i) INS_SETx(i, IRKC_MASK, IRKC_POS)
-#define ISET_Bx(i) INS_SETx(i, IBx_MASK, 0)
-#define ISET_sBx(i) (ISET_Bx(cast_int(i) + IsBx_MAX))
-
-typedef enum {
- #define OPCODE(opc) OP_##opc
- #include "be_opcodes.h"
- #undef OPCODE
-} bopcode;
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_exec.c b/lib/libesp32/Berry/src/be_exec.c
deleted file mode 100644
index 794987933442..000000000000
--- a/lib/libesp32/Berry/src/be_exec.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_exec.h"
-#include "be_parser.h"
-#include "be_vm.h"
-#include "be_vector.h"
-#include "be_mem.h"
-#include "be_sys.h"
-#include "be_debug.h"
-#include "be_bytecode.h"
-#include "be_decoder.h"
-#include
-#include
-
-#if !BE_USE_SCRIPT_COMPILER && !BE_USE_BYTECODE_LOADER
- #error no compiler or bytecode loader enabled.
-#endif
-
-#define FILE_BUFFER_SIZE 256
-
-#define __STR(s) #s
-#define STR(s) __STR(s)
-
-#define STACK_OVER_MSG(n) \
- "stack overflow (maximum stack size is " STR(n) ")"
-
-#ifdef BE_EXPLICIT_ABORT
- #define _os_abort BE_EXPLICIT_ABORT
-#else
- #define _os_abort abort
-#endif
-
-#ifdef BE_EXPLICIT_EXIT
- #define _os_exit BE_EXPLICIT_EXIT
-#else
- #define _os_exit exit
-#endif
-
-#define exec_try(j) if (be_setjmp((j)->b) == 0)
-#define exec_throw(j) be_longjmp((j)->b, 1)
-
-#define fixup_ptr(ptr, offset) ((ptr) = (void*)((bbyte*)(ptr) + (offset)))
-#define ptr_offset(ptr1, ptr2) ((bbyte*)(ptr1) - (bbyte*)(ptr2))
-
-struct pparser {
- const char *fname;
- breader reader;
- void *data;
- bbyte islocal;
-};
-
-struct pcall {
- bvalue *v;
- int argc;
-};
-
-struct vmstate {
- int top, reg, depth;
- int refcount;
-};
-
-struct strbuf {
- size_t len;
- const char *s;
-};
-
-struct filebuf {
- void *fp;
- char buf[FILE_BUFFER_SIZE];
-};
-
-void be_throw(bvm *vm, int errorcode)
-{
-#if BE_USE_PERF_COUNTERS
- vm->counter_exc++;
-#endif
- /* if BE_MALLOC_FAIL then call */
- if (errorcode == BE_MALLOC_FAIL) {
- if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_MALLOC_FAIL, vm->gc.usage);
- }
- if (vm->errjmp) {
- vm->errjmp->status = errorcode;
- exec_throw(vm->errjmp);
- } else {
- _os_abort();
- }
-}
-
-/* Fatal error Exit */
-/* Raise a BE_EXIT exception if within a try/catch block, or exit VM */
-BERRY_API void be_exit(bvm *vm, int status)
-{
- if (vm->errjmp) {
- be_pushint(vm, status);
- be_pop(vm, 1);
- be_throw(vm, BE_EXIT);
- } else {
- _os_exit(status);
- }
-}
-
-void be_throw_message(bvm *vm, int errorcode, const char *msg)
-{
- be_pushstring(vm, msg);
- be_throw(vm, errorcode);
-}
-
-/* Exec protected: exec function and capture any exception and contain it within call */
-/* Exceptions or fatal errors are not propagated */
-int be_execprotected(bvm *vm, bpfunc f, void *data)
-{
- struct blongjmp jmp;
- jmp.status = 0;
- jmp.prev = vm->errjmp; /* save long jump position */
- vm->errjmp = &jmp;
- exec_try(vm->errjmp) {
- f(vm, data);
- }
- vm->errjmp = jmp.prev; /* restore long jump position */
- return jmp.status;
-}
-
-static void vm_state_save(bvm *vm, struct vmstate *state)
-{
- state->depth = be_stack_count(&vm->callstack);
- state->top = cast_int(vm->top - vm->stack);
- state->reg = cast_int(vm->reg - vm->stack);
- state->refcount = vm->refstack.count;
-}
-
-static void copy_exception(bvm *vm, int res, int dstindex)
-{
- bvalue *dst = vm->stack + dstindex;
- if (res == BE_EXCEPTION || res == BE_EXIT) {
- bvalue *src = vm->top;
- *dst++ = *src++;
- if (res == BE_EXCEPTION) {
- *dst++ = *src++;
- }
- }
- vm->top = dst;
-}
-
-static void vm_state_restore(bvm *vm, const struct vmstate *state, int res)
-{
- vm->reg = vm->stack + state->reg;
- be_vector_resize(vm, &vm->refstack, state->refcount);
- /* copy exception information to top */
- copy_exception(vm, res, state->top);
- be_assert(be_stack_count(&vm->callstack) >= state->depth);
- if (be_stack_count(&vm->callstack) > state->depth) {
- be_vector_resize(vm, &vm->callstack, state->depth);
- vm->cf = be_stack_top(&vm->callstack);
- }
-}
-
-#if BE_USE_SCRIPT_COMPILER
-static void m_parser(bvm *vm, void *data)
-{
- struct pparser *p = cast(struct pparser*, data);
- bclosure *cl = be_parser_source(vm,
- p->fname, p->reader, p->data, p->islocal);
- var_setclosure(vm->top, cl);
- be_incrtop(vm);
-}
-
-int be_protectedparser(bvm *vm,
- const char *fname, breader reader, void *data, bbool islocal)
-{
- int res;
- struct pparser s;
- struct vmstate state;
- s.fname = fname;
- s.reader = reader;
- s.data = data;
- s.islocal = (bbyte)(islocal != 0);
- vm_state_save(vm, &state);
- res = be_execprotected(vm, m_parser, &s);
- if (res) { /* restore call stack */
- vm_state_restore(vm, &state, res);
- }
- return res;
-}
-
-static const char* _sgets(struct blexer* lexer, void *data, size_t *size)
-{
- (void)lexer;
- struct strbuf *sb = data;
- *size = sb->len;
- if (sb->len) {
- sb->len = 0;
- return sb->s;
- }
- return NULL;
-}
-
-static const char* _fgets(struct blexer* lexer, void *data, size_t *size)
-{
- (void)lexer;
- struct filebuf *fb = data;
- *size = be_fread(fb->fp, fb->buf, sizeof(fb->buf));
- if (*size) {
- return fb->buf;
- }
- return NULL;
-}
-
-BERRY_API int be_loadbuffer(bvm *vm,
- const char *name, const char *buffer, size_t length)
-{
- struct strbuf sbuf;
- sbuf.s = buffer;
- sbuf.len = length;
- return be_protectedparser(vm, name, _sgets, &sbuf, bfalse);
-}
-
-static int fileparser(bvm *vm, const char *name, bbool islocal)
-{
- int res = BE_IO_ERROR;
- struct filebuf *fbuf = be_malloc(vm, sizeof(struct filebuf));
- fbuf->fp = be_fopen(name, "r");
- if (fbuf->fp) {
- res = be_protectedparser(vm, name, _fgets, fbuf, islocal);
- be_fclose(fbuf->fp);
- }
- be_free(vm, fbuf, sizeof(struct filebuf));
- return res;
-}
-#endif /* BE_USE_SCRIPT_COMPILER */
-
-#if BE_USE_BYTECODE_LOADER
-static void bytecode_loader(bvm *vm, void *data)
-{
- bclosure *cl = be_bytecode_load(vm, (const char *)data);
- if (cl != NULL) {
- var_setclosure(vm->top, cl);
- } else {
- var_setnil(vm->top);
- }
- be_incrtop(vm);
-}
-
-/* load bytecode file */
-static int load_bytecode(bvm *vm, const char *name)
-{
- int res = BE_SYNTAX_ERROR;
- if (be_bytecode_check(name)) {
- struct vmstate state;
- vm_state_save(vm, &state);
- res = be_execprotected(vm, bytecode_loader, (void*)name);
- if (res) { /* restore call stack */
- vm_state_restore(vm, &state, res);
- }
- }
- return res;
-}
-
-#else
-#define load_bytecode(vm, name) BE_SYNTAX_ERROR
-#endif /* BE_USE_BYTECODE_LOADER */
-
-BERRY_API int be_loadmode(bvm *vm, const char *name, bbool islocal)
-{
- int res = load_bytecode(vm, name);
-#if BE_USE_SCRIPT_COMPILER
- if (res && res != BE_IO_ERROR && res != BE_EXCEPTION) {
- res = fileparser(vm, name, islocal);
- }
-#else
- (void)islocal;
-#endif
- if (res == BE_IO_ERROR) {
- be_pushfstring(vm, "cannot open file '%s'.", name);
- }
- return res;
-}
-
-#if BE_USE_BYTECODE_SAVER
-static void _bytecode_save(bvm *vm, void *data)
-{
- if (be_top(vm) > 0 && var_isclosure(vm->top - 1)) {
- bclosure *cl = var_toobj(vm->top - 1);
- be_bytecode_save(vm, (const char *)data, cl->proto);
- }
-}
-
-/* save bytecode file */
-BERRY_API int be_savecode(bvm *vm, const char *name)
-{
- int res;
- struct vmstate state;
- vm_state_save(vm, &state);
- res = be_execprotected(vm, _bytecode_save, (void *)name);
- if (res) { /* restore call stack */
- vm_state_restore(vm, &state, res);
- }
- return res;
-}
-#endif
-
-static void m_pcall(bvm *vm, void *data)
-{
- struct pcall *p = cast(struct pcall*, data);
- be_dofunc(vm, p->v, p->argc);
-}
-
-/* Protected call: contain any exception of fatal error and restore context if something went wrong */
-int be_protectedcall(bvm *vm, bvalue *v, int argc)
-{
- int res;
- struct pcall s;
- struct vmstate state;
- s.v = v;
- s.argc = argc;
- vm_state_save(vm, &state);
- res = be_execprotected(vm, m_pcall, &s);
- if (res) { /* restore call stack */
- vm_state_restore(vm, &state, res);
- }
- return res;
-}
-
-#if BE_DEBUG && defined(be_assert)
-/* increase top register and return new top */
-/* Does not expand the stack if there is not enough room, but may corrupt memory */
-bvalue* be_incrtop(bvm *vm)
-{
- bvalue *top = vm->top++;
- be_assert(top < vm->stacktop);
- return top;
-}
-#endif
-
-/* TODO what is the difference with be_stack_push? */
-void be_stackpush(bvm *vm)
-{
- /* make sure there is enough stack space */
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- be_incrtop(vm);
-}
-
-/* check that the stack is able to store `count` items, and increase stack if needed */
-BERRY_API void be_stack_require(bvm *vm, int count)
-{
-#if BE_USE_DEBUG_STACK == 0
- if (vm->top + count >= vm->stacktop) {
- be_stack_expansion(vm, count);
- }
-#else
- be_stack_expansion(vm, vm->top - vm->stacktop + count); /* force exact resize each time */
-#endif
-}
-
-/* Scan the entire callstack and adjust all pointer by `offset` */
-static void update_callstack(bvm *vm, intptr_t offset)
-{
- bcallframe *cf = be_stack_top(&vm->callstack);
- bcallframe *base = be_stack_base(&vm->callstack);
- for (; cf >= base; --cf) {
- fixup_ptr(cf->func, offset);
- fixup_ptr(cf->top, offset);
- fixup_ptr(cf->reg, offset);
- }
- fixup_ptr(vm->top, offset);
- fixup_ptr(vm->reg, offset);
-}
-
-static void update_upvalues(bvm *vm, intptr_t offset)
-{
- bupval *node = vm->upvalist;
- /* update the value referenced by open upvalues */
- for (; node != NULL; node = node->u.next) {
- fixup_ptr(node->value, offset);
- }
-}
-
-/* Resize the stack to new `size` as number of elements */
-/* Then update all pointers in callstack and upvalues with the new stack address */
-static void stack_resize(bvm *vm, size_t size)
-{
- intptr_t offset;
- bvalue *old = vm->stack; /* save original pointer of stack before resize */
- size_t os = (vm->stacktop - old) * sizeof(bvalue); /* size of current stack allocated in bytes */
-#if BE_USE_DEBUG_STACK == 0
- vm->stack = be_realloc(vm, old, os, sizeof(bvalue) * size); /* reallocate with the new size */
-#else /* force a reallocation */
- size_t ns = sizeof(bvalue) * size;
- vm->stack = be_malloc(vm, ns);
- size_t transf = (os < ns) ? os : ns; /* min size */
- memmove(vm->stack, old, transf); /* copy to new location */
- memset(old, 0xFF, os); /* fill the structure with invalid pointers */
- be_free(vm, old, os);
-#endif
- vm->stacktop = vm->stack + size; /* compute new stacktop */
- offset = ptr_offset(vm->stack, old); /* compute the address difference between old and ne stack addresses */
- /* update callframes */
- update_callstack(vm, offset);
- /* update open upvalues */
- update_upvalues(vm, offset);
-}
-
-/* Stack resize internal API */
-/* Increases the stack by `n` elements, reallocate stack if needed and update all callstacks and upvals */
-/* Check if we are above the max allowed stack */
-void be_stack_expansion(bvm *vm, int n)
-{
- int size = vm->stacktop - vm->stack; /* with debug enabled, stack increase may be negative */
- /* check new stack size */
- if (size + n > BE_STACK_TOTAL_MAX) {
- /* ensure the stack is enough when generating error messages. */
- stack_resize(vm, size + 1);
- be_raise(vm, "runtime_error", STACK_OVER_MSG(BE_STACK_TOTAL_MAX));
- }
- if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_STACK_RESIZE_START, size * sizeof(bvalue), (size + n) * sizeof(bvalue));
- stack_resize(vm, size + n);
-}
-
-static void fixup_exceptstack(bvm* vm, struct bexecptframe* lbase)
-{
- struct bexecptframe *base = be_stack_base(&vm->exceptstack);
- if (lbase != base) { /* the address has changed when the stack is expanded */
- struct bexecptframe *top = be_stack_top(&vm->exceptstack);
- bbyte *begin = (bbyte*)&lbase->errjmp;
- bbyte *end = (bbyte*)&(lbase + (top - base))->errjmp;
- intptr_t offset = ptr_offset(base, lbase);
- struct blongjmp *errjmp = vm->errjmp;
- while (errjmp) {
- bbyte *prev = (bbyte*)errjmp->prev;
- if (prev >= begin && prev < end) {
- fixup_ptr(prev, offset); /* fixup the prev pointer */
- errjmp->prev = (struct blongjmp*)prev;
- }
- errjmp = (struct blongjmp*)prev;
- }
- }
-}
-
-/* set an exception handling recovery point. To do this, we have to
- * push some VM states into the exception stack. */
-void be_except_block_setup(bvm *vm)
-{
- struct bexecptframe *frame;
- struct bexecptframe *lbase = be_stack_base(&vm->exceptstack);
- be_stack_push(vm, &vm->exceptstack, NULL);
- frame = be_stack_top(&vm->exceptstack);
- frame->depth = be_stack_count(&vm->callstack); /* the call stack depth */
- frame->ip = vm->ip; /* OP_EXBLK's next instruction pointer */
- /* set longjmp() jump point */
- frame->errjmp.status = 0;
- frame->errjmp.prev = vm->errjmp; /* save long jump list */
- frame->refcount = vm->refstack.count; /* save reference pointer */
- vm->errjmp = &frame->errjmp;
- fixup_exceptstack(vm, lbase);
-}
-
-/* resumes to the state of the previous frame when an exception occurs. */
-void be_except_block_resume(bvm *vm)
-{
- int errorcode = vm->errjmp->status;
- struct bexecptframe *frame = be_stack_top(&vm->exceptstack);
- if (errorcode == BE_EXCEPTION) {
- vm->errjmp = vm->errjmp->prev;
- be_vector_resize(vm, &vm->refstack, frame->refcount);
- /* jump to except instruction */
- vm->ip = frame->ip + IGET_sBx(frame->ip[-1]);
- if (be_stack_count(&vm->callstack) > frame->depth) {
- bvalue *top = vm->top;
- bcallframe *cf = be_vector_at(&vm->callstack, frame->depth);
- vm->top = cf->top;
- vm->reg = cf->reg;
- vm->cf = frame->depth ? cf - 1 : NULL;
- be_vector_resize(vm, &vm->callstack, frame->depth);
- /* copy the exception value and argument to the top of
- * the current function */
- vm->top[0] = top[0]; /* exception value */
- vm->top[1] = top[1]; /* exception argument */
- }
- be_stack_pop(&vm->exceptstack);
- } else { /* other errors cannot be catch by the except block */
- /* find the next error handling location */
- while (vm->errjmp == &frame->errjmp) {
- vm->errjmp = vm->errjmp->prev;
- be_stack_pop(&vm->exceptstack);
- frame = be_stack_top(&vm->exceptstack);
- }
- be_throw(vm, errorcode); /* rethrow this exception */
- }
-}
-
-/* only close the except block, no other operations */
-void be_except_block_close(bvm *vm, int count)
-{
- struct bexecptframe *frame;
- int size = be_stack_count(&vm->exceptstack);
- be_assert(count > 0 && count <= size);
- frame = be_vector_at(&vm->exceptstack, size - count);
- vm->errjmp = frame->errjmp.prev;
- be_vector_resize(vm, &vm->exceptstack, size - count);
-}
-
-void be_save_stacktrace(bvm *vm)
-{
- bstack *stack = &vm->tracestack;
- be_stack_clear(stack);
- if (be_stack_count(&vm->callstack)) {
- bcallframe *cf;
- bcallframe *base = be_stack_base(&vm->callstack);
- bcallframe *top = be_stack_top(&vm->callstack);
- for (cf = base; cf <= top; ++cf) {
- bcallsnapshot *st;
- be_stack_push(vm, stack, NULL);
- st = be_stack_top(stack);
- st->func = *cf->func;
- st->ip = cf == top ? vm->ip : cf[1].ip;
- }
- }
-}
diff --git a/lib/libesp32/Berry/src/be_exec.h b/lib/libesp32/Berry/src/be_exec.h
deleted file mode 100644
index af10bf255f67..000000000000
--- a/lib/libesp32/Berry/src/be_exec.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_EXEC_H
-#define BE_EXEC_H
-
-#include "be_object.h"
-#include
-
-/* protected-call function */
-typedef void (*bpfunc)(bvm *vm, void *data);
-
-#if BE_DEBUG
-bvalue* be_incrtop(bvm *vm);
-#else
-/* increase top register */
-#define be_incrtop(vm) ((vm)->top++)
-#endif
-
-#define be_stackpop(vm, n) ((vm)->top -= (n))
-
-/* in MinGW-w64, setjmp / longjmp may be broken,
- * so here is replaced by __builtin version. */
-#if defined(__GNUC__) && defined(__MINGW32__)
- #define be_setjmp(env) __builtin_setjmp(env)
- #define be_longjmp(env, v) __builtin_longjmp(env, v)
-#else
- #define be_setjmp(env) setjmp(env)
- #define be_longjmp(env, v) longjmp(env, v)
-#endif
-
-typedef jmp_buf bjmpbuf;
-
-struct blongjmp {
- bjmpbuf b;
- struct blongjmp *prev;
- volatile int status; /* error code */
-};
-
-struct bexecptframe {
- struct blongjmp errjmp; /* long jump information */
- int depth; /* function call stack depth */
- binstruction *ip; /* instruction pointer */
- int refcount; /* save object reference stack */
-};
-
-void be_throw(bvm *vm, int errorcode);
-int be_execprotected(bvm *vm, bpfunc f, void *data);
-int be_protectedparser(bvm *vm, const char *fname,
- breader reader, void *data, bbool islocal);
-int be_protectedcall(bvm *vm, bvalue *v, int argc);
-void be_stackpush(bvm *vm);
-void be_stack_expansion(bvm *vm, int n);
-void be_except_block_setup(bvm *vm);
-void be_except_block_resume(bvm *vm);
-void be_except_block_close(bvm *vm, int count);
-void be_save_stacktrace(bvm *vm);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_filelib.c b/lib/libesp32/Berry/src/be_filelib.c
deleted file mode 100644
index dcf661fded1e..000000000000
--- a/lib/libesp32/Berry/src/be_filelib.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_mem.h"
-#include "be_sys.h"
-#include "be_gc.h"
-#include "be_bytecode.h"
-#include "be_vm.h"
-#include
-
-#define READLINE_STEP 100
-
-static int i_write(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if(be_iscomptr(vm, -1) && (be_isstring(vm, 2) || be_isbytes(vm, 2))) {
- void *fh = be_tocomptr(vm, -1);
- size_t size = 0;
- const char *data = NULL;
- if (be_isstring(vm, 2)) {
- data = be_tostring(vm, 2);
- size = be_strlen(vm, 2);
- } else {
- data = be_tobytes(vm, 2, &size);
- }
- size_t bw = be_fwrite(fh, data, size);
- if (bw != size) {
- be_raise(vm, "io_error", "write failed");
- }
- }
- be_return_nil(vm);
-}
-
-static size_t readsize(bvm *vm, int argc, void *fh)
-{
- if (argc >=2 && be_isint(vm, 2)) {
- return be_toindex(vm, 2);
- }
- return be_fsize(fh) - be_ftell(fh);
-}
-
-static int i_read(bvm *vm)
-{
- int argc = be_top(vm);
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- size_t size = readsize(vm, argc, fh);
- if (size) {
- char *buffer = be_malloc(vm, size);
- size = be_fread(fh, buffer, size);
- be_pushnstring(vm, buffer, size);
- be_free(vm, buffer, size);
- } else {
- be_pushstring(vm, "");
- }
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int i_readbytes(bvm *vm)
-{
- int argc = be_top(vm);
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- size_t size = readsize(vm, argc, fh);
- if (size) {
- if (size > vm->bytesmaxsize) {
- be_raise(vm, "memory_error", "size exceeds maximum allowed for bytes");
- }
- /* avoid double allocation, using directly the internal buffer of bytes() */
- be_getbuiltin(vm, "bytes");
- be_pushint(vm, size);
- be_call(vm, 1); /* call bytes() constructor with pre-sized buffer */
- be_pop(vm, 1); /* bytes() instance is at top */
-
- /* read back the actual buffer size */
- be_getmember(vm, -1, ".size");
- int32_t bytes_size = be_toint(vm, -1);
- be_pop(vm, 1);
- if (bytes_size < (int32_t)size) {
- be_raise(vm, "memory_error", "could not allocated buffer");
- }
-
- be_getmember(vm, -1, "resize");
- be_pushvalue(vm, -2);
- be_pushint(vm, size);
- be_call(vm, 2); /* call b.resize(size) */
- be_pop(vm, 3); /* bytes() instance is at top */
-
- char *buffer = (char*) be_tobytes(vm, -1, NULL); /* we get the address of the internal buffer of size 'size' */
- size_t read_size = be_fread(fh, buffer, size);
-
- if (size != read_size) {
- /* resize if something went wrong */
- be_getmember(vm, -1, "resize");
- be_pushvalue(vm, -2);
- be_pushint(vm, read_size);
- be_call(vm, 2); /* call b.resize(size) */
- be_pop(vm, 3); /* bytes() instance is at top */
- }
- } else {
- be_pushbytes(vm, NULL, 0);
- }
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int i_readline(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- size_t pos = 0, size = READLINE_STEP;
- char *buffer = be_malloc(vm, size);
- char *res = be_fgets(fh, buffer, (int)size);
- while (res) {
- pos += strlen(buffer + pos);
- if (!pos || buffer[pos - 1] == '\n') {
- break;
- }
- buffer = be_realloc(vm, buffer, size, size + READLINE_STEP);
- res = be_fgets(fh, buffer + pos, READLINE_STEP);
- size += READLINE_STEP;
- }
- be_pushnstring(vm, buffer, pos);
- be_free(vm, buffer, size);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int i_seek(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1) && be_isint(vm, 2)) {
- void *fh = be_tocomptr(vm, -1);
- be_fseek(fh, be_toindex(vm, 2));
- }
- be_return_nil(vm);
-}
-
-static int i_tell(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- size_t pos = be_ftell(fh);
- be_pushint(vm, cast(bint, pos));
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int i_size(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- size_t pos = be_fsize(fh);
- be_pushint(vm, cast(bint, pos));
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int i_flush(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- be_fflush(fh);
- }
- be_return_nil(vm);
-}
-
-static int i_close(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- be_fclose(fh);
- be_pushnil(vm);
- be_setmember(vm, 1, ".p");
- }
- be_return_nil(vm);
-}
-
-static int i_savecode(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2 && be_isclosure(vm, 2)) {
- be_getmember(vm, 1, ".p");
- if (be_iscomptr(vm, -1)) {
- void *fh = be_tocomptr(vm, -1);
- bvalue *v = be_indexof(vm, 2);
- if (var_isclosure(v)) {
- bclosure *cl = var_toobj(v);
- bproto *pr = cl->proto;
- be_bytecode_save_to_fs(vm, fh, pr);
- }
- }
- } else {
- be_raise(vm, "type_error", "closure expected");
- }
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-static int m_open(bvm *vm)
-#else
-int be_nfunc_open(bvm *vm)
-#endif
-{
- int argc = be_top(vm);
- const char *fname, *mode;
- static const bnfuncinfo members[] = {
- { ".p", NULL },
- { "write", i_write },
- { "read", i_read },
- { "readbytes", i_readbytes },
- { "readline", i_readline },
- { "seek", i_seek },
- { "tell", i_tell },
- { "size", i_size },
- { "flush", i_flush },
- { "close", i_close },
- { "deinit", i_close },
- { "savecode", i_savecode },
- { NULL, NULL }
- };
- fname = argc >= 1 && be_isstring(vm, 1) ? be_tostring(vm, 1) : NULL;
- mode = argc >= 2 && be_isstring(vm, 2) ? be_tostring(vm, 2) : "r";
- if (fname) {
- void *fh = be_fopen(fname, mode);
- if (fh == NULL) {
- be_raise(vm, "io_error",
- be_pushfstring(vm, "cannot open file '%s'", fname));
- }
- be_pushclass(vm, "file", members);
- be_call(vm, 0);
- be_pushcomptr(vm, fh);
- be_setmember(vm, -2, ".p");
- be_pop(vm, 1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-void be_load_filelib(bvm *vm)
-{
- be_regfunc(vm, "open", m_open);
-}
-#endif
diff --git a/lib/libesp32/Berry/src/be_func.c b/lib/libesp32/Berry/src/be_func.c
deleted file mode 100644
index b1280d9ec0ae..000000000000
--- a/lib/libesp32/Berry/src/be_func.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_func.h"
-#include "be_gc.h"
-#include "be_mem.h"
-#include "be_vm.h"
-#include "be_exec.h"
-#include
-
-#define clousersize(n) \
- (sizeof(bclosure) + sizeof(bupval*) * ((size_t)(n) - 1))
-
-static bupval* findupval(bvm *vm, bvalue *level)
-{
- bupval *node = vm->upvalist;
- while (node != NULL && node->value > level) {
- node = node->u.next;
- }
- if (!node || node->value != level) {
- /* not found */
- node = be_malloc(vm, sizeof(bupval));
- node->value = level;
- node->refcnt = 0;
- /* insert to list head */
- node->u.next = vm->upvalist;
- vm->upvalist = node;
- }
- return node;
-}
-
-void be_initupvals(bvm *vm, bclosure *cl)
-{
- int count = cl->proto->nupvals;
- bupvaldesc *desc = cl->proto->upvals;
- bvalue *stack = vm->reg;
- bupval **uv = cl->upvals;
- bupval **superuv = cast(bclosure*, var_toobj(vm->cf->func))->upvals;
- for (; count--; desc++, uv++) {
- if (desc->instack) {
- bvalue *ref = stack + desc->idx;
- *uv = findupval(vm, ref);
- } else {
- *uv = superuv[desc->idx];
- }
- (*uv)->refcnt++;
- }
-}
-
-void be_upvals_close(bvm *vm, bvalue *level)
-{
- bupval *node = vm->upvalist, *next;
- bupval **prev = &vm->upvalist;
- while (node) {
- next = node->u.next;
- if (node->value >= level) {
- if (!node->refcnt) {
- be_free(vm, node, sizeof(bupval));
- } else {
- node->u.value = *node->value; /* move value to upvalue slot */
- node->value = &node->u.value;
- }
- *prev = next; /* remove from linked list */
- } else {
- prev = &node->u.next;
- }
- node = next;
- }
-}
-
-void be_release_upvalues(bvm *vm, bclosure *cl)
-{
- int i, count = cl->nupvals;
- for (i = 0; i < count; ++i) {
- bupval *uv = cl->upvals[i];
- if (uv) {
- if (uv->refcnt) {
- --uv->refcnt;
- }
- /* delete non-referenced closed upvalue */
- if (uv->value == &uv->u.value && !uv->refcnt) {
- be_free(vm, uv, sizeof(bupval));
- }
- }
- }
-}
-
-bproto* be_newproto(bvm *vm)
-{
- bgcobject *gco = be_gcnew(vm, BE_PROTO, bproto);
- bproto *p = cast_proto(gco);
- if (p) {
- p->upvals = NULL;
- p->ktab = NULL;
- p->ptab = NULL;
- p->code = NULL;
- p->name = NULL;
- p->gray = NULL;
- p->codesize = 0;
- p->nupvals = 0;
- p->nproto = 0;
- p->nconst = 0;
- p->nstack = 0;
- p->codesize = 0;
- p->argc = 0;
- p->varg = 0;
-#if BE_DEBUG_SOURCE_FILE
- p->source = NULL;
-#endif
-#if BE_DEBUG_RUNTIME_INFO
- p->lineinfo = NULL;
- p->nlineinfo = 0;
-#endif
-#if BE_DEBUG_VAR_INFO
- p->varinfo = NULL;
- p->nvarinfo = 0;
-#endif
- }
- return p;
-}
-
-bclosure* be_newclosure(bvm *vm, int nupval)
-{
- bgcobject *gco = be_newgcobj(vm, BE_CLOSURE, clousersize(nupval));
- bclosure *cl = cast_closure(gco);
- if (cl) {
- cl->proto = NULL;
- cl->nupvals = (bbyte)nupval;
- while (nupval--) {
- cl->upvals[nupval] = NULL;
- }
- }
- return cl;
-}
-
-static void init_upvals(bvm *vm, bntvclos *f)
-{
- int count = f->nupvals;
- bupval **upvals = &be_ntvclos_upval(f, 0);
- while (count--) {
- bupval *uv = be_malloc(vm, sizeof(bupval)); /* was closed */
- uv->value = &uv->u.value;
- uv->refcnt = 1;
- var_setnil(uv->value);
- *upvals++ = uv;
- }
-}
-
-bntvclos* be_newntvclosure(bvm *vm, bntvfunc cf, int nupvals)
-{
- size_t size = sizeof(bntvclos) + sizeof(bupval*) * nupvals;
- bgcobject *gco = be_newgcobj(vm, BE_NTVCLOS, size);
- bntvclos *f = cast_ntvclos(gco);
- if (f) {
- f->f = cf;
- f->nupvals = (bbyte)nupvals;
- if (nupvals) {
- var_setntvclos(vm->top, f);
- be_incrtop(vm);
- init_upvals(vm, f); /* may be GC */
- be_stackpop(vm, 1);
- }
- }
- return f;
-}
-
-#if BE_DEBUG_VAR_INFO
-bstring* be_func_varname(bproto *proto, int index, int pc)
-{
- int i, nvarinfo = proto->nvarinfo;
- bvarinfo *varinfo = proto->varinfo;
- for (i = 0; i < nvarinfo && varinfo[i].beginpc <= pc; ++i) {
- if (pc <= varinfo[i].endpc && index-- == 0) {
- return varinfo[i].name;
- }
- }
- return NULL;
-}
-#endif
diff --git a/lib/libesp32/Berry/src/be_func.h b/lib/libesp32/Berry/src/be_func.h
deleted file mode 100644
index a9cdaa127213..000000000000
--- a/lib/libesp32/Berry/src/be_func.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_FUNC_H
-#define BE_FUNC_H
-
-#include "be_object.h"
-
-#define be_newntvclos(vm, cf) \
- be_newntvclosure(vm, cf, 0)
-
-#define be_ntvclos_upval(cc, n) \
- (((bupval**)((size_t)cc + sizeof(bntvclos)))[n])
-
-void be_initupvals(bvm *vm, bclosure *cl);
-void be_upvals_close(bvm *vm, bvalue *level);
-void be_release_upvalues(bvm *vm, bclosure *cl);
-bproto* be_newproto(bvm *vm);
-bclosure* be_newclosure(bvm *vm, int nupval);
-bntvclos* be_newntvclosure(bvm *vm, bntvfunc cf, int nupvals);
-bstring* be_func_varname(bproto *proto, int index, int pc);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_gc.c b/lib/libesp32/Berry/src/be_gc.c
deleted file mode 100644
index 35b0737f77bc..000000000000
--- a/lib/libesp32/Berry/src/be_gc.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_gc.h"
-#include "be_vm.h"
-#include "be_mem.h"
-#include "be_var.h"
-#include "be_vector.h"
-#include "be_string.h"
-#include "be_class.h"
-#include "be_list.h"
-#include "be_func.h"
-#include "be_map.h"
-#include "be_module.h"
-#include "be_exec.h"
-#include "be_debug.h"
-
-#define GC_PAUSE (1 << 0) /* GC will not be executed automatically */
-#define GC_HALT (1 << 1) /* GC completely stopped */
-#define GC_ALLOC (1 << 2) /* GC in alloc */
-
-#define gc_try(expr) be_assert(expr); if (expr)
-#define gc_setdark_safe(o) if (o) gc_setdark(o)
-
-#define next_threshold(gc) ((gc).usage * ((size_t)(gc).steprate + 100) / 100)
-
-#define link_gray(vm, obj) { \
- (obj)->gray = (vm)->gc.gray; \
- (vm)->gc.gray = gc_object(obj); \
-}
-
-static void destruct_object(bvm *vm, bgcobject *obj);
-static void free_object(bvm *vm, bgcobject *obj);
-
-void be_gc_init(bvm *vm)
-{
- vm->gc.usage = sizeof(bvm);
- be_gc_setsteprate(vm, 200);
- be_gc_init_memory_pools(vm);
-}
-
-void be_gc_deleteall(bvm *vm)
-{
- bupval *uv, *uvnext;
- bgcobject *node, *next;
- /* halt GC and delete all objects */
- vm->gc.status |= GC_HALT;
- /* first: call destructor */
- for (node = vm->gc.list; node; node = node->next) {
- destruct_object(vm, node);
- }
- /* second: free objects */
- for (node = vm->gc.list; node; node = next) {
- next = node->next;
- free_object(vm, node);
- }
- /* delete open upvalue list */
- for (uv = vm->upvalist; uv; uv = uvnext) {
- uvnext = uv->u.next;
- be_free(vm, uv, sizeof(bupval));
- }
-}
-
-void be_gc_setsteprate(bvm *vm, int rate)
-{
- be_assert(rate >= 100 && rate <= 355);
- vm->gc.steprate = (bbyte)(rate - 100);
- vm->gc.threshold = next_threshold(vm->gc);
-}
-
-void be_gc_setpause(bvm *vm, int pause)
-{
- if (pause) {
- vm->gc.status |= GC_PAUSE;
- } else {
- vm->gc.status &= ~GC_PAUSE;
- }
-}
-
-bgcobject* be_newgcobj(bvm *vm, int type, size_t size)
-{
- bgcobject *obj = be_malloc(vm, size);
- be_gc_auto(vm);
- var_settype(obj, (bbyte)type); /* mark the object type */
- obj->marked = GC_WHITE; /* default gc object type is white */
- obj->next = vm->gc.list; /* link to the next field */
- vm->gc.list = obj; /* insert to head */
- return obj;
-}
-
-bgcobject* be_gc_newstr(bvm *vm, size_t size, int islong)
-{
- bgcobject *obj;
- if (islong) { /* creating long strings is similar to ordinary GC objects */
- return be_newgcobj(vm, BE_STRING, size);
- }
- obj = be_malloc(vm, size);
- be_gc_auto(vm);
- var_settype(obj, BE_STRING); /* mark the object type to BE_STRING */
- obj->marked = GC_WHITE; /* default string type is white */
- return obj;
-}
-
-void be_gc_fix(bvm *vm, bgcobject *obj)
-{
- (void)vm;
- if (!gc_isconst(obj)) {
- gc_setfixed(obj);
- }
-}
-
-void be_gc_unfix(bvm *vm, bgcobject *obj)
-{
- (void)vm;
- if (!gc_isconst(obj)) {
- gc_clearfixed(obj);
- }
-}
-
-bbool be_gc_fix_set(bvm *vm, bgcobject *obj, bbool fix)
-{
- (void)vm;
- bbool was_fixed = gc_isfixed(obj);
- if (!gc_isconst(obj)) {
- if (fix) {
- gc_setfixed(obj);
- } else {
- gc_clearfixed(obj);
- }
- }
- return was_fixed;
-}
-
-
-#if BE_USE_PERF_COUNTERS
-#define GC_MARK(type) do { vm->gc_mark_##type++; } while (0);
-#else
-#define GC_MARK(type) do { } while (0);
-#endif
-
-static void mark_gray_reset_counters(bvm *vm) {
-#if BE_USE_PERF_COUNTERS
- vm->gc_mark_string = 0;
- vm->gc_mark_class = 0;
- vm->gc_mark_proto = 0;
- vm->gc_mark_instance = 0;
- vm->gc_mark_map = 0;
- vm->gc_mark_list = 0;
- vm->gc_mark_closure = 0;
- vm->gc_mark_ntvclos = 0;
- vm->gc_mark_module = 0;
- vm->gc_mark_comobj = 0;
-#endif
-}
-
-static void mark_gray(bvm *vm, bgcobject *obj)
-{
- if (obj && gc_iswhite(obj) && !gc_isconst(obj)) {
- gc_setgray(obj);
- be_assert(!var_isstatic(obj));
- switch (var_primetype(obj)) {
- case BE_STRING: gc_setdark(obj); GC_MARK(string); break; /* just set dark */
- case BE_CLASS: link_gray(vm, cast_class(obj)); GC_MARK(class); break;
- case BE_PROTO: link_gray(vm, cast_proto(obj)); GC_MARK(proto); break;
- case BE_INSTANCE: link_gray(vm, cast_instance(obj)); GC_MARK(instance); break;
- case BE_MAP: link_gray(vm, cast_map(obj)); GC_MARK(map); break;
- case BE_LIST: link_gray(vm, cast_list(obj)); GC_MARK(list); break;
- case BE_CLOSURE: link_gray(vm, cast_closure(obj)); GC_MARK(closure); break;
- case BE_NTVCLOS: link_gray(vm, cast_ntvclos(obj)); GC_MARK(ntvclos); break;
- case BE_MODULE: link_gray(vm, cast_module(obj)); GC_MARK(module); break;
- case BE_COMOBJ: gc_setdark(obj); GC_MARK(comobj); break; /* just set dark */
- default: break;
- }
- }
-}
-
-static void mark_gray_var(bvm *vm, bvalue *value)
-{
- if (be_isgcobj(value)) {
- mark_gray(vm, var_togc(value));
- }
-}
-
-static void mark_map(bvm *vm, bgcobject *obj)
-{
- bmap *map = cast_map(obj);
- gc_try (map != NULL) {
- bmapnode *node;
- bmapiter iter = be_map_iter();
- vm->gc.gray = map->gray; /* remove object from gray list */
- while ((node = be_map_next(map, &iter)) != NULL) {
- bmapkey *key = &node->key;
- bvalue *val = &node->value;
- if (be_isgcobj(key)) {
- mark_gray(vm, var_togc(key));
- }
- mark_gray_var(vm, val);
- }
- }
-}
-
-static void mark_list(bvm *vm, bgcobject *obj)
-{
- blist *list = cast_list(obj);
- gc_try (list != NULL) {
- bvalue *val = be_list_data(list);
- bvalue *end = be_list_end(list);
- vm->gc.gray = list->gray; /* remove object from gray list */
- for (; val < end; val++) {
- mark_gray_var(vm, val);
- }
- }
-}
-
-static void mark_proto(bvm *vm, bgcobject *obj)
-{
- bproto *p = cast_proto(obj);
- gc_try (p != NULL) {
- int count;
- bvalue *k = p->ktab;
- bproto **ptab = p->ptab;
- vm->gc.gray = p->gray; /* remove object from gray list */
- for (count = p->nconst; count--; ++k) {
- mark_gray_var(vm, k);
- }
- for (count = p->nproto; count--; ++ptab) {
- mark_gray(vm, gc_object(*ptab));
- }
- gc_setdark_safe(p->name);
-#if BE_DEBUG_SOURCE_FILE
- gc_setdark_safe(p->source);
-#endif
-#if BE_DEBUG_VAR_INFO
- if (p->nvarinfo) {
- bvarinfo *vinfo = p->varinfo;
- be_assert(vinfo != NULL);
- for (count = p->nvarinfo; count--; ++vinfo) {
- gc_setdark_safe(vinfo->name);
- }
- }
-#endif
- }
-}
-
-static void mark_closure(bvm *vm, bgcobject *obj)
-{
- bclosure *cl = cast_closure(obj);
- gc_try (cl != NULL) {
- int count = cl->nupvals;
- bupval **uv = cl->upvals;
- vm->gc.gray = cl->gray; /* remove object from gray list */
- for (; count--; ++uv) {
- if (*uv && (*uv)->refcnt) {
- mark_gray_var(vm, (*uv)->value);
- }
- }
- mark_gray(vm, gc_object(cl->proto));
- }
-}
-
-static void mark_ntvclos(bvm *vm, bgcobject *obj)
-{
- bntvclos *f = cast_ntvclos(obj);
- gc_try (f != NULL) {
- int count = f->nupvals;
- bupval **uv = &be_ntvclos_upval(f, 0);
- vm->gc.gray = f->gray; /* remove object from gray list */
- for (; count--; ++uv) {
- if (*uv && (*uv)->refcnt) {
- mark_gray_var(vm, (*uv)->value);
- }
- }
- }
-}
-
-static void mark_class(bvm *vm, bgcobject *obj)
-{
- bclass *c = cast_class(obj);
- gc_try (c != NULL) {
- vm->gc.gray = c->gray; /* remove object from gray list */
- mark_gray(vm, gc_object(be_class_name(c)));
- mark_gray(vm, gc_object(be_class_members(c)));
- mark_gray(vm, gc_object(be_class_super(c)));
- }
-}
-
-static void mark_instance(bvm *vm, bgcobject *obj)
-{
- binstance *o = cast_instance(obj);
- gc_try (o != NULL) {
- bvalue *var = be_instance_members(o);
- int nvar = be_instance_member_count(o);
- vm->gc.gray = o->gray; /* remove object from gray list */
- mark_gray(vm, gc_object(be_instance_class(o)));
- mark_gray(vm, gc_object(be_instance_super(o)));
- for (; nvar--; var++) { /* mark variables */
- mark_gray_var(vm, var);
- }
- }
-}
-
-static void mark_module(bvm *vm, bgcobject *obj)
-{
- bmodule *o = cast_module(obj);
- gc_try (o != NULL) {
- vm->gc.gray = o->gray; /* remove object from gray list */
- mark_gray(vm, gc_object(o->table));
- if (!gc_isconst(o) && gc_exmark(o) & BE_MODULE_NAME) {
- mark_gray(vm, gc_object(o->info.sname));
- }
- }
-}
-
-static void free_proto(bvm *vm, bgcobject *obj)
-{
- bproto *proto = cast_proto(obj);
- gc_try (proto != NULL) {
- be_free(vm, proto->upvals, proto->nupvals * sizeof(bupvaldesc));
- if (!(proto->varg & BE_VA_SHARED_KTAB)) { /* do not free shared ktab */
- /*caveat: the shared ktab is never GCed, in practice this is not a problem */
- /* since shared ktab are primarily meant for solidification hence not gc-able */
- be_free(vm, proto->ktab, proto->nconst * sizeof(bvalue));
- }
- be_free(vm, proto->ptab, proto->nproto * sizeof(bproto*));
- be_free(vm, proto->code, proto->codesize * sizeof(binstruction));
-#if BE_DEBUG_RUNTIME_INFO
- be_free(vm, proto->lineinfo, proto->nlineinfo * sizeof(blineinfo));
-#endif
-#if BE_DEBUG_VAR_INFO
- be_free(vm, proto->varinfo, proto->nvarinfo * sizeof(bvarinfo));
-#endif
- be_free(vm, proto, sizeof(bproto));
- }
-}
-
-static void free_closure(bvm *vm, bgcobject *obj)
-{
- bclosure *cl = cast_closure(obj);
- gc_try (cl != NULL) {
- int count = cl->nupvals;
- be_release_upvalues(vm, cl);
- be_free(vm, cl, sizeof(bclosure)
- + sizeof(bupval*) * ((size_t)count - 1));
- }
-}
-
-static void free_ntvclos(bvm *vm, bgcobject *obj)
-{
- bntvclos *f = cast_ntvclos(obj);
- gc_try (f != NULL) {
- int count = f->nupvals;
- bupval **uv = &be_ntvclos_upval(f, 0);
- while (count--) {
- be_free(vm, *uv++, sizeof(bupval));
- }
- be_free(vm, f, sizeof(bntvclos) + sizeof(bupval*) * f->nupvals);
- }
-}
-
-static void free_lstring(bvm *vm, bgcobject *obj)
-{
- blstring *ls = gc_cast(obj, BE_STRING, blstring);
- gc_try (ls != NULL) {
- be_free(vm, ls, sizeof(blstring) + ls->llen + 1);
- }
-}
-
-static void free_instance(bvm *vm, bgcobject *obj)
-{
- binstance *o = cast_instance(obj);
- int nvar = be_instance_member_count(o);
- be_free(vm, obj, sizeof(binstance) + sizeof(bvalue) * (nvar - 1));
-}
-
-static void free_object(bvm *vm, bgcobject *obj)
-{
- switch (var_primetype(obj)) {
- case BE_STRING: free_lstring(vm, obj); break; /* long string */
- case BE_CLASS: be_free(vm, obj, sizeof(bclass)); break;
- case BE_INSTANCE: free_instance(vm, obj); break;
- case BE_MAP: be_map_delete(vm, cast_map(obj)); break;
- case BE_LIST: be_list_delete(vm, cast_list(obj)); break;
- case BE_CLOSURE: free_closure(vm, obj); break;
- case BE_NTVCLOS: free_ntvclos(vm, obj); break;
- case BE_PROTO: free_proto(vm, obj); break;
- case BE_MODULE: be_module_delete(vm, cast_module(obj)); break;
- case BE_COMOBJ: be_commonobj_delete(vm, obj); break;
- default: break; /* case BE_STRING: break; */
- }
-}
-
-static void premark_internal(bvm *vm)
-{
- mark_gray(vm, gc_object(vm->module.loaded));
- mark_gray(vm, gc_object(vm->module.path));
- mark_gray(vm, gc_object(vm->ntvclass));
-#if BE_USE_DEBUG_HOOK
- if (be_isgcobj(&vm->hook)) {
- mark_gray(vm, gc_object(var_toobj(&vm->hook)));
- }
-#endif
-}
-
-static void premark_global(bvm *vm)
-{
- bvalue *v = vm->gbldesc.global.vlist.data;
- bvalue *end = v + be_global_count(vm);
- while (v < end) {
- if (be_isgcobj(v)) {
- mark_gray(vm, var_togc(v));
- }
- ++v;
- }
- v = vm->gbldesc.builtin.vlist.data;
- end = v + be_builtin_count(vm);
- while (v < end) {
- mark_gray_var(vm, v++);
- }
-}
-
-static void premark_stack(bvm *vm)
-{
- bvalue *v = vm->stack, *end = vm->top;
- /* mark live objects */
- for (; v < end; ++v) {
- mark_gray_var(vm, v);
- }
- /* set other values to nil */
- end = vm->stacktop;
- for (; v < end; ++v) {
- var_setnil(v);
- }
-}
-
-static void premark_tracestack(bvm *vm)
-{
- bcallsnapshot *cf = be_vector_data(&vm->tracestack);
- bcallsnapshot *end = be_vector_end(&vm->tracestack);
- for (; cf <= end; ++cf) {
- mark_gray_var(vm, &cf->func);
- }
-}
-
-static void premark_fixed(bvm *vm)
-{
- bgcobject *node = vm->gc.list;
- for (; node; node = node->next) {
- if (gc_isfixed(node) && gc_iswhite(node)) {
- mark_gray(vm, node);
- }
- }
-}
-
-static void mark_unscanned(bvm *vm)
-{
- while (vm->gc.gray) {
- bgcobject *obj = vm->gc.gray;
- if (obj && !gc_isdark(obj) && !gc_isconst(obj)) {
- gc_setdark(obj);
- be_assert(!var_isstatic(obj));
- switch (var_primetype(obj)) {
- case BE_CLASS: mark_class(vm, obj); break;
- case BE_PROTO: mark_proto(vm, obj); break;
- case BE_INSTANCE: mark_instance(vm, obj); break;
- case BE_MAP: mark_map(vm, obj); break;
- case BE_LIST: mark_list(vm, obj); break;
- case BE_CLOSURE: mark_closure(vm, obj); break;
- case BE_NTVCLOS: mark_ntvclos(vm, obj); break;
- case BE_MODULE: mark_module(vm, obj); break;
- default:
- be_assert(0); /* error */
- break;
- }
- }
- }
-}
-
-static void destruct_object(bvm *vm, bgcobject *obj)
-{
- if (vm->gc.status & GC_ALLOC) {
- return; /* no destructor is called during the allocation. */
- }
- if (obj->type == BE_INSTANCE) {
- int type;
- binstance *ins = cast_instance(obj);
- /* does not GC when creating the string "deinit". */
- type = be_instance_member_simple(vm, ins, str_literal(vm, "deinit"), vm->top);
- be_incrtop(vm);
- if (basetype(type) == BE_FUNCTION) {
- var_setinstance(vm->top, ins); /* push instance on stack as arg 1 */
- be_incrtop(vm);
- be_dofunc(vm, vm->top - 2, 1); /* warning, there shoudln't be any exception raised here, or the gc stops */
- be_stackpop(vm, 1);
- }
- be_stackpop(vm, 1);
- }
-}
-
-static void destruct_white(bvm *vm)
-{
- bgcobject *node = vm->gc.list;
- /* since the destructor may allocate objects, we must first suspend the GC */
- vm->gc.status |= GC_HALT; /* mark GC is halt */
- while (node) {
- if (gc_iswhite(node)) {
- destruct_object(vm, node);
- }
- node = node->next;
- }
- vm->gc.status &= ~GC_HALT; /* reset GC halt flag */
-}
-
-static void delete_white(bvm *vm)
-{
- bgcobject *node, *prev, *next;
- for (node = vm->gc.list, prev = node; node; node = next) {
- next = node->next;
- if (gc_iswhite(node)) {
- if (node == vm->gc.list) { /* first node */
- vm->gc.list = node->next;
- prev = node->next;
- } else { /* not first node */
- prev->next = next;
- }
- free_object(vm, node);
-#if BE_USE_PERF_COUNTERS
- vm->counter_gc_freed++;
-#endif
- } else {
- gc_setwhite(node);
- prev = node;
- }
- }
-}
-
-static void reset_fixedlist(bvm *vm)
-{
- bgcobject *node;
- for (node = vm->gc.fixed; node; node = node->next) {
- if (gc_isdark(node)) {
- gc_setwhite(node);
- }
- }
-}
-
-void be_gc_auto(bvm *vm)
-{
- if (vm->gc.status & GC_PAUSE && (BE_USE_DEBUG_GC || vm->gc.usage > vm->gc.threshold || comp_is_gc_debug(vm))) {
- be_gc_collect(vm);
- }
-}
-
-size_t be_gc_memcount(bvm *vm)
-{
- return vm->gc.usage;
-}
-
-#if BE_USE_PERF_COUNTERS
-#define GC_TIMER(i) if (vm->microsfnct) { vm->micros_gc##i = vm->microsfnct(); }
-#else
-#define GC_TIMER(i)
-#endif
-
-void be_gc_collect(bvm *vm)
-{
- if (vm->gc.status & GC_HALT) {
- return; /* the GC cannot run for some reason */
- }
-#if BE_USE_PERF_COUNTERS
- size_t slors_used_before_gc, slots_allocated_before_gc;
- be_gc_memory_pools_info(vm, &slors_used_before_gc, &slots_allocated_before_gc);
- vm->counter_gc_kept = 0;
- vm->counter_gc_freed = 0;
-#endif
- if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_START, vm->gc.usage);
- GC_TIMER(0);
- /* step 1: set root-set reference objects to unscanned */
- mark_gray_reset_counters(vm); /* reset all internal counters */
- premark_internal(vm); /* object internal the VM */
- premark_global(vm); /* global objects */
- premark_stack(vm); /* stack objects */
- premark_tracestack(vm); /* trace stack objects */
- premark_fixed(vm); /* fixed objects */
- GC_TIMER(1);
- /* step 2: set unscanned objects to black */
- mark_unscanned(vm);
- GC_TIMER(2);
- /* step 3: destruct and delete unreachable objects */
- destruct_white(vm);
- delete_white(vm);
- be_gcstrtab(vm);
- GC_TIMER(3);
- /* step 4: reset the fixed objects */
- reset_fixedlist(vm);
- GC_TIMER(4);
- /* step 5: calculate the next GC threshold */
- vm->gc.threshold = next_threshold(vm->gc);
- be_gc_memory_pools(vm); /* free unsued memory pools */
- GC_TIMER(5);
-#if BE_USE_PERF_COUNTERS
- size_t slors_used_after_gc, slots_allocated_after_gc;
- be_gc_memory_pools_info(vm, &slors_used_after_gc, &slots_allocated_after_gc);
- if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage, vm->counter_gc_kept, vm->counter_gc_freed,
- slors_used_before_gc, slots_allocated_before_gc,
- slors_used_after_gc, slots_allocated_after_gc);
-#else
- if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage);
-#endif
-}
diff --git a/lib/libesp32/Berry/src/be_gc.h b/lib/libesp32/Berry/src/be_gc.h
deleted file mode 100644
index 1544041defa2..000000000000
--- a/lib/libesp32/Berry/src/be_gc.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_GC_H
-#define BE_GC_H
-
-#include "be_object.h"
-
-#define gc_object(o) cast(bgcobject*, o)
-#define gc_cast(o, t, T) ((o) && (o)->type == (t) ? (T*)(o) : NULL)
-#define cast_proto(o) gc_cast(o, BE_PROTO, bproto)
-#define cast_closure(o) gc_cast(o, BE_CLOSURE, bclosure)
-#define cast_ntvclos(o) gc_cast(o, BE_NTVCLOS, bntvclos)
-#define cast_str(o) gc_cast(o, BE_STRING, bstring)
-#define cast_class(o) gc_cast(o, BE_CLASS, bclass)
-#define cast_instance(o) gc_cast(o, BE_INSTANCE, binstance)
-#define cast_map(o) gc_cast(o, BE_MAP, bmap)
-#define cast_list(o) gc_cast(o, BE_LIST, blist)
-#define cast_module(o) gc_cast(o, BE_MODULE, bmodule)
-
-#define gc_ismark(o, m) (((o)->marked & 0x03) == m)
-#define gc_iswhite(o) gc_ismark((o), GC_WHITE)
-#define gc_isgray(o) gc_ismark((o), GC_GRAY)
-#define gc_isdark(o) gc_ismark((o), GC_DARK)
-
-#define gc_setmark(o, m) \
-if (!gc_isconst(o)) { \
- (o)->marked &= ~0x03; \
- (o)->marked |= (m) & 0x03; \
-}
-
-#define gc_setwhite(o) gc_setmark((o), GC_WHITE)
-#define gc_setgray(o) gc_setmark((o), GC_GRAY)
-#if BE_USE_PERF_COUNTERS
- #define gc_setdark(o) { vm->counter_gc_kept++; gc_setmark((o), GC_DARK); }
-#else
- #define gc_setdark(o) gc_setmark((o), GC_DARK)
-#endif
-#define gc_isfixed(o) (((o)->marked & GC_FIXED) != 0)
-#define gc_setfixed(o) ((o)->marked |= GC_FIXED)
-#define gc_clearfixed(o) ((o)->marked &= ~GC_FIXED)
-#define gc_isconst(o) (((o)->marked & GC_CONST) != 0)
-#define gc_exmark(o) (((o)->marked >> 4) & 0x0F)
-#define gc_setexmark(o, k) ((o)->marked |= (k) << 4)
-
-#define be_isgcobj(o) (var_primetype(o) >= BE_GCOBJECT && var_primetype(o) < BE_GCOBJECT_MAX)
-#define be_gcnew(v, t, s) be_newgcobj((v), (t), sizeof(s))
-
-#define set_fixed(s) bbool _was_fixed = be_gc_fix_set(vm, cast(bgcobject*, (s)), 1)
-#define restore_fixed(s) be_gc_fix_set(vm, cast(bgcobject*, (s)), _was_fixed);
-
-/* the GC mark uses bit4:0 of the `object->marked` field,
- * so other bits can be used for special flags (ex-mark). */
-typedef enum {
- GC_WHITE = 0x00, /* unreachable object */
- GC_GRAY = 0x01, /* unscanned object */
- GC_DARK = 0x02, /* scanned object */
- GC_FIXED = 0x04, /* disable collection mark */
- GC_CONST = 0x08 /* constant object mark */
-} bgcmark;
-
-void be_gc_init(bvm *vm);
-void be_gc_deleteall(bvm *vm);
-void be_gc_setsteprate(bvm *vm, int rate);
-void be_gc_setpause(bvm *vm, int pause);
-size_t be_gc_memcount(bvm *vm);
-bgcobject *be_newgcobj(bvm *vm, int type, size_t size);
-bgcobject* be_gc_newstr(bvm *vm, size_t size, int islong);
-void be_gc_fix(bvm *vm, bgcobject *obj);
-void be_gc_unfix(bvm *vm, bgcobject *obj);
-bbool be_gc_fix_set(bvm *vm, bgcobject *obj, bbool fix);
-void be_gc_collect(bvm *vm);
-void be_gc_auto(bvm *vm);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_gclib.c b/lib/libesp32/Berry/src/be_gclib.c
deleted file mode 100644
index 9ca9eab50597..000000000000
--- a/lib/libesp32/Berry/src/be_gclib.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_gc.h"
-
-#if BE_USE_GC_MODULE
-
-static int m_allocated(bvm *vm)
-{
- size_t count = be_gc_memcount(vm);
- if (count < 0x80000000) {
- be_pushint(vm, (bint)count);
- } else {
- be_pushreal(vm, (breal)count);
- }
- be_return(vm);
-}
-
-static int m_collect(bvm *vm)
-{
- be_gc_collect(vm);
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(gc){
- be_native_module_function("allocated", m_allocated),
- be_native_module_function("collect", m_collect)
-};
-
-be_define_native_module(gc, NULL);
-#else
-/* @const_object_info_begin
-module gc (scope: global, depend: BE_USE_GC_MODULE) {
- allocated, func(m_allocated)
- collect, func(m_collect)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_gc.h"
-#endif
-
-#endif /* BE_USE_SYS_MODULE */
diff --git a/lib/libesp32/Berry/src/be_globallib.c b/lib/libesp32/Berry/src/be_globallib.c
deleted file mode 100644
index 6597fe78ba23..000000000000
--- a/lib/libesp32/Berry/src/be_globallib.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2021 Guan Wenliang & Stephan Hadinger
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_module.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_class.h"
-#include "be_debug.h"
-#include "be_map.h"
-#include "be_vm.h"
-#include "be_var.h"
-#include
-
-#if BE_USE_GLOBAL_MODULE
-
-#define global(vm) ((vm)->gbldesc.global)
-
-static void dump_map_keys(bvm *vm, bmap *map)
-{
- if (!map) { return; } /* protect agains potential null pointer */
- bmapnode *node;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(map, &iter)) != NULL) {
- if (var_isstr(&node->key)) {
- bstring *s = var_tostr(&node->key);
- be_pushstring(vm, str(s));
- be_data_push(vm, -2);
- be_pop(vm, 1);
- }
- }
-}
-
-static int m_globals(bvm *vm)
-{
- be_newobject(vm, "list");
- dump_map_keys(vm, global(vm).vtab);
- be_pop(vm, 1);
- be_return(vm);
-}
-
-static int m_contains(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1 && be_isstring(vm, 1)) {
- const char * name = be_tostring(vm, 1);
- int idx = be_global_find(vm, be_newstr(vm, name));
- be_pushbool(vm, idx > -1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_findglobal(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1 && be_isstring(vm, 1)) {
- const char * name = be_tostring(vm, 1);
- be_getglobal(vm, name);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_setglobal(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 2 && be_isstring(vm, 1)) {
- const char * name = be_tostring(vm, 1);
- be_setglobal(vm, name);
- }
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(global) {
- be_native_module_function("()", m_globals),
- be_native_module_function("contains", m_contains),
- be_native_module_function("member", m_findglobal),
- be_native_module_function("setmember", m_setglobal),
-};
-
-be_define_native_module(global, NULL);
-#else
-/* @const_object_info_begin
-module global (scope: global, depend: BE_USE_GLOBAL_MODULE) {
- (), func(m_globals)
- contains, func(m_contains)
- member, func(m_findglobal)
- setmember, func(m_setglobal)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_global.h"
-#endif
-
-#endif /* BE_USE_GLOBAL_MODULE */
diff --git a/lib/libesp32/Berry/src/be_introspectlib.c b/lib/libesp32/Berry/src/be_introspectlib.c
deleted file mode 100644
index 78e7eb0e5a11..000000000000
--- a/lib/libesp32/Berry/src/be_introspectlib.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_module.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_class.h"
-#include "be_debug.h"
-#include "be_map.h"
-#include "be_vm.h"
-#include "be_exec.h"
-#include "be_gc.h"
-#include
-
-#if BE_USE_INTROSPECT_MODULE
-
-#define global(vm) ((vm)->gbldesc.global)
-#define builtin(vm) ((vm)->gbldesc.builtin)
-
-static void dump_map_keys(bvm *vm, bmap *map)
-{
- if (!map) { return; } /* protect agains potential null pointer */
- bmapnode *node;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(map, &iter)) != NULL) {
- if (var_isstr(&node->key)) {
- bstring *s = var_tostr(&node->key);
- be_pushstring(vm, str(s));
- be_data_push(vm, -2);
- be_pop(vm, 1);
- }
- }
-}
-
-static int m_attrlist(bvm *vm)
-{
- int top = be_top(vm);
- be_newobject(vm, "list");
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- void *obj = var_toobj(v);
- switch (var_type(v)) {
- case BE_NIL: dump_map_keys(vm, global(vm).vtab); break;
- case BE_MODULE: dump_map_keys(vm, ((bmodule*)obj)->table); break;
- case BE_CLASS: dump_map_keys(vm, ((bclass*)obj)->members); break;
- case BE_INSTANCE: dump_map_keys(vm, ((binstance*)obj)->_class->members); break;
- default: break;
- }
- } else { /* if no parameter, then dump globals */
- dump_map_keys(vm, global(vm).vtab);
- }
- be_pop(vm, 1);
- be_return(vm);
-}
-
-static void m_findmember_protected(bvm *vm, void* data)
-{
- be_getmember(vm, 1, (const char*) data);
-}
-
-static int m_findmember(bvm *vm)
-{
- int top = be_top(vm);
- bbool protected = btrue; /* run protected, i.e. don't raise an exception if not found */
- if (top >= 3) {
- protected = !be_tobool(vm, 3);
- }
- if (top >= 2 && be_isstring(vm, 2)) {
- if (protected) {
- if (be_isinstance(vm, 1) || be_ismodule(vm, 1) || be_isclass(vm, 1)) {
- int ret = be_execprotected(vm, &m_findmember_protected, (void*) be_tostring(vm, 2));
- if (ret == BE_OK) {
- be_return(vm);
- }
- }
- be_return_nil(vm);
- } else {
- /* run unprotected */
- if (be_getmember(vm, 1, be_tostring(vm, 2))) {
- be_return(vm);
- } else {
- /* not found, return module 'undefined' */
- be_getmodule(vm, "undefined");
- be_return(vm);
- }
- }
- }
- be_return_nil(vm);
-}
-
-static int m_contains(bvm *vm)
-{
- bbool contains = bfalse;
- int top = be_top(vm);
- if (top >= 2 && be_isstring(vm, 2) && (be_isinstance(vm, 1) || be_ismodule(vm, 1) || be_isclass(vm, 1))) {
- if (be_getmember(vm, 1, be_tostring(vm, 2))) {
- contains = btrue;
- }
- }
- be_pushbool(vm, contains);
- be_return(vm);
-}
-
-static int m_setmember(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 3 && (be_isinstance(vm, 1) || be_ismodule(vm, 1) || be_isclass(vm, 1)) && be_isstring(vm, 2)) {
- be_setmember(vm, 1, be_tostring(vm, 2));
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_toptr(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- if (var_type(v) == BE_STRING) {
- be_pushcomptr(vm, (void*)be_tostring(vm, 1));
- be_return(vm);
- } else if (var_basetype(v) >= BE_FUNCTION || var_type(v) == BE_COMPTR) {
- be_pushcomptr(vm, var_toobj(v));
- be_return(vm);
- } else if (var_type(v) == BE_INT) {
- be_pushcomptr(vm, (void*) (intptr_t) var_toint(v));
- be_return(vm);
- } else {
- be_raise(vm, "value_error", "unsupported for this type");
- }
- }
- be_return_nil(vm);
-}
-
-static int m_fromptr(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- void* v;
- if (be_iscomptr(vm, 1)) {
- v = be_tocomptr(vm, 1);
- } else {
- v = (void*) (intptr_t) be_toint(vm, 1);
- }
- if (v) {
- bgcobject *ptr = (bgcobject*)v;
- if (var_basetype(ptr) >= BE_GCOBJECT) {
- bvalue *top = be_incrtop(vm);
- var_setobj(top, ptr->type, ptr);
- } else {
- be_raise(vm, "value_error", "unsupported for this type");
- }
- be_return(vm);
- }
- }
- be_return_nil(vm);
-}
-
-/* load module by name, like `import` would do. But don't create a global variable from it. */
-static int m_getmodule(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- if (var_isstr(v)) {
- int ret = be_module_load(vm, var_tostr(v));
- if (ret == BE_OK) {
- be_return(vm);
- }
- }
- }
- be_return_nil(vm);
-}
-
-/* set or chang the cached value for the named module, this allows monkey patching. **USE WITH CARE** */
-static int m_setmodule(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 2) {
- bvalue *v = be_indexof(vm, 1);
- if (var_isstr(v)) {
- be_pushvalue(vm, 2); /* ensure the second arg is at top of stack */
- be_cache_module(vm, var_tostr(v));
- }
- }
- be_return_nil(vm);
-}
-
-/* checks if the function (berry bytecode bproto only) is hinted as a method */
-static int m_ismethod(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- if (var_isclosure(v)) {
- bclosure *cl = var_toobj(v);
- bproto *pr = cl->proto;
- be_pushbool(vm, pr->varg & BE_VA_METHOD);
- be_return(vm);
- }
- }
- be_return_nil(vm);
-}
-
-static int m_name(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- const char* name = NULL;
- switch (var_type(v)) {
- case BE_CLOSURE:
- name = str(((bclosure*) var_toobj(v))->proto->name);
- break;
- case BE_CLASS:
- name = str(((bclass*) var_toobj(v))->name);
- break;
- case BE_MODULE:
- name = be_module_name(var_toobj(v));
- break;
- }
- if (name) {
- be_pushstring(vm, name);
- be_return(vm);
- }
- }
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(introspect) {
- be_native_module_function("members", m_attrlist),
-
- be_native_module_function("get", m_findmember),
- be_native_module_function("set", m_setmember),
- be_native_module_function("contains", m_contains),
-
- be_native_module_function("module", m_getmodule),
- be_native_module_function("setmodule", m_setmodule),
-
- be_native_module_function("toptr", m_toptr),
- be_native_module_function("fromptr", m_fromptr),
-
- be_native_module_function("name", m_name),
-
- be_native_module_function("ismethod", m_ismethod),
-};
-
-be_define_native_module(introspect, NULL);
-#else
-/* @const_object_info_begin
-module introspect (scope: global, depend: BE_USE_INTROSPECT_MODULE) {
- members, func(m_attrlist)
-
- get, func(m_findmember)
- set, func(m_setmember)
- contains, func(m_contains)
-
- module, func(m_getmodule)
- setmodule, func(m_setmodule)
-
- toptr, func(m_toptr)
- fromptr, func(m_fromptr)
-
- name, func(m_name)
-
- ismethod, func(m_ismethod)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_introspect.h"
-#endif
-
-#endif /* BE_USE_INTROSPECT_MODULE */
diff --git a/lib/libesp32/Berry/src/be_jsonlib.c b/lib/libesp32/Berry/src/be_jsonlib.c
deleted file mode 100644
index 615e8bebcfa1..000000000000
--- a/lib/libesp32/Berry/src/be_jsonlib.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_mem.h"
-#include
-#include
-
-#if BE_USE_JSON_MODULE
-
-#define MAX_INDENT 24
-#define INDENT_WIDTH 2
-#define INDENT_CHAR ' '
-
-static const char* parser_value(bvm *vm, const char *json);
-static void value_dump(bvm *vm, int *indent, int idx, int fmt);
-
-static const char* skip_space(const char *s)
-{
- int c;
- while (((c = *s) != '\0') && ((c == ' ')
- || (c == '\t') || (c == '\r') || (c == '\n'))) {
- ++s;
- }
- return s;
-}
-
-static int is_digit(int c)
-{
- return c >= '0' && c <= '9';
-}
-
-static const char* match_char(const char *json, int ch)
-{
- json = skip_space(json);
- if (*json == ch) {
- return skip_space(json + 1);
- }
- return NULL;
-}
-
-static int is_object(bvm *vm, const char *class, int idx)
-{
- if (be_isinstance(vm, idx)) {
- be_pushvalue(vm, idx);
- while (1) {
- be_getsuper(vm, -1);
- if (be_isnil(vm, -1)) {
- be_pop(vm, 1);
- break;
- }
- be_remove(vm, -2);
- }
- const char *name = be_classname(vm, -1);
- bbool ret = !strcmp(name, class);
- be_pop(vm, 1);
- return ret;
- }
- return 0;
-}
-
-static int json_strlen(const char *json)
-{
- int ch;
- const char *s = json + 1; /* skip '"' */
- /* get string length "(\\.|[^"])*" */
- while ((ch = *s) != '\0' && ch != '"') {
- ++s;
- if (ch == '\\') {
- ch = *s++;
- if (ch == '\0') {
- return -1;
- }
- }
- }
- return ch ? cast_int(s - json - 1) : -1;
-}
-
-static void json2berry(bvm *vm, const char *class)
-{
- be_getbuiltin(vm, class);
- be_pushvalue(vm, -2);
- be_call(vm, 1);
- be_moveto(vm, -2, -3);
- be_pop(vm, 2);
-}
-
-static const char* parser_true(bvm *vm, const char *json)
-{
- if (!strncmp(json, "true", 4)) {
- be_pushbool(vm, btrue);
- return json + 4;
- }
- return NULL;
-}
-
-static const char* parser_false(bvm *vm, const char *json)
-{
- if (!strncmp(json, "false", 5)) {
- be_pushbool(vm, bfalse);
- return json + 5;
- }
- return NULL;
-}
-
-static const char* parser_null(bvm *vm, const char *json)
-{
- if (!strncmp(json, "null", 4)) {
- be_pushnil(vm);
- return json + 4;
- }
- return NULL;
-}
-
-static char* load_unicode(char *dst, const char *json)
-{
- int ucode = 0, i = 4;
- while (i--) {
- int ch = *json++;
- if (ch >= '0' && ch <= '9') {
- ucode = (ucode << 4) | (ch - '0');
- } else if (ch >= 'A' && ch <= 'F') {
- ucode = (ucode << 4) | (ch - 'A' + 0x0A);
- } else if (ch >= 'a' && ch <= 'f') {
- ucode = (ucode << 4) | (ch - 'a' + 0x0A);
- } else {
- return NULL;
- }
- }
- /* convert unicode to utf8 */
- if (ucode < 0x007F) {
- /* unicode: 0000 - 007F -> utf8: 0xxxxxxx */
- *dst++ = (char)(ucode & 0x7F);
- } else if (ucode < 0x7FF) {
- /* unicode: 0080 - 07FF -> utf8: 110xxxxx 10xxxxxx */
- *dst++ = (char)(((ucode >> 6) & 0x1F) | 0xC0);
- *dst++ = (char)((ucode & 0x3F) | 0x80);
- } else {
- /* unicode: 0800 - FFFF -> utf8: 1110xxxx 10xxxxxx 10xxxxxx */
- *dst++ = (char)(((ucode >> 12) & 0x0F) | 0xE0);
- *dst++ = (char)(((ucode >> 6) & 0x03F) | 0x80);
- *dst++ = (char)((ucode & 0x3F) | 0x80);
- }
- return dst;
-}
-
-static const char* parser_string(bvm *vm, const char *json)
-{
- if (*json == '"') {
- int len = json_strlen(json++);
- if (len > -1) {
- int ch;
- char *buf, *dst = buf = be_malloc(vm, len);
- while ((ch = *json) != '\0' && ch != '"') {
- ++json;
- if (ch == '\\') {
- ch = *json++; /* skip '\' */
- switch (ch) {
- case '"': *dst++ = '"'; break;
- case '\\': *dst++ = '\\'; break;
- case '/': *dst++ = '/'; break;
- case 'b': *dst++ = '\b'; break;
- case 'f': *dst++ = '\f'; break;
- case 'n': *dst++ = '\n'; break;
- case 'r': *dst++ = '\r'; break;
- case 't': *dst++ = '\t'; break;
- case 'u': { /* load unicode */
- dst = load_unicode(dst, json);
- if (dst == NULL) {
- be_free(vm, buf, len);
- return NULL;
- }
- json += 4;
- break;
- }
- default: be_free(vm, buf, len); return NULL; /* error */
- }
- } else if(ch >= 0 && ch <= 0x1f) {
- /* control characters must be escaped
- as per https://www.rfc-editor.org/rfc/rfc7159#section-7 */
- be_free(vm, buf, len);
- return NULL;
- } else {
- *dst++ = (char)ch;
- }
- }
- be_assert(ch == '"');
- /* require the stack to have some free space for the string,
- since parsing deeply nested objects might
- crash the VM due to insufficient stack space. */
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- be_pushnstring(vm, buf, cast_int(dst - buf));
- be_free(vm, buf, len);
- return json + 1; /* skip '"' */
- }
- }
- return NULL;
-}
-
-static const char* parser_field(bvm *vm, const char *json)
-{
- be_stack_require(vm, 2 + BE_STACK_FREE_MIN);
- if (json && *json == '"') {
- json = parser_string(vm, json);
- if (json) {
- json = match_char(json, ':');
- if (json) {
- json = parser_value(vm, json);
- if (json) {
- be_data_insert(vm, -3);
- be_pop(vm, 2); /* pop key and value */
- return json;
- }
- }
- be_pop(vm, 1); /* pop key */
- }
- }
- return NULL;
-}
-
-static const char* parser_object(bvm *vm, const char *json)
-{
- json = match_char(json, '{');
- be_newmap(vm);
- if (*json != '}') {
- const char *s;
- json = parser_field(vm, json);
- if (json == NULL) {
- be_pop(vm, 1); /* pop map */
- return NULL;
- }
- while ((s = match_char(json, ',')) != NULL) {
- json = parser_field(vm, s);
- if (json == NULL) {
- be_pop(vm, 1); /* pop map */
- return NULL;
- }
- }
- }
- if ((json = match_char(json, '}')) == NULL) {
- be_pop(vm, 1); /* pop map */
- return NULL;
- }
- json2berry(vm, "map");
- return json;
-}
-
-static const char* parser_array(bvm *vm, const char *json)
-{
- json = match_char(json, '[');
- be_newlist(vm);
- if (*json != ']') {
- const char *s;
- json = parser_value(vm, json);
- if (json == NULL) {
- be_pop(vm, 1); /* pop map */
- return NULL;
- }
- be_data_push(vm, -2);
- be_pop(vm, 1); /* pop value */
- while ((s = match_char(json, ',')) != NULL) {
- json = parser_value(vm, s);
- if (json == NULL) {
- be_pop(vm, 1); /* pop map */
- return NULL;
- }
- be_data_push(vm, -2);
- be_pop(vm, 1); /* pop value */
- }
- }
- if ((json = match_char(json, ']')) == NULL) {
- be_pop(vm, 1); /* pop map */
- return NULL;
- }
- json2berry(vm, "list");
- return json;
-}
-
-static const char* parser_number(bvm *vm, const char *json)
-{
- char c = *json++;
- bbool is_neg = c == '-';
- if(is_neg) {
- c = *json++;
- if(!is_digit(c)) {
- /* minus must be followed by digit */
- return NULL;
- }
- }
- bint intv = 0;
- if(c != '0') {
- /* parse integer part */
- while(is_digit(c)) {
- intv = intv * 10 + c - '0';
- c = *json++;
- }
-
- } else {
- /*
- Number starts with zero, this is only allowed
- if the number is just '0' or
- it has a fractional part or exponent.
- */
- c = *json++;
-
- }
- if(c != '.' && c != 'e' && c != 'E') {
- /*
- No fractional part or exponent follows, this is an integer.
- If digits follow after it (for example due to a leading zero)
- this will cause an error in the calling function.
- */
- be_pushint(vm, intv * (is_neg ? -1 : 1));
- json--;
- return json;
- }
- breal realval = (breal) intv;
- if(c == '.') {
-
- breal deci = 0.0, point = 0.1;
- /* fractional part */
- c = *json++;
- if(!is_digit(c)) {
- /* decimal point must be followed by digit */
- return NULL;
- }
- while (is_digit(c)) {
- deci = deci + ((breal)c - '0') * point;
- point *= (breal)0.1;
- c = *json++;
- }
-
- realval += deci;
- }
- if(c == 'e' || c == 'E') {
- c = *json++;
- /* exponent part */
- breal ratio = c == '-' ? (breal)0.1 : 10;
- if (c == '+' || c == '-') {
- c = *json++;
- if(!is_digit(c)) {
- return NULL;
- }
- }
- if(!is_digit(c)) {
- /* e and sign must be followed by digit */
- return NULL;
- }
- unsigned int e = 0;
- while (is_digit(c)) {
- e = e * 10 + c - '0';
- c = *json++;
- }
- /* e > 0 must be here to prevent infinite loops when e overflows */
- while (e--) {
- realval *= ratio;
- }
- }
-
- be_pushreal(vm, realval * (is_neg ? -1.0 : 1.0));
- json--;
- return json;
-}
-
-/* parser json value */
-static const char* parser_value(bvm *vm, const char *json)
-{
- json = skip_space(json);
- /*
- Each value will push at least one thig to the stack, so we must ensure it's big enough.
- We need to take special care to extend the stack in values which have variable length (arrays and objects)
- */
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- switch (*json) {
- case '{': /* object */
- return parser_object(vm, json);
- case '[': /* array */
- return parser_array(vm, json);
- case '"': /* string */
- return parser_string(vm, json);
- case 't': /* true */
- return parser_true(vm, json);
- case 'f': /* false */
- return parser_false(vm, json);
- case 'n': /* null */
- return parser_null(vm, json);
- default: /* number */
- if (*json == '-' || is_digit(*json)) {
- return parser_number(vm, json);
- }
- }
- return NULL;
-}
-
-static int m_json_load(bvm *vm)
-{
- if (be_isstring(vm, 1)) {
- const char *json = be_tostring(vm, 1);
- json = parser_value(vm, json);
- if (json != NULL && *json == '\0') {
- be_return(vm);
- }
- }
- be_return_nil(vm);
-}
-
-static void make_indent(bvm *vm, int stridx, int indent)
-{
- if (indent) {
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- char buf[MAX_INDENT * INDENT_WIDTH + 1];
- indent = (indent < MAX_INDENT ? indent : MAX_INDENT) * INDENT_WIDTH;
- memset(buf, INDENT_CHAR, indent);
- buf[indent] = '\0';
- stridx = be_absindex(vm, stridx);
- be_pushstring(vm, buf);
- be_strconcat(vm, stridx);
- be_pop(vm, 1);
- }
-}
-
-void string_dump(bvm *vm, int index)
-{
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- be_tostring(vm, index); /* convert value to string */
- be_toescape(vm, index, 'u');
- be_pushvalue(vm, index);
-}
-
-static void object_dump(bvm *vm, int *indent, int idx, int fmt)
-{
-
- be_stack_require(vm, 3 + BE_STACK_FREE_MIN); /* 3 pushes outside the loop */
- be_getmember(vm, idx, ".p");
- be_pushstring(vm, fmt ? "{\n" : "{");
- be_pushiter(vm, -2); /* map iterator use 1 register */
- *indent += fmt;
- while (be_iter_hasnext(vm, -3)) {
- be_stack_require(vm, 3 + BE_STACK_FREE_MIN); /* 3 pushes inside the loop */
- make_indent(vm, -2, fmt ? *indent : 0);
- be_iter_next(vm, -3);
- /* key.tostring() */
- string_dump(vm, -2);
- be_strconcat(vm, -5);
- be_pop(vm, 1);
- be_pushstring(vm, fmt ? ": " : ":"); /* add ': ' */
- be_strconcat(vm, -5);
- be_pop(vm, 1);
- /* value.tostring() */
- value_dump(vm, indent, -1, fmt);
- be_strconcat(vm, -5);
- be_pop(vm, 3);
- if (be_iter_hasnext(vm, -3)) {
- be_pushstring(vm, fmt ? ",\n" : ",");
- be_strconcat(vm, -3);
- be_pop(vm, 1);
- } else if (fmt) {
- be_pushstring(vm, "\n");
- be_strconcat(vm, -3);
- be_pop(vm, 1);
- }
- }
- *indent -= fmt;
- be_pop(vm, 1); /* pop iterator */
- make_indent(vm, -1, fmt ? *indent : 0);
- be_pushstring(vm, "}");
- be_strconcat(vm, -2);
- be_moveto(vm, -2, -3);
- be_pop(vm, 2);
-}
-
-static void array_dump(bvm *vm, int *indent, int idx, int fmt)
-{
- be_stack_require(vm, 3 + BE_STACK_FREE_MIN);
- be_getmember(vm, idx, ".p");
- be_pushstring(vm, fmt ? "[\n" : "[");
- be_pushiter(vm, -2);
- *indent += fmt;
- while (be_iter_hasnext(vm, -3)) {
- make_indent(vm, -2, fmt ? *indent : 0);
- be_iter_next(vm, -3);
- value_dump(vm, indent, -1, fmt);
- be_strconcat(vm, -4);
- be_pop(vm, 2);
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- if (be_iter_hasnext(vm, -3)) {
- be_pushstring(vm, fmt ? ",\n" : ",");
- be_strconcat(vm, -3);
- be_pop(vm, 1);
- } else if (fmt) {
- be_pushstring(vm, "\n");
- be_strconcat(vm, -3);
- be_pop(vm, 1);
- }
- }
- *indent -= fmt;
- be_pop(vm, 1); /* pop iterator */
- make_indent(vm, -1, fmt ? *indent : 0);
- be_pushstring(vm, "]");
- be_strconcat(vm, -2);
- be_moveto(vm, -2, -3);
- be_pop(vm, 2);
-}
-
-static void value_dump(bvm *vm, int *indent, int idx, int fmt)
-{
- // be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- if (is_object(vm, "map", idx)) { /* convert to json object */
- object_dump(vm, indent, idx, fmt);
- } else if (is_object(vm, "list", idx)) { /* convert to json array */
- array_dump(vm, indent, idx, fmt);
- } else if (be_isnil(vm, idx)) { /* convert to json null */
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- be_pushstring(vm, "null");
- } else if (be_isreal(vm, idx)) {
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- breal v = be_toreal(vm, idx);
- if (isnan(v) || isinf(v)) {
- be_pushstring(vm, "null");
- } else {
- be_tostring(vm, idx);
- be_pushvalue(vm, idx); /* push to top */
- };
- } else if (be_isnumber(vm, idx) || be_isbool(vm, idx)) { /* convert to json number and boolean */
- be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
- be_tostring(vm, idx);
- be_pushvalue(vm, idx); /* push to top */
- } else { /* convert to string */
- string_dump(vm, idx);
- }
-}
-
-static int m_json_dump(bvm *vm)
-{
- int indent = 0, argc = be_top(vm);
- int fmt = 0;
- if (argc > 1) {
- fmt = !strcmp(be_tostring(vm, 2), "format");
- }
- value_dump(vm, &indent, 1, fmt);
- be_return(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(json) {
- be_native_module_function("load", m_json_load),
- be_native_module_function("dump", m_json_dump)
-};
-
-be_define_native_module(json, NULL);
-#else
-/* @const_object_info_begin
-module json (scope: global, depend: BE_USE_JSON_MODULE) {
- load, func(m_json_load)
- dump, func(m_json_dump)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_json.h"
-#endif
-
-#endif /* BE_USE_JSON_MODULE */
diff --git a/lib/libesp32/Berry/src/be_lexer.c b/lib/libesp32/Berry/src/be_lexer.c
deleted file mode 100644
index 4e41bf8f61c4..000000000000
--- a/lib/libesp32/Berry/src/be_lexer.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_lexer.h"
-#include "be_string.h"
-#include "be_mem.h"
-#include "be_gc.h"
-#include "be_exec.h"
-#include "be_map.h"
-#include "be_vm.h"
-#include "be_strlib.h"
-#include
-
-#define SHORT_STR_LEN 32
-#define EOS '\0' /* end of source */
-
-#define type_count() (int)array_count(kwords_tab)
-#define lexbuf(lex) ((lex)->buf.s)
-#define isvalid(lex) ((lex)->reader.cursor < (lex)->endbuf)
-#define lgetc(lex) ((lex)->reader.cursor)
-#define setstr(lex, v) ((lex)->token.u.s = (v))
-#define setint(lex, v) ((lex)->token.u.i = (v))
-#define setreal(lex, v) ((lex)->token.u.r = (v))
-#define match(lex, pattern) while (pattern(lgetc(lex))) { save(lex); }
-
-#if BE_USE_SCRIPT_COMPILER
-
-/* IMPORTANT: This must follow the enum found in be_lexer.h !!! */
-static const char* const kwords_tab[] = {
- "NONE", "EOS", "ID", "INT", "REAL", "STR",
- "=", "+=","-=", "*=", "/=", "%=", "&=", "|=",
- "^=", "<<=", ">>=", "+", "-", "*", "/", "%",
- "<", "<=", "==", "!=", ">", ">=", "&", "|",
- "^", "<<", ">>", "..", "&&", "||", "!", "~",
- "(", ")", "[", "]", "{", "}", ".", ",", ";",
- ":", "?", "->", "if", "elif", "else", "while",
- "for", "def", "end", "class", "break", "continue",
- "return", "true", "false", "nil", "var", "do",
- "import", "as", "try", "except", "raise", "static",
- ":=",
-};
-
-void be_lexerror(blexer *lexer, const char *msg)
-{
- bvm *vm = lexer->vm;
- const char *error = be_pushfstring(vm,
- "%s:%d: %s", lexer->fname, lexer->linenumber, msg);
- be_lexer_deinit(lexer);
- be_raise(vm, "syntax_error", error);
-}
-
-static void keyword_registe(bvm *vm)
-{
- int i;
- for (i = KeyIf; i < type_count(); ++i) {
- bstring *s = be_newstr(vm, kwords_tab[i]);
- be_gc_fix(vm, gc_object(s));
- be_str_setextra(s, i);
- }
-}
-
-static void keyword_unregiste(bvm *vm)
-{
- int i;
- for (i = KeyIf; i < type_count(); ++i) {
- bstring *s = be_newstr(vm, kwords_tab[i]);
- be_gc_unfix(vm, gc_object(s));
- }
-}
-
-static bstring* cache_string(blexer *lexer, bstring *s)
-{
- bvalue *res;
- bvm *vm = lexer->vm;
- var_setstr(vm->top, s);
- be_stackpush(vm); /* cache string to stack */
- res = be_map_findstr(lexer->vm, lexer->strtab, s);
- if (res) {
- s = var_tostr(&be_map_val2node(res)->key);
- } else {
- res = be_map_insertstr(vm, lexer->strtab, s, NULL);
- var_setnil(res);
- }
- be_stackpop(vm, 1); /* pop string frome stack */
- return s;
-}
-
-static bstring* lexer_newstrn(blexer *lexer, const char *str, size_t len)
-{
- return cache_string(lexer, be_newstrn(lexer->vm, str, len));
-}
-
-bstring* be_lexer_newstr(blexer *lexer, const char *str)
-{
- return cache_string(lexer, be_newstr(lexer->vm, str));
-}
-
-static int next(blexer *lexer)
-{
- struct blexerreader *lr = &lexer->reader;
- if (!(lr->len--)) {
- static const char eos = EOS;
- const char *s = lr->readf(lexer, lr->data, &lr->len);
- lr->s = s ? s : &eos;
- --lr->len;
- }
- lexer->reader.cursor = *lr->s++;
- return lexer->reader.cursor;
-}
-
-static void clear_buf(blexer *lexer)
-{
- lexer->buf.len = 0;
-}
-
-static void save_char(blexer *lexer, int ch) {
- struct blexerbuf *buf = &lexer->buf;
- if (buf->len >= buf->size) {
- size_t size = buf->size << 1;
- buf->s = be_realloc(lexer->vm, buf->s, buf->size, size);
- buf->size = size;
- }
- buf->s[buf->len++] = (char)ch;
-}
-
-/* save and next */
-static int save(blexer *lexer)
-{
- int ch = lgetc(lexer);
- save_char(lexer, ch);
- return next(lexer);
-}
-
-static bstring* buf_tostr(blexer *lexer)
-{
- struct blexerbuf *buf = &lexer->buf;
- return lexer_newstrn(lexer, buf->s, buf->len);
-}
-
-static int is_newline(int c)
-{
- return c == '\n' || c == '\r';
-}
-
-static int is_digit(int c)
-{
- return c >= '0' && c <= '9';
-}
-
-static int is_octal(int c)
-{
- return c >= '0' && c <= '7';
-}
-
-static int is_letter(int c)
-{
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
-}
-
-static int is_word(int c)
-{
- return is_letter(c) || is_digit(c);
-}
-
-static int check_next(blexer *lexer, int c)
-{
- if (lgetc(lexer) == c) {
- next(lexer);
- return 1;
- }
- return 0;
-}
-
-static int check2hex(blexer *lexer, int c)
-{
- c = be_char2hex(c);
- if (c < 0) {
- be_lexerror(lexer, "invalid hexadecimal number");
- }
- return c;
-}
-
-static int read_hex(blexer *lexer, const char *src)
-{
- int c = check2hex(lexer, *src++);
- return ((unsigned)c << 4) + check2hex(lexer, *src);
-}
-
-static int read_oct(blexer *lexer, const char *src)
-{
- int c = 0;
- const char *end = src + 3;
- while (src < end && is_octal(*src)) {
- c = 8 * c + *src++ - '0';
- }
- if (src < end) {
- be_lexerror(lexer, "invalid octal number");
- }
- return c;
-}
-
-static void tr_string(blexer *lexer)
-{
- char *dst, *src, *end;
- dst = src = lexbuf(lexer);
- end = lexbuf(lexer) + lexer->buf.len;
- while (src < end) {
- int c = *src++;
- switch (c) {
- case '\n': case '\r':
- be_lexerror(lexer, "unfinished string");
- break;
- case '\\':
- switch (*src) {
- case 'a': c = '\a'; break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
- case '\\': c = '\\'; break;
- case '\'': c = '\''; break;
- case '"': c = '"'; break;
- case '?': c = '?'; break;
- case 'x': c = read_hex(lexer, ++src); ++src; break;
- default:
- c = read_oct(lexer, src);
- if (c != EOS) {
- src += 2;
- }
- break;
- }
- ++src;
- break;
- default:
- break;
- }
- *dst++ = (char)c;
- }
- lexer->buf.len = dst - lexbuf(lexer);
-}
-
-static int skip_newline(blexer *lexer)
-{
- int lc = lgetc(lexer);
- next(lexer);
- if (is_newline(lgetc(lexer)) && lgetc(lexer) != lc) {
- next(lexer); /* skip "\n\r" or "\r\n" */
- }
- lexer->linenumber++;
- return lexer->reader.cursor;
-}
-
-static void skip_comment(blexer *lexer)
-{
- next(lexer); /* skip '#' */
- if (lgetc(lexer) == '-') { /* mult-line comment */
- int lno = lexer->linenumber;
- int mark, c = 'x'; /* skip first '-' (#- ... -#) */
- do {
- mark = c == '-';
- if (is_newline(c)) {
- c = skip_newline(lexer);
- continue;
- }
- c = next(lexer);
- } while (!(mark && c == '#') && c != EOS);
- if (c == EOS) {
- be_lexerror(lexer, be_pushfstring(lexer->vm, "unterminated comment block started in line %d", lno));
- }
- next(lexer); /* skip '#' */
- } else { /* line comment */
- while (!is_newline(lgetc(lexer)) && lgetc(lexer)) {
- next(lexer);
- }
- }
-}
-
-static bbool scan_realexp(blexer *lexer)
-{
- int c = lgetc(lexer);
- if (c == 'e' || c == 'E') {
- c = save(lexer);
- if (c == '+' || c == '-') {
- c = save(lexer);
- }
- if (!is_digit(c)) {
- be_lexerror(lexer, "malformed number");
- }
- match(lexer, is_digit);
- return btrue;
- }
- return bfalse;
-}
-
-static btokentype scan_dot_real(blexer *lexer)
-{
- if (save(lexer) == '.') { /* is '..' */
- next(lexer);
- return OptConnect;
- }
- if (is_digit(lgetc(lexer))) {
- match(lexer, is_digit);
- scan_realexp(lexer);
- setreal(lexer, be_str2real(lexbuf(lexer), NULL));
- return TokenReal;
- }
- return OptDot;
-}
-
-/* check the dots is a decimal dot or '..' operator */
-static bbool decimal_dots(blexer *lexer)
-{
- if (lgetc(lexer) == '.') { /* '..' or real */
- if (save(lexer) != '.') { /* read numberic => \.\b* */
- match(lexer, is_digit); /* match and skip numberic */
- return btrue;
- }
- /* token '..' */
- next(lexer); /* skip the second '.' */
- lexer->cacheType = OptConnect;
- }
- return bfalse; /* operator '..' */
-}
-
-static bint scan_hexadecimal(blexer *lexer)
-{
- bint res = 0;
- int dig, num = 0;
- while ((dig = be_char2hex(lgetc(lexer))) >= 0) {
- res = ((bint)res << 4) + dig;
- next(lexer);
- ++num;
- }
- if (num == 0) {
- be_lexerror(lexer, "invalid hexadecimal number");
- }
- return res;
-}
-
-static btokentype scan_decimal(blexer *lexer)
-{
- btokentype type = TokenInteger;
- match(lexer, is_digit);
- /* decimal_dots() and scan_realexp() have side effect, so we call each explicitly */
- /* to prevent binary shortcut if the first is true */
- bbool has_decimal_dots = decimal_dots(lexer);
- bbool is_realexp = scan_realexp(lexer);
- if (has_decimal_dots || is_realexp) {
- type = TokenReal;
- }
- /* use save_char to add the null terminator, */
- /* since it handles expanding the buffer if needed. */
- save_char(lexer, '\0');
- if (type == TokenReal) {
- setreal(lexer, be_str2real(lexbuf(lexer), NULL));
- } else {
- setint(lexer, be_str2int(lexbuf(lexer), NULL));
- }
- return type;
-}
-
-static btokentype scan_numeral(blexer *lexer)
-{
- btokentype type = TokenInteger;
- int c0 = lgetc(lexer), c1 = save(lexer);
- /* hex: 0[xX][0-9a-fA-F]+ */
- if (c0 == '0' && (c1 == 'x' || c1 == 'X')) {
- next(lexer);
- setint(lexer, scan_hexadecimal(lexer));
- } else {
- type = scan_decimal(lexer);
- }
- /* can't follow decimal or letter after numeral */
- if (lexer->cacheType == TokenNone) {
- if (is_letter(lgetc(lexer)) || decimal_dots(lexer)) {
- be_lexerror(lexer, "malformed number");
- }
- }
- return type;
-}
-
-/* structure for a temporary reader used by transpiler, with attributes for an allocated buffer and size */
-struct blexerreader_save {
- struct blexerreader reader;
- char* s;
- size_t size;
- char cursor;
-};
-
-/* buf reader for transpiled code from f-strings */
-/* it restores the original reader when the transpiler buffer is empty */
-/* the first pass returns a single byte buffer with the saved cursor */
-/* the second pass restores the original reader */
-static const char* _bufgets(struct blexer* lexer, void *data, size_t *size)
-{
- /* this is called once the temporaty transpiler buffer is empty */
- struct blexerreader *reader = &lexer->reader; /* current reader which is temporary only for the transpiler */
- struct blexerreader_save *reader_save = data; /* original reader that needs to be restored once the buffer is empty */
-
- /* first case, we saved the cursor (fist char), we server it now */
- if (reader_save->reader.cursor >= 0) { /* serve the previously saved cursor */
- /* copy cursor to a 'char' type */
- reader_save->cursor = reader_save->reader.cursor;
- reader_save->reader.cursor = -1; /* no more cursor saved */
- *size = 1;
- return &reader_save->cursor;
- }
-
- /* second case, the saved cursor was returned, now restore the normal flow of the original reader */
- /* restore the original reader */
- *reader = reader_save->reader;
-
- /* free the memory from the structure */
- be_free(lexer->vm, reader_save->s, reader_save->size); /* free the buffer */
- be_free(lexer->vm, reader_save, sizeof(struct blexerreader_save)); /* free the structure */
-
- if (!reader->len) { /* just in case the original buffer was also */
- return reader->readf(lexer, reader->data, size);
- }
- /* the following is not necessary, but safer */
- *size = reader->len;
- return reader->s;
-}
-
-static btokentype scan_string(blexer *lexer); /* forward declaration */
-
-/* scan f-string and transpile it to `format(...)` syntax then feeding the normal lexer and parser */
-static void scan_f_string(blexer *lexer)
-{
- char ch = '\0';
- clear_buf(lexer);
- scan_string(lexer); /* first scan the entire string in lexer->buf */
-
- /* save original reader until the transpiled is processed */
- /* reader will be restored by the reader function once the transpiled buffer is empty */
- struct blexerreader_save *reader_save = (struct blexerreader_save *) be_malloc(lexer->vm, sizeof(struct blexerreader_save)); /* temporary reader */
- reader_save->reader = lexer->reader;
-
- /* save blexerbuf which contains the unparsed_fstring */
- struct blexerbuf buf_unparsed_fstr = lexer->buf;
-
- /* prepare and allocated a temporary buffer to save parsed f_string */
- lexer->buf.size = lexer->buf.size + 20;
- lexer->buf.s = be_malloc(lexer->vm, lexer->buf.size);
- lexer->buf.len = 0;
-
- /* parse f_string */
- /* First pass, check syntax and extract string literals, and format */
- save_char(lexer, '(');
- save_char(lexer, '"');
- for (size_t i = 0; i < buf_unparsed_fstr.len; i++) {
- ch = buf_unparsed_fstr.s[i];
- switch (ch) {
- case '%': /* % needs to be encoded as %% */
- save_char(lexer, '%');
- save_char(lexer, '%');
- break;
- case '\\': /* \ needs to be encoded as \\ */
- save_char(lexer, '\\');
- save_char(lexer, '\\');
- break;
- case '"': /* " needs to be encoded as \" */
- save_char(lexer, '\\');
- save_char(lexer, '"');
- break;
- case '}': /* }} is converted as } yet we tolerate a single } */
- if ((i+1 < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i+1] == '}')) { i++; } /* if '}}' replace with '}' */
- save_char(lexer, '}');
- break;
- case '\n':
- save_char(lexer, '\\');
- save_char(lexer, 'n');
- break;
- case '\r':
- save_char(lexer, '\\');
- save_char(lexer, 'r');
- break;
- default: /* copy any other character */
- save_char(lexer, ch);
- break;
- case '{': /* special case for { */
- i++; /* in all cases skip to next char */
- if ((i < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i] == '{')) {
- save_char(lexer, '{'); /* {{ is simply encoded as { and continue parsing */
- } else {
- /* we still don't know if '=' is present, so we copy the expression each time, and rollback if we find out the '=' is not present */
- size_t rollback = lexer->buf.len; /* mark the end of string for later rollback if '=' is not present */
- /* parse inner part */
- /* skip everything until either ':' or '}' or '=' */
- /* if end of string is reached before '}' raise en error */
- for (; i < buf_unparsed_fstr.len; i++) {
- ch = buf_unparsed_fstr.s[i];
- if (ch == ':' || ch == '}') { break; }
- save_char(lexer, ch); /* copy any character unless it's ':' or '}' */
- if (ch == '=') { break; } /* '=' is copied but breaks parsing as well */
- }
- /* safe check if we reached the end of the string */
- if (i >= buf_unparsed_fstr.len) { be_raise(lexer->vm, "syntax_error", "'}' expected"); }
- /* if '=' detected then do some additional checks */
- if (ch == '=') {
- i++; /* skip '=' and check we haven't reached the end */
- if (i >= buf_unparsed_fstr.len) { be_raise(lexer->vm, "syntax_error", "'}' expected"); }
- ch = buf_unparsed_fstr.s[i];
- if ((ch != ':') && (ch != '}')) { /* '=' must be immediately followed by ':' or '}' */
- be_raise(lexer->vm, "syntax_error", "':' or '}' expected after '='");
- }
- } else {
- /* no '=' present, rollback the text of the expression */
- lexer->buf.len = rollback;
- }
- save_char(lexer, '%'); /* start format encoding */
- if (ch == ':') {
- /* copy format */
- i++;
- if ((i < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i] == '%')) { i++; } /* skip '%' following ':' */
- for (; i < buf_unparsed_fstr.len; i++) {
- ch = buf_unparsed_fstr.s[i];
- if (ch == '}') { break; }
- save_char(lexer, ch);
- }
- if (i >= buf_unparsed_fstr.len) { be_raise(lexer->vm, "syntax_error", "'}' expected"); }
- } else {
- /* if no formatting, output '%s' */
- save_char(lexer, 's');
- }
- }
- break;
- }
- }
- save_char(lexer, '"'); /* finish format string */
-
- /* Second pass - add arguments if any */
- for (size_t i = 0; i < buf_unparsed_fstr.len; i++) {
- /* skip any character that is not '{' followed by '{' */
- if (buf_unparsed_fstr.s[i] == '{') {
- i++; /* in all cases skip to next char */
- if ((i < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i] == '{')) { continue; }
- /* extract argument */
- save_char(lexer, ','); /* add ',' to start next argument to `format()` */
- for (; i < buf_unparsed_fstr.len; i++) {
- ch = buf_unparsed_fstr.s[i];
- if (ch == '=' || ch == ':' || ch == '}') { break; }
- save_char(lexer, ch); /* copy expression until we reach ':', '=' or '}' */
- }
- /* no need to check for end of string here, it was done already in first pass */
- if (ch == ':' || ch == '=') { /* if '=' or ':', skip everyting until '}' */
- i++;
- for (; i < buf_unparsed_fstr.len; i++) {
- ch = buf_unparsed_fstr.s[i];
- if (ch == '}') { break; }
- }
- }
- }
- }
- save_char(lexer, ')'); /* add final ')' */
-
- /* Situation now: */
- /* `buf_unparsed_fstr` contains the buffer of the input unparsed f-string, ex: "age: {age:2i}" */
- /* `lexer->buf` contains the buffer of the transpiled f-string without call to format(), ex: '("age: %2i", age)' */
- /* `reader_save` contains the original reader to continue parsing after f-string */
- /* `lexer->reader` will contain a temporary reader from the parsed f-string */
-
- /* extract the parsed f-string from the temporary buffer (needs later deallocation) */
- char * parsed_fstr_s = lexer->buf.s; /* needs later deallocation with parsed_fstr_size */
- size_t parsed_fstr_len = lexer->buf.len;
- size_t parsed_fstr_size = lexer->buf.size;
-
- /* restore buf to lexer */
- lexer->buf = buf_unparsed_fstr;
-
- /* change the temporary reader to the parsed f-string */
- lexer->reader.len = parsed_fstr_len;
- lexer->reader.data = (void*) reader_save; /* link to the saved context */
- lexer->reader.s = parsed_fstr_s; /* reader is responisble to deallocate later this buffer */
- lexer->reader.readf = _bufgets;
-
- /* add information needed for `_bufgets` to later deallocate the buffer */
- reader_save->size = parsed_fstr_size;
- reader_save->s = parsed_fstr_s;
-
- /* start parsing the parsed f-string, which is btw always '(' */
- next(lexer);
-
- /* remember that we are still in `scan_identifier()`, we replace the 'f' identifier to 'format' which is the global function to call */
- static const char FORMAT[] = "format";
- lexer->buf.len = sizeof(FORMAT) - 1; /* we now that buf size is at least SHORT_STR_LEN (32) */
- memmove(lexer->buf.s, FORMAT, lexer->buf.len);
-}
-
-static btokentype scan_identifier(blexer *lexer)
-{
- int type;
- bstring *s;
- save(lexer);
- match(lexer, is_word);
- /* check if the form is f"aaaa" or f'aaa' */
- char ch = lgetc(lexer);
- if ((lexer->buf.len == 1) && (lexer->buf.s[0] == 'f') && (ch == '"' || ch == '\'')) {
- scan_f_string(lexer);
- }
- s = buf_tostr(lexer);
- type = str_extra(s);
- if (type >= KeyIf && type < type_count()) {
- lexer->token.type = (btokentype)type;
- return lexer->token.type;
- }
- setstr(lexer, s); /* set identifier name */
- return TokenId;
-}
-
-/* munch any delimeter and return 1 if any found */
-static int skip_delimiter(blexer *lexer) {
- int c = lgetc(lexer);
- int delimeter_present = 0;
- while (1) {
- if (c == '#') {
- skip_comment(lexer);
- } else if (c == '\r' || c == '\n') {
- skip_newline(lexer);
- } else if (c == ' ' || c == '\t' || c == '\f' || c == '\v') {
- next(lexer);
- } else {
- break;
- }
- c = lgetc(lexer);
- delimeter_present = 1;
- }
- return delimeter_present;
-}
-
-static btokentype scan_string(blexer *lexer)
-{
- while (1) { /* handle multiple string literals in a row */
- int c;
- int end = lgetc(lexer); /* string delimiter, either '"' or '\'' */
- next(lexer); /* skip '"' or '\'' */
- while ((c = lgetc(lexer)) != EOS && (c != end)) {
- save(lexer);
- if (c == '\\') {
- save(lexer); /* skip '\\.' */
- }
- }
- if (c == EOS) {
- be_lexerror(lexer, "unfinished string");
- }
- c = next(lexer); /* skip '"' or '\'' */
- /* check if there's an additional string literal right after */
- skip_delimiter(lexer);
- c = lgetc(lexer);
- if (c != '"' && c != '\'') { break; }
- }
- tr_string(lexer);
- setstr(lexer, buf_tostr(lexer));
- return TokenString;
-}
-
-static btokentype scan_assign(blexer *lexer, btokentype is, btokentype not)
-{
- next(lexer);
- return check_next(lexer, '=') ? is : not;
-}
-
-static btokentype scan_sub(blexer *lexer)
-{
- btokentype op;
- switch (next(lexer)) {
- case '>': op = OptArrow; break;
- case '=': op = OptSubAssign; break;
- default: return OptSub;
- }
- next(lexer);
- return op;
-}
-
-static btokentype scan_and(blexer *lexer)
-{
- btokentype op;
- switch (next(lexer)) {
- case '&': op = OptAnd; break;
- case '=': op = OptAndAssign; break;
- default: return OptBitAnd;
- }
- next(lexer);
- return op;
-}
-
-static btokentype scan_or(blexer *lexer)
-{
- btokentype op;
- switch (next(lexer)) {
- case '|': op = OptOr; break;
- case '=': op = OptOrAssign; break;
- default: return OptBitOr;
- }
- next(lexer);
- return op;
-}
-
-static btokentype scan_le(blexer *lexer)
-{
- switch (next(lexer)) {
- case '=':
- next(lexer);
- return OptLE;
- case '<':
- next(lexer);
- return check_next(lexer, '=') ? OptLsfAssign : OptShiftL;
- default:
- return OptLT;
- }
-}
-
-static btokentype scan_ge(blexer *lexer)
-{
- switch (next(lexer)) {
- case '=':
- next(lexer);
- return OptGE;
- case '>':
- next(lexer);
- return check_next(lexer, '=') ? OptRsfAssign : OptShiftR;
- default:
- return OptGT;
- }
-}
-
-static btokentype lexer_next(blexer *lexer)
-{
- for (;;) {
- switch (lgetc(lexer)) {
- case '\r': case '\n': /* newline */
- skip_newline(lexer);
- break;
- case ' ': case '\t': case '\f': case '\v': /* spaces */
- next(lexer);
- break;
- case '#': /* comment */
- skip_comment(lexer);
- break;
- case EOS: return TokenEOS; /* end of source stream */
- /* operator */
- case '+': return scan_assign(lexer, OptAddAssign, OptAdd);
- case '-': return scan_sub(lexer);
- case '*': return scan_assign(lexer, OptMulAssign, OptMul);
- case '/': return scan_assign(lexer, OptDivAssign, OptDiv);
- case '%': return scan_assign(lexer, OptModAssign, OptMod);
- case '(': next(lexer); return OptLBK;
- case ')': next(lexer); return OptRBK;
- case '[': next(lexer); return OptLSB;
- case ']': next(lexer); return OptRSB;
- case '{': next(lexer); return OptLBR;
- case '}': next(lexer); return OptRBR;
- case ',': next(lexer); return OptComma;
- case ';': next(lexer); return OptSemic;
- case ':':
- next(lexer);
- return check_next(lexer, '=') ? OptWalrus : OptColon;
- case '?': next(lexer); return OptQuestion;
- case '^': return scan_assign(lexer, OptXorAssign, OptBitXor);
- case '~': next(lexer); return OptFlip;
- case '&': return scan_and(lexer);
- case '|': return scan_or(lexer);
- case '<': return scan_le(lexer);
- case '>': return scan_ge(lexer);
- case '=':
- next(lexer);
- return check_next(lexer, '=') ? OptEQ : OptAssign;
- case '!':
- next(lexer);
- return check_next(lexer, '=') ? OptNE : OptNot;
- case '\'': case '"':
- return scan_string(lexer);
- case '.':
- return scan_dot_real(lexer);
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- return scan_numeral(lexer);
- default:
- if (is_letter(lgetc(lexer))) {
- return scan_identifier(lexer);
- }
- be_lexerror(lexer, be_pushfstring(lexer->vm,
- "stray '\\%d' in program", (unsigned char)lgetc(lexer)));
- return TokenNone; /* error */
- }
- }
-}
-
-static void lexerbuf_init(blexer *lexer)
-{
- lexer->buf.size = SHORT_STR_LEN;
- lexer->buf.s = be_malloc(lexer->vm, SHORT_STR_LEN);
- lexer->buf.len = 0;
-}
-
-void be_lexer_init(blexer *lexer, bvm *vm,
- const char *fname, breader reader, void *data)
-{
- lexer->vm = vm;
- lexer->cacheType = TokenNone;
- lexer->fname = fname;
- lexer->linenumber = 1;
- lexer->lastline = 1;
- lexer->reader.readf = reader;
- lexer->reader.data = data;
- lexer->reader.len = 0;
- lexerbuf_init(lexer);
- keyword_registe(vm);
- lexer->strtab = be_map_new(vm);
- var_setmap(vm->top, lexer->strtab);
- be_stackpush(vm); /* save string to cache */
- next(lexer); /* read the first character */
-}
-
-void be_lexer_deinit(blexer *lexer)
-{
- be_free(lexer->vm, lexer->buf.s, lexer->buf.size);
- keyword_unregiste(lexer->vm);
-}
-
-int be_lexer_scan_next(blexer *lexer)
-{
- btokentype type;
- if (lexer->cacheType != TokenNone) {
- lexer->token.type = lexer->cacheType;
- lexer->cacheType = TokenNone;
- return 1;
- }
- if (lgetc(lexer) == EOS) { /* clear lexer */
- lexer->token.type = TokenEOS;
- return 0;
- }
- lexer->lastline = lexer->linenumber;
- type = lexer_next(lexer);
- clear_buf(lexer);
- if (type != TokenNone) {
- lexer->token.type = type;
- } else {
- lexer->token.type = TokenEOS;
- return 0;
- }
- return 1;
-}
-
-const char* be_token2str(bvm *vm, btoken *token)
-{
- switch (token->type) {
- case TokenString:
- case TokenId:
- return str(token->u.s);
- case TokenInteger:
- return be_pushfstring(vm, "%d", token->u.i);
- case TokenReal:
- return be_pushfstring(vm, "%g", token->u.r);
- default:
- return kwords_tab[token->type];
- }
-}
-
-const char* be_tokentype2str(btokentype type)
-{
- return kwords_tab[type];
-}
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_lexer.h b/lib/libesp32/Berry/src/be_lexer.h
deleted file mode 100644
index e166a1a64f51..000000000000
--- a/lib/libesp32/Berry/src/be_lexer.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_LEXER_H
-#define BE_LEXER_H
-
-#include "be_object.h"
-
-typedef enum {
- TokenNone = 0,
- TokenEOS, /* end of source */
- TokenId, /* identifier */
- TokenInteger,
- TokenReal,
- TokenString,
- /* operator, don't change order */
- /* assign operator */
- OptAssign, /* operator, = */
- OptAddAssign, /* operator, += */
- OptSubAssign, /* operator, -= */
- OptMulAssign, /* operator, *= */
- OptDivAssign, /* operator, /= */
- OptModAssign, /* operator, %= */
- OptAndAssign, /* operator, &= */
- OptOrAssign, /* operator, |= */
- OptXorAssign, /* operator, ^= */
- OptLsfAssign, /* operator, <<= */
- OptRsfAssign, /* operator, >>= */
- /* binary operator */
- OptAdd, /* operator, + */
- OptSub, /* operator, - */
- OptMul, /* operator, * */
- OptDiv, /* operator, / */
- OptMod, /* operator, % */
- OptLT, /* operator, < */
- OptLE, /* operator, <= */
- OptEQ, /* operator, == */
- OptNE, /* operator, != */
- OptGT, /* operator, > */
- OptGE, /* operator, >= */
- OptBitAnd, /* operatoe, & */
- OptBitOr, /* operatoe, | */
- OptBitXor, /* operatoe, ^ */
- OptShiftL, /* operatoe, << */
- OptShiftR, /* operatoe, >> */
- OptConnect, /* operator, .. */
- OptAnd, /* operator, && */
- OptOr, /* operator, || */
- /* unary operator */
- OptNot, /* operator, ! */
- OptFlip, /* operator, ~ */
- /* postfix operator or bracket */
- OptLBK, /* operator, ( bracket */
- OptRBK, /* operator, ) bracket */
- OptLSB, /* operator, [ square bracket */
- OptRSB, /* operator, ] square bracket */
- OptLBR, /* operator, { brace */
- OptRBR, /* operator, } brace */
- OptDot, /* operator, . dot */
- /* other symbol */
- OptComma, /* operator, , */
- OptSemic, /* operator, ; */
- OptColon, /* operator, : */
- OptQuestion, /* operator, ? */
- OptArrow, /* operator, -> */
- /* keyword */
- KeyIf, /* keyword if */
- KeyElif, /* keyword elif */
- KeyElse, /* keyword else */
- KeyWhile, /* keyword while */
- KeyFor, /* keyword for */
- KeyDef, /* keyword def */
- KeyEnd, /* keyword end */
- KeyClass, /* keyword class */
- KeyBreak, /* keyword break */
- KeyContinue, /* keyword continue */
- KeyReturn, /* keyword return */
- KeyTrue, /* keyword true */
- KeyFalse, /* keyword false */
- KeyNil, /* keyword nil */
- KeyVar, /* keyword var */
- KeyDo, /* keyword do */
- KeyImport, /* keyword import */
- KeyAs, /* keyword as */
- KeyTry, /* keyword try */
- KeyExcept, /* keyword except */
- KeyRaise, /* keyword raise */
- KeyStatic, /* keyword static */
- /* Walrus operator */
- OptWalrus, /* operator, := */
-} btokentype;
-
-struct blexerreader {
- const char *s;
- size_t len;
- void *data;
- breader readf;
- int cursor;
-};
-
-struct blexerbuf {
- char *s;
- size_t len, size;
-};
-
-typedef struct btoken {
- btokentype type;
- union {
- bstring *s;
- bint i;
- breal r;
- } u;
-} btoken;
-
-typedef struct blexer {
- const char *fname;
- btoken token;
- int linenumber;
- int lastline;
- btokentype cacheType;
- struct blexerbuf buf;
- struct blexerreader reader;
- bmap *strtab;
- bvm *vm;
-} blexer;
-
-void be_lexer_init(blexer *lexer, bvm *vm,
- const char *fname, breader reader, void *data);
-void be_lexer_deinit(blexer *lexer);
-void be_lexerror(blexer *lexer, const char *msg);
-int be_lexer_scan_next(blexer *lexer);
-bstring* be_lexer_newstr(blexer *lexer, const char *str);
-const char *be_token2str(bvm *vm, btoken *token);
-const char* be_tokentype2str(btokentype type);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_libs.c b/lib/libesp32/Berry/src/be_libs.c
deleted file mode 100644
index a9a2f0e39909..000000000000
--- a/lib/libesp32/Berry/src/be_libs.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_libs.h"
-
-extern void be_load_baselib(bvm *vm);
-extern void be_load_baselib_next(bvm *vm);
-extern void be_load_listlib(bvm *vm);
-extern void be_load_maplib(bvm *vm);
-extern void be_load_rangelib(bvm *vm);
-extern void be_load_filelib(bvm *vm);
-extern void be_load_byteslib(bvm *vm);
-
-void be_loadlibs(bvm *vm)
-{
- be_load_baselib(vm);
-#if !BE_USE_PRECOMPILED_OBJECT
- be_load_listlib(vm);
- be_load_maplib(vm);
- be_load_rangelib(vm);
- be_load_filelib(vm);
- be_load_byteslib(vm);
- be_load_baselib_next(vm);
-#endif
-}
diff --git a/lib/libesp32/Berry/src/be_libs.h b/lib/libesp32/Berry/src/be_libs.h
deleted file mode 100644
index a8014790bbfe..000000000000
--- a/lib/libesp32/Berry/src/be_libs.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_LIBS_H
-#define BE_LIBS_H
-
-#include "berry.h"
-
-void be_loadlibs(bvm *vm);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_list.c b/lib/libesp32/Berry/src/be_list.c
deleted file mode 100644
index 7d696d736aee..000000000000
--- a/lib/libesp32/Berry/src/be_list.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_list.h"
-#include "be_mem.h"
-#include "be_gc.h"
-#include "be_vm.h"
-#include "be_vector.h"
-#include "be_exec.h"
-#include
-
-#define datasize(size) ((size) * sizeof(bvalue))
-
-blist* be_list_new(bvm *vm)
-{
- bgcobject *gco = be_gcnew(vm, BE_LIST, blist);
- blist *list = cast_list(gco);
- if (list) {
- list->count = 0;
- list->capacity = 2;
- var_setlist(vm->top, list);
- be_incrtop(vm);
- list->data = be_malloc(vm, datasize(list->capacity));
- be_stackpop(vm, 1);
- }
- return list;
-}
-
-void be_list_delete(bvm *vm, blist *list)
-{
- be_free(vm, list->data, datasize(list->capacity));
- be_free(vm, list, sizeof(blist));
-}
-
-blist* be_list_copy(bvm *vm, blist *original)
-{
- bgcobject *gco = be_gcnew(vm, BE_LIST, blist);
- blist *list = cast_list(gco);
- if (list) {
- size_t size = datasize(original->capacity);
- list->count = original->count;
- list->capacity = original->capacity;
- var_setlist(vm->top, list);
- be_incrtop(vm);
- list->data = be_malloc(vm, size);
- be_stackpop(vm, 1);
- memcpy(list->data, original->data, size);
- }
- return list;
-}
-
-bvalue* be_list_index(blist *list, int index)
-{
- if (index < 0) {
- index = list->count + index;
- }
- if (index < 0 || index >= list->count) {
- return NULL;
- }
- return be_list_at(list, index);
-}
-
-bvalue* be_list_push(bvm *vm, blist *list, bvalue *value)
-{
- bvalue *slot;
- if (list->count >= list->capacity) {
- int newcap = be_nextsize(list->capacity);
- list->data = be_realloc(vm, list->data,
- datasize(list->capacity), datasize(newcap));
- list->capacity = newcap;
- }
- slot = list->data + list->count++;
- if (value != NULL) {
- *slot = *value;
- }
- return slot;
-}
-
-bvalue* be_list_insert(bvm *vm, blist *list, int index, bvalue *value)
-{
- int i;
- bvalue *data;
- if (index < 0) {
- index = list->count + index;
- }
- if (index < 0 || index > list->count) {
- return NULL;
- }
- if (list->count >= list->capacity) {
- int newcap = be_nextsize(list->capacity);
- list->data = be_realloc(vm, list->data,
- datasize(list->capacity), datasize(newcap));
- list->capacity = newcap;
- }
- data = list->data;
- for (i = list->count++; i > index; --i) {
- data[i] = data[i - 1];
- }
- data = list->data + index;
- if (value != NULL) {
- *data = *value;
- }
- return data;
-}
-
-int be_list_remove(bvm *vm, blist *list, int index)
-{
- int i;
- bvalue *data;
- (void)vm;
- if (index < 0) {
- index = list->count + index;
- }
- if (index < 0 || index >= list->count) {
- return bfalse;
- }
- data = list->data;
- list->count--;
- for (i = index; i < list->count; ++i) {
- data[i] = data[i + 1];
- }
- return btrue;
-}
-
-void be_list_resize(bvm *vm, blist *list, int count)
-{
- if (count != list->count) {
- int newcap = be_nextsize(count);
- if (newcap > list->capacity) {
- bvalue *v, *end;
- list->data = be_realloc(vm, list->data,
- datasize(list->capacity), datasize(newcap));
- list->capacity = newcap;
- v = list->data + list->count;
- end = list->data + count;
- while (v < end) {
- var_setnil(v++);
- }
- }
- list->count = count;
- }
-}
-
-void be_list_merge(bvm *vm, blist *list, const blist *other)
-{
- int dst_len = list->count;
- int src_len = other->count;
- int length = src_len + dst_len;
- if (length != 0) {
- int newcap = be_nextsize(length);
- if (newcap > list->capacity) {
- list->data = be_realloc(vm, list->data,
- datasize(list->capacity), datasize(newcap));
- list->capacity = newcap;
- }
- memcpy(list->data + dst_len, other->data, src_len * sizeof(bvalue));
- list->count = length;
- }
-}
-
-void be_list_reverse(blist *list)
-{
- bvalue *left = list->data;
- bvalue *right = left + list->count - 1;
- for (; left < right; ++left, --right) {
- bvalue temp = *left;
- *left = *right;
- *right = temp;
- }
-}
-
-void be_list_pool_init(bvm *vm, blist *list)
-{
- bvalue *head;
- be_list_resize(vm, list, 0);
- head = be_list_push(vm, list, NULL);
- var_setint(head, 0);
-}
-
-int be_list_pool_alloc(bvm *vm, blist *list, bvalue *src)
-{
- bvalue *head = be_list_data(list), *node;
- int id = var_toidx(head); /* get the first free node */
- if (id) {
- node = head + id;
- head->v.i = var_toint(node); /* link the next free node to head */
- } else {
- id = be_list_count(list);
- node = be_list_push(vm, list, NULL);
- }
- *node = *src;
- return id;
-}
-
-void be_list_pool_free(blist *list, int id)
-{
- bvalue *head = be_list_data(list);
- bvalue *node = head + id;
- be_assert(id > 0 && id < list->count);
- /* insert a new free node to head */
- *node = *head;
- head->v.i = id;
-}
diff --git a/lib/libesp32/Berry/src/be_list.h b/lib/libesp32/Berry/src/be_list.h
deleted file mode 100644
index 9f574572586f..000000000000
--- a/lib/libesp32/Berry/src/be_list.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_LIST_H
-#define BE_LIST_H
-
-#include "be_object.h"
-
-struct blist {
- bcommon_header;
- bgcobject *gray; /* for gc gray list */
- int count, capacity;
- bvalue *data;
-};
-
-#define be_list_data(list) ((list)->data)
-#define be_list_count(list) ((list)->count)
-#define be_list_at(list, index) ((list)->data + index)
-#define be_list_end(list) ((list)->data + (list)->count)
-
-blist* be_list_new(bvm *vm);
-void be_list_delete(bvm *vm, blist *list);
-blist* be_list_copy(bvm *vm, blist *original);
-bvalue* be_list_index(blist *list, int index);
-bvalue* be_list_push(bvm *vm, blist *list, bvalue *value);
-bvalue* be_list_insert(bvm *vm, blist *list, int index, bvalue *value);
-int be_list_remove(bvm *vm, blist *list, int index);
-void be_list_resize(bvm *vm, blist *list, int count);
-void be_list_merge(bvm *vm, blist *list, const blist *other);
-void be_list_reverse(blist *list);
-void be_list_pool_init(bvm *vm, blist *list);
-int be_list_pool_alloc(bvm *vm, blist *list, bvalue *src);
-void be_list_pool_free(blist *list, int id);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_listlib.c b/lib/libesp32/Berry/src/be_listlib.c
deleted file mode 100644
index 9cbfa38b0994..000000000000
--- a/lib/libesp32/Berry/src/be_listlib.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_string.h"
-#include "be_strlib.h"
-#include "be_list.h"
-#include "be_func.h"
-#include "be_exec.h"
-#include "be_vm.h"
-#include
-
-#define list_check_data(vm, argc) \
- if (!be_islist(vm, -1) || be_top(vm) - 1 < argc) { \
- be_return_nil(vm); \
- }
-
-#define list_check_ref(vm) \
- if (be_refcontains(vm, 1)) { \
- be_pushstring(vm, "[...]"); \
- be_return(vm); \
- }
-
-static void list_getindex(bvm *vm, int index)
-{
- if (!be_getindex(vm, index)) {
- be_raise(vm, "index_error", "list index out of range");
- }
-}
-
-static int m_init(bvm *vm)
-{
- int i, argc = be_top(vm);
- if (argc > 1 && be_islist(vm, 2)) {
- be_pushvalue(vm, 2);
- be_setmember(vm, 1, ".p");
- } else {
- be_newlist(vm);
- be_setmember(vm, 1, ".p");
- for (i = 2; i <= argc; ++i) {
- be_pushvalue(vm, i);
- be_data_push(vm, -2);
- be_pop(vm, 1);
- }
- }
- be_return_nil(vm);
-}
-
-static void push_element(bvm *vm)
-{
- be_toescape(vm, -1, 'x'); /* escape string */
- be_strconcat(vm, -3);
- be_pop(vm, 1);
-}
-
-static int m_tostring(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- list_check_ref(vm);
- be_refpush(vm, 1);
- be_pushstring(vm, "[");
- be_pushiter(vm, -2);
- while (be_iter_hasnext(vm, -3)) {
- be_iter_next(vm, -3);
- push_element(vm);
- if (be_iter_hasnext(vm, -3)) {
- be_pushstring(vm, ", ");
- be_strconcat(vm, -3);
- be_pop(vm, 1);
- }
- }
- be_pop(vm, 1); /* pop iterator */
- be_pushstring(vm, "]");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_refpop(vm);
- be_return(vm);
-}
-
-static int m_push(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 2);
- be_pushvalue(vm, 2);
- be_data_push(vm, -2);
- be_return_nil(vm);
-}
-
-static int m_pop(bvm *vm)
-{
- int argc = be_top(vm);
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- if (argc >= 2) {
- be_pushvalue(vm, 2);
- } else {
- be_pushint(vm, -1);
- }
- list_getindex(vm, -2);
- be_pushvalue(vm, -2);
- be_data_remove(vm, -4);
- be_pop(vm, 1);
- be_return(vm);
-}
-
-static int m_insert(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 3);
- be_pushvalue(vm, 2);
- be_pushvalue(vm, 3);
- be_data_insert(vm, -3);
- be_return_nil(vm);
-}
-
-static int m_remove(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 2);
- be_pushvalue(vm, 2);
- be_data_remove(vm, -2);
- be_return_nil(vm);
-}
-
-static int item_range(bvm *vm)
-{
- bint lower, upper;
- bint size = be_data_size(vm, -1); /* get source list size */
- /* get index range */
- be_getmember(vm, 2, "__lower__");
- lower = be_toint(vm, -1);
- if (lower < 0) {
- lower = size + lower;
- }
- be_pop(vm, 1);
- be_getmember(vm, 2, "__upper__");
- upper = be_toint(vm, -1);
- if (upper < 0) {
- upper = size + upper;
- }
- be_pop(vm, 1);
- /* protection scope */
- upper = upper < size ? upper : size - 1;
- lower = lower < 0 ? 0 : lower;
- /* construction result list instance */
- be_newobject(vm, "list"); /* result list */
- be_getmember(vm, 1, ".p"); /* source list */
- /* copy elements */
- for (; lower <= upper; ++lower) {
- be_pushint(vm, lower);
- list_getindex(vm, -2);
- be_data_push(vm, -4);
- be_pop(vm, 2);
- }
- be_pop(vm, 2);
- be_return(vm);
-}
-
-static int item_list(bvm *vm)
-{
- int i, srcsize, idxsize;
- be_getmember(vm, 2, ".p"); /* get index list */
- srcsize = be_data_size(vm, -2); /* get source list size */
- idxsize = be_data_size(vm, -1); /* get index list size */
- /* construction result list instance */
- be_newobject(vm, "list"); /* result list */
- be_getmember(vm, 1, ".p"); /* source list */
- /* copy elements */
- for (i = 0; i < idxsize; ++i) {
- be_pushint(vm, i);
- be_getindex(vm, -5);
- if (be_isint(vm, -1)) {
- int idx = be_toindex(vm, -1);
- if (idx >= 0 && idx < srcsize) {
- be_getindex(vm, -3);
- } else {
- be_pushnil(vm);
- }
- } else {
- be_pushnil(vm);
- }
- be_data_push(vm, -5);
- be_pop(vm, 3);
- }
- be_pop(vm, 2);
- be_return(vm);
-}
-
-static int m_item(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 2);
- if (be_isint(vm, 2)) {
- be_pushvalue(vm, 2);
- list_getindex(vm, -2);
- be_return(vm);
- }
- if (be_isinstance(vm, 2)) {
- const char *cname = be_classname(vm, 2);
- if (!strcmp(cname, "range")) {
- return item_range(vm);
- }
- if (!strcmp(cname, "list")) {
- return item_list(vm);
- }
- }
- be_raise(vm, "index_error", "list index out of range");
- be_return_nil(vm);
-}
-
-static int m_find(bvm *vm)
-{
- bbool found = bfalse;
- int idx;
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 2);
- list_check_ref(vm);
- be_refpush(vm, 1);
- be_pushiter(vm, -1);
- for (idx=0; be_iter_hasnext(vm, -2); idx++) {
- be_iter_next(vm, -2);
- be_pushvalue(vm, 2); /* push needle to compare */
- if (be_iseq(vm)) {
- found = btrue;
- be_pop(vm, 2);
- break;
- }
- be_pop(vm, 2);
- }
- be_pop(vm, 1); /* pop iterator */
- be_refpop(vm);
- if (found) {
- be_pushint(vm, idx);
- be_return(vm);
- } else {
- be_return_nil(vm);
- }
-}
-
-static int m_setitem(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 3);
- be_pushvalue(vm, 2);
- be_pushvalue(vm, 3);
- if (!be_setindex(vm, -3)) {
- be_raise(vm, "index_error", "list assignment index out of range");
- }
- be_return_nil(vm);
-}
-
-static int m_size(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- be_pushint(vm, be_data_size(vm, -1));
- be_return(vm);
-}
-
-static int m_tobool(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- be_pushbool(vm, be_data_size(vm, -1) > 0);
- be_return(vm);
-}
-
-static int m_resize(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 2);
- be_pushvalue(vm, 2);
- be_data_resize(vm, -2);
- be_return_nil(vm);
-}
-
-static int m_clear(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- be_pushint(vm, 0);
- be_data_resize(vm, -2);
- be_return_nil(vm);
-}
-
-static int iter_closure(bvm *vm)
-{
- /* for better performance, we operate the upvalues
- * directly without using by the stack. */
- bntvclos *func = var_toobj(vm->cf->func);
- bvalue *uv0 = be_ntvclos_upval(func, 0)->value; /* list value */
- bvalue *uv1 = be_ntvclos_upval(func, 1)->value; /* iter value */
- bvalue *next = cast(bvalue*, var_toobj(uv1)) + 1;
- blist *list = var_toobj(uv0);
- if (next >= be_list_end(list)) {
- be_stop_iteration(vm);
- }
- var_toobj(uv1) = next; /* set upvale[1] (iter value) */
- /* push next value to top */
- var_setval(vm->top, next);
- be_incrtop(vm);
- be_return(vm);
-}
-
-static int m_iter(bvm *vm)
-{
- be_pushntvclosure(vm, iter_closure, 2);
- be_getmember(vm, 1, ".p");
- be_setupval(vm, -2, 0);
- be_pushiter(vm, -1);
- be_setupval(vm, -3, 1);
- be_pop(vm, 2);
- be_return(vm);
-}
-
-static int m_connect(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2) {
- be_getmember(vm, 1, ".p");
- be_pushvalue(vm, 2);
- be_data_push(vm, -2);
- be_pop(vm, argc + 1);
- }
- be_return(vm); /* return self */
-}
-
-static int m_merge(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 2) {
- be_newobject(vm, "list"); /* stack contains instance and .p */
- be_getmember(vm, 1, ".p");
- be_data_merge(vm, -2);
- be_getmember(vm, 2, ".p");
- if (!be_islist(vm, -1)) {
- be_raise(vm, "type_error", "operand must be a list");
- }
- be_data_merge(vm, -3);
- be_pop(vm, 3);
- }
- be_return(vm); /* return self */
-}
-
-static void connect(bvm *vm, bvalue *begin, bvalue *end, const char * delimiter, bbool first_element)
-{
- size_t l0 = be_strlen(vm, -1), len = l0;
- size_t d = delimiter ? strlen(delimiter) : 0; /* len of delimiter */
- char *buf, *p;
- bvalue *it;
- for (it = begin; it < end; ++it) {
- len += str_len(var_tostr(it)) + d;
- }
- if (first_element) {
- len -= d; /* remove size for first delimiter non needed */
- }
- buf = be_pushbuffer(vm, len);
- memcpy(buf, be_tostring(vm, -2), l0);
- p = buf + l0;
- for (it = begin; it < end; ++it) {
- if ((it != begin || !first_element) && delimiter) {
- /* add delimiter */
- memcpy(p, delimiter, d);
- p += d;
- }
- bstring *s = var_tostr(it);
- size_t l = str_len(s);
- memcpy(p, str(s), l);
- p += l;
- }
- be_pushstring(vm, buf);
- be_moveto(vm, -1, -3);
- be_pop(vm, 2);
-}
-
-static void list_concat(bvm *vm, blist *list, const char * delimiter)
-{
- bvalue *it, *begin = be_list_data(list);
- bvalue *end = be_list_end(list);
- be_pushstring(vm, ""); /* push a empty string */
- bbool first_element = btrue;
- for (it = begin; it < end;) {
- for (; it < end && var_isstr(it); ++it);
- if (begin < it) {
- connect(vm, begin, it, delimiter, first_element); /* connect string list */
- first_element = bfalse;
- }
- if (it < end) {
- if (delimiter && !first_element) {
- be_pushstring(vm, delimiter);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- }
- /* connect other value */
- var_setval(vm->top, it);
- be_incrtop(vm);
- be_val2str(vm, -1);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- begin = ++it;
- first_element = bfalse;
- }
- }
-}
-
-static int m_concat(bvm *vm)
-{
- bvalue *value;
- int top = be_top(vm);
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- value = be_indexof(vm, -1);
- const char * delimiter = NULL;
- if (top >= 2) {
- delimiter = be_tostring(vm, 2);
- }
- list_concat(vm, var_toobj(value), delimiter);
- be_return(vm);
-}
-
-static int m_reverse(bvm *vm)
-{
- int top = be_top(vm);
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- be_data_reverse(vm, -1);
- be_pop(vm, top);
- be_return(vm);
-}
-
-static int m_copy(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- be_getbuiltin(vm, "list");
- be_copy(vm, -2);
- be_call(vm, 1);
- be_pop(vm, 1);
- be_return(vm);
-}
-
-static int list_equal(bvm *vm, bbool iseq)
-{
- int i, j, res;
- bbool (*eqfunc)(bvm*) = iseq ? be_iseq : be_isneq;
- be_getmember(vm, 1, ".p");
- be_getmember(vm, 2, ".p");
- i = be_data_size(vm, -2);
- j = be_data_size(vm, -1);
- if (i == j) {
- res = iseq;
- for (i = 0; res == iseq && i < j; ++i) {
- be_pushint(vm, i);
- be_getindex(vm, -3);
- be_pushint(vm, i);
- be_getindex(vm, -4);
- be_remove(vm, -2);
- res = eqfunc(vm);
- be_pop(vm, 3);
- }
- } else {
- res = !iseq;
- }
- be_pushbool(vm, res);
- be_return(vm);
-}
-
-static int m_keys(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- list_check_data(vm, 1);
- int size = be_data_size(vm, -1);
- be_getbuiltin(vm, "range");
- be_pushint(vm, 0);
- be_pushint(vm, size - 1);
- be_call(vm, 2);
- be_pop(vm, 2);
- be_return(vm);
-}
-
-static int m_equal(bvm *vm)
-{
- return list_equal(vm, btrue);
-}
-
-static int m_nequal(bvm *vm)
-{
- return list_equal(vm, bfalse);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-void be_load_listlib(bvm *vm)
-{
- static const bnfuncinfo members[] = {
- { ".p", NULL },
- { "init", m_init },
- { "tostring", m_tostring },
- { "push", m_push },
- { "pop", m_pop },
- { "insert", m_insert },
- { "remove", m_remove },
- { "item", m_item },
- { "find", m_find },
- { "setitem", m_setitem },
- { "size", m_size },
- { "resize", m_resize },
- { "clear", m_clear },
- { "iter", m_iter },
- { "concat", m_concat },
- { "reverse", m_reverse },
- { "copy", m_copy },
- { "keys", m_keys },
- { "tobool", m_tobool }
- { "..", m_connect },
- { "+", m_merge },
- { "==", m_equal },
- { "!=", m_nequal },
- { NULL, NULL }
- };
- be_regclass(vm, "list", members);
-}
-#else
-/* @const_object_info_begin
-class be_class_list (scope: global, name: list) {
- .p, var
- init, func(m_init)
- tostring, func(m_tostring)
- push, func(m_push)
- pop, func(m_pop)
- insert, func(m_insert)
- remove, func(m_remove)
- item, func(m_item)
- find, func(m_find)
- setitem, func(m_setitem)
- size, func(m_size)
- resize, func(m_resize)
- clear, func(m_clear)
- iter, func(m_iter)
- concat, func(m_concat)
- reverse, func(m_reverse)
- copy, func(m_copy)
- keys, func(m_keys)
- tobool, func(m_tobool)
- .., func(m_connect)
- +, func(m_merge)
- ==, func(m_equal)
- !=, func(m_nequal)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_be_class_list.h"
-#endif
diff --git a/lib/libesp32/Berry/src/be_map.c b/lib/libesp32/Berry/src/be_map.c
deleted file mode 100644
index ea3b81c6f157..000000000000
--- a/lib/libesp32/Berry/src/be_map.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_map.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_class.h"
-#include "be_mem.h"
-#include "be_gc.h"
-#include "be_vm.h"
-#include "be_exec.h"
-#include
-
-#define key(node) (&(node)->key)
-#define value(node) (&(node)->value)
-#define isnil(node) var_isnil(key(node))
-#define setnil(node) var_setnil(key(node))
-#define hash2slot(m, h) ((m)->slots + (h) % (m)->size)
-#define hashcode(_v) _hashcode(vm, (_v)->type, (_v)->v)
-#define keytype(key) ((signed char)(key)->type)
-
-#define next(node) ((node)->key.next)
-#define pos2slot(map, n) ((n) != LASTNODE ? ((map)->slots + (n)) : NULL)
-#define pos(map, node) ((int)((node) - (map)->slots))
-#define setkey(node, _v) { (node)->key.type = (bbyte)(_v)->type; \
- (node)->key.v = (_v)->v; }
-
-#define datasize(size) ((size) * sizeof(bmapnode))
-
-#define LASTNODE ((1 << 24) - 1)
-
-static int map_nextsize(int size)
-{
- be_assert(size < LASTNODE);
- if (size < LASTNODE) {
- return be_nextsize(size);
- }
- return LASTNODE + 1;
-}
-
-static uint32_t hashptr(void *p)
-{
- uintptr_t i = (uintptr_t)p;
- return (uint32_t)((i ^ (i >> 16)) & 0xFFFFFFFF);
-}
-
-#if BE_USE_SINGLE_FLOAT
-#define hashreal(v) ((uint32_t)((v).i))
-#else
-static uint32_t hashreal(union bvaldata v)
-{
- union { breal r; uint32_t i[2]; } u;
- u.r = v.r;
- return u.i[0] ^ u.i[1];
-}
-#endif
-
-#if BE_USE_OVERLOAD_HASH
-static uint32_t hashins(bvm *vm, binstance *obj)
-{
- int type = be_instance_member(vm, obj, str_literal(vm, "hash"), vm->top);
- if (basetype(type) == BE_FUNCTION) {
- bvalue *top = vm->top;
- var_setinstance(top + 1, obj);
- vm->top += 2;
- be_dofunc(vm, top, 1); /* call method 'item' */
- vm->top -= 2;
- if (!var_isint(vm->top)) { /* check the return value */
- const char *name = str(be_instance_name(obj));
- be_raise(vm, "runtime_error", be_pushfstring(vm,
- "the value of `%s::hash()` is not a 'int'",
- strlen(name) ? name : ""));
- }
- return (uint32_t)var_toint(vm->top);
- }
- return hashptr(obj);
-}
-#endif
-
-static uint32_t _hashcode(bvm *vm, int type, union bvaldata v)
-{
- (void)vm;
- switch (type) {
- case BE_NIL: return 0;
- case BE_BOOL: return (uint32_t)v.b;
- case BE_INT: return (uint32_t)v.i;
- case BE_REAL: return hashreal(v);
- case BE_STRING: return be_strhash(v.s);
-#if BE_USE_OVERLOAD_HASH
- case BE_INSTANCE: return hashins(vm, v.p);
-#endif
- default: return hashptr(v.p);
- }
-}
-
-static int eqnode(bvm *vm, bmapnode *node, bvalue *key, uint32_t hash)
-{
- (void)vm;
- if (!var_isnil(key)) {
- bmapkey *k = key(node);
-#if BE_USE_OVERLOAD_HASH
- if (var_isinstance(key)) {
- bvalue kv;
- kv.type = k->type;
- kv.v = k->v;
- return be_vm_iseq(vm, key, &kv);
- }
-#endif
- if(keytype(k) == key->type && hashcode(k) == hash) {
- switch (key->type) {
- case BE_BOOL: return var_tobool(key) == var_tobool(k);
- case BE_INT: return var_toint(key) == var_toint(k);
- case BE_REAL: return var_toreal(key) == var_toreal(k);
- case BE_STRING: return be_eqstr(var_tostr(key), var_tostr(k));
- default: return var_toobj(key) == var_toobj(k);
- }
- }
- }
- return 0;
-}
-
-static bmapnode* findprev(bmap *map, bmapnode *list, bmapnode *slot)
-{
- int n, pos = pos(map, slot);
- bmapnode *prev = list;
- for (;;) {
- n = next(prev);
- if (n == pos || n == LASTNODE) {
- break;
- }
- prev = map->slots + n;
- }
- return n == pos ? prev : NULL;
-}
-
-static bmapnode* nextfree(bmap *map)
-{
- bmapnode *base = map->slots;
- while (map->lastfree >= base) {
- if (isnil(map->lastfree)) {
- return map->lastfree;
- }
- --map->lastfree;
- }
- return NULL;
-}
-
-static bmapnode* insert(bvm *vm, bmap *map, bvalue *key, uint32_t hash)
-{
- bmapnode *slot = hash2slot(map, hash);
- if (isnil(slot)) { /* empty slot */
- setkey(slot, key);
- next(slot) = LASTNODE;
- } else {
- uint32_t h = hashcode(key(slot)); /* get the hashcode of the exist node */
- bmapnode *mainslot = hash2slot(map, h); /* get the main-slot */
- bmapnode *new = nextfree(map); /* get a free slot */
- if (mainslot == slot) { /* old is main slot */
- /* insert in first */
- setkey(new, key);
- next(new) = next(slot);
- next(slot) = pos(map, new);
- slot = new;
- } else {
- bmapnode *prev = findprev(map, mainslot, slot);
- next(prev) = pos(map, new); /* link the previous node */
- *new = *slot; /* copy to new slot */
- setkey(slot, key);
- next(slot) = LASTNODE;
- }
- }
- return slot;
-}
-
-static bmapnode* find(bvm *vm, bmap *map, bvalue *key, uint32_t hash)
-{
- bmapnode *slot = hash2slot(map, hash);
- if (isnil(slot)) {
- return NULL;
- }
- while (!eqnode(vm, slot, key, hash)) {
- int n = next(slot);
- if (n == LASTNODE) {
- return NULL;
- }
- slot = map->slots + n;
- }
- return slot;
-}
-
-static void resize(bvm *vm, bmap *map, int size)
-{
- int i, oldsize;
- bmapnode *slots, *oldslots;
- if (size < map->count) {
- return;
- }
- oldsize = map->size;
- oldslots = map->slots;
- slots = be_malloc(vm, datasize(size));
- for (i = 0; i < size; ++i) {
- setnil(slots + i);
- next(slots + i) = LASTNODE;
- }
- map->size = size;
- map->slots = slots;
- map->lastfree = slots + size - 1;
- /* rehash */
- for (i = 0; i < oldsize; ++i) {
- bmapnode *node = oldslots + i;
- if (!isnil(node)) {
- bvalue v;
- bmapnode *newslot;
- v.type = node->key.type;
- v.v = node->key.v;
- newslot = insert(vm, map, &v, hashcode(&v));
- newslot->value = node->value;
- }
- }
- be_free(vm, oldslots, datasize(oldsize));
-}
-
-bmap* be_map_new(bvm *vm)
-{
- bgcobject *gco = be_gcnew(vm, BE_MAP, bmap);
- bmap *map = cast_map(gco);
- if (map) {
- map->size = 0;
- map->count = 0;
- map->slots = NULL;
- var_setmap(vm->top, map);
- be_incrtop(vm);
- resize(vm, map, 2);
- be_stackpop(vm, 1);
- }
- return map;
-}
-
-void be_map_delete(bvm *vm, bmap *map)
-{
- be_free(vm, map->slots, datasize(map->size));
- be_free(vm, map, sizeof(bmap));
-}
-
-bvalue* be_map_find(bvm *vm, bmap *map, bvalue *key)
-{
- bmapnode *entry = find(vm, map, key, hashcode(key));
- return entry ? value(entry) : NULL;
-}
-
-bvalue* be_map_insert(bvm *vm, bmap *map, bvalue *key, bvalue *value)
-{
- uint32_t hash = hashcode(key);
- bmapnode *entry = find(vm, map, key, hash);
- if (!entry) { /* new entry */
- if (map->count >= map->size) {
- resize(vm, map, map_nextsize(map->size));
- }
- entry = insert(vm, map, key, hash);
- ++map->count;
- }
- if (value) {
- entry->value = *value;
- }
- return value(entry);
-}
-
-int be_map_remove(bvm *vm, bmap *map, bvalue *key)
-{
- uint32_t hash = hashcode(key);
- bmapnode *slot = hash2slot(map, hash); /* main slot */
-
- if (eqnode(vm, slot, key, hash)) { /* first node */
- bmapnode *next = pos2slot(map, next(slot));
- if (next) { /* has next */
- *slot = *next; /* first: copy the second node to the slot */
- slot = next; /* second: set the second node to nil (empty) */
- }
- } else { /* the node will be remove is not first-node */
- bmapnode *prev = slot;
- for (;;) { /* find the previous node */
- int n = next(prev);
- slot = pos2slot(map, n);
- if (slot == NULL) { /* node not found */
- return bfalse;
- }
- if (eqnode(vm, slot, key, hash)) {
- break;
- }
- prev = slot;
- }
- /* link the list */
- next(prev) = next(slot);
- }
- /* set to nil */
- setnil(slot);
- /* add to lastfree */
- if (map->lastfree < slot) {
- map->lastfree = slot;
- }
- --map->count;
- return btrue;
-}
-
-bvalue* be_map_findstr(bvm *vm, bmap *map, bstring *key)
-{
- bvalue v;
- var_setstr(&v, key);
- return be_map_find(vm, map, &v);
-}
-
-bvalue* be_map_insertstr(bvm *vm, bmap *map, bstring *key, bvalue *value)
-{
- bvalue v;
- var_setstr(&v, key);
- set_fixed(key);
- bvalue * r = be_map_insert(vm, map, &v, value);
- restore_fixed(key);
- return r;
-}
-
-void be_map_removestr(bvm *vm, bmap *map, bstring *key)
-{
- bvalue v;
- var_setstr(&v, key);
- be_map_remove(vm, map, &v);
-}
-
-bmapnode* be_map_next(bmap *map, bmapiter *iter)
-{
- bmapnode *end = map->slots + map->size;
- *iter = *iter ? *iter + 1 : map->slots;
- while (*iter < end && isnil(*iter)) {
- ++(*iter);
- }
- return *iter < end ? *iter : NULL;
-}
-
-bmapnode* be_map_val2node(bvalue *value)
-{
- return (bmapnode *)((size_t)value - sizeof(bmapkey));
-}
-
-void be_map_compact(bvm *vm, bmap *map)
-{
- (void)vm;
- if (!gc_isconst(map)) {
- resize(vm, map, map->count ? map->count : 1);
- }
-}
diff --git a/lib/libesp32/Berry/src/be_map.h b/lib/libesp32/Berry/src/be_map.h
deleted file mode 100644
index 7ae76962c940..000000000000
--- a/lib/libesp32/Berry/src/be_map.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_MAP_H
-#define BE_MAP_H
-
-#include "be_object.h"
-
-typedef struct bmapkey {
- union bvaldata v;
- uint32_t type:8;
- uint32_t next:24;
-} bmapkey;
-
-typedef struct bmapnode {
- bmapkey key;
- bvalue value;
-} bmapnode;
-
-struct bmap {
- bcommon_header;
- bgcobject *gray; /* for gc gray list */
- bmapnode *slots;
- bmapnode *lastfree;
- int size;
- int count;
-#ifdef __cplusplus
- BE_CONSTEXPR bmap(bmapnode *s, int n) :
- next(0), type(BE_MAP), marked(GC_CONST), gray(0),
- slots(s), lastfree(0), size(n), count(n) {}
-#endif
-};
-
-typedef bmapnode *bmapiter;
-
-#define be_map_iter() NULL
-#define be_map_count(map) ((map)->count)
-#define be_map_size(map) (map->size)
-
-#define be_map_key2value(dst, node) do { \
- (dst)->type = (node)->key.type; \
- (dst)->v = (node)->key.v; \
-} while (0);
-
-bmap* be_map_new(bvm *vm);
-void be_map_delete(bvm *vm, bmap *map);
-bvalue* be_map_find(bvm *vm, bmap *map, bvalue *key);
-bvalue* be_map_insert(bvm *vm, bmap *map, bvalue *key, bvalue *value);
-int be_map_remove(bvm *vm, bmap *map, bvalue *key);
-bvalue* be_map_findstr(bvm *vm, bmap *map, bstring *key);
-bvalue* be_map_insertstr(bvm *vm, bmap *map, bstring *key, bvalue *value);
-void be_map_removestr(bvm *vm, bmap *map, bstring *key);
-bmapnode* be_map_next(bmap *map, bmapiter *iter);
-bmapnode* be_map_val2node(bvalue *value);
-void be_map_compact(bvm *vm, bmap *map);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_maplib.c b/lib/libesp32/Berry/src/be_maplib.c
deleted file mode 100644
index bf05f1a2934b..000000000000
--- a/lib/libesp32/Berry/src/be_maplib.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_func.h"
-#include "be_exec.h"
-#include "be_map.h"
-#include "be_vm.h"
-
-#define map_check_data(vm, argc) \
- if (!be_ismap(vm, -1) || be_top(vm) - 1 < argc) { \
- be_return_nil(vm); \
- }
-
-#define map_check_ref(vm) \
- if (be_refcontains(vm, 1)) { \
- be_pushstring(vm, "{...}"); \
- be_return(vm); \
- }
-
-static int m_init(bvm *vm)
-{
- if (be_top(vm) > 1 && be_ismap(vm, 2)) {
- be_pushvalue(vm, 2);
- be_setmember(vm, 1, ".p");
- } else {
- be_newmap(vm);
- be_setmember(vm, 1, ".p");
- }
- be_return_nil(vm);
-}
-
-static void push_key(bvm *vm)
-{
- be_toescape(vm, -2, 'x'); /* escape string */
- be_pushvalue(vm, -2); /* push to top */
- be_strconcat(vm, -5);
- be_pop(vm, 1);
-}
-
-static void push_value(bvm *vm)
-{
- be_toescape(vm, -1, 'x'); /* escape string */
- be_strconcat(vm, -4);
- be_pop(vm, 2);
- if (be_iter_hasnext(vm, -3)) {
- be_pushstring(vm, ", ");
- be_strconcat(vm, -3);
- be_pop(vm, 1);
- }
-}
-
-static int m_tostring(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 1);
- map_check_ref(vm);
- be_refpush(vm, 1);
- be_pushstring(vm, "{");
- be_pushiter(vm, -2); /* map iterator use 1 register */
- while (be_iter_hasnext(vm, -3)) {
- be_iter_next(vm, -3);
- push_key(vm); /* key.tostring() */
- be_pushstring(vm, ": "); /* add ': ' */
- be_strconcat(vm, -5);
- be_pop(vm, 1);
- push_value(vm); /* value.tostring() */
- }
- be_pop(vm, 1); /* pop iterator */
- be_pushstring(vm, "}");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_refpop(vm);
- be_return(vm);
-}
-
-static int m_remove(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 2);
- be_pushvalue(vm, 2);
- be_data_remove(vm, -2);
- be_return_nil(vm);
-}
-
-static int m_item(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 2);
- be_pushvalue(vm, 2);
- if (!be_getindex(vm, -2)) {
- be_raise(vm, "key_error", be_tostring(vm, 2));
- }
- be_return(vm);
-}
-
-static int m_setitem(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 3);
- be_pushvalue(vm, 2);
- be_pushvalue(vm, 3);
- be_setindex(vm, -3);
- be_return_nil(vm);
-}
-
-static int m_find(bvm *vm)
-{
- int argc = be_top(vm);
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 2);
- be_pushvalue(vm, 2);
- /* not find and has default value */
- if (!be_getindex(vm, -2) && argc >= 3) {
- be_pushvalue(vm, 3);
- }
- be_return(vm);
-}
-
-static int m_contains(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 2);
- be_pushvalue(vm, 2);
- be_pushbool(vm, be_getindex(vm, -2));
- be_return(vm);
-}
-
-static int m_insert(bvm *vm)
-{
- bbool res;
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 3);
- be_pushvalue(vm, 2);
- be_pushvalue(vm, 3);
- res = be_data_insert(vm, -3);
- be_pushbool(vm, res);
- be_return(vm);
-}
-
-static int m_size(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 1);
- be_pushint(vm, be_data_size(vm, -1));
- be_return(vm);
-}
-
-static int m_tobool(bvm *vm)
-{
- be_getmember(vm, 1, ".p");
- map_check_data(vm, 1);
- be_pushbool(vm, be_data_size(vm, -1) > 0);
- be_return(vm);
-}
-
-static int iter_closure(bvm *vm)
-{
- /* for better performance, we operate the upvalues
- * directly without using by the stack. */
- bntvclos *func = var_toobj(vm->cf->func);
- bvalue *uv0 = be_ntvclos_upval(func, 0)->value; /* list value */
- bvalue *uv1 = be_ntvclos_upval(func, 1)->value; /* iter value */
- bmapiter iter = var_toobj(uv1);
- bmapnode *next = be_map_next(var_toobj(uv0), &iter);
- if (next == NULL) {
- be_stop_iteration(vm);
- be_return_nil(vm); /* will not be executed */
- }
- var_setobj(uv1, BE_COMPTR, iter); /* set upvale[1] (iter value) */
- /* push next value to top */
- var_setval(vm->top, &next->value);
- be_incrtop(vm);
- be_return(vm);
-}
-
-static int m_iter(bvm *vm)
-{
- be_pushntvclosure(vm, iter_closure, 2);
- be_getmember(vm, 1, ".p");
- be_setupval(vm, -2, 0);
- be_pushiter(vm, -1);
- be_setupval(vm, -3, 1);
- be_pop(vm, 2);
- be_return(vm);
-}
-
-static int keys_iter_closure(bvm *vm)
-{
- /* for better performance, we operate the upvalues
- * directly without using by the stack. */
- bntvclos *func = var_toobj(vm->cf->func);
- bvalue *uv0 = be_ntvclos_upval(func, 0)->value; /* list value */
- bvalue *uv1 = be_ntvclos_upval(func, 1)->value; /* iter value */
- bmapiter iter = var_toobj(uv1);
- bmapnode *next = be_map_next(var_toobj(uv0), &iter);
- if (next == NULL) {
- be_stop_iteration(vm);
- be_return_nil(vm); /* will not be executed */
- }
- var_setobj(uv1, BE_COMPTR, iter); /* set upvale[1] (iter value) */
- /* push next value to top */
- var_setobj(vm->top, next->key.type, next->key.v.p);
- be_incrtop(vm);
- be_return(vm);
-}
-
-static int m_keys(bvm *vm)
-{
- be_pushntvclosure(vm, keys_iter_closure, 2);
- be_getmember(vm, 1, ".p");
- be_setupval(vm, -2, 0);
- be_pushiter(vm, -1);
- be_setupval(vm, -3, 1);
- be_pop(vm, 2);
- be_return(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-void be_load_maplib(bvm *vm)
-{
- static const bnfuncinfo members[] = {
- { ".p", NULL },
- { "init", m_init },
- { "tostring", m_tostring },
- { "remove", m_remove },
- { "item", m_item },
- { "setitem", m_setitem },
- { "find", m_find },
- { "contains", m_contains },
- { "has", m_contains }, /* deprecated */
- { "size", m_size },
- { "insert", m_insert },
- { "iter", m_iter },
- { "keys", m_keys },
- { "tobool", m_tobool }
- { NULL, NULL }
- };
- be_regclass(vm, "map", members);
-}
-#else
-/* @const_object_info_begin
-class be_class_map (scope: global, name: map) {
- .p, var
- init, func(m_init)
- tostring, func(m_tostring)
- remove, func(m_remove)
- item, func(m_item)
- setitem, func(m_setitem)
- find, func(m_find)
- contains, func(m_contains)
- has, func(m_contains)
- size, func(m_size)
- insert, func(m_insert)
- iter, func(m_iter)
- keys, func(m_keys)
- tobool, func(m_tobool)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_be_class_map.h"
-#endif
diff --git a/lib/libesp32/Berry/src/be_mathlib.c b/lib/libesp32/Berry/src/be_mathlib.c
deleted file mode 100644
index 0cef918e0edf..000000000000
--- a/lib/libesp32/Berry/src/be_mathlib.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include
-#include
-#include
-
-#if BE_USE_MATH_MODULE
-
-#ifdef M_PI
- #undef M_PI
-#endif
-#define M_PI 3.141592653589793238462643383279
-
-#if BE_INTGER_TYPE == 0 /* int */
- #define M_IMAX INT_MAX
- #define M_IMIN INT_MIN
-#elif BE_INTGER_TYPE == 1 /* long */
- #define M_IMAX LONG_MAX
- #define M_IMIN LONG_MIN
-#else /* int64_t (long long) */
- #define M_IMAX LLONG_MAX
- #define M_IMIN LLONG_MIN
-#endif
-
-#if BE_USE_SINGLE_FLOAT
- #define mathfunc(func) func##f
-#else
- #define mathfunc(func) func
-#endif
-
-static int m_isnan(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isreal(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushbool(vm, isnan(x));
- } else {
- be_pushbool(vm, bfalse);
- }
- be_return(vm);
-}
-
-static int m_isinf(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isreal(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushbool(vm, isinf(x));
- } else {
- be_pushbool(vm, bfalse);
- }
- be_return(vm);
-}
-
-static int m_abs(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(fabs)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_ceil(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(ceil)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_floor(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(floor)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_round(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(round)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_sin(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(sin)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_cos(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(cos)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_tan(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(tan)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_asin(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(asin)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_acos(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(acos)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_atan(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(atan)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_atan2(bvm *vm)
-{
- if (be_top(vm) >= 2 && be_isnumber(vm, 1) && be_isnumber(vm, 2)) {
- breal y = be_toreal(vm, 1);
- breal x = be_toreal(vm, 2);
- be_pushreal(vm, mathfunc(atan2)(y, x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_sinh(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(sinh)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_cosh(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(cosh)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_tanh(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(tanh)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_sqrt(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(sqrt)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_exp(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(exp)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_log(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(log)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_log10(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, mathfunc(log10)(x));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_deg(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, x * (breal)(180.0 / M_PI));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_rad(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isnumber(vm, 1)) {
- breal x = be_toreal(vm, 1);
- be_pushreal(vm, x * (breal)(M_PI / 180.0));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_pow(bvm *vm)
-{
- if (be_top(vm) >= 2 && be_isnumber(vm, 1) && be_isnumber(vm, 2)) {
- breal x = be_toreal(vm, 1);
- breal y = be_toreal(vm, 2);
- be_pushreal(vm, mathfunc(pow)(x, y));
- } else {
- be_pushreal(vm, (breal)0.0);
- }
- be_return(vm);
-}
-
-static int m_srand(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isint(vm, 1)) {
- srand((unsigned int)be_toint(vm, 1));
- }
- be_return_nil(vm);
-}
-
-static int m_rand(bvm *vm)
-{
- be_pushint(vm, rand());
- be_return(vm);
-}
-
-/* check that all arguments are either int or real, and return true if at least one is real */
-static int m_check_int_or_has_real(bvm *vm)
-{
- int argc = be_top(vm);
- int has_real = 0;
- for (int i = 1; i <= argc; ++i) {
- if (be_isreal(vm, i)) {
- has_real = 1;
- } else if (!be_isint(vm, i)) {
- be_raise(vm, "type_error", "arguments must be numbers");
- }
- }
- return has_real;
-}
-
-static int m_min_max(bvm *vm, int is_min) {
- int argc = be_top(vm);
- if (argc > 0) {
- /* see if at least one argument is float, else they are all ints */
- int has_real = m_check_int_or_has_real(vm);
- if (has_real) {
- breal bound = be_toreal(vm, 1);
- for (int i = 2; i <= argc; ++i) {
- breal x = be_toreal(vm, i);
- if (is_min ? (x < bound) : (x > bound)) {
- bound = x;
- }
- }
- be_pushreal(vm, bound);
- } else {
- bint bound = be_toint(vm, 1);
- for (int i = 2; i <= argc; ++i) {
- bint x = be_toint(vm, i);
- if (is_min ? (x < bound) : (x > bound)) {
- bound = x;
- }
- }
- be_pushint(vm, bound);
- }
- be_return(vm);
- }
- be_return_nil(vm);
-
-}
-
-int m_min(bvm *vm)
-{
- return m_min_max(vm, 1);
-}
-
-int m_max(bvm *vm)
-{
- return m_min_max(vm, 0);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(math) {
- be_native_module_function("isnan", m_isnan),
- be_native_module_function("isinf", m_isinf),
- be_native_module_function("abs", m_abs),
- be_native_module_function("ceil", m_ceil),
- be_native_module_function("floor", m_floor),
- be_native_module_function("round", m_round),
- be_native_module_function("sin", m_sin),
- be_native_module_function("cos", m_cos),
- be_native_module_function("tan", m_tan),
- be_native_module_function("asin", m_asin),
- be_native_module_function("acos", m_acos),
- be_native_module_function("atan", m_atan),
- be_native_module_function("atan2", m_atan2),
- be_native_module_function("sinh", m_sinh),
- be_native_module_function("cosh", m_cosh),
- be_native_module_function("tanh", m_tanh),
- be_native_module_function("sqrt", m_sqrt),
- be_native_module_function("exp", m_exp),
- be_native_module_function("log", m_log),
- be_native_module_function("log10", m_log10),
- be_native_module_function("deg", m_deg),
- be_native_module_function("rad", m_rad),
- be_native_module_function("pow", m_pow),
- be_native_module_function("srand", m_srand),
- be_native_module_function("rand", m_rand),
- be_native_module_function("min", m_min),
- be_native_module_function("max", m_max),
- be_native_module_real("pi", M_PI),
- be_native_module_real("nan", NAN),
- be_native_module_real("inf", INFINITY),
- be_native_module_int("imax", M_IMAX),
- be_native_module_int("imin", M_IMIN),
-};
-
-be_define_native_module(math, NULL);
-#else
-/* @const_object_info_begin
-module math (scope: global, depend: BE_USE_MATH_MODULE) {
- isnan, func(m_isnan)
- isinf, func(m_isinf)
- abs, func(m_abs)
- ceil, func(m_ceil)
- floor, func(m_floor)
- round, func(m_round)
- sin, func(m_sin)
- cos, func(m_cos)
- tan, func(m_tan)
- asin, func(m_asin)
- acos, func(m_acos)
- atan, func(m_atan)
- atan2, func(m_atan2)
- sinh, func(m_sinh)
- cosh, func(m_cosh)
- tanh, func(m_tanh)
- sqrt, func(m_sqrt)
- exp, func(m_exp)
- log, func(m_log)
- log10, func(m_log10)
- deg, func(m_deg)
- rad, func(m_rad)
- pow, func(m_pow)
- srand, func(m_srand)
- rand, func(m_rand)
- min, func(m_min)
- max, func(m_max)
- pi, real(M_PI)
- nan, real(NAN)
- inf, real(INFINITY)
- imax, int(M_IMAX)
- imin, int(M_IMIN)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_math.h"
-#endif
-
-#endif /* BE_USE_MATH_MODULE */
diff --git a/lib/libesp32/Berry/src/be_mem.c b/lib/libesp32/Berry/src/be_mem.c
deleted file mode 100644
index 9d20ca055121..000000000000
--- a/lib/libesp32/Berry/src/be_mem.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_mem.h"
-#include "be_exec.h"
-#include "be_vm.h"
-#include "be_gc.h"
-#include
-#include
-
-#define GC_ALLOC (1 << 2) /* GC in alloc */
-
-#ifdef BE_EXPLICIT_MALLOC
- #define malloc BE_EXPLICIT_MALLOC
-#endif
-
-#ifdef BE_EXPLICIT_FREE
- #define free BE_EXPLICIT_FREE
-#endif
-
-#ifdef BE_EXPLICIT_REALLOC
- #define realloc BE_EXPLICIT_REALLOC
-#endif
-
-#define POOL16_SIZE 16
-#define POOL32_SIZE 32
-
-#ifdef _MSC_VER
-#include
-#pragma intrinsic(_BitScanForward)
-#endif
-
-#if defined(__GNUC__)
-#define popcount(v) __builtin_popcount(v)
-#define ffs(v) __builtin_ffs(v)
-#elif defined(_MSC_VER)
-#define popcount(v) __popcnt(v)
-
-static int ffs(unsigned x)
-{
- unsigned long i;
- return _BitScanForward(&i, x) ? i : 0;
-}
-#else
-/* https://github.com/hcs0/Hackers-Delight/blob/master/pop.c.txt - count number of 1-bits */
-static int popcount(uint32_t n)
-{
- n = (n & 0x55555555u) + ((n >> 1) & 0x55555555u);
- n = (n & 0x33333333u) + ((n >> 2) & 0x33333333u);
- n = (n & 0x0f0f0f0fu) + ((n >> 4) & 0x0f0f0f0fu);
- n = (n & 0x00ff00ffu) + ((n >> 8) & 0x00ff00ffu);
- n = (n & 0x0000ffffu) + ((n >>16) & 0x0000ffffu);
- return n;
-}
-
-#error "unsupport compiler for ffs()"
-#endif
-
-static void* malloc_from_pool(bvm *vm, size_t size);
-static void free_from_pool(bvm *vm, void* ptr, size_t old_size);
-
-BERRY_API void* be_os_malloc(size_t size)
-{
- return malloc(size);
-}
-
-BERRY_API void be_os_free(void *ptr)
-{
- free(ptr);
-}
-
-BERRY_API void* be_os_realloc(void *ptr, size_t size)
-{
- return realloc(ptr, size);
-}
-
-BERRY_API void* be_realloc(bvm *vm, void *ptr, size_t old_size, size_t new_size)
-{
- void *block = NULL;
- // serial_debug("be_realloc ptr=%p old_size=%i new_size=%i\n", ptr, old_size, new_size);
-
- bbool gc_occured = bfalse; /* if allocation failed, retry after forced GC */
- if (old_size == new_size) { /* the block unchanged, this also captures creation of a zero byte object */
- return ptr;
- }
- /* from now on, block == NULL means allocation failure */
-
- while (1) {
- /* Case 1: new allocation */
-#if BE_USE_PERF_COUNTERS
- vm->counter_mem_alloc++;
-#endif
- if (!ptr || (old_size == 0)) {
- block = malloc_from_pool(vm, new_size);
- }
-
- /* Case 2: deallocate */
- else if (new_size == 0) {
-#if BE_USE_PERF_COUNTERS
- vm->counter_mem_free++;
-#endif
- if (ptr == NULL) { return NULL; } /* safeguard */
- if (BE_USE_DEBUG_GC || comp_is_gc_debug(vm)) {
- memset(ptr, 0xFF, old_size); /* fill the structure with invalid pointers */
- }
- free_from_pool(vm, ptr, old_size);
- break; /* early exit */
- }
-
- /* Case 3: reallocate with a different size */
- else if (new_size && old_size) { // TODO we already know they are not null TODO
-#if BE_USE_PERF_COUNTERS
- vm->counter_mem_realloc++;
-#endif
- if (new_size <= POOL32_SIZE || old_size <=POOL32_SIZE) {
- /* complex case with different pools */
- if (new_size <= POOL16_SIZE && old_size <= POOL16_SIZE) {
- // no change of slot
- block = ptr;
- break;
- } else if (new_size > POOL16_SIZE && old_size > POOL16_SIZE && new_size <= POOL32_SIZE && old_size <= POOL32_SIZE) {
- // no change of slot
- block = ptr;
- break;
- } else {
- /* one of the buffer is out of pool, the other not */
- block = malloc_from_pool(vm, new_size);
- if (block) {
- /* copy memory */
- size_t min_size = old_size < new_size ? old_size : new_size;
- memmove(block, ptr, min_size);
- // serial_debug("memmove from %p to %p size=%i\n", ptr, block, min_size);
- free_from_pool(vm, ptr, old_size);
- }
- }
- } else {
- block = realloc(ptr, new_size);
- // serial_debug("realloc from %p to %p size=%i", ptr, block, new_size);
- }
- } /* end of reallocation */
-
- /* exit allocator, do we need to GC ? */
- if (block) { break; } /* all good */
- if (gc_occured) { /* already tried gc, can't do much anymore */
- be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */
- }
- // serial_debug("be_realloc force_gc\n");
- /* force GC now */
- vm->gc.status |= GC_ALLOC;
- be_gc_collect(vm); /* try to allocate again after GC */
- vm->gc.status &= ~GC_ALLOC;
- gc_occured = btrue; /* don't try again GC */
- }
- vm->gc.usage = vm->gc.usage + new_size - old_size; /* update allocated count */
-
- // serial_debug("be_realloc ret=%p\n", block);
- return block;
-}
-
-BERRY_API void* be_move_to_aligned(bvm *vm, void *ptr, size_t size) {
- (void)vm;
- (void)size;
-#if BE_USE_MEM_ALIGNED
- if (size <= POOL32_SIZE) {
- return ptr; /* if in memory pool, don't move it so be_free() will continue to work */
- }
- void* iram = berry_malloc32(size);
- if (iram) {
- memcpy(iram, ptr, size); /* new_size is always smaller than initial mem zone */
- free(ptr); // TODO gc size is now wrong
- return iram;
- }
-#endif
- return ptr;
-}
-
-/* Special allocator for structures under 32 bytes */
-typedef uint8_t mem16[16]; /* memory line of 16 bytes */
-typedef uint8_t mem32[32]; /* memory line of 32 bytes */
-#define POOL16_SLOTS 31
-#define POOL16_BITMAP_FULL ((1UL<gc.pool16;
- while (pool16) {
- /* look for an empty slot */
- if (pool16->bitmap != 0x0000) {
- /* there is a free slot */
- int bit = ffs(pool16->bitmap) - 1;
- if (bit >= 0) {
- /* we found a free slot */
- // bitClear(pool16->bitmap, bit);
- pool16->bitmap &= ~(1UL << bit);
- // serial_debug("malloc_from_pool found slot in pool %p, bit %i, ptr=%p\n", pool16, bit, &pool16->lines[bit]);
- return &pool16->lines[bit];
- }
- }
- pool16 = pool16->next;
- }
- /* no slot available, we allocate a new pool */
- pool16 = (gc16_t*) malloc(sizeof(gc16_t));
- if (!pool16) { return NULL; } /* out of memory */
- pool16->next = vm->gc.pool16;
- pool16->bitmap = POOL16_BITMAP_FULL - 1; /* allocate first line */
- vm->gc.pool16 = pool16; /* insert at head of linked list */
- // serial_debug("malloc_from_pool allocated new pool %p, size=%i p=%p\n", pool16, sizeof(gc16_t), &pool16->lines[0]);
- return &pool16->lines[0];
- }
-
- if (size <= POOL32_SIZE) {
- /* allocate in pool 32 */
- gc32_t* pool32 = vm->gc.pool32;
- while (pool32) {
- /* look for an empty slot */
- if (pool32->bitmap != 0x0000) {
- /* there is a free slot */
- int bit = ffs(pool32->bitmap) - 1;
- if (bit >= 0) {
- /* we found a free slot */
- // bitClear(pool32->bitmap, bit);
- pool32->bitmap &= ~(1UL << bit);
- // serial_debug("malloc_from_pool found slot in pool %p, bit %i, ptr=%p\n", pool32, bit, &pool32->lines[bit]);
- return &pool32->lines[bit];
- }
- }
- pool32 = pool32->next;
- }
- /* no slot available, we allocate a new pool */
- pool32 = (gc32_t*) malloc(sizeof(gc32_t));
- if (!pool32) { return NULL; } /* out of memory */
- pool32->next = vm->gc.pool32;
- pool32->bitmap = POOL32_BITMAP_FULL - 1; /* allocate first line */
- vm->gc.pool32 = pool32; /* insert at head of linked list */
- // serial_debug("malloc_from_pool allocated new pool %p, size=%i p=%p\n", pool32, sizeof(gc32_t), &pool32->lines[0]);
- return &pool32->lines[0];
- }
-
- return malloc(size); /* default to system malloc */
-}
-
-static void free_from_pool(bvm *vm, void* ptr, size_t old_size) {
- if (old_size <= POOL16_SIZE) {
- gc16_t* pool16 = vm->gc.pool16;
- while (pool16) {
- int32_t offset = (uint8_t*)ptr - (uint8_t*) &pool16->lines[0];
- // serial_debug("free_from_pool ptr=%p pool=%p offset=%i\n", ptr,pool16, offset);
- if ((offset >= 0) && (offset < POOL16_SLOTS*16) && ((offset & 0x0F) == 0)) {
- int bit = offset >> 4;
- // serial_debug("free_from_pool ptr=%p fond pool=%p bit=%i\n", ptr, pool16, bit);
- // bitSet(pool16->bitmap, bit);
- pool16->bitmap |= 1UL << bit;
- return;
- }
- pool16 = pool16->next;
- }
- }
- else if (old_size <= POOL32_SIZE) {
- gc32_t* pool32 = vm->gc.pool32;
- while (pool32) {
- int32_t offset = (uint8_t*)ptr - (uint8_t*) &pool32->lines[0];
- // serial_debug("free_from_pool pool=%p offset=%i\n", pool32, offset);
- if ((offset >= 0) && (offset < POOL16_SLOTS*16) && ((offset & 0x1F) == 0)) {
- int bit = offset >> 5;
- // serial_debug("free_from_pool ptr=%p fond pool=%p bit=%i\n", ptr, pool32, bit);
- // bitSet(pool32->bitmap, bit);
- pool32->bitmap |= 1UL << bit;
- return;
- }
- pool32 = pool32->next;
- }
- }
- else {
- // serial_debug("free_from_pool free=%p\n", ptr);
- free(ptr);
- }
-}
-
-BERRY_API void be_gc_memory_pools(bvm *vm) {
- gc16_t** prev16 = &vm->gc.pool16;
- gc16_t* pool16 = vm->gc.pool16;
- while (pool16) {
- if (pool16->bitmap == POOL16_BITMAP_FULL) {
- /* pool is empty, we can free it */
- *prev16 = pool16->next;
- gc16_t* pool_to_freed = pool16;
- pool16 = pool16->next; /* move to next */
- free(pool_to_freed);
- } else {
- prev16 = &pool16->next;
- pool16 = pool16->next; /* move to next */
- }
- }
- gc32_t** prev32 = &vm->gc.pool32;
- gc32_t* pool32 = vm->gc.pool32;
- while (pool32) {
- if (pool32->bitmap == POOL32_BITMAP_FULL) {
- /* pool is empty, we can free it */
- *prev32 = pool32->next;
- gc32_t* pool_to_freed = pool32;
- pool32 = pool32->next; /* move to next */
- free(pool_to_freed);
- } else {
- prev32 = &pool32->next;
- pool32 = pool32->next; /* move to next */
- }
- }
-}
-
-BERRY_API void be_gc_init_memory_pools(bvm *vm) {
- vm->gc.pool16 = NULL;
- vm->gc.pool32 = NULL;
-}
-
-BERRY_API void be_gc_free_memory_pools(bvm *vm) {
- gc16_t* pool16 = vm->gc.pool16;
- while (pool16) {
- gc16_t* pool_to_freed = pool16;
- pool16 = pool16->next;
- be_os_free(pool_to_freed);
- }
- vm->gc.pool16 = NULL;
-
- gc32_t* pool32 = vm->gc.pool32;
- while (pool32) {
- gc32_t* pool_to_freed = pool32;
- pool32 = pool32->next;
- be_os_free(pool_to_freed);
- }
- vm->gc.pool32 = NULL;
-}
-
-BERRY_API void be_gc_memory_pools_info(bvm *vm, size_t* slots_used, size_t* slots_allocated) {
- size_t used = 0;
- size_t allocated = 0;
-
- gc16_t* pool16 = vm->gc.pool16;
- while (pool16) {
- allocated += POOL16_SLOTS;
- used += POOL16_SLOTS - popcount(pool16->bitmap);
- pool16 = pool16->next;
- }
-
- gc32_t* pool32 = vm->gc.pool32;
- while (pool32) {
- allocated += POOL32_SLOTS;
- used += POOL32_SLOTS - popcount(pool32->bitmap);
- pool32 = pool32->next;
- }
- if (slots_used) { *slots_used = used; }
- if (slots_allocated) { *slots_allocated = allocated; }
-}
diff --git a/lib/libesp32/Berry/src/be_mem.h b/lib/libesp32/Berry/src/be_mem.h
deleted file mode 100644
index 9545cec49f71..000000000000
--- a/lib/libesp32/Berry/src/be_mem.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_MEM_H
-#define BE_MEM_H
-
-#include "berry.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define be_malloc(vm, size) be_realloc((vm), NULL, 0, (size))
-#define be_free(vm, ptr, size) be_realloc((vm), (ptr), (size), 0)
-
-BERRY_API void* be_os_malloc(size_t size);
-BERRY_API void be_os_free(void *ptr);
-BERRY_API void* be_os_realloc(void *ptr, size_t size);
-BERRY_API void* be_realloc(bvm *vm, void *ptr, size_t old_size, size_t new_size);
-BERRY_API void be_gc_memory_pools(bvm *vm);
-BERRY_API void be_gc_free_memory_pools(bvm *vm);
-BERRY_API void be_gc_init_memory_pools(bvm *vm);
-BERRY_API void be_gc_memory_pools_info(bvm *vm, size_t* slots_used, size_t* slots_allocated);
-
-/* The following moves a portion of memory to constraint regions with 32-bits read/write acess */
-/* Effective only if `BE_USE_MEM_ALIGNED` is set to `1`*/
-BERRY_API void* be_move_to_aligned(bvm *vm, void *ptr, size_t size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_module.c b/lib/libesp32/Berry/src/be_module.c
deleted file mode 100644
index f02b9dedbefd..000000000000
--- a/lib/libesp32/Berry/src/be_module.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_module.h"
-#include "be_string.h"
-#include "be_strlib.h"
-#include "be_list.h"
-#include "be_exec.h"
-#include "be_map.h"
-#include "be_gc.h"
-#include "be_mem.h"
-#include "be_vm.h"
-#include
-
-/* the maximum suffix length */
-#define SUFFIX_LEN 5 /* length of (.be .bec .so .dll) + 1 */
-
-/* check POSIX platforms */
-#if defined(__linux__) || \
- defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__)
- #define __POSIX_OS__
-#endif
-
-#if BE_USE_SHARED_LIB
- #if defined(__POSIX_OS__)
- #define DLL_SUFFIX ".so"
- #elif defined(_WIN32)
- #define DLL_SUFFIX ".dll"
- #else
- #define DLL_SUFFIX ""
- #warning module: unsuppord OS
- #endif
-#endif
-
-extern BERRY_LOCAL const bntvmodule_t* const be_module_table[];
-
-static bmodule* native_module(bvm *vm, const bntvmodule_t *nm, bvalue *dst);
-
-static const bntvmodule_t* find_native(bstring *path)
-{
- const bntvmodule_t *module;
- const bntvmodule_t* const *node = be_module_table;
- for (; (module = *node) != NULL; ++node) {
- if (!strcmp(module->name, str(path))) {
- return module;
- }
- }
- return NULL;
-}
-
-static void insert_attrs(bvm *vm, bmap *table, const bntvmodule_t *nm)
-{
- size_t i;
- for (i = 0; i < nm->size; ++i) {
- const bntvmodobj_t *node = nm->attrs + i;
- bstring *name = be_newstr(vm, node->name);
- bvalue *v = be_map_insertstr(vm, table, name, NULL);
- be_assert(node->type <= BE_CMODULE);
- switch (node->type) {
- case BE_CNIL:
- var_setnil(v);
- break;
- case BE_CINT:
- var_setint(v, node->u.i);
- break;
- case BE_CREAL:
- var_setreal(v, node->u.r);
- break;
- case BE_CBOOL:
- var_setbool(v, node->u.b);
- break;
- case BE_CFUNCTION:
- var_setntvfunc(v, node->u.f);
- break;
- case BE_CSTRING:
- var_setstr(v, be_newstr(vm, node->u.s));
- break;
- case BE_CMODULE:
- native_module(vm, node->u.o, v);
- break;
- default: /* error */
- break;
- }
- }
-}
-
-static bmodule* new_module(bvm *vm, const bntvmodule_t *nm)
-{
- bgcobject *gco = be_gcnew(vm, BE_MODULE, bmodule);
- bmodule *obj = cast_module(gco);
- if (obj) {
- var_setmodule(vm->top, obj);
- be_incrtop(vm);
- obj->info.native = nm;
- obj->table = NULL; /* gc protection */
- obj->table = be_map_new(vm);
- insert_attrs(vm, obj->table, nm);
- be_map_compact(vm, obj->table); /* clear space */
- be_stackpop(vm, 1);
- }
- return obj;
-}
-
-static bmodule* native_module(bvm *vm, const bntvmodule_t *nm, bvalue *dst)
-{
- if (nm) {
- bmodule *obj;
- if (nm->module) {
- obj = (bmodule *)nm->module;
- } else { /* new module */
- obj = new_module(vm, nm);
- }
- if (obj && dst) {
- var_setmodule(dst, obj);
- }
- return obj;
- }
- return NULL;
-}
-
-static char* fixpath(bvm *vm, bstring *path, size_t *size)
-{
- char *buffer;
- const char *split, *base;
-#if BE_DEBUG_SOURCE_FILE
- bvalue *func = vm->cf->func;
- bclosure *cl = var_toobj(func);
- if (var_isclosure(func)) {
- base = str(cl->proto->source); /* get the source file path */
- } else {
- base = "/";
- }
-#else
- base = "/";
-#endif
- split = be_splitpath(base);
- *size = split - base + (size_t)str_len(path) + SUFFIX_LEN;
- buffer = be_malloc(vm, *size);
- strncpy(buffer, base, split - base);
- strcpy(buffer + (split - base), str(path));
- return buffer;
-}
-
-static char* conpath(bvm *vm, bstring *path1, bstring *path2, size_t *size)
-{
- char *buffer;
- int len1 = str_len(path1);
- *size = (size_t)len1 + (size_t)str_len(path2) + 1 + SUFFIX_LEN;
- buffer = be_malloc(vm, *size);
- strcpy(buffer, str(path1));
- buffer[len1] = '/';
- strcpy(buffer + len1 + 1, str(path2));
- return buffer;
-}
-
-static int open_script(bvm *vm, char *path)
-{
- int res = be_loadmodule(vm, path);
- if (res == BE_OK)
- be_call(vm, 0);
- return res;
-}
-
-#if BE_USE_SHARED_LIB
-static int open_dllib(bvm *vm, char *path)
-{
- int res = be_loadlib(vm, path);
- if (res == BE_OK)
- be_call(vm, 0);
- return res;
-}
-#endif
-
-static int open_libfile(bvm *vm, char *path, size_t size)
-{
- int res, idx = 0;
- const char *sfxs[] = { "", ".bec", ".be" };
- do {
- strcpy(path + size - SUFFIX_LEN, sfxs[idx]);
- res = open_script(vm, path);
- } while (idx++ < 2 && res == BE_IO_ERROR);
- if (res == BE_IO_ERROR) {
-#if BE_USE_SHARED_LIB
- strcpy(path + size - SUFFIX_LEN, DLL_SUFFIX);
- res = open_dllib(vm, path);
-#endif
- }
- be_free(vm, path, size);
- return res;
-}
-
-static int load_path(bvm *vm, bstring *path, bstring *mod)
-{
- size_t size;
- char *fullpath = conpath(vm, path, mod, &size);
- return open_libfile(vm, fullpath, size);
-}
-
-static int load_cwd(bvm *vm, bstring *path)
-{
- size_t size;
- char *fullpath = fixpath(vm, path, &size);
- return open_libfile(vm, fullpath, size);
-}
-
-static int load_package(bvm *vm, bstring *path)
-{
- int res = load_cwd(vm, path); /* load from current directory */
- if (res == BE_IO_ERROR && vm->module.path) {
- blist *list = vm->module.path;
- bvalue *v = be_list_end(list) - 1;
- bvalue *first = be_list_data(list);
- for (; res == BE_IO_ERROR && v >= first; v--) {
- if (var_isstr(v)) {
- res = load_path(vm, var_tostr(v), path);
- }
- }
- }
- return res;
-}
-
-static int load_native(bvm *vm, bstring *path)
-{
- const bntvmodule_t *nm = find_native(path);
- bmodule *mod = native_module(vm, nm, NULL);
- if (mod != NULL) {
- /* the pointer vm->top may be changed */
- var_setmodule(vm->top, mod);
- be_incrtop(vm);
- return BE_OK;
- }
- return BE_IO_ERROR;
-}
-
-static bvalue* load_cached(bvm *vm, bstring *path)
-{
- bvalue *v = NULL;
- if (vm->module.loaded) {
- v = be_map_findstr(vm, vm->module.loaded, path);
- if (v) {
- *vm->top = *v;
- be_incrtop(vm);
- }
- }
- return v;
-}
-
-void be_cache_module(bvm *vm, bstring *name)
-{
- bvalue *v;
- if (vm->module.loaded == NULL) {
- vm->module.loaded = be_map_new(vm);
- }
- v = be_map_insertstr(vm, vm->module.loaded, name, NULL);
- *v = vm->top[-1];
-}
-
-/* Try to run 'init(m)' function of module. Module is already loaded. */
-static void module_init(bvm *vm) {
- if (be_ismodule(vm, -1)) {
- if (be_getmember(vm, -1, "init")) {
- /* found, call it with current module as parameter */
- be_pushvalue(vm, -2);
- be_call(vm, 1);
- /* the result of init() is cached and returned */
- be_pop(vm, 1);
- be_remove(vm, -2); /* remove initial module */
- } else {
- be_pop(vm, 1);
- }
- }
-}
-
-/* load module to vm->top */
-int be_module_load(bvm *vm, bstring *path)
-{
- int res = BE_OK;
- if (!load_cached(vm, path)) {
- res = load_native(vm, path);
- if (res == BE_IO_ERROR)
- res = load_package(vm, path);
- if (res == BE_OK) {
- /* on first load of the module, try running the '()' function */
- module_init(vm);
- be_cache_module(vm, path);
- }
- }
- return res;
-}
-
-BERRY_API bbool be_getmodule(bvm *vm, const char *k)
-{
- int res = be_module_load(vm, be_newstr(vm, k));
- return res == BE_OK;
-}
-
-bmodule* be_module_new(bvm *vm)
-{
- bgcobject *gco = be_gcnew(vm, BE_MODULE, bmodule);
- bmodule *obj = cast_module(gco);
- if (obj) {
- var_setmodule(vm->top, obj);
- be_incrtop(vm);
- obj->info.native = NULL;
- obj->table = NULL; /* gc protection */
- obj->table = be_map_new(vm);
- be_stackpop(vm, 1);
- }
- return obj;
-}
-
-void be_module_delete(bvm *vm, bmodule *module)
-{
- be_free(vm, module, sizeof(bmodule));
-}
-
-int be_module_attr(bvm *vm, bmodule *module, bstring *attr, bvalue *dst)
-{
- bvalue *member = be_map_findstr(vm, module->table, attr);
- if (!member) { /* try the 'member' function */
- /* if 'init' does not exist, don't call member() */
- if (strcmp(str(attr), "init") == 0) {
- var_setntvfunc(dst, be_default_init_native_function);
- return var_primetype(dst);
- }
- member = be_map_findstr(vm, module->table, str_literal(vm, "member"));
- if (member && var_basetype(member) == BE_FUNCTION) {
- bvalue *top = vm->top;
- top[0] = *member;
- var_setstr(&top[1], attr);
- vm->top += 2; /* prevent collection results */
- be_dofunc(vm, top, 1); /* call method 'method' */
- vm->top -= 2;
- *dst = *vm->top; /* copy result to R(A) */
-
- int type = var_type(dst);
- if (type == BE_MODULE) {
- /* check if the module is named `undefined` */
- bmodule *mod = var_toobj(dst);
- if (strcmp(be_module_name(mod), "undefined") == 0) {
- return BE_NONE; /* if the return value is module `undefined`, consider it is an error */
- }
- }
- return type;
- }
- return BE_NONE;
- }
- *dst = *member;
- return var_type(dst);
-}
-
-bbool be_module_setmember(bvm *vm, bmodule *module, bstring *attr, bvalue *src)
-{
- be_assert(src);
- bmap *attrs = module->table;
- if (!gc_isconst(attrs)) {
- bvalue *v = be_map_findstr(vm, attrs, attr);
- if (v == NULL) {
- v = be_map_insertstr(vm, attrs, attr, NULL);
- }
- if (v) {
- *v = *src;
- return btrue;
- }
- } else {
- /* if not writable, try 'setmember' */
- int type = be_module_attr(vm, module, str_literal(vm, "setmember"), vm->top);
- if (basetype(type) == BE_FUNCTION) {
- bvalue *top = vm->top;
- // top[0] already has 'member'
- var_setstr(&top[1], attr); /* attribute name */
- top[2] = *src; /* new value */
- vm->top += 3; /* prevent collection results */
- be_dofunc(vm, top, 2); /* call method 'setmember' */
- vm->top -= 3;
- int type = var_type(vm->top);
- if (type == BE_BOOL) {
- bbool ret = var_tobool(vm->top);
- if (!ret) {
- return bfalse;
- }
- } else if (type == BE_MODULE) {
- /* check if the module is named `undefined` */
- bmodule *mod = var_toobj(vm->top);
- if (strcmp(be_module_name(mod), "undefined") == 0) {
- return bfalse; /* if the return value is module `undefined`, consider it is an error */
- }
- }
- return btrue;
- }
- }
- return bfalse;
-}
-
-const char* be_module_name(const bmodule *module)
-{
- if (gc_isconst(module)) {
- return module->info.name;
- }
- if (gc_exmark(module) & BE_MODULE_NAME) {
- return str(module->info.sname);
- }
- if (module->info.native) {
- return module->info.native->name;
- }
- return NULL;
-}
-
-bbool be_module_setname(bmodule *module, bstring *name)
-{
- if (!gc_isconst(module)) {
- module->info.sname = name;
- gc_setexmark(module, BE_MODULE_NAME);
- return btrue;
- }
- return bfalse;
-}
-
-static blist* pathlist(bvm *vm)
-{
- if (!vm->module.path) {
- vm->module.path = be_list_new(vm);
- }
- return vm->module.path;
-}
-
-/* push the path list to the top */
-BERRY_API void be_module_path(bvm *vm)
-{
- blist *list = pathlist(vm);
- bvalue *reg = be_incrtop(vm);
- var_setlist(reg, list);
-}
-
-BERRY_API void be_module_path_set(bvm *vm, const char *path)
-{
- blist *list = pathlist(vm);
- bvalue *value = be_list_push(vm, list, NULL);
- var_setnil(value);
- var_setstr(value, be_newstr(vm, path))
-}
-
-/* shared library support */
-#if BE_USE_SHARED_LIB
-
-#if defined(__POSIX_OS__)
-#include
-
-#if defined(__GNUC__)
- #define cast_func(f) (__extension__(bntvfunc)(f))
-#else
- #define cast_func(f) ((bntvfunc)(f))
-#endif
-
-/* load shared library */
-BERRY_API int be_loadlib(bvm *vm, const char *path)
-{
- void *handle = dlopen(path, RTLD_LAZY);
- bntvfunc func = cast_func(dlsym(handle, "berry_export"));
- if (func == NULL) {
- return BE_IO_ERROR;
- }
- be_pushntvfunction(vm, func);
- return BE_OK;
-}
-#elif defined(_WIN32)
-#include
-#include
-
-BERRY_API int be_loadlib(bvm *vm, const char *path)
-{
- HINSTANCE handle = LoadLibrary(path);
- if (handle) {
- union {
- FARPROC proc;
- bntvfunc func;
- } u;
- u.proc = GetProcAddress(handle, "berry_export");
- if (u.func != NULL) {
- be_pushntvfunction(vm, u.func);
- return BE_OK;
- }
- }
- return BE_IO_ERROR;
-}
-#else
-BERRY_API int be_loadlib(bvm *vm, const char *path)
-{
- (void)vm, (void)path;
- return BE_IO_ERROR;
-}
-#endif
-
-#endif /* BE_USE_SHARED_LIB */
diff --git a/lib/libesp32/Berry/src/be_module.h b/lib/libesp32/Berry/src/be_module.h
deleted file mode 100644
index 89ae682ae922..000000000000
--- a/lib/libesp32/Berry/src/be_module.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_MODULE_H
-#define BE_MODULE_H
-
-#include "be_object.h"
-
-#define BE_MODULE_NAME 1
-
-typedef struct bmodule {
- bcommon_header;
- bmap *table;
- union infodata {
- const bntvmodule_t *native;
- const char *name;
- const bstring *sname;
-#ifdef __cplusplus
- BE_CONSTEXPR infodata(const char *name) : name(name) {}
-#endif
- } info;
- bgcobject *gray; /* for gc gray list */
-#ifdef __cplusplus
- BE_CONSTEXPR bmodule(bmap *tab, const char *name) :
- next(0), type(BE_MODULE), marked(GC_CONST),
- table(tab), info(infodata(name)), gray(0) {}
-#endif
-} bmodule;
-
-bmodule* be_module_new(bvm *vm);
-void be_module_delete(bvm *vm, bmodule *module);
-int be_module_load(bvm *vm, bstring *path);
-void be_cache_module(bvm *vm, bstring *name);
-int be_module_attr(bvm *vm, bmodule *module, bstring *attr, bvalue *dst);
-bbool be_module_setmember(bvm *vm, bmodule *module, bstring *attr, bvalue *src);
-const char* be_module_name(const bmodule *module);
-bbool be_module_setname(bmodule *module, bstring *name);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_object.c b/lib/libesp32/Berry/src/be_object.c
deleted file mode 100644
index aa2f7179966d..000000000000
--- a/lib/libesp32/Berry/src/be_object.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_exec.h"
-#include "be_mem.h"
-#include "be_gc.h"
-#include "be_vm.h"
-
-#define cast_comobj(o) gc_cast(o, BE_COMOBJ, bcommomobj)
-
-const char* be_vtype2str(bvalue *v)
-{
- switch(var_primetype(v)) {
- case BE_NIL: return "nil";
- case BE_INT: return "int";
- case BE_REAL: return "real";
- case BE_BOOL: return "bool";
- case BE_CLOSURE: case BE_NTVCLOS: case BE_CTYPE_FUNC:
- case BE_NTVFUNC: return "function";
- case BE_PROTO: return "proto";
- case BE_CLASS: return "class";
- case BE_STRING: return "string";
- case BE_LIST: return "list";
- case BE_MAP: return "map";
- case BE_INSTANCE: return "instance";
- case BE_MODULE: return "module";
- case BE_INDEX: return "var";
- case BE_COMPTR: return "ptr";
- default: return "invalid type";
- }
-}
-
-bvalue* be_indexof(bvm *vm, int idx)
-{
- if (idx > 0) { /* absolute index */
- be_assert(vm->reg + idx <= vm->top);
- return vm->reg + idx - 1;
- }
- /* relative index */
- be_assert(vm->top + idx >= vm->reg);
- return vm->top + idx;
-}
-
-BERRY_API void be_newcomobj(bvm *vm, void *data, bntvfunc destroy)
-{
- bcommomobj *obj;
- bgcobject *gco = be_gcnew(vm, BE_COMOBJ, bcommomobj);
- if ((obj = cast_comobj(gco)) != NULL) {
- bvalue* top = be_incrtop(vm);
- obj->data = data;
- obj->destroy = destroy;
- var_setobj(top, BE_COMOBJ, obj);
- }
-}
-
-void be_commonobj_delete(bvm *vm, bgcobject *obj)
-{
- bcommomobj *co = cast_comobj(obj);
- if (co) {
- if (co->destroy && co->data) {
- be_pushntvfunction(vm, co->destroy);
- be_pushcomptr(vm, co->data);
- be_call(vm, 1);
- be_pop(vm, 2);
- }
- be_free(vm, co, sizeof(bcommomobj));
- }
-}
-
-/* generic destroy method for comobj, just call be_os_free() on the pointer */
-int be_commonobj_destroy_generic(bvm* vm)
-{
- int argc = be_top(vm);
- if (argc > 0) {
- void * obj = be_tocomptr(vm, 1);
- if (obj != NULL) { be_os_free(obj); }
- }
- be_return_nil(vm);
-}
diff --git a/lib/libesp32/Berry/src/be_object.h b/lib/libesp32/Berry/src/be_object.h
deleted file mode 100644
index 1c8d405725a6..000000000000
--- a/lib/libesp32/Berry/src/be_object.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_OBJECT_H
-#define BE_OBJECT_H
-
-#include "berry.h"
-
-/* basic types, do not change value */
-#define BE_NONE -256 /* unknown type */
-#define BE_NIL 0
-#define BE_INT 1
-#define BE_REAL 2
-#define BE_BOOL 3
-#define BE_COMPTR 4 /* common pointer */
-#define BE_INDEX 5 /* index for instance variable, previously BE_INT */
-#define BE_FUNCTION 6
-
-#define BE_GCOBJECT 16 /* from this type can be gced */
-#define BE_GCOBJECT_MAX (3<<5) /* 96 - from this type can't be gced */
-
-#define BE_STRING 16
-#define BE_CLASS 17
-#define BE_INSTANCE 18
-#define BE_PROTO 19
-#define BE_LIST 20
-#define BE_MAP 21
-#define BE_MODULE 22
-#define BE_COMOBJ 23 /* common object */
-
-#define BE_NTVFUNC ((0 << 5) | BE_FUNCTION) /* 6 - cannot be gced */
-#define BE_CLOSURE ((1 << 5) | BE_FUNCTION) /* 38 - can be gced */
-#define BE_NTVCLOS ((2 << 5) | BE_FUNCTION) /* 70 - can be gced*/
-#define BE_CTYPE_FUNC ((3 << 5) | BE_FUNCTION) /* 102 - cannot be gced */
-#define BE_STATIC (1 << 7) /* 128 */
-
-/* values for bproto.varg */
-#define BE_VA_VARARG (1 << 0) /* function has variable number of arguments */
-#define BE_VA_METHOD (1 << 1) /* function is a method (this is only a hint) */
-#define BE_VA_STATICMETHOD (1 << 2) /* the function is a static method and has the class as implicit '_class' variable */
-#define BE_VA_SHARED_KTAB (1 << 3) /* the funciton has a shared consolidated ktab */
-#define BE_VA_NOCOMPACT (1 << 4) /* the funciton has a shared consolidated ktab */
-#define array_count(a) (sizeof(a) / sizeof((a)[0]))
-
-#define bcommon_header \
- struct bgcobject *next; \
- bbyte type; \
- bbyte marked
-
-#define bstring_header \
- bcommon_header; \
- bbyte extra; \
- bbyte slen
-
-typedef struct bgcobject {
- bcommon_header;
-} bgcobject;
-
-typedef struct bclosure bclosure;
-typedef struct bntvclos bntvclos;
-typedef struct bclass bclass;
-typedef struct binstance binstance;
-typedef struct binstance_arg3 binstance_arg3;
-typedef struct blist blist;
-typedef struct bmap bmap;
-typedef struct bupval bupval;
-
-typedef uint32_t binstruction;
-
-typedef struct bstring {
- bstring_header;
-} bstring;
-
-/* the definition of the vector and stack data structures.
- * in fact, the stack is implemented by vector. */
-typedef struct bvector {
- int capacity; /* the number of elements that the vector can store */
- int size; /* the size of each element (bytes) */
- int count; /* number of elements of the vector */
- void *data; /* the data block pointer, if vector is empty,
- it will point to the first element */
- void *end; /* pointer to the last element, if the vector is empty,
- the end pointer will be smaller than the data pointer */
-} bvector, bstack;
-
-/* berry value data union, a berry value is always described
- * by the data structure contained in the bvaldata union. */
-union bvaldata {
- bbool b; /* boolean */
- breal r; /* real number */
- bint i; /* integer number */
- void *p; /* object pointer */
- const void *c; /* const object pointer */
- bstring *s; /* string pointer */
- bgcobject *gc; /* GC object */
- bntvfunc nf; /* native C function */
-#ifdef __cplusplus
- BE_CONSTEXPR bvaldata(bbool v) : b(v) {}
- BE_CONSTEXPR bvaldata(breal v) : r(v) {}
- BE_CONSTEXPR bvaldata(bint v) : i(v) {}
- BE_CONSTEXPR bvaldata(void *v) : p(v) {}
- BE_CONSTEXPR bvaldata(const void *v) : c(v) {}
- BE_CONSTEXPR bvaldata(bntvfunc v) : nf(v) {}
-#endif
-};
-
-/* berry value. for simple types, the value of the data is stored,
- * while the complex type stores a reference to the data. */
-typedef struct bvalue {
- union bvaldata v; /* the value data */
- int type; /* the value type */
-} bvalue;
-
-typedef struct {
-#if BE_DEBUG_VAR_INFO
- bstring *name;
-#endif
- bbyte instack;
- bbyte idx;
-} bupvaldesc;
-
-typedef struct {
-#if BE_DEBUG_RUNTIME_INFO > 1
- uint16_t linenumber;
- uint16_t endpc;
-#else
- int linenumber;
- int endpc;
-#endif
-} blineinfo;
-
-typedef struct {
- bstring *name;
-#if BE_DEBUG_RUNTIME_INFO > 1
- uint16_t beginpc;
- uint16_t endpc;
-#else
- int beginpc;
- int endpc;
-#endif
-} bvarinfo;
-
-typedef struct bproto {
- bcommon_header;
- bbyte nstack; /* number of stack size by this function */
- bbyte nupvals; /* upvalue count */
- bbyte argc; /* argument count */
- bbyte varg; /* variable argument position + 1 */
- int16_t codesize; /* code size */
- int16_t nconst; /* constants count */
- int16_t nproto; /* proto count */
- bgcobject *gray; /* for gc gray list */
- bupvaldesc *upvals;
- bvalue *ktab; /* constants table */
- struct bproto **ptab; /* proto table */
- binstruction *code; /* instructions sequence */
- bstring *name; /* function name */
-#if BE_DEBUG_SOURCE_FILE
- bstring *source; /* source file name */
-#endif
-#if BE_DEBUG_RUNTIME_INFO /* debug information */
- blineinfo *lineinfo;
- int nlineinfo;
-#endif
-#if BE_DEBUG_VAR_INFO
- bvarinfo *varinfo;
- int nvarinfo;
-#endif
-} bproto;
-
-/* berry closure */
-struct bclosure {
- bcommon_header;
- bbyte nupvals;
- bgcobject *gray; /* for gc gray list */
- bproto *proto;
- bupval *upvals[1];
-};
-
-/* C native function or closure */
-struct bntvclos {
- bcommon_header;
- bbyte nupvals;
- bgcobject *gray; /* for gc gray list */
- bntvfunc f;
-};
-
-/* common object */
-typedef struct {
- bcommon_header;
- void *data;
- bntvfunc destroy;
-} bcommomobj;
-
-struct blexer;
-typedef const char* (*breader)(struct blexer*, void*, size_t*);
-
-#define cast(_T, _v) ((_T)(_v))
-#define cast_int(_v) cast(int, _v)
-#define cast_bool(_v) cast(bbool, _v)
-#define basetype(_t) ((_t) & 0x1F)
-
-#define var_type(_v) ((_v)->type)
-#define var_basetype(_v) basetype((_v)->type)
-#define var_primetype(_v) (var_type(_v) & ~BE_STATIC)
-#define var_isstatic(_v) ((var_type(_v) & BE_STATIC) == BE_STATIC)
-#define var_istype(_v, _t) (var_primetype(_v) == _t)
-#define var_settype(_v, _t) ((_v)->type = _t)
-#define var_markstatic(_v) var_settype(_v, var_type(_v) | BE_STATIC)
-#define var_clearstatic(_v) var_settype(_v, var_type(_v) & ~BE_STATIC)
-#define var_setobj(_v, _t, _o) { (_v)->v.p = _o; var_settype(_v, _t); }
-
-#define var_isnil(_v) var_istype(_v, BE_NIL)
-#define var_isbool(_v) var_istype(_v, BE_BOOL)
-#define var_isint(_v) var_istype(_v, BE_INT)
-#define var_isreal(_v) var_istype(_v, BE_REAL)
-#define var_isstr(_v) var_istype(_v, BE_STRING)
-#define var_isclosure(_v) var_istype(_v, BE_CLOSURE)
-#define var_isntvclos(_v) var_istype(_v, BE_NTVCLOS)
-#define var_isntvfunc(_v) var_istype(_v, BE_NTVFUNC)
-#define var_isfunction(_v) (var_basetype(_v) == BE_FUNCTION)
-#define var_isproto(_v) var_istype(_v, BE_PROTO)
-#define var_isclass(_v) var_istype(_v, BE_CLASS)
-#define var_isinstance(_v) var_istype(_v, BE_INSTANCE)
-#define var_islist(_v) var_istype(_v, BE_LIST)
-#define var_ismap(_v) var_istype(_v, BE_MAP)
-#define var_ismodule(_v) var_istype(_v, BE_MODULE)
-#define var_isindex(_v) var_istype(_v, BE_INDEX)
-#define var_iscomptr(_v) var_istype(_v, BE_COMPTR)
-#define var_isnumber(_v) (var_isint(_v) || var_isreal(_v))
-
-#define var_setnil(_v) var_settype(_v, BE_NIL)
-#define var_setval(_v, _s) (*(_v) = *(_s))
-#define var_setbool(_v, _b) { var_settype(_v, BE_BOOL); (_v)->v.b = (bbool)(_b); }
-#define var_setint(_v, _i) { var_settype(_v, BE_INT); (_v)->v.i = (_i); }
-#define var_setreal(_v, _r) { var_settype(_v, BE_REAL); (_v)->v.r = (_r); }
-#define var_setstr(_v, _s) var_setobj(_v, BE_STRING, _s)
-#define var_setinstance(_v, _o) var_setobj(_v, BE_INSTANCE, _o)
-#define var_setclass(_v, _o) var_setobj(_v, BE_CLASS, _o)
-#define var_setclosure(_v, _o) var_setobj(_v, BE_CLOSURE, _o)
-#define var_setntvclos(_v, _o) var_setobj(_v, BE_NTVCLOS, _o)
-#define var_setntvfunc(_v, _o) { (_v)->v.nf = (_o); var_settype(_v, BE_NTVFUNC); }
-#define var_setlist(_v, _o) var_setobj(_v, BE_LIST, _o)
-#define var_setmap(_v, _o) var_setobj(_v, BE_MAP, _o)
-#define var_setmodule(_v, _o) var_setobj(_v, BE_MODULE, _o)
-#define var_setindex(_v, _i) { var_settype(_v, BE_INDEX); (_v)->v.i = (_i); }
-#define var_setproto(_v, _o) var_setobj(_v, BE_PROTO, _o)
-
-#define var_tobool(_v) ((_v)->v.b)
-#define var_toint(_v) ((_v)->v.i)
-#define var_toreal(_v) ((_v)->v.r)
-#define var_tostr(_v) ((_v)->v.s)
-#define var_togc(_v) ((_v)->v.gc)
-#define var_toobj(_v) ((_v)->v.p)
-#define var_tontvfunc(_v) ((_v)->v.nf)
-#define var_toidx(_v) cast_int(var_toint(_v))
-
-const char* be_vtype2str(bvalue *v);
-bvalue* be_indexof(bvm *vm, int idx);
-void be_commonobj_delete(bvm *vm, bgcobject *obj);
-int be_commonobj_destroy_generic(bvm* vm);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_opcodes.h b/lib/libesp32/Berry/src/be_opcodes.h
deleted file mode 100644
index 12c3781e0645..000000000000
--- a/lib/libesp32/Berry/src/be_opcodes.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-/* define opcode, don't change order */
-/* opcode parameters description */
-OPCODE(ADD), /* A, B, C | R(A) <- RK(B) + RK(C) */
-OPCODE(SUB), /* A, B, C | R(A) <- RK(B) - RK(C) */
-OPCODE(MUL), /* A, B, C | R(A) <- RK(B) * RK(C) */
-OPCODE(DIV), /* A, B, C | R(A) <- RK(B) / RK(C) */
-OPCODE(MOD), /* A, B, C | R(A) <- RK(B) % RK(C) */
-OPCODE(LT), /* A, B, C | R(A) <- RK(B) < RK(C) */
-OPCODE(LE), /* A, B, C | R(A) <- RK(B) <= RK(C) */
-OPCODE(EQ), /* A, B, C | R(A) <- RK(B) == RK(C) */
-OPCODE(NE), /* A, B, C | R(A) <- RK(B) != RK(C) */
-OPCODE(GT), /* A, B, C | R(A) <- RK(B) > RK(C) */
-OPCODE(GE), /* A, B, C | R(A) <- RK(B) >= RK(C) */
-OPCODE(AND), /* A, B, C | R(A) <- RK(B) & RK(C) */
-OPCODE(OR), /* A, B, C | R(A) <- RK(B) | RK(C) */
-OPCODE(XOR), /* A, B, C | R(A) <- RK(B) ^ RK(C) */
-OPCODE(SHL), /* A, B, C | R(A) <- RK(B) << RK(C) */
-OPCODE(SHR), /* A, B, C | R(A) <- RK(B) >> RK(C) */
-OPCODE(CONNECT), /* A, B, C | R(A) <- connect(RK(B), RK(C)) */
-OPCODE(NEG), /* A, B | R(A) <- -RK(B) */
-OPCODE(FLIP), /* A, B | R(A) <- ~RK(B) */
-OPCODE(LDNIL), /* A | R(A) <- nil */
-OPCODE(LDBOOL), /* A, B, C | R(A) <- cast_bool(B), if(C): pc++ */
-OPCODE(LDINT), /* A, sBx | R(A) <- sBx */
-OPCODE(LDCONST), /* A, Bx | R(A) <- K(Bx) */
-OPCODE(MOVE), /* A, B, C | R(A) <- RK(B) */
-OPCODE(GETGBL), /* A, Bx | R(A) <- GLOBAL(Bx) */
-OPCODE(SETGBL), /* A, Bx | R(A) -> GLOBAL(Bx) */
-OPCODE(GETUPV), /* A, Bx | R(A) <- UPVALUE(Bx)*/
-OPCODE(SETUPV), /* A, Bx | R(A) -> UPVALUE(Bx)*/
-OPCODE(JMP), /* sBx | pc <- pc + sBx */
-OPCODE(JMPT), /* A, sBx | if(R(A)): pc <- pc + sBx */
-OPCODE(JMPF), /* A, sBx | if(not R(A)): pc <- pc + sBx */
-OPCODE(CALL), /* A, B | CALL(R(A), B) */
-OPCODE(RET), /* A, B | if (R(A)) R(-1) <- RK(B) else R(-1) <- nil */
-OPCODE(CLOSURE), /* A, Bx | R(A) <- CLOSURE(proto_table[Bx])*/
-OPCODE(GETMBR), /* A, B, C | R(A) <- RK(B).RK(C) */
-OPCODE(GETMET), /* A, B, C | R(A) <- RK(B).RK(C), R(A+1) <- RK(B) */
-OPCODE(SETMBR), /* A, B, C | R(A).RK(B) <- RK(C) */
-OPCODE(GETIDX), /* A, B, C | R(A) <- RK(B)[RK(C)] */
-OPCODE(SETIDX), /* A, B, C | R(A)[RK(B)] <- RK(C) */
-OPCODE(SETSUPER), /* A, B | class:R(A) set super with class:RK(B) */
-OPCODE(CLOSE), /* A | close upvalues */
-OPCODE(IMPORT), /* A, B, C | IF (A == C) import module name as RK(B) to RK(A), ELSE from module RK(C) import name as RK(B) to RK(A) */
-OPCODE(EXBLK), /* A, Bx | ... */
-OPCODE(CATCH), /* A, B, C | ... */
-OPCODE(RAISE), /* A, B, C | RAISE(B,C) B is code, C is description. A==0 only B provided, A==1 B and C are provided, A==2 rethrow with both parameters already on stack */
-OPCODE(CLASS), /* Bx | init class in K[Bx] */
-OPCODE(GETNGBL), /* A, B | R(A) <- GLOBAL[RK(B)] by name */
-OPCODE(SETNGBL) /* A, B | R(A) -> GLOBAL[RK(B)] by name */
diff --git a/lib/libesp32/Berry/src/be_oslib.c b/lib/libesp32/Berry/src/be_oslib.c
deleted file mode 100644
index 1d4f029c29e7..000000000000
--- a/lib/libesp32/Berry/src/be_oslib.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_strlib.h"
-#include "be_mem.h"
-#include "be_sys.h"
-#include
-#include
-
-#define FNAME_BUF_SIZE 512
-
-#if BE_USE_OS_MODULE
-
-#if !BE_USE_FILE_SYSTEM
- #error the dependent macro BE_USE_FILE_SYSTEM must be enabled
-#endif
-
-static int m_getcwd(bvm *vm)
-{
- char *buf = be_malloc(vm, FNAME_BUF_SIZE);
- if (be_getcwd(buf, FNAME_BUF_SIZE)) {
- be_pushstring(vm, buf);
- } else {
- be_pushstring(vm, "");
- }
- be_free(vm, buf, FNAME_BUF_SIZE);
- be_return(vm);
-}
-
-static int m_chdir(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- int res = be_chdir(be_tostring(vm, 1));
- be_pushbool(vm, res == 0);
- }
- be_return(vm);
-}
-
-static int m_mkdir(bvm *vm)
-{
- int res = 1;
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- res = be_mkdir(be_tostring(vm, 1));
- }
- be_pushbool(vm, res == 0);
- be_return(vm);
-}
-
-static int m_remove(bvm *vm)
-{
- int res = 1;
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- res = be_unlink(be_tostring(vm, 1));
- }
- be_pushbool(vm, res == 0);
- be_return(vm);
-}
-
-static int m_listdir(bvm *vm)
-{
- int res;
- bdirinfo info;
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- res = be_dirfirst(&info, be_tostring(vm, 1));
- } else {
- res = be_dirfirst(&info, ".");
- }
- be_newobject(vm, "list");
- while (res == 0) {
- const char *fn = info.name;
- if (strcmp(fn, ".") && strcmp(fn, "..")) {
- be_pushstring(vm, fn);
- be_data_push(vm, -2);
- be_pop(vm, 1);
- }
- res = be_dirnext(&info);
- }
- be_dirclose(&info);
- be_pop(vm, 1);
- be_return(vm);
-}
-
-static int m_system(bvm *vm)
-{
- int res = -1, i, argc = be_top(vm);
- if (argc > 0) {
- be_tostring(vm, 1);
- be_pushstring(vm, " ");
- for (i = 2; i <= argc; ++i) {
- be_strconcat(vm, 1); /* add " " */
- be_tostring(vm, i);
- be_pushvalue(vm, i);
- be_strconcat(vm, 1); /* concat arg */
- be_pop(vm, 1);
- }
- be_pop(vm, argc);
- res = system(be_tostring(vm, 1));
- }
- be_pushint(vm, res);
- be_return(vm);
-}
-
-static int m_exit(bvm *vm)
-{
- int status = 0;
- if (be_top(vm)) {
- if (be_isint(vm, 1)) {
- status = be_toindex(vm, 1); /* get the exit code */
- } else if (be_isbool(vm, 1)) {
- status = be_tobool(vm, 1) - 1; /* true: 0, false: -1 */
- } else {
- status = -1;
- }
- }
- be_exit(vm, status);
- be_return_nil(vm);
-}
-
-static int m_path_isdir(bvm *vm)
-{
- const char *path = NULL;
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- path = be_tostring(vm, 1);
- }
- be_pushbool(vm, be_isdir(path));
- be_return(vm);
-}
-
-static int m_path_isfile(bvm *vm)
-{
- const char *path = NULL;
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- path = be_tostring(vm, 1);
- }
- be_pushbool(vm, be_isfile(path));
- be_return(vm);
-}
-
-static int m_path_split(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- const char *path = be_tostring(vm, 1);
- const char *split = be_splitpath(path);
- size_t len = split - path;
- if (split > path + 1 && split[-1] == '/') {
- const char *p = split - 1;
- for (; p >= path && *p == '/'; --p);
- if (p >= path) {
- len = p - path + 1;
- }
- }
- be_getbuiltin(vm, "list");
- be_pushnstring(vm, path, len);
- be_pushstring(vm, split);
- be_call(vm, 2);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_path_splitext(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- const char *path = be_tostring(vm, 1);
- const char *split = be_splitname(path);
- be_getbuiltin(vm, "list");
- be_pushnstring(vm, path, split - path);
- be_pushstring(vm, split);
- be_call(vm, 2);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_path_exists(bvm *vm)
-{
- const char *path = NULL;
- if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
- path = be_tostring(vm, 1);
- }
- be_pushbool(vm, be_isexist(path));
- be_return(vm);
-}
-
-static int m_path_join(bvm *vm)
-{
- char *buf, *p;
- int i, len = 0, argc = be_top(vm);
- for (i = 1; i <= argc; ++i) {
- if (be_isstring(vm, i)) {
- len += be_strlen(vm, i) + 1;
- } else {
- be_raise(vm, "type_error", "arguments must be string");
- }
- }
- buf = p = be_malloc(vm, (size_t)len + 1);
- for (i = 1; i <= argc; ++i) {
- int l = be_strlen(vm, i);
- const char *s = be_tostring(vm, i);
- if (s[0] == '/') {
- p = buf;
- }
- strcpy(p, s);
- p += l;
- if (l && s[l - 1] != '/' && i != argc) {
- *p++ = '/';
- }
- }
- be_pushnstring(vm, buf, p - buf);
- be_free(vm, buf, (size_t)len + 1);
- be_return(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(path) {
- be_native_module_function("isdir", m_path_isdir),
- be_native_module_function("isfile", m_path_isfile),
- be_native_module_function("exists", m_path_exists),
- be_native_module_function("split", m_path_split),
- be_native_module_function("splitext", m_path_splitext),
- be_native_module_function("join", m_path_join)
-};
-
-static be_define_native_module(path, NULL);
-
-be_native_module_attr_table(os) {
- be_native_module_function("getcwd", m_getcwd),
- be_native_module_function("chdir", m_chdir),
- be_native_module_function("mkdir", m_mkdir),
- be_native_module_function("remove", m_remove),
- be_native_module_function("listdir", m_listdir),
- be_native_module_function("system", m_system),
- be_native_module_function("exit", m_exit),
- be_native_module_module("path", be_native_module(path))
-};
-
-be_define_native_module(os, NULL);
-#else
-/* @const_object_info_begin
-module path (scope: local, file: os_path, depend: BE_USE_OS_MODULE) {
- isdir, func(m_path_isdir)
- isfile, func(m_path_isfile)
- exists, func(m_path_exists)
- split, func(m_path_split)
- splitext, func(m_path_splitext)
- join, func(m_path_join)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_os_path.h"
-
-/* @const_object_info_begin
-module os (scope: global, depend: BE_USE_OS_MODULE) {
- getcwd, func(m_getcwd)
- chdir, func(m_chdir)
- mkdir, func(m_mkdir)
- remove, func(m_remove)
- listdir, func(m_listdir)
- system, func(m_system)
- exit, func(m_exit)
- path, module(m_libpath)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_os.h"
-#endif
-
-#endif /* BE_USE_OS_MODULE */
diff --git a/lib/libesp32/Berry/src/be_parser.c b/lib/libesp32/Berry/src/be_parser.c
deleted file mode 100644
index 9737cdf81cc7..000000000000
--- a/lib/libesp32/Berry/src/be_parser.c
+++ /dev/null
@@ -1,1838 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_parser.h"
-#include "be_lexer.h"
-#include "be_vector.h"
-#include "be_mem.h"
-#include "be_vm.h"
-#include "be_map.h"
-#include "be_list.h"
-#include "be_var.h"
-#include "be_code.h"
-#include "be_string.h"
-#include "be_func.h"
-#include "be_class.h"
-#include "be_decoder.h"
-#include "be_exec.h"
-#include
-
-#define OP_NOT_BINARY TokenNone
-#define OP_NOT_UNARY TokenNone
-#define OP_NOT_ASSIGN TokenNone
-#define UNARY_OP_PRIO 3
-#define ASSIGN_OP_PRIO 16
-
-#define FUNC_METHOD 1
-#define FUNC_ANONYMOUS 2
-#define FUNC_STATIC 4
-
-#if BE_INTGER_TYPE == 0 /* int */
- #define M_IMAX INT_MAX
- #define M_IMIN INT_MIN
-#elif BE_INTGER_TYPE == 1 /* long */
- #define M_IMAX LONG_MAX
- #define M_IMIN LONG_MIN
-#else /* int64_t (long long) */
- #define M_IMAX LLONG_MAX
- #define M_IMIN LLONG_MIN
-#endif
-
-/* get binary operator priority */
-#define binary_op_prio(op) (binary_op_prio_tab[cast_int(op) - OptAdd])
-
-#define scan_next_token(parser) (be_lexer_scan_next(&(parser)->lexer))
-#define next_token(parser) ((parser)->lexer.token)
-#define next_type(parser) (next_token(parser).type)
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define token2str(parser) be_token2str((parser)->vm, &next_token(parser))
-#define funcname(parser) ((parser)->islocal ? "loader" : "main")
-
-#define upval_index(v) ((v) & 0xFF)
-#define upval_target(v) ((bbyte)(((v) >> 8) & 0xFF))
-#define upval_instack(v) ((bbyte)(((v) >> 16) != 0))
-#define upval_desc(i, t, s) (((i) & 0xFF) | (((t) & 0xFF) << 8) \
- | (((s) != 0) << 16))
-
-#define match_id(parser, s) ((s) = _match_id(parser))
-
-#define parser_newstr(p, str) be_lexer_newstr(&(p)->lexer, (str))
-
-#define parser_error(p, msg) be_lexerror(&(p)->lexer, msg)
-
-#define push_error(parser, ...) \
- parser_error(parser, be_pushfstring(parser->vm, __VA_ARGS__))
-
-typedef struct {
- blexer lexer;
- bvm *vm;
- bfuncinfo *finfo;
- bclosure *cl;
- bbyte islocal;
-} bparser;
-
-#if BE_USE_SCRIPT_COMPILER
-
-static void stmtlist(bparser *parser);
-static void block(bparser *parser, int type);
-static void expr(bparser *parser, bexpdesc *e);
-static void walrus_expr(bparser *parser, bexpdesc *e);
-static void sub_expr(bparser *parser, bexpdesc *e, int prio);
-
-static const bbyte binary_op_prio_tab[] = {
- 5, 5, 4, 4, 4, /* + - * / % */
- 11, 11, 12, 12, 11, 11, /* < <= == != > >= */
- 7, 9, 8, 6, 6, 10, 13, 14 /* & | ^ << >> .. && || */
-};
-
-static void match_token(bparser *parser, btokentype type)
-{
- if (next_type(parser) != type) { /* error when token is no match */
- btoken *token = &next_token(parser);
- const char *s1 = be_tokentype2str(type);
- const char *s2 = be_token2str(parser->vm, token);
- push_error(parser, "expected '%s' before '%s'", s1, s2);
- }
- scan_next_token(parser); /* skip this token */
-}
-
-/* Check that the next token is not of type `type` */
-/* or raise an exception */
-static void match_notoken(bparser *parser, btokentype type)
-{
- if (next_type(parser) == type) { /* error when token is match */
- push_error(parser,
- "expected statement before '%s'", token2str(parser));
- }
-}
-
-/* check that if the expdesc is a symbol, it is a valid one or raise an exception */
-static void check_symbol(bparser *parser, bexpdesc *e)
-{
- if (e->type == ETVOID && e->v.s == NULL) { /* error when token is not a symbol */
- push_error(parser,
- "unexpected symbol near '%s'", token2str(parser));
- }
-}
-
-/* check that the value in `e` is valid for a variable, i.e. contains a value or a valid symbol */
-static void check_var(bparser *parser, bexpdesc *e)
-{
- check_symbol(parser, e); /* check the token is a symbol */
- if (e->type == ETVOID) { /* error when symbol is undefined */
- int line = parser->lexer.linenumber;
- parser->lexer.linenumber = parser->lexer.lastline;
- push_error(parser,
- "'%s' undeclared (first use in this function)", str(e->v.s));
- parser->lexer.linenumber = line;
- }
-}
-
-static int match_skip(bparser *parser, btokentype type)
-{
- if (next_type(parser) == type) { /* match */
- scan_next_token(parser); /* skip this token */
- return btrue;
- }
- return bfalse;
-}
-
-static bstring* _match_id(bparser *parser)
-{
- if (next_type(parser) == TokenId) {
- bstring *str = next_token(parser).u.s;
- scan_next_token(parser); /* skip ID */
- return str;
- }
- return NULL;
-}
-
-#if BE_DEBUG_VAR_INFO
-
-void begin_varinfo(bparser *parser, bstring *name)
-{
- bvarinfo *var;
- bfuncinfo *finfo = parser->finfo;
- be_vector_push_c(parser->vm, &finfo->varvec, NULL);
- var = be_vector_end(&finfo->varvec);
- var->name = name;
- var->beginpc = finfo->pc;
- var->endpc = 0; /* */
- finfo->proto->varinfo = be_vector_data(&finfo->varvec);
- finfo->proto->nvarinfo = be_vector_capacity(&finfo->varvec);
-}
-
-void end_varinfo(bparser *parser, int beginpc)
-{
- bfuncinfo *finfo = parser->finfo;
- bblockinfo *binfo = finfo->binfo;
- bvarinfo *it = be_vector_data(&finfo->varvec);
- bvarinfo *end = be_vector_end(&finfo->varvec);
- if (beginpc == -1) /* use block->beginpc by default */
- beginpc = binfo->beginpc;
- /* skip the variable of the previous blocks */
- for (; (it <= end) && (it->beginpc < beginpc); ++it);
- for (; it <= end; ++it) {
- if (!it->endpc) /* write to endpc only once */
- it->endpc = finfo->pc;
- }
-}
-
-#else
-
-#define begin_varinfo(parser, name)
-#define end_varinfo(parser, beginpc) (void)(beginpc)
-
-#endif
-
-/* Initialize bblockinfo structure */
-static void begin_block(bfuncinfo *finfo, bblockinfo *binfo, int type)
-{
- binfo->prev = finfo->binfo; /* save previous block */
- finfo->binfo = binfo; /* tell parser this is the current block */
- binfo->type = (bbyte)type;
- binfo->hasupval = 0;
- binfo->sideeffect = 0;
- binfo->lastjmp = 0;
- binfo->beginpc = finfo->pc; /* set starting pc for this block */
- binfo->nactlocals = (bbyte)be_list_count(finfo->local); /* count number of local variables in previous block */
- if (type & BLOCK_LOOP) {
- binfo->breaklist = NO_JUMP;
- binfo->continuelist = NO_JUMP;
- }
-}
-
-static void end_block_ex(bparser *parser, int beginpc)
-{
- bfuncinfo *finfo = parser->finfo;
- bblockinfo *binfo = finfo->binfo;
- be_code_close(finfo, 0); /* close upvalues */
- if (binfo->type & BLOCK_LOOP) {
- be_code_jumpto(finfo, binfo->beginpc);
- be_code_patchjump(finfo, binfo->breaklist);
- be_code_patchlist(finfo, binfo->continuelist, binfo->beginpc);
- }
- end_varinfo(parser, beginpc);
- be_list_resize(parser->vm, finfo->local, binfo->nactlocals); /* remove local variables from this block, they are now out of scope */
- finfo->freereg = binfo->nactlocals; /* adjust first free register accordingly */
- finfo->binfo = binfo->prev; /* restore previous block */
-}
-
-static void end_block(bparser *parser)
-{
- end_block_ex(parser, -1);
-}
-
-#if BE_DEBUG_SOURCE_FILE
-/* Return the name of the source for this parser, could be `string`,
- `stdin` or the name of the current function */
-static bstring* parser_source(bparser *parser)
-{
- if (parser->finfo) {
- return parser->finfo->proto->source;
- }
- return be_newstr(parser->vm, parser->lexer.fname);
-}
-#endif
-
-/* Initialize a function block and create a new `bprotoˋ */
-static void begin_func(bparser *parser, bfuncinfo *finfo, bblockinfo *binfo)
-{
- bvm *vm = parser->vm;
- bproto *proto = be_newproto(vm);
- var_setproto(vm->top, proto);
- be_stackpush(vm);
- be_vector_init(vm, &finfo->code, sizeof(binstruction)); /* vector for code, vectors are not gced */
- proto->code = be_vector_data(&finfo->code);
- proto->codesize = be_vector_capacity(&finfo->code);
- be_vector_init(vm, &finfo->kvec, sizeof(bvalue)); /* vector for constants */
- proto->ktab = be_vector_data(&finfo->kvec);
- proto->nconst = be_vector_capacity(&finfo->kvec);
- be_vector_init(vm, &finfo->pvec, sizeof(bproto*)); /* vector for subprotos */
- proto->ptab = be_vector_data(&finfo->pvec);
- proto->nproto = be_vector_capacity(&finfo->pvec);
-#if BE_DEBUG_SOURCE_FILE
- proto->source = parser_source(parser); /* keep a copy of source for function */
-#endif
- finfo->local = be_list_new(vm); /* list for local variables */
- var_setlist(vm->top, finfo->local); /* push list of local variables on the stack (avoid gc) */
- be_stackpush(vm);
- finfo->upval = be_map_new(vm); /* push a map for upvals on stack */
- var_setmap(vm->top, finfo->upval);
- be_stackpush(vm);
- finfo->prev = parser->finfo; /* init finfo */
- finfo->lexer = &parser->lexer;
- finfo->proto = proto;
- finfo->freereg = 0;
- finfo->binfo = NULL;
- finfo->pc = 0;
- finfo->flags = 0;
- parser->finfo = finfo;
-#if BE_DEBUG_RUNTIME_INFO
- be_vector_init(vm, &finfo->linevec, sizeof(blineinfo));
- proto->lineinfo = be_vector_data(&finfo->linevec);
- proto->nlineinfo = be_vector_capacity(&finfo->linevec);
-#endif
-#if BE_DEBUG_VAR_INFO
- be_vector_init(vm, &finfo->varvec, sizeof(bvarinfo));
- proto->varinfo = be_vector_data(&finfo->varvec);
- proto->nvarinfo = be_vector_capacity(&finfo->varvec);
-#endif
- begin_block(finfo, binfo, 0);
-}
-
-/* compute the upval structure */
-static void setupvals(bfuncinfo *finfo)
-{
- bproto *proto = finfo->proto;
- int nupvals = be_map_count(finfo->upval);
- if (nupvals) {
- bmapnode *node;
- bmap *map = finfo->upval;
- bmapiter iter = be_map_iter();
- bupvaldesc *upvals = be_malloc(
- finfo->lexer->vm, sizeof(bupvaldesc) * nupvals);
- while ((node = be_map_next(map, &iter)) != NULL) {
- uint32_t v = (uint32_t)var_toint(&node->value);
- bupvaldesc *uv = upvals + upval_index(v);
- uv->idx = upval_target(v);
- uv->instack = upval_instack(v);
-#if BE_DEBUG_VAR_INFO
- uv->name = var_tostr(&node->key);
-#endif
- }
- proto->upvals = upvals;
- proto->nupvals = (bbyte)nupvals;
- }
-}
-
-/* Function is complete, finalize bproto */
-static void end_func(bparser *parser)
-{
- bvm *vm = parser->vm;
- bfuncinfo *finfo = parser->finfo;
- bproto *proto = finfo->proto;
-
- be_code_ret(finfo, NULL); /* append a return to last code */
- end_block(parser); /* close block */
- setupvals(finfo); /* close upvals */
- proto->code = be_vector_release(vm, &finfo->code); /* compact all vectors and return NULL if empty */
- proto->codesize = finfo->pc;
- proto->ktab = be_vector_release(vm, &finfo->kvec);
- proto->nconst = be_vector_count(&finfo->kvec);
- proto->nproto = be_vector_count(&finfo->pvec);
- proto->ptab = be_vector_release(vm, &finfo->pvec);
-#if BE_USE_MEM_ALIGNED
- proto->code = be_move_to_aligned(vm, proto->code, proto->codesize * sizeof(binstruction)); /* move `code` to 4-bytes aligned memory region */
- proto->ktab = be_move_to_aligned(vm, proto->ktab, proto->nconst * sizeof(bvalue)); /* move `ktab` to 4-bytes aligned memory region */
-#endif /* BE_USE_MEM_ALIGNED */
-#if BE_DEBUG_RUNTIME_INFO
- proto->lineinfo = be_vector_release(vm, &finfo->linevec); /* move `lineinfo` to 4-bytes aligned memory region */
- proto->nlineinfo = be_vector_count(&finfo->linevec);
-#if BE_USE_MEM_ALIGNED
- proto->lineinfo = be_move_to_aligned(vm, proto->lineinfo, proto->nlineinfo * sizeof(blineinfo));
-#endif /* BE_USE_MEM_ALIGNED */
-#endif /* BE_DEBUG_RUNTIME_INFO */
-#if BE_DEBUG_VAR_INFO
- proto->varinfo = be_vector_release(vm, &finfo->varvec);
- proto->nvarinfo = be_vector_count(&finfo->varvec);
-#endif
- parser->finfo = parser->finfo->prev; /* restore previous `finfo` */
- be_stackpop(vm, 2); /* pop upval and local */
-}
-
-/* is the next token a binary operator? If yes return the operator or `OP_NOT_BINARY` */
-static btokentype get_binop(bparser *parser)
-{
- btokentype op = next_type(parser);
- if (op >= OptAdd && op <= OptOr) {
- return op;
- }
- return OP_NOT_BINARY;
-}
-
-/* is the next token a unary operator? If yes return the operator or `OP_NOT_BINARY` */
-/* operator 'negative' 'not' and 'flip' */
-static btokentype get_unary_op(bparser *parser)
-{
- btokentype op = next_type(parser);
- if (op == OptSub || op == OptNot || op == OptFlip) {
- return op; /* operator 'negative' 'not' and 'flip' */
- }
- return OP_NOT_UNARY;
-}
-
-/* is the next token an assignment operator? If yes return the operator or `OP_NOT_BINARY` */
-/* `=`, `+=`, ... `>>=` */
-static btokentype get_assign_op(bparser *parser)
-{
- btokentype op = next_type(parser);
- if ((op >= OptAssign && op <= OptRsfAssign) || op == OptWalrus) {
- return op;
- }
- return OP_NOT_ASSIGN;
-}
-
-/* Initialize bexpdesc structure with specific type and value as int */
-static void init_exp(bexpdesc *e, exptype_t type, bint i)
-{
- e->type = (bbyte)type;
- e->t = NO_JUMP;
- e->f = NO_JUMP;
- e->not = 0;
- e->v.s = NULL;
- e->v.i = i;
-}
-
-/* find local variable by name, starting at index `begin` */
-/* linear search, returns -1 if not found */
-static int find_localvar(bfuncinfo *finfo, bstring *s, int begin)
-{
- int i, count = be_list_count(finfo->local);
- bvalue *var = be_list_data(finfo->local);
- for (i = count - 1; i >= begin; --i) {
- if (be_eqstr(var[i].v.s, s)) {
- return i;
- }
- }
- return -1; /* not found */
-}
-
-/* create a new local variable by name, or return the current register if already exists */
-/* returns the Reg number for the variable */
-/* If STRICT, we don't allow a var to hide a var from outer scope */
-/* We don't allow the same var to be defined twice in same scope */
-static int new_localvar(bparser *parser, bstring *name)
-{
- bfuncinfo *finfo = parser->finfo;
- int reg = find_localvar(finfo, name, finfo->binfo->nactlocals); /* look if already exists skipping the local variables from upper blocks */
- /* 'strict': raise an exception if the local variable shadows another local variable */
- if (reg == -1) {
- bvalue *var;
- if (comp_is_strict(parser->vm)) {
- if (find_localvar(finfo, name, 0) >= 0 && str(name)[0] != '.') { /* we do accept nested redifinition of internal variables starting with '.' */
- push_error(parser, "strict: redefinition of '%s' from outer scope", str(name));
- }
- }
- reg = be_list_count(finfo->local); /* new local index */
- var = be_list_push(parser->vm, finfo->local, NULL);
- var_setstr(var, name);
- if (reg >= finfo->freereg) {
- be_code_allocregs(finfo, 1); /* use a register */
- }
- begin_varinfo(parser, name);
- } else {
- push_error(parser, "redefinition of '%s'", str(name));
- }
- return reg;
-}
-
-/* Find upval by name, if found return its index number, or -1 */
-static int find_upval(bfuncinfo *finfo, bstring *s)
-{
- bvm *vm = finfo->lexer->vm;
- bvalue *desc = be_map_findstr(vm, finfo->upval, s);
- if (desc) {
- return upval_index(desc->v.i);
- }
- return -1;
-}
-
-/* Recursively search for upper blocks that are referenced in upvals */
-/* and mark them with `hasupval` */
-static void mark_upval(bfuncinfo *finfo, int level)
-{
- bblockinfo *binfo = finfo->prev->binfo;
- while (binfo->nactlocals > level) {
- binfo = binfo->prev;
- }
- binfo->hasupval = 1;
-}
-
-static int new_upval(bvm *vm, bfuncinfo *finfo, bstring *name, bexpdesc *var)
-{
- int index;
- bvalue *desc;
- int target = var->v.idx;
- int instack = var->type == ETLOCAL;
- if (instack) { /* mark upvalue's block */
- mark_upval(finfo, target);
- }
- index = be_map_count(finfo->upval);
- if (index >= 255) {
- be_lexerror(finfo->lexer, be_pushfstring(vm,
- "too many upvalues (in '%s')", str(name)));
- }
- desc = be_map_insertstr(vm, finfo->upval, name, NULL);
- var_setint(desc, upval_desc(index, target, instack));
- return index;
-}
-
-/* create a new variable in currenr context as name, and create expdesc for it */
-/* If within a block, create as local, otherwise as global */
-static void new_var(bparser *parser, bstring *name, bexpdesc *var)
-{
- bfuncinfo *finfo = parser->finfo;
- if (comp_is_strict(parser->vm)) {
- /* check if we are masking a builtin */
- if (be_builtin_find(parser->vm, name) >= 0) {
- push_error(parser, "strict: redefinition of builtin '%s'", str(name));
- }
- }
- if (finfo->prev || finfo->binfo->prev || parser->islocal) {
- init_exp(var, ETLOCAL, 0);
- var->v.idx = new_localvar(parser, name); /* if local, contains the index in current local var list */
- } else {
- init_exp(var, ETGLOBAL, 0);
- var->v.idx = be_global_new(parser->vm, name);
- if (var->v.idx > (int)IBx_MASK) {
- push_error(parser,
- "too many global variables (in '%s')", str(name));
- }
- if (comp_is_named_gbl(parser->vm)) {
- /* change to ETNGLBAL */
- bexpdesc key;
- init_exp(&key, ETSTRING, 0);
- key.v.s = name;
- init_exp(var, ETNGLOBAL, 0);
- var->v.idx = be_code_nglobal(parser->finfo, &key);
- }
- }
-}
-
-static int singlevaraux(bvm *vm, bfuncinfo *finfo, bstring *s, bexpdesc *var)
-{
- if (finfo == NULL) {
- return ETVOID;
- } else {
- int idx = find_localvar(finfo, s, 0);
- if (idx >= 0) { /* local variable */
- init_exp(var, ETLOCAL, 0);
- var->v.idx = idx;
- return ETLOCAL;
- } else {
- idx = find_upval(finfo, s);
- if (idx < 0) {
- /* find the previous scope */
- int res = singlevaraux(vm, finfo->prev, s, var);
- if (res == ETUPVAL || res == ETLOCAL) {
- idx = new_upval(vm, finfo, s, var); /* new upvalue */
- } else {
- idx = be_global_find(vm, s);
- if (idx >= 0) {
- if (idx < be_builtin_count(vm)) {
- return ETGLOBAL; /* global variable */
- } else {
- return comp_is_named_gbl(vm) ? ETNGLOBAL : ETGLOBAL; /* global variable */
- }
- } else {
- return ETVOID; /* unknow (new variable or error) */
- }
- }
- }
- init_exp(var, ETUPVAL, idx);
- return ETUPVAL;
- }
- }
-}
-
-/* get variable from next toden as name */
-/* and create an expdesc from it */
-/* can be new, global, named global, upval */
-static void singlevar(bparser *parser, bexpdesc *var)
-{
- bexpdesc key;
- bstring *varname = next_token(parser).u.s;
- int type = singlevaraux(parser->vm, parser->finfo, varname, var);
- switch (type) {
- case ETVOID:
- init_exp(var, ETVOID, 0);
- var->v.s = varname;
- break;
- case ETGLOBAL:
- init_exp(var, ETGLOBAL, 0);
- var->v.idx = be_global_find(parser->vm, varname);
- break;
- case ETNGLOBAL:
- init_exp(&key, ETSTRING, 0);
- key.v.s = varname;
- init_exp(var, ETNGLOBAL, 0);
- var->v.idx = be_code_nglobal(parser->finfo, &key);
- break;
- default:
- break;
- }
-}
-
-/* parse a vararg argument in the form `def f(a, *b) end` */
-/* Munch the '*', read the token, create variable and declare the function as vararg */
-static void func_vararg(bparser *parser) {
- bexpdesc v;
- bstring *str;
- match_token(parser, OptMul); /* skip '*' */
- str = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- new_var(parser, str, &v); /* new variable */
- parser->finfo->proto->varg |= BE_VA_VARARG; /* set varg flag */
-}
-
-/* Parse function or method definition variable list */
-/* Create an implicit local variable for each argument starting at R0 */
-/* Update function proto argc to the expected number or arguments */
-/* Raise an exception if multiple arguments have the same name */
-/* New: vararg support */
-static void func_varlist(bparser *parser)
-{
- bexpdesc v;
- bstring *str;
- /* '(' [ ID {',' ID}] ')' or */
- /* '(' '*' ID ')' or */
- /* '(' [ ID {',' ID}] ',' '*' ID ')' */
- match_token(parser, OptLBK); /* skip '(' */
- if (next_type(parser) == OptMul) {
- func_vararg(parser);
- } else if (match_id(parser, str) != NULL) {
- new_var(parser, str, &v); /* new variable */
- while (match_skip(parser, OptComma)) { /* ',' */
- if (next_type(parser) == OptMul) {
- func_vararg(parser);
- break;
- } else {
- str = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- /* new local variable */
- new_var(parser, str, &v);
- }
- }
- }
- match_token(parser, OptRBK); /* skip ')' */
- parser->finfo->proto->argc = parser->finfo->freereg;
-}
-
-/* Parse a function includind arg list and body */
-/* Given name and type (function or method) */
-/* Returns `bproto` object */
-static bproto* funcbody(bparser *parser, bstring *name, bclass *c, int type)
-{
- bfuncinfo finfo;
- bblockinfo binfo;
-
- /* '(' varlist ')' block 'end' */
- begin_func(parser, &finfo, &binfo); /* init new function context */
- finfo.proto->name = name;
- if (type & FUNC_METHOD) { /* If method, add an implicit first argument `self` */
- new_localvar(parser, parser_newstr(parser, "self"));
- finfo.proto->varg |= BE_VA_METHOD;
- }
- func_varlist(parser); /* parse arg list */
- if ((type & FUNC_STATIC) && (c != NULL)) { /* If static method, add an implicit local variable `_class` */
- bexpdesc e1, e2;
- new_var(parser, parser_newstr(parser, "_class"), &e1); /* new implicit variable '_class' */
- init_exp(&e2, ETCONST, 0);
- be_code_implicit_class(parser->finfo, &e2, c);
- be_code_setvar(parser->finfo, &e1, &e2, bfalse);
- finfo.proto->varg |= BE_VA_STATICMETHOD;
- }
- stmtlist(parser); /* parse statement without final `end` */
- end_func(parser); /* close function context */
- match_token(parser, KeyEnd); /* skip 'end' */
- return finfo.proto; /* return fully constructed `bproto` */
-}
-
-/* anonymous function, build `bproto` object with name `_anonymous_` */
-/* and build a expdesc for the bproto */
-static void anon_func(bparser *parser, bexpdesc *e)
-{
- bproto *proto;
- bstring *name = parser_newstr(parser, "_anonymous_");
- /* 'def' ID '(' varlist ')' block 'end' */
- scan_next_token(parser); /* skip 'def' */
- proto = funcbody(parser, name, NULL, FUNC_ANONYMOUS);
- init_exp(e, ETPROTO, be_code_proto(parser->finfo, proto));
- be_stackpop(parser->vm, 1);
-}
-
-static void lambda_varlist(bparser *parser)
-{
- bexpdesc v;
- bstring *str;
- /* [ID {',' ID}] | {ID}] */
- if (match_id(parser, str) != NULL) {
- bbool comma;
- new_var(parser, str, &v); /* new variable */
- comma = next_type(parser) == OptComma;
- while (next_type(parser) != OptArrow) {
- if (comma) {
- match_token(parser, OptComma); /* match and skip ',' */
- }
- str = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- /* new local variable */
- new_var(parser, str, &v);
- }
- }
- match_token(parser, OptArrow); /* skip '->' */
- parser->finfo->proto->argc = parser->finfo->freereg;
-}
-
-/* lambda expression */
-static void lambda_expr(bparser *parser, bexpdesc *e)
-{
- bexpdesc e1;
- bfuncinfo finfo;
- bblockinfo binfo;
- bstring *name = parser_newstr(parser, "");
- /* '/' ID {[',' ID]} '->' expr */
- scan_next_token(parser); /* skip '/' */
- begin_func(parser, &finfo, &binfo);
- finfo.proto->name = name;
- lambda_varlist(parser);
- expr(parser, &e1);
- check_var(parser, &e1);
- be_code_ret(parser->finfo, &e1);
- end_func(parser);
- init_exp(e, ETPROTO, be_code_proto(parser->finfo, finfo.proto));
- be_stackpop(parser->vm, 1);
-}
-
-/* Instanciate a builtin type by name */
-/* Allocates a new register for the value, and call empty constructor */
-/* Is allocated as LOCAL and must be changed to REG when completed */
-static void new_primtype(bparser *parser, const char *type, bexpdesc *e)
-{
- int idx;
- bvm *vm = parser->vm;
- bfuncinfo *finfo = parser->finfo;
-
- scan_next_token(parser);
- idx = be_builtin_find(vm, parser_newstr(parser, type));
- init_exp(e, ETGLOBAL, idx);
- idx = be_code_nextreg(finfo, e);
- be_code_call(finfo, idx, 0);
- e->type = ETLOCAL; /* declare as local, will be changed to ETREG when completely initialized */
-}
-
-/* Parse next member within a list */
-/* `l` contains the current list. The expr is evaluated and added to the list */
-static void list_nextmember(bparser *parser, bexpdesc *l)
-{
- bexpdesc e, v = *l;
- bfuncinfo *finfo = parser->finfo;
- expr(parser, &e); /* value */
- check_var(parser, &e); /* check that we don´t have an unknown symbol */
- be_code_binop(finfo, OptConnect, &v, &e, -1); /* add it to list with CONNECT */
- be_code_freeregs(finfo, 1); /* since left arg is LOCAL, an ETREG was allocated. Free it */
-}
-
-static void map_nextmember(bparser *parser, bexpdesc *l)
-{
- bexpdesc e, v = *l;
- bfuncinfo *finfo = parser->finfo;
- expr(parser, &e); /* key */
- check_var(parser, &e); /* check if value is valid */
- be_code_index(finfo, &v, &e); /* package as `v` as INDEX suffix for value `e` */
- match_token(parser, OptColon); /* ':' */
- expr(parser, &e); /* value in `e` */
- check_var(parser, &e); /* check if value is correct */
- be_code_setvar(finfo, &v, &e, bfalse); /* set suffi INDEX value to e */
-}
-
-static void list_expr(bparser *parser, bexpdesc *e)
-{
- /* '[' {expr ','} [expr] ']' */
- new_primtype(parser, "list", e); /* new list, created as LOCAL first */
- while (next_type(parser) != OptRSB) {
- list_nextmember(parser, e);
- if (!match_skip(parser, OptComma)) { /* ',' */
- break;
- }
- }
- e->type = ETREG; /* then turned to REG */
- match_token(parser, OptRSB); /* skip ']' */
-}
-
-static void map_expr(bparser *parser, bexpdesc *e)
-{
- /* '{' {expr ':' expr ','} [expr ':' expr] '}' */
- new_primtype(parser, "map", e); /* new map */
- while (next_type(parser) != OptRBR) {
- map_nextmember(parser, e);
- if (!match_skip(parser, OptComma)) { /* ',' */
- break;
- }
- }
- e->type = ETREG;
- match_token(parser, OptRBR); /* skip '}' */
-}
-
-/* push each argument as new reg and return number of args */
-/* TODO `e` is ignored by caller */
-static int exprlist(bparser *parser, bexpdesc *e)
-{
- bfuncinfo *finfo = parser->finfo;
- int n = 1;
- /* expr { ',' expr } */
- expr(parser, e); /* parse expr */
- check_var(parser, e); /* check if valid */
- be_code_nextreg(finfo, e); /* move result to next reg */
- while (match_skip(parser, OptComma)) { /* ',' */
- expr(parser, e);
- check_var(parser, e);
- be_code_nextreg(finfo, e);
- ++n;
- }
- return n;
-}
-
-/* parse call to method or function */
-/* `e` can be a member (method) or a register */
-/* On return, `e` is ETREG to the result of the call */
-static void call_expr(bparser *parser, bexpdesc *e)
-{
- bexpdesc args;
- bfuncinfo *finfo = parser->finfo;
- int argc = 0, base;
- int ismember = e->type == ETMEMBER;
-
- parser->finfo->binfo->sideeffect = 1; /* has side effect */
- /* func '(' [exprlist] ')' */
- check_var(parser, e);
- /* code function index to next register */
- if (ismember) {
- base = be_code_getmethod(finfo, e);
- } else {
- base = be_code_nextreg(finfo, e); /* allocate a new base reg if not at top already */
- }
- /* base is always taken at top of freereg and allocates 1 reg for function and 2 regs for method */
- scan_next_token(parser); /* skip '(' */
- if (next_type(parser) != OptRBK) { /* if arg list is not empty */
- argc = exprlist(parser, &args); /* push each argument as new reg and return number of args */
- }
- match_token(parser, OptRBK); /* skip ')' */
- argc += ismember; /* if method there is an additional implicit arg */
- be_code_call(finfo, base, argc);
- if (e->type != ETREG) {
- e->type = ETREG;
- e->v.idx = base;
- }
-}
-
-/* Parse member expression */
-/* Generates an ETMEMBER object that is materialized later into GETMBR, GETMET or SETMBR */
-static void member_expr(bparser *parser, bexpdesc *e)
-{
- bstring *str;
- /* . ID */
- check_var(parser, e);
- scan_next_token(parser); /* skip '.' */
- if (match_id(parser, str) != NULL) {
- bexpdesc key;
- init_exp(&key, ETSTRING, 0);
- key.v.s = str;
- be_code_member(parser->finfo, e, &key);
- } else if (next_type(parser) == OptLBK) {
- scan_next_token(parser); /* skip '(' */
- bexpdesc key;
- expr(parser, &key);
- check_var(parser, &key);
- match_token(parser, OptRBK); /* skip ')' */
- be_code_member(parser->finfo, e, &key);
- } else {
- push_error(parser, "invalid syntax near '%s'",
- be_token2str(parser->vm, &next_token(parser)));
- }
-}
-
-static void index_expr(bparser *parser, bexpdesc *e)
-{
- bexpdesc e1;
- /* [expr] */
- check_var(parser, e);
- scan_next_token(parser); /* skip '[' */
- expr(parser, &e1);
- check_var(parser, &e1);
- be_code_index(parser->finfo, e, &e1);
- match_token(parser, OptRSB); /* skip ']' */
-}
-
-static void simple_expr(bparser *parser, bexpdesc *e)
-{
- switch (next_type(parser)) {
- case TokenInteger:
- init_exp(e, ETINT, next_token(parser).u.i);
- break;
- case TokenReal:
- init_exp(e, ETREAL, 0);
- e->v.r = next_token(parser).u.r;
- break;
- case TokenString:
- init_exp(e, ETSTRING, 0);
- e->v.s = next_token(parser).u.s;
- break;
- case TokenId:
- singlevar(parser, e);
- break;
- case KeyTrue:
- init_exp(e, ETBOOL, 1);
- break;
- case KeyFalse:
- init_exp(e, ETBOOL, 0);
- break;
- case KeyNil:
- init_exp(e, ETNIL, 0);
- break;
- default: /* unknow expr */
- return;
- }
- scan_next_token(parser);
-}
-
-static void primary_expr(bparser *parser, bexpdesc *e)
-{
- switch (next_type(parser)) {
- case OptLBK: /* '(' expr ')' */
- scan_next_token(parser); /* skip '(' */
- expr(parser, e);
- check_var(parser, e);
- match_token(parser, OptRBK); /* skip ')' */
- break;
- case OptLSB: /* list */
- list_expr(parser, e);
- break;
- case OptLBR: /* map */
- map_expr(parser, e);
- break;
- case KeyDef: /* anonymous function */
- anon_func(parser, e);
- break;
- case OptDiv: /* lambda expression */
- lambda_expr(parser, e);
- break;
- default: /* simple expr */
- simple_expr(parser, e);
- break;
- }
-}
-
-static void suffix_expr(bparser *parser, bexpdesc *e)
-{
- primary_expr(parser, e);
- for (;;) {
- switch (next_type(parser)) {
- case OptLBK: /* '(' function call */
- call_expr(parser, e);
- break;
- case OptDot: /* '.' member */
- member_expr(parser, e);
- break;
- case OptLSB: /* '[' index */
- index_expr(parser, e);
- break;
- default:
- return;
- }
- }
-}
-
-static void suffix_alloc_reg(bparser *parser, bexpdesc *l)
-{
- bfuncinfo *finfo = parser->finfo;
- bbool is_suffix = l->type == ETINDEX || l->type == ETMEMBER; /* is suffix */
- bbool is_suffix_reg = l->v.ss.tt == ETREG || l->v.ss.tt == ETLOCAL || l->v.ss.tt == ETGLOBAL || l->v.ss.tt == ETNGLOBAL; /* if suffix, does it need a register */
- bbool is_global = l->type == ETGLOBAL || l->type == ETNGLOBAL;
- bbool is_upval = l->type == ETUPVAL;
- /* in the suffix expression, if the object is a temporary
- * variable (l->v.ss.tt == ETREG), it needs to be cached. */
- if (is_global || is_upval || (is_suffix && is_suffix_reg)) {
- be_code_allocregs(finfo, 1);
- }
-}
-
-/* compound assignment */
-static void compound_assign(bparser *parser, int op, bexpdesc *l, bexpdesc *r)
-{
- int dst = -1; /* destination register in case of compound assignment */
- if (op != OptAssign) { /* check left variable */
- check_var(parser, l);
- /* cache the register of the object when continuously assigning */
- dst = parser->finfo->freereg;
- suffix_alloc_reg(parser, l);
- }
- expr(parser, r); /* right expression */
- check_var(parser, r);
- if (op != OptAssign) { /* compound assignment */
- bexpdesc e = *l;
- op = op < OptAndAssign ? op - OptAddAssign + OptAdd
- : op - OptAndAssign + OptBitAnd;
- be_code_binop(parser->finfo, op, &e, r, dst); /* coding operation */
- *r = e;
- }
-}
-
-/* check if we need to create a new local variable with this name to be assigned to */
-/* Returns true if it´s a new local variable */
-/* A new implicit local variable is created if no global has the same name (excluding builtins) */
-/* This means that you can override a builtin silently */
-/* This also means that a function cannot create a global, they must preexist or create with `global` module */
-static int check_newvar(bparser *parser, bexpdesc *e)
-{
- if (e->type == ETGLOBAL) {
- if (e->v.idx < be_builtin_count(parser->vm)) {
- e->v.s = be_builtin_name(parser->vm, e->v.idx);
- if (comp_is_strict(parser->vm)) {
- push_error(parser, "strict: redefinition of builtin '%s'",
- str(e->v.s));
- }
- return btrue;
- }
- return bfalse;
- }
- if (comp_is_strict(parser->vm)) {
- bfuncinfo *finfo = parser->finfo;
- if ((e->type == ETVOID) && (finfo->prev || finfo->binfo->prev || parser->islocal)) {
- push_error(parser, "strict: no global '%s', did you mean 'var %s'?",
- str(e->v.s), str(e->v.s));
- }
- }
- return e->type == ETVOID;
-}
-
-static void assign_expr(bparser *parser)
-{
- bexpdesc e;
- btokentype op;
- int line = parser->lexer.linenumber;
- parser->finfo->binfo->sideeffect = 0; /* reinit side effect marker */
- expr(parser, &e); /* left expression */
- check_symbol(parser, &e);
- op = get_assign_op(parser);
- if (op != OP_NOT_ASSIGN) { /* assign operator */
- bexpdesc e1;
- parser->finfo->binfo->sideeffect = 1;
- scan_next_token(parser);
- compound_assign(parser, op, &e, &e1);
- if (check_newvar(parser, &e)) { /* new variable */
- new_var(parser, e.v.s, &e);
- }
- if (be_code_setvar(parser->finfo, &e, &e1, bfalse)) {
- parser->lexer.linenumber = line;
- parser_error(parser,
- "try to assign constant expressions.");
- }
- } else if (e.type >= ETMEMBER) {
- bfuncinfo *finfo = parser->finfo;
- /* these expressions occupy a register and need to be freed */
- finfo->freereg = (bbyte)be_list_count(finfo->local);
- } else if (e.type == ETVOID) { /* not assign expression */
- /* undeclared symbol */
- parser->lexer.linenumber = line;
- check_var(parser, &e);
- }
-}
-
-/* conditional expression */
-static void cond_expr(bparser *parser, bexpdesc *e)
-{
- /* expr '?' expr ':' expr */
- if (next_type(parser) == OptQuestion) {
- int jf, jl = NO_JUMP; /* jump list */
- bfuncinfo *finfo = parser->finfo;
- check_var(parser, e); /* check if valid */
- scan_next_token(parser); /* skip '?' */
- be_code_jumpbool(finfo, e, bfalse); /* go if true */
- jf = e->f;
- expr(parser, e);
- check_var(parser, e);
- be_code_nextreg(finfo, e);
- be_code_freeregs(finfo, 1);
- be_code_conjump(finfo, &jl, be_code_jump(finfo)); /* connect jump */
- be_code_patchjump(finfo, jf);
- match_token(parser, OptColon); /* match and skip ':' */
- expr(parser, e);
- check_var(parser, e);
- e->v.idx = be_code_nextreg(finfo, e);
- be_code_patchjump(finfo, jl);
- e->type = ETREG;
- }
-}
-
-/* binary operator: + - * / % && || < <= == != > >=
- * unary operator: + - !
- */
-static void sub_expr(bparser *parser, bexpdesc *e, int prio)
-{
- bfuncinfo *finfo = parser->finfo;
- btokentype op = get_unary_op(parser); /* check if first token in unary op */
- if (op != OP_NOT_UNARY) { /* unary op found */
- int line, res;
- scan_next_token(parser); /* move to next token */
- line = parser->lexer.linenumber; /* remember line number for error reporting */
- sub_expr(parser, e, UNARY_OP_PRIO); /* parse subexpr with new prio */
- check_var(parser, e); /* check that the value is ok */
- res = be_code_unop(finfo, op, e); /* apply unary op with optimizations if the token is a value */
- if (res) { /* encode unary op */
- parser->lexer.linenumber = line;
- push_error(parser, "wrong type argument to unary '%s'",
- res == 1 ? "negative" : "bit-flip");
- }
- } else {
- suffix_expr(parser, e); /* parse left part of binop */
- }
- op = get_binop(parser); /* check if binop */
- while (op != OP_NOT_BINARY && prio > binary_op_prio(op)) { /* is binop applicable */
- bexpdesc e2;
- check_var(parser, e); /* check that left part is valid */
- scan_next_token(parser); /* move to next token */
- be_code_prebinop(finfo, op, e); /* and or */
- if (op == OptConnect) {
- parser->finfo->binfo->sideeffect = 1;
- }
- init_exp(&e2, ETVOID, 0);
- sub_expr(parser, &e2, binary_op_prio(op)); /* parse right side */
- if ((op == OptConnect) && (e2.type == ETVOID) && (e2.v.s == NULL)) { /* 'e2.v.s == NULL' checks that it's not an undefined variable */
- init_exp(&e2, ETINT, M_IMAX);
- } else {
- check_var(parser, &e2); /* check if valid */
- }
- be_code_binop(finfo, op, e, &e2, -1); /* encode binary op */
- op = get_binop(parser); /* is there a following binop? */
- }
- if (prio == ASSIGN_OP_PRIO) {
- cond_expr(parser, e);
- }
-}
-
-static void walrus_expr(bparser *parser, bexpdesc *e)
-{
- int line = parser->lexer.linenumber;
- sub_expr(parser, e, ASSIGN_OP_PRIO); /* left expression */
- btokentype op = next_type(parser);
- if (op == OptWalrus) {
- check_symbol(parser, e);
- bexpdesc e1 = *e; /* copy var to e1, e will get the result of expression */
- parser->finfo->binfo->sideeffect = 1; /* has side effect */
- scan_next_token(parser); /* skip ':=' */
- expr(parser, e);
- check_var(parser, e);
- if (check_newvar(parser, &e1)) { /* new variable */
- new_var(parser, e1.v.s, &e1);
- }
- if (be_code_setvar(parser->finfo, &e1, e, btrue /* do not release register */ )) {
- parser->lexer.linenumber = line;
- parser_error(parser,
- "try to assign constant expressions.");
- }
- }
-}
-
-/* Parse new expression and return value in `e` (overwritten) */
-/* Initializes an empty expdes and parse subexpr */
-/* Always allocates a new temp register at top of freereg */
-static void expr(bparser *parser, bexpdesc *e)
-{
- init_exp(e, ETVOID, 0);
- walrus_expr(parser, e);
-}
-
-static void expr_stmt(bparser *parser)
-{
- assign_expr(parser);
-}
-
-static int block_follow(bparser *parser)
-{
- switch (next_type(parser)) {
- case KeyElse: case KeyElif:
- case KeyEnd: case KeyExcept:
- case TokenEOS:
- return 0;
- default:
- return 1;
- }
-}
-
-static int cond_stmt(bparser *parser)
-{
- bexpdesc e;
- /* expr */
- match_notoken(parser, OptRBK);
- expr(parser, &e);
- check_var(parser, &e);
- be_code_jumpbool(parser->finfo, &e, bfalse); /* go if true */
- return e.f;
-}
-
-static void condition_block(bparser *parser, int *jmp)
-{
- bfuncinfo *finfo = parser->finfo;
- int br = cond_stmt(parser);
- block(parser, 0);
- if (next_type(parser) == KeyElif
- || next_type(parser) == KeyElse) {
- be_code_conjump(finfo, jmp, be_code_jump(finfo)); /* connect jump */
- }
- be_code_patchjump(finfo, br);
-}
-
-static void if_stmt(bparser *parser)
-{
- int jl = NO_JUMP; /* jump list */
- /* IF expr block {ELSEIF expr block}, [ELSE block], end */
- scan_next_token(parser); /* skip 'if' */
- condition_block(parser, &jl);
- while (match_skip(parser, KeyElif)) { /* 'elif' */
- condition_block(parser, &jl);
- }
- if (match_skip(parser, KeyElse)) { /* 'else' */
- block(parser, 0);
- }
- match_token(parser, KeyEnd); /* skip end */
- be_code_patchjump(parser->finfo, jl);
-}
-
-static void do_stmt(bparser *parser)
-{
- /* DO block END */
- scan_next_token(parser); /* skip 'do' */
- block(parser, 0);
- match_token(parser, KeyEnd); /* skip 'end' */
-}
-
-static void while_stmt(bparser *parser)
-{
- int brk;
- bblockinfo binfo;
- bfuncinfo *finfo = parser->finfo;
- /* WHILE expr block END */
- scan_next_token(parser); /* skip 'while' */
- begin_block(parser->finfo, &binfo, BLOCK_LOOP);
- brk = cond_stmt(parser);
- stmtlist(parser);
- end_block(parser);
- be_code_patchjump(finfo, brk);
- match_token(parser, KeyEnd); /* skip 'end' */
-}
-
-static bstring* for_itvar(bparser *parser)
-{
- bstring *str;
- if (match_id(parser, str) == NULL) {
- push_error(parser,
- "missing iteration variable before '%s'",
- token2str(parser));
- }
- return str;
-}
-
-static void for_init(bparser *parser, bexpdesc *v)
-{
- bexpdesc e;
- bstring *s;
- bfuncinfo *finfo = parser->finfo;
- /* .it = __iterator__(expr) */
- s = parser_newstr(parser, "__iterator__");
- init_exp(&e, ETGLOBAL, be_builtin_find(parser->vm, s));
- be_code_nextreg(finfo, &e); /* code function '__iterator__' */
- expr(parser, v);
- check_var(parser, v);
- be_code_nextreg(finfo, v);
- be_code_call(finfo, e.v.idx, 1); /* call __iterator__(expr) */
- be_code_freeregs(finfo, 1); /* free register of __iterator__ */
- s = parser_newstr(parser, ".it");
- init_exp(v, ETLOCAL, new_localvar(parser, s));
-}
-
-static void for_iter(bparser *parser, bstring *var, bexpdesc *it)
-{
- bexpdesc e;
- bfuncinfo *finfo = parser->finfo;
- /* reset the jump head PC of the for loop body */
- finfo->binfo->beginpc = finfo->pc;
- /* itvar = .it() */
- init_exp(&e, ETLOCAL, new_localvar(parser, var)); /* new itvar */
- be_code_setvar(finfo, &e, it, bfalse); /* code function to variable '.it' */
- be_code_call(finfo, e.v.idx, 0); /* itvar <- call .it() */
- stmtlist(parser);
-}
-
-static void for_leave(bparser *parser, int jcatch, int beginpc)
-{
- bexpdesc e;
- bfuncinfo *finfo = parser->finfo;
- int jbrk = finfo->binfo->breaklist;
- init_exp(&e, ETSTRING, 0);
- e.v.s = parser_newstr(parser, "stop_iteration");
- end_block_ex(parser, beginpc); /* leave except & loop block */
- if (jbrk != NO_JUMP) { /* has `break` statement in iteration block */
- be_code_exblk(finfo, 1);
- jbrk = be_code_jump(finfo);
- }
- be_code_conjump(finfo, &jcatch, finfo->pc);
- be_code_catch(finfo, be_code_nextreg(finfo, &e), 1, 0, NULL);
- be_code_raise(finfo, NULL, NULL);
- be_code_conjump(finfo, &jbrk, finfo->pc);
- be_code_freeregs(finfo, 1);
-}
-
-/* approximate equivalent script code:
- * .it = __iter__(expr)
- * try
- * while (1)
- * itvar = .it()
- * stmtlist
- * end
- * except ('stop_iteration')
- * end
- * */
-static void for_stmt(bparser *parser)
-{
- bstring *var;
- bexpdesc iter;
- bblockinfo binfo;
- int jcatch, beginpc = parser->finfo->pc;
- /* FOR ID : expr block END */
- scan_next_token(parser); /* skip 'for' */
- begin_block(parser->finfo, &binfo, BLOCK_EXCEPT | BLOCK_LOOP);
- var = for_itvar(parser);
- match_token(parser, OptColon); /* skip ':' */
- for_init(parser, &iter);
- jcatch = be_code_exblk(parser->finfo, 0);
- for_iter(parser, var, &iter);
- for_leave(parser, jcatch, beginpc);
- match_token(parser, KeyEnd); /* skip 'end' */
-}
-
-static bblockinfo* break_block(bparser *parser)
-{
- int try_depth = 0; /* count of exception catch blocks */
- bblockinfo *binfo = parser->finfo->binfo;
- /* BREAK | CONTINUE */
- scan_next_token(parser); /* skip 'break' or 'continue' */
- while (binfo && !(binfo->type & BLOCK_LOOP)) {
- if (binfo->type & BLOCK_EXCEPT) {
- ++try_depth; /* leave the exception catch block */
- }
- binfo = binfo->prev;
- }
- if (binfo && try_depth) { /* exception catch blocks that needs to leave */
- be_code_exblk(parser->finfo, try_depth);
- }
- return binfo;
-}
-
-static void break_stmt(bparser *parser)
-{
- bfuncinfo *f = parser->finfo;
- bblockinfo *binfo = break_block(parser);
- if (binfo != NULL) { /* connect jump */
- be_code_conjump(f, &binfo->breaklist, be_code_jump(f));
- } else {
- parser_error(parser, "break not loop");
- }
-}
-
-static void continue_stmt(bparser *parser)
-{
- bfuncinfo *f = parser->finfo;
- bblockinfo *b = break_block(parser);
- if (b != NULL) { /* connect jump */
- be_code_conjump(f, &b->continuelist, be_code_jump(f));
- } else {
- parser_error(parser, "continue not loop");
- }
-}
-
-static bbool isoverloadable(btokentype type)
-{
- return (type >= OptAdd && type <= OptConnect) /* overloaded binary operator */
- || type == OptFlip || type == OptLBK; /* '~' and '()' operator */
-}
-
-static bstring* func_name(bparser* parser, bexpdesc* e, int ismethod)
-{
- btokentype type = next_type(parser);
- if (type == TokenId) {
- bstring *name = next_token(parser).u.s;
- if (!ismethod) {
- new_var(parser, name, e); /* new variable */
- }
- scan_next_token(parser); /* skip name */
- return name;
- } else if (ismethod && isoverloadable(type)) {
- scan_next_token(parser); /* skip token */
- /* '-*' negative operator */
- if (type == OptSub && next_type(parser) == OptMul) {
- scan_next_token(parser); /* skip '*' */
- return parser_newstr(parser, "-*");
- }
- /* '()' call operator */
- if (type == OptLBK && next_type(parser) == OptRBK) {
- scan_next_token(parser); /* skip ')' */
- return parser_newstr(parser, "()");
- }
- return parser_newstr(parser, be_tokentype2str(type));
- }
- push_error(parser,
- "the token '%s' is not a valid function name.",
- token2str(parser));
- return NULL;
-}
-
-static void def_stmt(bparser *parser)
-{
- bexpdesc e;
- bproto *proto;
- bfuncinfo *finfo = parser->finfo;
- /* 'def' ID '(' varlist ')' block 'end' */
- scan_next_token(parser); /* skip 'def' */
- proto = funcbody(parser, func_name(parser, &e, 0), NULL, 0);
- be_code_closure(finfo, &e, be_code_proto(finfo, proto));
- be_stackpop(parser->vm, 1);
-}
-
-static void return_stmt(bparser *parser)
-{
- bexpdesc e;
- /* 'return' expr */
- scan_next_token(parser); /* skip 'return' */
- expr(parser, &e);
- if (e.v.s) { /* expression is not empty */
- check_var(parser, &e);
- }
- be_code_ret(parser->finfo, &e);
-}
-
-static void check_class_attr(bparser *parser, bclass *c, bstring *attr)
-{
- if (be_class_attribute(parser->vm, c, attr) != BE_NONE) {
- push_error(parser,
- "redefinition of the attribute '%s'", str(attr));
- }
-}
-
-static void classvar_stmt(bparser *parser, bclass *c)
-{
- bstring *name;
- /* 'var' ID {',' ID} */
- scan_next_token(parser); /* skip 'var' */
- if (match_id(parser, name) != NULL) {
- check_class_attr(parser, c, name);
- be_class_member_bind(parser->vm, c, name, btrue);
- while (match_skip(parser, OptComma)) { /* ',' */
- if (match_id(parser, name) != NULL) {
- check_class_attr(parser, c, name);
- be_class_member_bind(parser->vm, c, name, btrue);
- } else {
- parser_error(parser, "class var error");
- }
- }
- } else {
- parser_error(parser, "class var error");
- }
-}
-
-static void class_static_assignment_expr(bparser *parser, bexpdesc *e, bstring *name)
-{
- if (match_skip(parser, OptAssign)) { /* '=' */
- bexpdesc e1, e2;
- /* parse the right expression */
- expr(parser, &e2);
-
- e1 = *e; /* copy the class description */
- bexpdesc key; /* build the member key */
- init_exp(&key, ETSTRING, 0);
- key.v.s = name;
-
- be_code_member(parser->finfo, &e1, &key); /* compute member accessor */
- be_code_setvar(parser->finfo, &e1, &e2, bfalse); /* set member */
- }
-}
-
-static void classdef_stmt(bparser *parser, bclass *c, bbool is_static)
-{
- bexpdesc e;
- bstring *name;
- bproto *proto;
- /* 'def' ID '(' varlist ')' block 'end' */
- scan_next_token(parser); /* skip 'def' */
- name = func_name(parser, &e, 1);
- check_class_attr(parser, c, name);
- proto = funcbody(parser, name, c, is_static ? FUNC_STATIC : FUNC_METHOD);
- be_class_method_bind(parser->vm, c, proto->name, proto, is_static);
- be_stackpop(parser->vm, 1);
-}
-
-static void classstaticclass_stmt(bparser *parser, bclass *c_out, bexpdesc *e_out);
-
-static void classstatic_stmt(bparser *parser, bclass *c, bexpdesc *e)
-{
- bstring *name;
- /* 'static' ['var'] ID ['=' expr] {',' ID ['=' expr] } */
- /* 'static' 'def' ID '(' varlist ')' block 'end' */
- scan_next_token(parser); /* skip 'static' */
- if (next_type(parser) == KeyDef) { /* 'static' 'def' ... */
- classdef_stmt(parser, c, btrue);
- } else if (next_type(parser) == KeyClass) { /* 'static' 'class' ... */
- classstaticclass_stmt(parser, c, e);
- } else {
- if (next_type(parser) == KeyVar) {
- scan_next_token(parser); /* skip 'var' if any */
- }
- if (match_id(parser, name) != NULL) {
- check_class_attr(parser, c, name);
- be_class_member_bind(parser->vm, c, name, bfalse);
- class_static_assignment_expr(parser, e, name);
-
- while (match_skip(parser, OptComma)) { /* ',' */
- if (match_id(parser, name) != NULL) {
- check_class_attr(parser, c, name);
- be_class_member_bind(parser->vm, c, name, bfalse);
- class_static_assignment_expr(parser, e, name);
- } else {
- parser_error(parser, "class static error");
- }
- }
- } else {
- parser_error(parser, "class static error");
- }
- }
-}
-
-static void class_inherit(bparser *parser, bexpdesc *e)
-{
- if (next_type(parser) == OptColon) { /* ':' */
- bexpdesc ec = *e; /* work on a copy because we preserve original class */
- bexpdesc e1;
- scan_next_token(parser); /* skip ':' */
- expr(parser, &e1);
- check_var(parser, &e1);
- be_code_setsuper(parser->finfo, &ec, &e1);
- }
-}
-
-static void class_block(bparser *parser, bclass *c, bexpdesc *e)
-{
- /* { [;] } */
- while (block_follow(parser)) {
- switch (next_type(parser)) {
- case KeyVar: classvar_stmt(parser, c); break;
- case KeyStatic: classstatic_stmt(parser, c, e); break;
- case KeyDef: classdef_stmt(parser, c, bfalse); break;
- case OptSemic: scan_next_token(parser); break;
- default: push_error(parser,
- "unexpected token '%s'", token2str(parser));
- }
- }
-}
-
-static void class_stmt(bparser *parser)
-{
- bstring *name;
- /* 'class' ID [':' ID] class_block 'end' */
- scan_next_token(parser); /* skip 'class' */
- if (match_id(parser, name) != NULL) {
- bexpdesc e;
- bclass *c = be_newclass(parser->vm, name, NULL);
- new_var(parser, name, &e);
- be_code_class(parser->finfo, &e, c);
- class_inherit(parser, &e);
-
- bblockinfo binfo;
- begin_block(parser->finfo, &binfo, 0);
-
- bstring *class_str = parser_newstr(parser, "_class"); /* we always define `_class` local variable */
- bexpdesc e1; /* if inline class, we add a second local variable for _class */
- init_exp(&e1, ETLOCAL, 0);
- e1.v.idx = new_localvar(parser, class_str);
- be_code_setvar(parser->finfo, &e1, &e, btrue);
-
- begin_varinfo(parser, class_str);
-
- class_block(parser, c, &e);
- end_block(parser);
-
- be_class_compress(parser->vm, c); /* compress class size */
- match_token(parser, KeyEnd); /* skip 'end' */
- } else {
- parser_error(parser, "class name error");
- }
-}
-
-static void classstaticclass_stmt(bparser *parser, bclass *c_out, bexpdesc *e_out)
-{
- bstring *name;
- /* [preceding 'static'] 'class' ID [':' ID] class_block 'end' */
- scan_next_token(parser); /* skip 'class' */
- if (match_id(parser, name) != NULL) {
- bexpdesc e_class; /* new class object */
- check_class_attr(parser, c_out, name); /* check that the class names does not collide with another member */
- be_class_member_bind(parser->vm, c_out, name, bfalse); /* add the member slot as static */
- /* create the class object */
- bclass *c = be_newclass(parser->vm, name, NULL);
- new_var(parser, name, &e_class); /* add a local var to the static initialization code for static members */
- be_code_class(parser->finfo, &e_class, c);
- class_inherit(parser, &e_class);
- class_block(parser, c, &e_class);
- be_class_compress(parser->vm, c); /* compress class size */
- match_token(parser, KeyEnd); /* skip 'end' */
- /* add the code to copy the class object to the static member */
- bexpdesc e1 = *e_out; /* copy the class description */
- bexpdesc key; /* build the member key */
- init_exp(&key, ETSTRING, 0);
- key.v.s = name;
- /* assign the class to the static member */
- be_code_member(parser->finfo, &e1, &key); /* compute member accessor */
- be_code_setvar(parser->finfo, &e1, &e_class, bfalse); /* set member */
- } else {
- parser_error(parser, "class name error");
- }
-}
-
-static void import_stmt(bparser *parser)
-{
- bstring *name; /* variable name */
- bexpdesc m, v;
- /* 'import' (ID (['as' ID] | {',' ID}) | STRING 'as' ID ) */
- scan_next_token(parser); /* skip 'import' */
- init_exp(&m, ETSTRING, 0);
- m.v.s = name = next_token(parser).u.s;
- if (next_type(parser) == TokenString) { /* STRING 'as' ID */
- scan_next_token(parser); /* skip the module path */
- match_token(parser, KeyAs); /* match and skip 'as' */
- name = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- } else { /* ID (['as' ID] | {',' ID}) */
- match_token(parser, TokenId); /* match and skip ID */
- if (match_skip(parser, KeyAs)) { /* 'as' */
- name = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- } else { /* {',' ID} */
- while (match_skip(parser, OptComma)) { /* ',' */
- new_var(parser, name, &v);
- be_code_import(parser->finfo, &m, &v); /* code import */
- init_exp(&m, ETSTRING, 0); /* scanning for next node */
- m.v.s = name = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- }
- }
- }
- new_var(parser, name, &v);
- be_code_import(parser->finfo, &m, &v);
-}
-
-static void var_field(bparser *parser)
-{
- /* ID ['=' expr] */
- bexpdesc e1, e2;
- bstring *name;
- name = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- if (match_skip(parser, OptAssign)) { /* '=' */
- expr(parser, &e2);
- check_var(parser, &e2);
- } else {
- init_exp(&e2, ETNIL, 0);
- }
- new_var(parser, name, &e1); /* new variable */
- be_code_setvar(parser->finfo, &e1, &e2, bfalse);
-}
-
-static void var_stmt(bparser *parser)
-{
- /* 'var' ID ['=' expr] {',' ID ['=' expr]} */
- scan_next_token(parser); /* skip 'var' */
- var_field(parser);
- while (match_skip(parser, OptComma)) { /* ',' */
- var_field(parser);
- }
-}
-
-static int except_case_list(bparser *parser, int *base)
-{
- int idx;
- bexpdesc e;
- bfuncinfo *finfo = parser->finfo;
- /* expr {',' expr} | '..' */
- if (match_skip(parser, OptConnect)) { /* '..' */
- *base = finfo->freereg;
- return 0;
- }
- expr(parser, &e); /* first exception expression */
- check_var(parser, &e);
- *base = idx = be_code_nextreg(finfo, &e);
- while (match_skip(parser, OptComma)) { /* ',' */
- expr(parser, &e);
- check_var(parser, &e);
- idx = be_code_nextreg(finfo, &e);
- }
- idx = idx - *base + 1; /* count of exception expression */
- be_code_freeregs(finfo, idx);
- return idx;
-}
-
-static int except_var_list(bparser *parser, int base)
-{
- bexpdesc v;
- (void)base; /* unused variable (no debugging) */
- /* [as ID [, ID]] */
- if (match_skip(parser, KeyAs)) { /* 'as' */
- bstring *name = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- new_var(parser, name, &v); /* new local variable */
- be_assert(v.type == ETLOCAL && v.v.idx == base);
- if (match_skip(parser, OptComma)) { /* match and skip ',' */
- name = next_token(parser).u.s;
- match_token(parser, TokenId); /* match and skip ID */
- new_var(parser, name, &v); /* new local variable */
- be_assert(v.type == ETLOCAL && v.v.idx == base + 1);
- return 2;
- }
- return 1;
- }
- return 0;
-}
-
-static void except_block(bparser *parser, int *jmp, int *jbrk)
-{
- int base = 0; /* the first register of the catch opcode */
- int ecnt = 0; /* exception cases count */
- int vcnt = 0; /* exception variable count */
- bblockinfo binfo;
- bfuncinfo *finfo = parser->finfo;
- /* 'except' (expr {',' expr} | '..') ['as' ID [',' ID]] */
- match_token(parser, KeyExcept); /* skip 'except' */
- begin_block(finfo, &binfo, 0); /* begin catch block */
- /* link from the previous except failure point */
- be_code_conjump(finfo, jmp, finfo->pc);
- /* (expr {',' expr} | '..') ['as' ID [',' ID]] */
- ecnt = except_case_list(parser, &base);
- vcnt = except_var_list(parser, base);
- be_code_catch(finfo, base, ecnt, vcnt, jmp);
- stmtlist(parser);
- be_code_conjump(finfo, jbrk, be_code_jump(finfo));
- end_block(parser); /* leave catch block */
-}
-
-static void try_stmt(bparser *parser)
-{
- int jcatch, jbrk;
- /* 'try' block 'except' except_stmt block 'end' */
- scan_next_token(parser); /* skip 'try' */
- jcatch = be_code_exblk(parser->finfo, 0);
- block(parser, BLOCK_EXCEPT);
- be_code_exblk(parser->finfo, 1);
- jbrk = be_code_jump(parser->finfo);
- except_block(parser, &jcatch, &jbrk);
- while (next_type(parser) == KeyExcept) {
- except_block(parser, &jcatch, &jbrk);
- }
- be_code_patchjump(parser->finfo, jcatch);
- be_code_raise(parser->finfo, NULL, NULL);
- be_code_patchjump(parser->finfo, jbrk);
- match_token(parser, KeyEnd); /* skip 'end' */
-}
-
-static void throw_stmt(bparser *parser)
-{
- bexpdesc e1, e2;
- /* 'raise' expr */
- scan_next_token(parser); /* skip 'raise' */
- expr(parser, &e1);
- check_var(parser, &e1);
- if (match_skip(parser, OptComma)) {
- expr(parser, &e2);
- check_var(parser, &e2);
- be_code_raise(parser->finfo, &e1, &e2);
- } else {
- be_code_raise(parser->finfo, &e1, NULL);
- }
-}
-
-static void statement(bparser *parser)
-{
- /* save value of sideeffect */
- bbyte sideeffect = parser->finfo->binfo->sideeffect;
- parser->finfo->binfo->sideeffect = 1; /* by default declare side effect */
- switch (next_type(parser)) {
- case KeyIf: if_stmt(parser); break;
- case KeyWhile: while_stmt(parser); break;
- case KeyFor: for_stmt(parser); break;
- case KeyDo: do_stmt(parser); break;
- case KeyBreak: break_stmt(parser); break;
- case KeyContinue: continue_stmt(parser); break;
- case KeyDef: def_stmt(parser); break;
- case KeyClass: class_stmt(parser); break;
- case KeyReturn: return_stmt(parser); break;
- case KeyImport: import_stmt(parser); break;
- case KeyVar: var_stmt(parser); break;
- case KeyTry: try_stmt(parser); break;
- case KeyRaise: throw_stmt(parser); break;
- case OptSemic:
- parser->finfo->binfo->sideeffect = sideeffect; /* restore sideeffect */
- scan_next_token(parser); break; /* empty statement */
- default:
- parser->finfo->binfo->sideeffect = sideeffect; /* restore sideeffect */
- expr_stmt(parser);
- if (comp_is_strict(parser->vm) && parser->finfo->binfo->sideeffect == 0) {
- push_error(parser, "strict: expression without side effect detected");
- }
- break;
- }
- be_assert(parser->finfo->freereg >= be_list_count(parser->finfo->local));
-}
-
-static void stmtlist(bparser *parser)
-{
- while (block_follow(parser)) {
- statement(parser);
- }
-}
-
-static void block(bparser *parser, int type)
-{
- bblockinfo binfo;
- begin_block(parser->finfo, &binfo, type);
- stmtlist(parser);
- end_block(parser);
-}
-
-static void mainfunc(bparser *parser, bclosure *cl)
-{
- bblockinfo binfo;
- bfuncinfo finfo;
- begin_func(parser, &finfo, &binfo);
- finfo.proto->argc = 0; /* args */
- finfo.proto->name = be_newstr(parser->vm, funcname(parser));
- cl->proto = finfo.proto;
- be_remove(parser->vm, -3); /* pop proto from stack */
- stmtlist(parser);
- end_func(parser);
- match_token(parser, TokenEOS); /* skip EOS */
-}
-
-bclosure* be_parser_source(bvm *vm,
- const char *fname, breader reader, void *data, bbool islocal)
-{
- bparser parser;
- bclosure *cl = be_newclosure(vm, 0);
- parser.vm = vm;
- parser.finfo = NULL;
- parser.cl = cl;
- parser.islocal = (bbyte)islocal;
- var_setclosure(vm->top, cl);
- be_stackpush(vm);
- be_lexer_init(&parser.lexer, vm, fname, reader, data);
- scan_next_token(&parser); /* scan first token */
- mainfunc(&parser, cl);
- be_lexer_deinit(&parser.lexer);
- be_global_release_space(vm); /* clear global space */
- be_stackpop(vm, 2); /* pop strtab */
- scan_next_token(&parser); /* clear lexer */
- return cl;
-}
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_parser.h b/lib/libesp32/Berry/src/be_parser.h
deleted file mode 100644
index 9b7d11e0e2fb..000000000000
--- a/lib/libesp32/Berry/src/be_parser.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_PARSER_H
-#define BE_PARSER_H
-
-#include "be_object.h"
-#include "be_string.h"
-
-typedef enum {
- ETVOID, /* unknown (new variable or error) */
- ETNIL,
- ETBOOL,
- ETREAL,
- ETINT,
- ETSTRING,
- ETPROTO,
- ETCONST,
- ETLOCAL, /* local variable, allocated until end of scope */
- ETGLOBAL, /* global by index number */
- ETUPVAL,
- ETMEMBER, /* member accessor (by name) */
- ETINDEX, /* index accessor (ex array index) */
- ETREG, /* temporary register, can be freed if top of stack */
- ETNGLOBAL /* named global */
-} exptype_t;
-
-typedef struct {
- union {
- struct { /* for suffix */
- unsigned int idx:9; /* suffix RK index */
- unsigned int obj:9; /* object RK index */
- unsigned int tt:5; /* object type */
- } ss;
- breal r; /* for ETREAL */
- bint i; /* for ETINT */
- bstring *s; /* for ETSTRING */
- bproto *p; /* for ETPROTO */
- int idx; /* variable index */
- } v;
- int t; /* patch list of 'exit when true' */
- int f; /* patch list of 'exit when false' */
- bbyte not; /* not mark */
- bbyte type;
-} bexpdesc;
-
-typedef struct bblockinfo {
- struct bblockinfo *prev;
- bbyte nactlocals; /* number of active local variables */
- bbyte type; /* block type mask */
- bbyte hasupval; /* has upvalue mark */
- bbyte sideeffect; /* did the last expr/statement had a side effect */
- int lastjmp; /* pc for the last jump, prevents false register optimizations */
- int breaklist; /* break list */
- int beginpc; /* begin pc */
- int continuelist; /* continue list */
-} bblockinfo;
-
-typedef struct bfuncinfo {
- struct bfuncinfo *prev; /* outer function */
- bproto *proto; /* the function prototype */
- bblockinfo *binfo; /* block information */
- struct blexer *lexer; /* the lexer pointer */
- blist *local; /* local variable */
- bmap *upval; /* upvalue variable */
- bvector code; /* code vector */
- bvector kvec; /* constants table */
- bvector pvec; /* proto table */
-#if BE_DEBUG_RUNTIME_INFO /* debug information */
- bvector linevec;
-#endif
-#if BE_DEBUG_VAR_INFO
- bvector varvec;
-#endif
- int pc; /* program count */
- bbyte freereg; /* first free register */
- bbyte flags; /* some flages */
-} bfuncinfo;
-
-/* code block type definitions */
-#define BLOCK_LOOP 1
-#define BLOCK_EXCEPT 2
-
-bclosure *be_parser_source(bvm *vm,
- const char *fname, breader reader, void *data, bbool islocal);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_rangelib.c b/lib/libesp32/Berry/src/be_rangelib.c
deleted file mode 100644
index 187807021205..000000000000
--- a/lib/libesp32/Berry/src/be_rangelib.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_func.h"
-#include "be_vm.h"
-
-static int m_init(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc < 3) { be_raise(vm, "value_error", "missing arguments"); }
- if (!be_isint(vm, 2) || !be_isint(vm, 3)) { be_raise(vm, "value_error", "arguments must be 'int'"); }
- be_pushvalue(vm, 2);
- be_setmember(vm, 1, "__lower__");
- be_pop(vm, 1);
- be_pushvalue(vm, 3);
- be_setmember(vm, 1, "__upper__");
- int incr = 1; /* default increment is '1' */
- if (argc >= 4) {
- if (!be_isint(vm, 4)) { be_raise(vm, "value_error", "arguments must be 'int'"); }
- incr = be_toint(vm, 4);
- if (incr == 0) { be_raise(vm, "value_error", "increment cannot be zero"); }
- }
- be_pushint(vm, incr);
- be_setmember(vm, 1, "__incr__");
- be_return_nil(vm);
-}
-
-static int m_tostring(bvm *vm)
-{
- be_getmember(vm, 1, "__incr__");
- int incr = be_toint(vm, -1);
- be_pop(vm, 1);
- if (incr == 1) {
- be_pushstring(vm, "(");
- be_getmember(vm, 1, "__lower__");
- be_tostring(vm, -1);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_pushstring(vm, "..");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_getmember(vm, 1, "__upper__");
- be_tostring(vm, -1);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_pushstring(vm, ")");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- } else {
- be_pushstring(vm, "range(");
- be_getmember(vm, 1, "__lower__");
- be_tostring(vm, -1);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_pushstring(vm, ", ");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_getmember(vm, 1, "__upper__");
- be_tostring(vm, -1);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_pushstring(vm, ", ");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_getmember(vm, 1, "__incr__");
- be_tostring(vm, -1);
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- be_pushstring(vm, ")");
- be_strconcat(vm, -2);
- be_pop(vm, 1);
- }
- be_return(vm);
-}
-
-static int m_upper(bvm *vm)
-{
- be_getmember(vm, 1, "__upper__");
- be_return(vm);
-}
-
-static int m_lower(bvm *vm)
-{
- be_getmember(vm, 1, "__lower__");
- be_return(vm);
-}
-
-static int m_incr(bvm *vm)
-{
- be_getmember(vm, 1, "__incr__");
- be_return(vm);
-}
-
-static int m_setrange(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc < 3) { be_raise(vm, "value_error", "missing arguments"); }
- if (!be_isint(vm, 2) || !be_isint(vm, 3)) { be_raise(vm, "value_error", "arguments must be 'int'"); }
- be_pushvalue(vm, 2);
- be_setmember(vm, 1, "__lower__");
- be_pop(vm, 1);
- be_pushvalue(vm, 3);
- be_setmember(vm, 1, "__upper__");
- int incr = 1; /* default increment is '1' */
- if (argc >= 4) {
- if (!be_isint(vm, 4)) { be_raise(vm, "value_error", "arguments must be 'int'"); }
- incr = be_toint(vm, 4);
- if (incr == 0) { be_raise(vm, "value_error", "increment cannot be zero"); }
- }
- be_pushint(vm, incr);
- be_setmember(vm, 1, "__incr__");
- be_return_nil(vm);
-}
-
-static int iter_closure(bvm *vm)
-{
- /* for better performance, we operate the upvalues
- * directly without using by the stack. */
- bntvclos *func = var_toobj(vm->cf->func);
- bvalue *uv0 = be_ntvclos_upval(func, 0)->value;
- bvalue *uv1 = be_ntvclos_upval(func, 1)->value;
- bvalue *uv2 = be_ntvclos_upval(func, 2)->value;
- bint lower = var_toint(uv0); /* upvalue[0] => lower */
- bint upper = var_toint(uv1); /* upvalue[1] => upper */
- bint incr = var_toint(uv2); /* upvalue[2] => incr */
- if ((incr > 0 && lower > upper) || (incr < 0 && lower < upper)) {
- be_stop_iteration(vm);
- }
- var_toint(uv0) = lower + incr; /* set upvale[0] */
- be_pushint(vm, lower); /* push the return value */
- be_return(vm);
-}
-
-static int m_iter(bvm *vm)
-{
- be_pushntvclosure(vm, iter_closure, 3);
- be_getmember(vm, 1, "__lower__");
- be_setupval(vm, -2, 0);
- be_pop(vm, 1);
- be_getmember(vm, 1, "__upper__");
- be_setupval(vm, -2, 1);
- be_pop(vm, 1);
- be_getmember(vm, 1, "__incr__");
- be_setupval(vm, -2, 2);
- be_pop(vm, 1);
- be_return(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-void be_load_rangelib(bvm *vm)
-{
- static const bnfuncinfo members[] = {
- { "__lower__", NULL },
- { "__upper__", NULL },
- { "__incr__", NULL },
- { "init", m_init },
- { "tostring", m_tostring },
- { "lower", m_lower },
- { "upper", m_upper },
- { "setrange", m_setrange },
- { "iter", m_iter },
- { NULL, NULL }
- };
- be_regclass(vm, "range", members);
-}
-#else
-/* @const_object_info_begin
-class be_class_range (scope: global, name: range) {
- __lower__, var
- __upper__, var
- __incr__, var
- init, func(m_init)
- tostring, func(m_tostring)
- lower, func(m_lower)
- upper, func(m_upper)
- incr, func(m_incr)
- setrange, func(m_setrange)
- iter, func(m_iter)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_be_class_range.h"
-#endif
diff --git a/lib/libesp32/Berry/src/be_repl.c b/lib/libesp32/Berry/src/be_repl.c
deleted file mode 100644
index 17b766df797b..000000000000
--- a/lib/libesp32/Berry/src/be_repl.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "berry.h"
-#include "be_repl.h"
-#include
-
-#define safecall(func, ...) if (func) { func(__VA_ARGS__); }
-
-#if BE_USE_SCRIPT_COMPILER
-
-static int try_return(bvm *vm, const char *line)
-{
- int res, idx;
- line = be_pushfstring(vm, "return (%s)", line);
- idx = be_absindex(vm, -1); /* get the source text absolute index */
- res = be_loadbuffer(vm, "stdin", line, strlen(line)); /* compile line */
- be_remove(vm, idx); /* remove source string */
- return res;
-}
-
-static bbool is_multline(bvm *vm)
-{
- const char *msg = be_tostring(vm, -1);
- size_t len = strlen(msg);
- if (len > 5) { /* multi-line text if the error message is 'EOS' at the end */
- return !strcmp(msg + len - 5, "'EOS'");
- }
- return bfalse;
-}
-
-static int compile(bvm *vm, char *line, breadline getl, bfreeline freel)
-{
- int res = try_return(vm, line);
- if (be_getexcept(vm, res) == BE_SYNTAX_ERROR) {
- be_pop(vm, 2); /* pop exception values */
- be_pushstring(vm, line);
- safecall(freel, line); /* free line buffer */
- for (;;) {
- const char *src = be_tostring(vm, -1); /* get source code */
- int idx = be_absindex(vm, -1); /* get the source text absolute index */
- /* compile source line */
- res = be_loadbuffer(vm, "stdin", src, strlen(src));
- if (!res || !is_multline(vm)) {
- be_remove(vm, idx); /* remove source code */
- return res;
- }
- be_pop(vm, 2); /* pop exception values */
- line = getl(">> "); /* read a new input line */
- be_pushfstring(vm, "\n%s", line);
- safecall(freel, line); /* free line buffer */
- be_strconcat(vm, -2);
- be_pop(vm, 1); /* pop new line */
- }
- } else {
- safecall(freel, line); /* free line buffer */
- }
- return res;
-}
-
-static int call_script(bvm *vm)
-{
- int res = be_pcall(vm, 0); /* call the main function */
- switch (res) {
- case BE_OK: /* execution succeed */
- if (!be_isnil(vm, -1)) { /* print return value when it's not nil */
- be_dumpvalue(vm, -1);
- }
- be_pop(vm, 1); /* pop the result value */
- break;
- case BE_EXCEPTION: /* vm run error */
- be_dumpexcept(vm);
- be_pop(vm, 1); /* pop the function value */
- break;
- default: /* BE_EXIT or BE_MALLOC_FAIL */
- return res;
- }
- return 0;
-}
-
-BERRY_API int be_repl(bvm *vm, breadline getline, bfreeline freeline)
-{
- char *line;
- be_assert(getline != NULL);
- while ((line = getline("> ")) != NULL) {
- int res = compile(vm, line, getline, freeline);
- if (res == BE_MALLOC_FAIL)
- return BE_MALLOC_FAIL;
- if (res) {
- be_dumpexcept(vm);
- } else { /* compiled successfully */
- res = call_script(vm);
- if (res) {
- return res == BE_EXIT ? be_toindex(vm, -1) : res;
- }
- }
- }
- be_writenewline();
- return 0;
-}
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_repl.h b/lib/libesp32/Berry/src/be_repl.h
deleted file mode 100644
index 7d27e7850d62..000000000000
--- a/lib/libesp32/Berry/src/be_repl.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_REPL_H
-#define BE_REPL_H
-
-#include "berry.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef char* (*breadline)(const char *prompt);
-typedef void (*bfreeline)(char *ptr);
-
-BERRY_API int be_repl(bvm *vm, breadline getline, bfreeline freeline);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_solidifylib.c b/lib/libesp32/Berry/src/be_solidifylib.c
deleted file mode 100644
index ecfb7589065e..000000000000
--- a/lib/libesp32/Berry/src/be_solidifylib.c
+++ /dev/null
@@ -1,886 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_module.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_class.h"
-#include "be_list.h"
-#include "be_debug.h"
-#include "be_map.h"
-#include "be_vm.h"
-#include "be_decoder.h"
-#include "be_sys.h"
-#include "be_mem.h"
-#include "be_byteslib.h"
-#include "be_gc.h"
-#include
-#include
-#include
-#include
-
-extern const bclass be_class_list;
-extern const bclass be_class_map;
-extern const bclass be_class_bytes;
-
-#if BE_USE_SOLIDIFY_MODULE
-#include
-
-#define be_builtin_count(vm) \
- be_vector_count(&(vm)->gbldesc.builtin.vlist)
-
-#ifndef INST_BUF_SIZE
-#define INST_BUF_SIZE 768
-#endif
-
-#define logfmt(...) \
- do { \
- char __lbuf[INST_BUF_SIZE]; \
- snprintf(__lbuf, sizeof(__lbuf), __VA_ARGS__); \
- if (fout) { \
- be_fwrite(fout, __lbuf, strlen(__lbuf)); \
- } else { \
- be_writestring(__lbuf); \
- } \
- } while (0)
-
-/* minimal version without formatting and without size limit */
-#define lognofmt(__s) \
- do { \
- if (fout) { \
- be_fwrite(fout, __s, strlen(__s)); \
- } else { \
- be_writestring(__s); \
- } \
- } while (0)
-
-/********************************************************************\
- * Encode string to identifiers
- *
- * `_X` is used as an escape marker
-\********************************************************************/
-static unsigned toidentifier_length(const char *s)
-{
- unsigned len = 1;
- const char * p = s;
- while (*p) {
- if (p[0] == '_' && p[1] == 'X') {
- len += 3;
- p += 2;
- } else if (isalnum(p[0]) || p[0] == '_') {
- p++;
- len++;
- } else { // escape
- p++;
- len += 4;
- }
- }
- return len;
-}
-
-inline static char hexdigit(int v)
-{
- v = v & 0xF;
- if (v >= 10) return v - 10 + 'A';
- return v + '0';
-}
-
-static void toidentifier(char *to, const char *p)
-{
- while (*p) {
- if (p[0] == '_' && p[1] == 'X') {
- to[0] = '_';
- to[1] = 'X';
- to[2] = '_';
- p += 2;
- to += 3;
- } else if (isalnum(p[0]) || p[0] == '_') {
- *to = *p;
- to++;
- p++;
- } else { // escape
- to[0] = '_';
- to[1] = 'X';
- to[2] = hexdigit((*p & 0xF0) >> 4);
- to[3] = hexdigit(*p & 0x0F);
- p++;
- to += 4;
- }
- }
- *to = 0; // final NULL
-}
-
-static void m_solidify_bvalue(bvm *vm, bbool str_literal, const bvalue * value, const char *prefix_name, const char *key, void* fout);
-
-static void m_solidify_map(bvm *vm, bbool str_literal, bmap * map, const char *prefix_name, void* fout)
-{
- // compact first
- be_map_compact(vm, map);
-
- logfmt(" be_nested_map(%i,\n", map->count);
-
- logfmt(" ( (struct bmapnode*) &(const bmapnode[]) {\n");
- for (int i = 0; i < map->size; i++) {
- bmapnode * node = &map->slots[i];
- if (node->key.type == BE_NIL) {
- continue; /* key not used */
- }
- int key_next = node->key.next;
- if (0xFFFFFF == key_next) {
- key_next = -1; /* more readable */
- }
- if (node->key.type == BE_STRING) {
- /* convert the string literal to identifier */
- const char * key = str(node->key.v.s);
- size_t id_len = toidentifier_length(key);
- char id_buf[id_len];
- toidentifier(id_buf, key);
- if (!str_literal) {
- logfmt(" { be_const_key(%s, %i), ", id_buf, key_next);
- } else {
- logfmt(" { be_const_key_weak(%s, %i), ", id_buf, key_next);
- }
- m_solidify_bvalue(vm, str_literal, &node->value, prefix_name, str(node->key.v.s), fout);
- } else if (node->key.type == BE_INT) {
-#if BE_INTGER_TYPE == 2
- logfmt(" { be_const_key_int(%lli, %i), ", node->key.v.i, key_next);
-#else
- logfmt(" { be_const_key_int(%i, %i), ", node->key.v.i, key_next);
-#endif
- m_solidify_bvalue(vm, str_literal, &node->value, prefix_name, NULL, fout);
- } else {
- char error[64];
- snprintf(error, sizeof(error), "Unsupported type in key: %i", node->key.type);
- be_raise(vm, "internal_error", error);
- }
-
- logfmt(" },\n");
- }
- logfmt(" }))"); // TODO need terminal comma?
-
-}
-
-static void m_solidify_list(bvm *vm, bbool str_literal, const blist * list, const char *prefix_name, void* fout)
-{
- logfmt(" be_nested_list(%i,\n", list->count);
-
- logfmt(" ( (struct bvalue*) &(const bvalue[]) {\n");
- for (int i = 0; i < list->count; i++) {
- logfmt(" ");
- m_solidify_bvalue(vm, str_literal, &list->data[i], prefix_name, "", fout);
- logfmt(",\n");
- }
- logfmt(" }))"); // TODO need terminal comma?
-}
-
-// pass key name in case of class, or NULL if none
-static void m_solidify_bvalue(bvm *vm, bbool str_literal, const bvalue * value, const char *prefix_name, const char *key, void* fout)
-{
- int type = var_primetype(value);
- switch (type) {
- case BE_NIL:
- logfmt("be_const_nil()");
- break;
- case BE_BOOL:
- logfmt("be_const_bool(%i)", var_tobool(value));
- break;
- case BE_INT:
-#if BE_INTGER_TYPE == 2
- logfmt("be_const_int(%lli)", var_toint(value));
-#else
- logfmt("be_const_int(%i)", var_toint(value));
-#endif
- break;
- case BE_INDEX:
-#if BE_INTGER_TYPE == 2
- logfmt("be_const_var(%lli)", var_toint(value));
-#else
- logfmt("be_const_var(%i)", var_toint(value));
-#endif
- break;
- case BE_REAL:
-#if BE_USE_SINGLE_FLOAT
- logfmt("be_const_real_hex(0x%08" PRIX32 ")", (uint32_t)(uintptr_t)var_toobj(value));
-#else
- logfmt("be_const_real_hex(0x%016" PRIx64 ")", (uint64_t)var_toobj(value));
-#endif
- break;
- case BE_STRING:
- {
- const char * str = str(var_tostr(value));
- size_t len = strlen(str);
- size_t id_len = toidentifier_length(str);
- char id_buf_stack[64];
- char *id_buf = id_buf_stack;
- if (id_len >= 64) {
- id_buf = be_os_malloc(id_len);
- if (!id_buf) {
- be_raise(vm, "memory_error", "could not allocated buffer");
- }
- }
- toidentifier(id_buf, str);
- if (len >= 255) {
- /* decompose to avoid any size limit */
- lognofmt("be_nested_str_long(");
- lognofmt(id_buf);
- lognofmt(")");
- } else if (!str_literal) {
- logfmt("be_nested_str(%s)", id_buf);
- } else {
- logfmt("be_nested_str_weak(%s)", id_buf);
- }
- if (id_buf != id_buf_stack) {
- be_os_free(id_buf);
- }
- }
- break;
- case BE_CLOSURE:
- {
- bclosure *clo = (bclosure*) var_toobj(value);
- const char * func_name = str(clo->proto->name);
- size_t id_len = toidentifier_length(func_name);
- char func_name_id[id_len];
- toidentifier(func_name_id, func_name);
- logfmt("be_const_%sclosure(%s%s%s_closure)",
- var_isstatic(value) ? "static_" : "",
- prefix_name ? prefix_name : "", prefix_name ? "_" : "",
- func_name_id);
- }
- break;
- case BE_CLASS:
- logfmt("be_const_class(be_class_%s)", str(((bclass*) var_toobj(value))->name));
- break;
- case BE_COMPTR:
- logfmt("be_const_comptr(&be_ntv_%s_%s)", prefix_name ? prefix_name : "unknown", key ? key : "unknown");
- break;
- case BE_NTVFUNC:
- logfmt("be_const_%sfunc(be_ntv_%s_%s)",
- var_isstatic(value) ? "static_" : "",
- prefix_name ? prefix_name : "unknown", key ? key : "unknown");
- break;
- case BE_INSTANCE:
- {
- binstance * ins = (binstance *) var_toobj(value);
- bclass * cl = ins->_class;
-
- if (cl == &be_class_bytes) {
- const void * bufptr = var_toobj(&ins->members[0]);
- int32_t len = var_toint(&ins->members[1]);
- size_t hex_len = len * 2 + 1;
-
- char * hex_out = be_pushbuffer(vm, hex_len);
- be_bytes_tohex(hex_out, hex_len, bufptr, len);
- logfmt("be_const_bytes_instance(%s)", hex_out);
- be_pop(vm, 1);
- } else if (ins->super || ins->sub) {
- be_raise(vm, "internal_error", "instance must not have a super/sub class");
- } else {
- const char * cl_ptr = "";
- if (cl == &be_class_map) { cl_ptr = "map"; }
- else if (cl == &be_class_list) { cl_ptr = "list"; }
- else { be_raise(vm, "internal_error", "unsupported class"); }
-
- logfmt("be_const_simple_instance(be_nested_simple_instance(&be_class_%s, {\n", cl_ptr);
- if (cl == &be_class_map) {
- logfmt(" be_const_map( * ");
- } else {
- logfmt(" be_const_list( * ");
- }
- m_solidify_bvalue(vm, str_literal, &ins->members[0], prefix_name, key, fout);
- logfmt(" ) } ))");
- }
- }
- break;
- case BE_MAP:
- m_solidify_map(vm, str_literal, (bmap *) var_toobj(value), prefix_name, fout);
- break;
- case BE_LIST:
- m_solidify_list(vm, str_literal, (blist *) var_toobj(value), prefix_name, fout);
- break;
- default:
- {
- char error[64];
- snprintf(error, sizeof(error), "Unsupported type in function constants: %i", type);
- be_raise(vm, "internal_error", error);
- }
- }
-}
-
-static void m_solidify_subclass(bvm *vm, bbool str_literal, const bclass *cl, void* fout);
-
-/* solidify any inner class */
-static void m_solidify_closure_inner_class(bvm *vm, bbool str_literal, const bclosure *clo, void* fout)
-{
- // parse any class in constants to output it first
- bproto *pr = clo->proto;
- if ((!gc_isconst(clo)) && (pr->nconst > 0) && (!(pr->varg & BE_VA_SHARED_KTAB)) && (!(pr->varg & BE_VA_NOCOMPACT))) { /* if shared ktab or nocompact, skip */
- for (int k = 0; k < pr->nconst; k++) {
- if (var_type(&pr->ktab[k]) == BE_CLASS) {
- if ((k == 0) && (pr->varg & BE_VA_STATICMETHOD)) {
- // it is the implicit '_class' variable from a static method, don't dump the class
- } else {
- // output the class
- m_solidify_subclass(vm, str_literal, (bclass*) var_toobj(&pr->ktab[k]), fout);
- }
- }
- }
- }
-}
-
-static void m_solidify_proto(bvm *vm, bbool str_literal, const bproto *pr, const char * func_name, int indent, const char * prefix_name, void* fout)
-{
- logfmt("%*sbe_nested_proto(\n", indent, "");
- indent += 2;
-
- logfmt("%*s%d, /* nstack */\n", indent, "", pr->nstack);
- logfmt("%*s%d, /* argc */\n", indent, "", pr->argc);
- logfmt("%*s%d, /* varg */\n", indent, "", pr->varg);
- logfmt("%*s%d, /* has upvals */\n", indent, "", (pr->nupvals > 0) ? 1 : 0);
-
- if (pr->nupvals > 0) {
- logfmt("%*s( &(const bupvaldesc[%2d]) { /* upvals */\n", indent, "", pr->nupvals);
- for (int32_t i = 0; i < pr->nupvals; i++) {
- logfmt("%*s be_local_const_upval(%i, %i),\n", indent, "", pr->upvals[i].instack, pr->upvals[i].idx);
- }
- logfmt("%*s}),\n", indent, "");
- } else {
- logfmt("%*sNULL, /* no upvals */\n", indent, "");
- }
-
- logfmt("%*s%d, /* has sup protos */\n", indent, "", (pr->nproto > 0) ? 1 : 0);
- if (pr->nproto > 0) {
- logfmt("%*s( &(const struct bproto*[%2d]) {\n", indent, "", pr->nproto);
- for (int32_t i = 0; i < pr->nproto; i++) {
- size_t sub_len = strlen(func_name) + 10;
- char sub_name[sub_len];
- snprintf(sub_name, sizeof(sub_name), "%s_%"PRId32, func_name, i);
- m_solidify_proto(vm, str_literal, pr->ptab[i], sub_name, indent+2, prefix_name, fout);
- logfmt(",\n");
- }
- logfmt("%*s}),\n", indent, "");
- } else {
- logfmt("%*sNULL, /* no sub protos */\n", indent, "");
- }
-
- logfmt("%*s%d, /* has constants */\n", indent, "", (pr->nconst > 0) ? 1 : 0);
- if (pr->nconst > 0) {
- // we output the full table unless it's a shared ktab
- if (pr->varg & BE_VA_SHARED_KTAB) {
- logfmt("%*s&be_ktab_%s, /* shared constants */\n", indent, "", prefix_name);
- } else {
- logfmt("%*s( &(const bvalue[%2d]) { /* constants */\n", indent, "", pr->nconst);
- for (int k = 0; k < pr->nconst; k++) {
- logfmt("%*s/* K%-3d */ ", indent, "", k);
- m_solidify_bvalue(vm, str_literal, &pr->ktab[k], NULL, NULL, fout);
- logfmt(",\n");
- }
- logfmt("%*s}),\n", indent, "");
- }
- } else {
- logfmt("%*sNULL, /* no const */\n", indent, "");
- }
-
- /* convert the string literal to identifier */
- const char * key = str(pr->name);
- size_t id_len = toidentifier_length(key);
- char id_buf[id_len];
- toidentifier(id_buf, key);
- if (!str_literal) {
- logfmt("%*s&be_const_str_%s,\n", indent, "", id_buf);
- } else {
- logfmt("%*sbe_str_weak(%s),\n", indent, "", id_buf);
- }
- // hard-code source as "solidified" for solidified
- logfmt("%*s&be_const_str_solidified,\n", indent, "");
-
- logfmt("%*s( &(const binstruction[%2d]) { /* code */\n", indent, "", pr->codesize);
- for (int pc = 0; pc < pr->codesize; pc++) {
- uint32_t ins = pr->code[pc];
- logfmt("%*s 0x%08"PRIX32", //", indent, "", ins);
- be_print_inst(ins, pc, fout);
- bopcode op = IGET_OP(ins);
- if (op == OP_GETGBL || op == OP_SETGBL) {
- // check if the global is in built-ins
- int glb = IGET_Bx(ins);
- if (glb > be_builtin_count(vm)) {
- // not supported
- logfmt("\n===== unsupported global G%d\n", glb);
- be_raise(vm, "internal_error", "Unsupported access to non-builtin global");
- }
- }
- }
- logfmt("%*s})\n", indent, "");
- indent -= 2;
- logfmt("%*s)", indent, "");
-
-}
-
-static void m_solidify_closure(bvm *vm, bbool str_literal, const bclosure *clo, const char * prefix_name, void* fout)
-{
- bproto *pr = clo->proto;
- const char * func_name = str(pr->name);
-
- if (clo->nupvals > 0) {
- logfmt("--> Unsupported upvals in closure <---");
- // be_raise(vm, "internal_error", "Unsupported upvals in closure");
- }
-
- int indent = 2;
-
- m_solidify_closure_inner_class(vm, str_literal, clo, fout);
-
- logfmt("\n");
- logfmt("/********************************************************************\n");
- logfmt("** Solidified function: %s\n", func_name);
- logfmt("********************************************************************/\n");
-
- {
- size_t id_len = toidentifier_length(func_name);
- char func_name_id[id_len];
- toidentifier(func_name_id, func_name);
- logfmt("be_local_closure(%s%s%s, /* name */\n",
- prefix_name ? prefix_name : "", prefix_name ? "_" : "",
- func_name_id);
- }
-
- m_solidify_proto(vm, str_literal, pr, func_name, indent, prefix_name, fout);
- logfmt("\n");
-
- // closure
- logfmt(");\n");
- logfmt("/*******************************************************************/\n\n");
-}
-
-static void m_compact_class(bvm *vm, bbool str_literal, const bclass *cla, void* fout);
-
-static void m_solidify_subclass(bvm *vm, bbool str_literal, const bclass *cla, void* fout)
-{
- const char * classname = str(cla->name);
-
- /* TODO try compacting for now */
- m_compact_class(vm, str_literal, cla, fout);
-
- char prefix_name[strlen(classname) + 10];
- snprintf(prefix_name, sizeof(prefix_name), "class_%s", classname);
- /* pre-declare class to support '_class' implicit variable */
- logfmt("\nextern const bclass be_class_%s;\n", classname);
-
- /* iterate on members to dump closures */
- if (cla->members) {
- bmapnode *node;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(cla->members, &iter)) != NULL) {
- if (var_isstr(&node->key) && var_isclosure(&node->value)) {
- bclosure *f = var_toobj(&node->value);
- m_solidify_closure(vm, str_literal, f, prefix_name, fout);
- }
- }
- }
-
-
- logfmt("\n");
- logfmt("/********************************************************************\n");
- logfmt("** Solidified class: %s\n", classname);
- logfmt("********************************************************************/\n");
-
- if (cla->super) {
- logfmt("extern const bclass be_class_%s;\n", str(cla->super->name));
- }
-
- logfmt("be_local_class(%s,\n", classname);
- logfmt(" %i,\n", cla->nvar);
- if (cla->super) {
- logfmt(" &be_class_%s,\n", str(cla->super->name));
- } else {
- logfmt(" NULL,\n");
- }
-
- if (cla->members) {
- m_solidify_map(vm, str_literal, cla->members, prefix_name, fout);
- logfmt(",\n");
- } else {
- logfmt(" NULL,\n");
- }
-
- size_t id_len = toidentifier_length(classname);
- char id_buf[id_len];
- toidentifier(id_buf, classname);
- if (!str_literal) {
- logfmt(" (bstring*) &be_const_str_%s\n", id_buf);
- } else {
- logfmt(" be_str_weak(%s)\n", id_buf);
- }
- logfmt(");\n");
-}
-
-static void m_solidify_class(bvm *vm, bbool str_literal, bclass *cl, void* fout)
-{
- m_solidify_subclass(vm, str_literal, cl, fout);
-}
-
-static void m_solidify_module(bvm *vm, bbool str_literal, bmodule *ml, void* fout)
-{
- const char * modulename = be_module_name(ml);
- if (!modulename) { modulename = ""; }
- // char prefix_name[strlen(modulename) + 10];
- // snprintf(prefix_name, sizeof(prefix_name), "module_%s", modulename);
-
- /* iterate on members to dump closures and classes */
- if (ml->table) {
- bmapnode *node;
- bmapiter iter = be_map_iter();
- while ((node = be_map_next(ml->table, &iter)) != NULL) {
- if (var_isstr(&node->key) && var_isclosure(&node->value)) {
- bclosure *f = var_toobj(&node->value);
- m_solidify_closure(vm, str_literal, f, NULL, fout);
- }
- if (var_isstr(&node->key) && var_isclass(&node->value)) {
- bclass *cl = var_toobj(&node->value);
- m_solidify_subclass(vm, str_literal, cl, fout);
- }
- }
- }
-
-
- logfmt("\n");
- logfmt("/********************************************************************\n");
- logfmt("** Solidified module: %s\n", modulename);
- logfmt("********************************************************************/\n");
-
- logfmt("be_local_module(%s,\n", modulename);
- logfmt(" \"%s\",\n", modulename);
-
- if (ml->table) {
- m_solidify_map(vm, str_literal, ml->table, NULL, fout);
- logfmt("\n");
- } else {
- logfmt(" NULL,\n");
- }
- logfmt(");\n");
- logfmt("BE_EXPORT_VARIABLE be_define_const_native_module(%s);\n", modulename);
- logfmt("/********************************************************************/\n");
-
-}
-
-static int m_dump(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- bbool str_literal = bfalse;
- if (top >= 2) {
- str_literal = be_tobool(vm, 2);
- }
- void* fout = NULL; /* output file */
- if (top >= 3 && be_isinstance(vm, 3)) {
- be_getmember(vm, 3, ".p");
- if (be_iscomptr(vm, -1)) {
- fout = be_tocomptr(vm, -1);
- }
- be_pop(vm, 1);
- }
- const char *prefix_name = NULL; /* allow to specify an explicit prefix */
- if (top >= 4 && be_isstring(vm, 4)) {
- prefix_name = be_tostring(vm, 4);
- }
- if (var_isclosure(v)) {
- m_solidify_closure(vm, str_literal, var_toobj(v), prefix_name, fout);
- } else if (var_isclass(v)) {
- m_solidify_class(vm, str_literal, var_toobj(v), fout);
- } else if (var_ismodule(v)) {
- m_solidify_module(vm, str_literal, var_toobj(v), fout);
- } else {
- be_raise(vm, "value_error", "unsupported type");
- }
- }
- be_return_nil(vm);
-}
-
-static void m_compact_class(bvm *vm, bbool str_literal, const bclass *cla, void* fout)
-{
- const char * classname = str(cla->name);
-
- /* reserve an array big enough for max size ktab (256) */
- const int MAX_KTAB_SIZE = 256;
- bvalue ktab[MAX_KTAB_SIZE]; /* size is 2048 byte for 32 bits, so fitting in ESP32, may need to be changed on smaller architectures */
- int ktab_size = 0;
-
- /* for statistics, keep the aggregate number of bvalues */
- int ktab_total = 0;
-
- /* iterate on members to dump closures */
- if (cla->members) {
- bmapnode *node;
- bmapiter iter = be_map_iter();
-
- /* first iteration to build the global ktab */
- while ((node = be_map_next(cla->members, &iter)) != NULL) {
- if (var_isstr(&node->key) && var_isclosure(&node->value)) {
- bclosure *cl = var_toobj(&node->value);
- bproto *pr = cl->proto;
-
- if ((gc_isconst(cl)) || (pr->varg & BE_VA_SHARED_KTAB) || (pr->varg & BE_VA_NOCOMPACT)) { continue; }
-
- // iterate on each bvalue in ktab
- for (int i = 0; i < pr->nconst; i++) {
- // look if the bvalue pair is already in ktab
- int found = 0;
- for (int j = 0; j < ktab_size; j++) {
- // to avoid any size issue, we compare all bytes
- // berry_log_C("// p1=%p p2=%p sz=%i", &pr->ktab[i], &ktab[j], sizeof(bvalue));
- if ((pr->ktab[i].type == ktab[j].type) && (pr->ktab[i].v.i == ktab[j].v.i) && (pr->ktab[i].v.c == ktab[j].v.c)) {
- // if (memcmp(&pr->ktab[i], &ktab[j], sizeof(bvalue)) == 0) {
- found = 1;
- break;
- }
- }
- // if not already there, add it
- if (!found) {
- ktab[ktab_size++] = pr->ktab[i];
- }
- if (ktab_size >= MAX_KTAB_SIZE) {
- logfmt("// ktab too big for class '%s' - skipping\n", classname);
- return;
- }
- }
- ktab_total += pr->nconst;
- }
- }
-
- if (ktab_size == ktab_total) {
- return; /* nothing to optimize, can happen for classes with zero or 1 method */
- }
- /* allocate a proper ktab */
- bvalue *new_ktab = be_malloc(vm, sizeof(bvalue) * ktab_size);
- memmove(new_ktab, ktab, sizeof(bvalue) * ktab_size);
-
- /* second iteration to replace ktab and patch code */
- iter = be_map_iter();
- while ((node = be_map_next(cla->members, &iter)) != NULL) {
- if (var_isstr(&node->key) && var_isclosure(&node->value)) {
- bclosure *cl = var_toobj(&node->value);
- bproto *pr = cl->proto;
-
- if ((gc_isconst(cl)) || (pr->varg & BE_VA_SHARED_KTAB) || (pr->varg & BE_VA_NOCOMPACT)) { continue; }
-
- uint8_t mapping_array[MAX_KTAB_SIZE];
- // iterate in proto ktab to get the index in the global ktab
- for (int i = 0; i < pr->nconst; i++) {
- for (int j = 0; j < ktab_size; j++) {
- // compare all bytes
- if ((pr->ktab[i].type == ktab[j].type) && (pr->ktab[i].v.i == ktab[j].v.i) && (pr->ktab[i].v.c == ktab[j].v.c)) {
- // if (memcmp(&pr->ktab[i], &ktab[j], sizeof(bvalue)) == 0) {
- mapping_array[i] = j;
- break;
- }
- }
- }
-
- // replace ktab
- pr->ktab = new_ktab;
- pr->nconst = ktab_size;
- // flag as shared ktab
- pr->varg |= BE_VA_SHARED_KTAB;
- // parse code to replace any K reference
- for (int pc = 0; pc < pr->codesize; pc++) {
- uint32_t ins = pr->code[pc];
- bopcode op = IGET_OP(ins);
-
- /* handle all impacted opcodes */
- /* Possibilities: */
- /* "B" | "B and C" | "Bx" contain a constant code */
- /* special case for OP_RET where "B" may not contain anything */
- switch (op) {
- case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
- case OP_MOD: case OP_LT: case OP_LE: case OP_EQ:
- case OP_NE: case OP_GT: case OP_GE: case OP_CONNECT:
- case OP_GETMBR: case OP_SETMBR: case OP_GETMET:
- case OP_GETIDX: case OP_SETIDX: case OP_AND:
- case OP_OR: case OP_XOR: case OP_SHL: case OP_SHR:
- case OP_RAISE:
- // B and C might contain 'K' constant
- if (isKB(ins)) {
- int kidx = IGET_RKB(ins) & KR_MASK;
- if (kidx >= ktab_size) {
- be_raise(vm, "value_error", "invalid ktab index");
- }
- ins = (ins & ~IRKB_MASK) | ISET_RKB(setK(mapping_array[kidx]));
- }
- if (isKC(ins)) {
- int kidx = IGET_RKC(ins) & KR_MASK;
- if (kidx >= ktab_size) {
- be_raise(vm, "value_error", "invalid ktab index");
- }
- ins = (ins & ~IRKC_MASK) | ISET_RKC(setK(mapping_array[kidx]));
- }
- pr->code[pc] = ins;
- break;
- case OP_MOVE: case OP_SETSUPER: case OP_NEG: case OP_FLIP: case OP_IMPORT:
- case OP_GETNGBL: case OP_SETNGBL:
- // Only B might contain 'K' constant
- if (isKB(ins)) {
- int kidx = IGET_RKB(ins) & KR_MASK;
- if (kidx >= ktab_size) {
- be_raise(vm, "value_error", "invalid ktab index");
- }
- ins = (ins & ~IRKB_MASK) | ISET_RKB(setK(mapping_array[kidx]));
- }
- pr->code[pc] = ins;
- break;
- case OP_CLASS:
- case OP_LDCONST:
- // Bx contains the K
- {
- int kidx = IGET_Bx(ins);
- if (kidx >= ktab_size) {
- be_raise(vm, "value_error", "invalid ktab index");
- }
- ins = (ins & ~IBx_MASK) | ISET_Bx(mapping_array[kidx]);
- pr->code[pc] = ins;
- }
- break;
- case OP_RET:
- if (IGET_RA(ins)) {
- // Only B might contain 'K' constant
- if (isKB(ins)) {
- int kidx = IGET_RKB(ins) & KR_MASK;
- if (kidx >= ktab_size) {
- be_raise(vm, "value_error", "invalid ktab index");
- }
- ins = (ins & ~IRKB_MASK) | ISET_RKB(setK(mapping_array[kidx]));
- }
- }
- pr->code[pc] = ins;
- break;
- /* The following opcodes are not impacted by shared constant table
- case OP_GETUPV: case OP_SETUPV:
- case OP_LDCONST:
- case OP_CALL:
- case OP_CLOSURE:
- case OP_CLOSE: case OP_LDNIL:
- case OP_EXBLK:
- case OP_CATCH:
- case OP_GETGBL: case OP_SETGBL:
- case OP_JMP:
- case OP_JMPT: case OP_JMPF:
- case OP_LDINT:
- case OP_LDBOOL: */
- default:
- break;
- }
-
- }
- }
- }
- }
- // logfmt("extern const bclass be_class_%s;\n", classname);
- // scan classes and generate extern statements for classes
- for (int k = 0; k < ktab_size; k++) {
- // if it's a class, print an extern statement
- if (var_isclass(&ktab[k])) {
- bclass *cl = var_toobj(&ktab[k]);
- logfmt("extern const bclass be_class_%s;\n", str(cl->name));
- }
- }
-
- // scan again to export all sub-classes
- for (int k = 0; k < ktab_size; k++) {
- // if it's a class, print an extern statement
- if (var_isclass(&ktab[k])) {
- bclass *cl = var_toobj(&ktab[k]);
- if (cl != cla) {
- m_solidify_subclass(vm, str_literal, cl, fout);
- }
- }
- }
-
- // output shared ktab
- int indent = 0;
- logfmt("// compact class '%s' ktab size: %d, total: %d (saved %i bytes)\n", classname, ktab_size, ktab_total, (ktab_total - ktab_size) * 8);
- logfmt("static const bvalue be_ktab_class_%s[%i] = {\n", classname, ktab_size);
- for (int k = 0; k < ktab_size; k++) {
- logfmt("%*s/* K%-3d */ ", indent + 2, "", k);
- m_solidify_bvalue(vm, str_literal, &ktab[k], NULL, NULL, fout);
- logfmt(",\n");
- }
- logfmt("%*s};\n", indent, "");
- logfmt("\n");
-}
-
-// takes a class or a module
-// scans all first level bproto
-// build a consolidated 'ktab' array
-// check that the array is not bigger than 256 (which is the max acceptable constants)
-// (for now) print the potential saving
-static int m_compact(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- bbool str_literal = bfalse;
- if (top >= 2) {
- str_literal = be_tobool(vm, 2);
- }
- void* fout = NULL; /* output file */
- if (top >= 3 && be_isinstance(vm, 3)) {
- be_getmember(vm, 3, ".p");
- if (be_iscomptr(vm, -1)) {
- fout = be_tocomptr(vm, -1);
- }
- be_pop(vm, 1);
- }
- // const char *prefix_name = NULL; /* allow to specify an explicit prefix */
- // if (top >= 4 && be_isstring(vm, 4)) {
- // prefix_name = be_tostring(vm, 4);
- // }
- if (var_isclass(v)) {
- m_compact_class(vm, str_literal, var_toobj(v), fout);
- } else if (var_ismodule(v)) {
- // TODO
- } else {
- be_raise(vm, "value_error", "unsupported type");
- }
- }
- be_return_nil(vm);
-}
-
-static int m_nocompact(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1) {
- bvalue *v = be_indexof(vm, 1);
- if (var_isclosure(v)) {
- bclosure *cl = var_toobj(v);
- bproto *pr = cl->proto;
- pr->varg |= BE_VA_NOCOMPACT;
- } else {
- be_raise(vm, "value_error", "unsupported type");
- }
- }
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(solidify) {
- be_native_module_function("dump", m_dump),
- be_native_module_function("compact", m_compact),
-};
-
-be_define_native_module(solidify, NULL);
-#else
-/* @const_object_info_begin
-module solidify (scope: global, depend: BE_USE_SOLIDIFY_MODULE) {
- dump, func(m_dump)
- compact, func(m_compact)
- nocompact, func(m_nocompact)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_solidify.h"
-#endif
-
-#endif /* BE_USE_SOLIFIDY_MODULE */
diff --git a/lib/libesp32/Berry/src/be_strictlib.c b/lib/libesp32/Berry/src/be_strictlib.c
deleted file mode 100644
index b40329886187..000000000000
--- a/lib/libesp32/Berry/src/be_strictlib.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2021 Guan Wenliang & Stephan Hadinger
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-#include "be_module.h"
-#include "be_string.h"
-#include "be_vector.h"
-#include "be_class.h"
-#include "be_debug.h"
-#include "be_map.h"
-#include "be_vm.h"
-
-#if BE_USE_STRICT_MODULE
-
-static int m_init(bvm *vm)
-{
- comp_set_strict(vm); /* enable compiler strict mode */
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(strict) {
- be_native_module_function("init", m_init),
-};
-
-be_define_native_module(strict, NULL);
-#else
-/* @const_object_info_begin
-module strict (scope: strict, depend: BE_USE_STRICT_MODULE) {
- init, func(m_init)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_strict.h"
-#endif
-
-#endif /* BE_USE_STRICT_MODULE */
diff --git a/lib/libesp32/Berry/src/be_string.c b/lib/libesp32/Berry/src/be_string.c
deleted file mode 100644
index 806e37ff0c8a..000000000000
--- a/lib/libesp32/Berry/src/be_string.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_string.h"
-#include "be_vm.h"
-#include "be_mem.h"
-#include "be_constobj.h"
-#include
-
-#define next(_s) cast(void*, cast(bstring*, (_s)->next))
-#define sstr(_s) cast(char*, cast(bsstring*, _s) + 1)
-#define lstr(_s) cast(char*, cast(blstring*, _s) + 1)
-#define cstr(_s) (cast(bcstring*, _s)->s)
-
-#define be_define_const_str(_name, _s, _hash, _extra, _len, _next) \
- BERRY_LOCAL const bcstring be_const_str_##_name = { \
- .next = (bgcobject *)_next, \
- .type = BE_STRING, \
- .marked = GC_CONST, \
- .extra = _extra, \
- .slen = _len, \
- .hash = _hash, \
- .s = _s \
- }
-
-#define be_define_const_str_long(_name, _s, _len) \
- BERRY_LOCAL const bclstring be_const_str_##_name = { \
- .next = (bgcobject *)NULL, \
- .type = BE_STRING, \
- .marked = GC_CONST, \
- .extra = 0, \
- .slen = 255, \
- .llen = _len, \
- .s = _s \
- }
-
-/* const string table */
-struct bconststrtab {
- const bstring* const *table;
- int count; /* string count */
- int size;
-};
-
-#if BE_USE_PRECOMPILED_OBJECT
-#include "../generate/be_const_strtab_def.h"
-#endif
-
-int be_eqstr(bstring *s1, bstring *s2)
-{
- int slen;
- if (s1 == s2) { /* short string or the same string */
- return 1;
- }
- slen = s1->slen;
- /* discard different lengths */
- if (slen != s2->slen) {
- return 0;
- }
- /* long string */
- if (slen == 255) { /* s2->slen is also 255 */
- blstring *ls1 = cast(blstring*, s1);
- blstring *ls2 = cast(blstring*, s2);
- return ls1->llen == ls2->llen && !strcmp(lstr(ls1), lstr(ls2));
- }
- /* const short strings */
- if (gc_isconst(s1) || gc_isconst(s2)) { /* one of the two string is short const */
- uint32_t hash1 = cast(bcstring*, s1)->hash;
- uint32_t hash2 = cast(bcstring*, s2)->hash;
- if (hash1 && hash2 && hash1 != hash2) {
- return 0; /* if hash differ, since we know both are non-null */
- }
- /* if hash are equals, there might be a chance that they are different */
- /* This can happen with solidified code that a same string is present more than once */
- /* so just considering that two strings with the same hash must be same pointer, this is no more true */
- return !strcmp(str(s1), str(s2));
- }
-
- /* if both strings are in-memory, they can't be equal without having the same pointer */
- return 0;
-}
-
-static void resize(bvm *vm, int size)
-{
- int i;
- struct bstringtable *tab = &vm->strtab;
- if (size > tab->size) {
- tab->table = be_realloc(vm, tab->table,
- tab->size * sizeof(bstring*), size * sizeof(bstring*));
- for (i = tab->size; i < size; ++i) {
- tab->table[i] = NULL;
- }
- }
- for (i = 0; i < tab->size; ++i) { /* rehash */
- bstring *p = tab->table[i];
- tab->table[i] = NULL;
- while (p) { /* for each node in the list */
- bstring *hnext = next(p);
- uint32_t hash = be_strhash(p) & (size - 1);
- p->next = cast(void*, tab->table[hash]);
- tab->table[hash] = p;
- p = hnext;
- }
- }
- if (size < tab->size) {
- for (i = size; i < tab->size; ++i) {
- tab->table[i] = NULL;
- }
- tab->table = be_realloc(vm, tab->table,
- tab->size * sizeof(bstring*), size * sizeof(bstring*));
- }
- tab->size = size;
-}
-
-static void free_sstring(bvm *vm, bstring *str)
-{
- be_free(vm, str, sizeof(bsstring) + str->slen + 1);
-}
-
-/* FNV-1a Hash */
-static uint32_t str_hash(const char *str, size_t len)
-{
- uint32_t hash = 2166136261u;
- be_assert(str || !len);
- while (len--) {
- hash = (hash ^ (unsigned char)*str++) * 16777619u;
- }
- return hash;
-}
-
-void be_string_init(bvm *vm)
-{
- resize(vm, 8);
-#if !BE_USE_PRECOMPILED_OBJECT
- /* the destructor name deinit needs to exist all the time, to ensure
- * that it does not need to be created when the heap is exhausted. */
- be_gc_fix(vm, cast(bgcobject*, str_literal(vm, "deinit")));
-#endif
- /* be_const_str_deinit --> for precompiled */
-}
-
-void be_string_deleteall(bvm *vm)
-{
- int i;
- struct bstringtable *tab = &vm->strtab;
- for (i = 0; i < tab->size; ++i) {
- bstring *node = tab->table[i];
- while (node) {
- bstring *next = next(node);
- free_sstring(vm, node);
- node = next;
- }
- }
- be_free(vm, tab->table, tab->size * sizeof(bstring*));
-}
-
-static bstring* createstrobj(bvm *vm, size_t len, int islong)
-{
- size_t size = (islong ? sizeof(blstring)
- : sizeof(bsstring)) + len + 1;
- bgcobject *gco = be_gc_newstr(vm, size, islong);
- bstring *s = cast_str(gco);
- if (s) {
- s->slen = islong ? 255 : (bbyte)len;
- char *str = cast(char *, islong ? lstr(s) : sstr(s));
- str[len] = '\0';
- }
- return s;
-}
-
-#if BE_USE_PRECOMPILED_OBJECT
-static bstring* find_conststr(const char *str, size_t len)
-{
- const struct bconststrtab *tab = &m_const_string_table;
- uint32_t hash = str_hash(str, len);
- bcstring *s = (bcstring*)tab->table[hash % tab->size];
- for (; s != NULL; s = next(s)) {
- if (len == 0 && s->slen == 0) {
- /* special case for the empty string,
- since we don't want to compare it using strncmp,
- because str might be NULL */
- return (bstring*)s;
- }
- if (len == s->slen && !strncmp(str, s->s, len)) {
- return (bstring*)s;
- }
- }
- return NULL;
-}
-#endif
-
-static bstring* newshortstr(bvm *vm, const char *str, size_t len)
-{
- bstring *s;
- int size = vm->strtab.size;
- uint32_t hash = str_hash(str, len);
- bstring **list = vm->strtab.table + (hash & (size - 1));
-
- for (s = *list; s != NULL; s = next(s)) {
- if (len == s->slen && !strncmp(str, sstr(s), len)) {
- return s;
- }
- }
- s = createstrobj(vm, len, 0);
- if (s) {
- /* recompute size and list that may have changed due to a GC */
- size = vm->strtab.size;
- list = vm->strtab.table + (hash & (size - 1));
- memcpy(cast(char *, sstr(s)), str, len);
- s->extra = 0;
- s->next = cast(void*, *list);
-#if BE_USE_STR_HASH_CACHE
- cast(bsstring*, s)->hash = hash;
-#endif
- *list = s;
- vm->strtab.count++;
- if (vm->strtab.count > size << 2) {
- resize(vm, size << 1);
- }
- }
- return s;
-}
-
-bstring* be_newlongstr(bvm *vm, const char *str, size_t len)
-{
- bstring *s;
- blstring *ls;
- s = createstrobj(vm, len, 1);
- ls = cast(blstring*, s);
- s->extra = 0;
- ls->llen = cast_int(len);
- if (str) { /* if the argument 'str' is NULL, we just allocate space */
- memcpy(cast(char *, lstr(s)), str, len);
- }
- return s;
-}
-
-bstring* be_newstr(bvm *vm, const char *str)
-{
- return be_newstrn(vm, str, strlen(str));
-}
-
-bstring *be_newstrn(bvm *vm, const char *str, size_t len)
-{
- if (len <= SHORT_STR_MAX_LEN) {
-#if BE_USE_PRECOMPILED_OBJECT
- bstring *s = find_conststr(str, len);
- return s ? s : newshortstr(vm, str, len);
-#else
- return newshortstr(vm, str, len);
-#endif
- }
- return be_newlongstr(vm, str, len); /* long string */
-}
-
-void be_gcstrtab(bvm *vm)
-{
- struct bstringtable *tab = &vm->strtab;
- int size = tab->size, i;
- for (i = 0; i < size; ++i) {
- bstring **list = tab->table + i;
- bstring *prev = NULL, *node, *next;
- for (node = *list; node; node = next) {
- next = next(node);
- if (!gc_isfixed(node) && gc_iswhite(node)) {
- free_sstring(vm, node);
- tab->count--;
- if (prev) { /* link list */
- prev->next = cast(void*, next);
- } else {
- *list = next;
- }
- } else {
- prev = node;
- gc_setwhite(node);
- }
- }
- }
- if (BE_USE_DEBUG_GC || comp_is_gc_debug(vm)) {
- resize(vm, tab->count + 4);
- } else {
- if (tab->count < size >> 2 && size > 8) {
- resize(vm, size >> 1);
- }
- }
-}
-
-uint32_t be_strhash(const bstring *s)
-{
- if (gc_isconst(s) && (s->slen != 255)) {
- bcstring* cs = cast(bcstring*, s);
- if (cs->hash) { /* if hash is null we need to compute it */
- return cs->hash;
- } else {
- return str_hash(cstr(s), str_len(s));
- }
- }
-#if BE_USE_STR_HASH_CACHE
- if (s->slen != 255) {
- return cast(bsstring*, s)->hash;
- }
-#endif
- return str_hash(str(s), str_len(s));
-}
-
-const char* be_str2cstr(const bstring *s)
-{
- be_assert(cast_str(s) != NULL);
- if (s->slen == 255) {
- return lstr(s);
- }
- if (gc_isconst(s)) {
- return cstr(s);
- }
- return sstr(s);
-}
-
-void be_str_setextra(bstring *s, int extra)
-{
- if (!gc_isconst(s)) {
- s->extra = cast(bbyte, extra);
- }
-}
diff --git a/lib/libesp32/Berry/src/be_string.h b/lib/libesp32/Berry/src/be_string.h
deleted file mode 100644
index f39ae6c4f438..000000000000
--- a/lib/libesp32/Berry/src/be_string.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_STRING_H
-#define BE_STRING_H
-
-#include "be_object.h"
-
-#define SHORT_STR_MAX_LEN 64
-
-typedef struct {
- bstring_header;
-#if BE_USE_STR_HASH_CACHE
- uint32_t hash;
-#endif
- /* char s[]; */
-} bsstring;
-
-typedef struct {
- bstring str;
- int llen;
- /* char s[]; */
-} blstring;
-
-typedef struct { /* const long string */
- bstring_header;
- int llen;
- char s[];
-} bclstring;
-
-typedef struct {
- bstring_header;
- uint32_t hash;
- const char *s;
-} bcstring;
-
-#define str_len(_s) \
- ((_s)->slen == 255 ? cast(blstring*, _s)->llen : (_s)->slen)
-
-#define str(_s) be_str2cstr(_s)
-#define str_extra(_s) ((_s)->extra)
-#define str_literal(_vm, _s) be_newstrn((_vm), (_s), sizeof(_s) - 1)
-
-#if BE_USE_PRECOMPILED_OBJECT
-#include "../generate/be_const_strtab.h"
-#endif
-
-void be_string_init(bvm *vm);
-void be_string_deleteall(bvm *vm);
-int be_eqstr(bstring *s1, bstring *s2);
-bstring* be_newstr(bvm *vm, const char *str);
-bstring* be_newstrn(bvm *vm, const char *str, size_t len);
-bstring* be_newlongstr(bvm *vm, const char *str, size_t len);
-void be_gcstrtab(bvm *vm);
-uint32_t be_strhash(const bstring *s);
-const char* be_str2cstr(const bstring *s);
-void be_str_setextra(bstring *s, int extra);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_strlib.c b/lib/libesp32/Berry/src/be_strlib.c
deleted file mode 100644
index 2ce560910926..000000000000
--- a/lib/libesp32/Berry/src/be_strlib.c
+++ /dev/null
@@ -1,1069 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_strlib.h"
-#include "be_string.h"
-#include "be_vm.h"
-#include "be_class.h"
-#include "be_module.h"
-#include "be_exec.h"
-#include "be_mem.h"
-#include "be_baselib.h"
-#include
-#include
-#include
-
-#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
-#define is_digit(c) ((c) >= '0' && (c) <= '9')
-#define skip_space(s) while (is_space(*(s))) { ++(s); }
-
-static int str_strncasecmp(const char *s1, const char *s2, size_t n)
-{
- if (n == 0) return 0;
-
- while (n-- != 0 && tolower(*s1) == tolower(*s2)) {
- if (n == 0 || *s1 == '\0' || *s2 == '\0')
- break;
- s1++;
- s2++;
- }
-
- return tolower(*(const unsigned char *)s1)
- - tolower(*(const unsigned char *)s2);
-}
-
-typedef bint (*str_opfunc)(const char*, const char*, bint, bint);
-
-bstring* be_strcat(bvm *vm, bstring *s1, bstring *s2)
-{
- size_t len = (size_t)str_len(s1) + str_len(s2);
- if (len <= SHORT_STR_MAX_LEN) {
- char buf[SHORT_STR_MAX_LEN + 1];
- strcpy(buf, str(s1));
- strncat(buf, str(s2), len);
- return be_newstrn(vm, buf, len);
- } else { /* long string */
- bstring *s = be_newstrn(vm, NULL, len);
- char *sbuf = (char*)str(s);
- strcpy(sbuf, str(s1));
- strcpy(sbuf + str_len(s1), str(s2));
- return s;
- }
-}
-
-int be_strcmp(bstring *s1, bstring *s2)
-{
- if (be_eqstr(s1, s2)) {
- return 0;
- }
- return strcmp(str(s1), str(s2));
-}
-
-bstring* be_num2str(bvm *vm, bvalue *v)
-{
- char buf[25];
- if (var_isint(v)) {
- snprintf(buf, sizeof(buf),BE_INT_FORMAT, var_toint(v));
- } else if (var_isreal(v)) {
- snprintf(buf, sizeof(buf), "%g", var_toreal(v));
- } else {
- snprintf(buf, sizeof(buf), "(nan)");
- }
- return be_newstr(vm, buf);
-}
-
-static void module2str(char *buf, size_t buf_len, bvalue *v)
-{
- const char *name = be_module_name(cast(bmodule*, var_toobj(v)));
- if (name) {
- snprintf(buf, buf_len, "", name);
- } else {
- snprintf(buf, buf_len, "", var_toobj(v));
- }
-}
-
-static bstring* sim2str(bvm *vm, bvalue *v)
-{
- char sbuf[64]; /* BUG: memory overflow */
- switch (var_type(v)) {
- case BE_NIL:
- strcpy(sbuf, "nil");
- break;
- case BE_BOOL:
- strcpy(sbuf, var_tobool(v) ? "true" : "false");
- break;
- case BE_INDEX:
- case BE_INT:
- snprintf(sbuf, sizeof(sbuf), BE_INT_FORMAT, var_toint(v));
- break;
- case BE_REAL:
- snprintf(sbuf, sizeof(sbuf), "%g", var_toreal(v));
- break;
- case BE_CLOSURE: case BE_NTVCLOS: case BE_NTVFUNC: case BE_CTYPE_FUNC:
- snprintf(sbuf, sizeof(sbuf), "", var_toobj(v));
- break;
- case BE_CLASS:
- snprintf(sbuf, sizeof(sbuf), "",
- str(be_class_name(cast(bclass*, var_toobj(v)))));
- break;
- case BE_MODULE:
- module2str(sbuf, sizeof(sbuf), v);
- break;
- case BE_COMPTR:
- snprintf(sbuf, sizeof(sbuf), "", var_toobj(v));
- break;
- default:
- strncpy(sbuf, "(unknown value)", sizeof(sbuf));
- break;
- }
- return be_newstr(vm, sbuf);
-}
-
-static bstring* ins2str(bvm *vm, int idx)
-{
- bstring *s = str_literal(vm, "tostring");
- binstance *obj = var_toobj(vm->reg + idx);
- /* get method 'tostring' */
- int type = be_instance_member(vm, obj, s, vm->top);
- be_incrtop(vm); /* push the obj::tostring to stack */
- if (basetype(type) != BE_FUNCTION) {
- bstring *name = be_class_name(be_instance_class(obj));
- size_t buf_len = (size_t) str_len(name) + 16;
- char *sbuf = be_malloc(vm, buf_len);
- /* TODO what if sbuf cannot be allocated */
- snprintf(sbuf, buf_len, "", str(name));
- be_stackpop(vm, 1); /* pop the obj::tostring */
- s = be_newstr(vm, sbuf);
- be_free(vm, sbuf, (size_t)str_len(name) + 16);
- } else {
- *vm->top = vm->reg[idx];
- be_dofunc(vm, vm->top - 1, 1);
- be_stackpop(vm, 1); /* pop the obj::tostring */
- if (!var_isstr(vm->top)) { /* check the return value */
- const char *name = str(be_instance_name(obj));
- be_raise(vm, "runtime_error", be_pushfstring(vm,
- "the value of `%s::tostring()` is not a 'string'",
- strlen(name) ? name : ""));
- }
- s = var_tostr(vm->top);
- }
- return s;
-}
-
-void be_val2str(bvm *vm, int index)
-{
- bstring *s;
- int idx = be_absindex(vm, index) - 1;
- bvalue *v = vm->reg + idx;
- if (var_isstr(v)) return; /* do nothing */
- s = var_isinstance(v) ? ins2str(vm, idx) : sim2str(vm, v);
- v = vm->reg + idx; /* the stack may change */
- var_setstr(v, s);
-}
-
-static void pushstr(bvm *vm, const char *s, size_t len)
-{
- /* to create a string and then update the top pointer,
- * otherwise the GC may crash due to uninitialized values.
- **/
- bstring *str = be_newstrn(vm, s, len);
- bvalue *reg = be_incrtop(vm);
- var_setstr(reg, str);
-}
-
-static const char* concat2(bvm *vm)
-{
- bvalue *dst = vm->top - 2;
- bstring *s1 = var_tostr(dst);
- bstring *s2 = var_tostr(dst + 1);
- bstring *s = be_strcat(vm, s1, s2);
- be_assert(var_isstr(vm->top - 2) && var_isstr(vm->top - 1));
- dst = vm->top - 2; /* the stack may change */
- var_setstr(dst, s);
- --vm->top;
- return str(s);
-}
-
-const char* be_pushvfstr(bvm *vm, const char *format, va_list arg)
-{
- pushstr(vm, "", 0);
- for (;;) {
- const char *p = strchr(format, '%');
- if (p == NULL) {
- break;
- }
- pushstr(vm, format, p - format);
- concat2(vm);
- switch (p[1]) {
- case 's': {
- const char *s = va_arg(arg, char*);
- if (s == NULL) {
- s = "(null)";
- }
- pushstr(vm, s, strlen(s));
- break;
- }
- case 'd': {
- bstring *s;
- bvalue *v = be_incrtop(vm);
- var_setint(v, va_arg(arg, int));
- s = be_num2str(vm, v);
- var_setstr(v, s);
- break;
- }
- case 'f': case 'g': {
- bstring *s;
- bvalue *v = be_incrtop(vm);
- var_setreal(v, cast(breal, va_arg(arg, double)));
- s = be_num2str(vm, v);
- var_setstr(v, s);
- break;
- }
- case 'c': {
- char c = cast(char, va_arg(arg, int));
- pushstr(vm, &c, 1);
- break;
- }
- case '%': {
- pushstr(vm, "%", 1);
- break;
- }
- case 'p': {
- char buf[2 * sizeof(void*) + 4];
- snprintf(buf, sizeof(buf), "%p", va_arg(arg, void*));
- pushstr(vm, buf, strlen(buf));
- break;
- }
- default:
- pushstr(vm, "(unknown)", 8);
- break;
- }
- concat2(vm);
- format = p + 2;
- }
- pushstr(vm, format, strlen(format));
- return concat2(vm);
-}
-
-int be_char2hex(int c)
-{
- if (c >= '0' && c <= '9') {
- return c - '0';
- } else if (c >= 'a' && c <= 'f') {
- return c - 'a' + 0x0A;
- } else if (c >= 'A' && c <= 'F') {
- return c - 'A' + 0x0A;
- }
- return -1;
-}
-
-/*******************************************************************
- * the function be_str2int():
- * >>-+------------+--+--+-----+----digits-------+----------------><
- * '-whitespace-' | +- + -+ |
- * | '- - -' |
- * | |
- * +- 0x or 0X ---hex_digits--+
- *
- *******************************************************************/
-BERRY_API bint be_str2int(const char *str, const char **endstr)
-{
- int c, sign;
- bint sum = 0;
- skip_space(str);
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
- /* hex literal */
- str += 2; /* skip 0x or 0X */
- while ((c = be_char2hex(*str++)) >= 0) {
- sum = sum * 16 + c;
- }
- if (endstr) {
- *endstr = str - 1;
- }
- return sum;
- } else {
- /* decimal literal */
- sign = c = *str++;
- if (c == '+' || c == '-') {
- c = *str++;
- }
- while (is_digit(c)) {
- sum = sum * 10 + c - '0';
- c = *str++;
- }
- if (endstr) {
- *endstr = str - 1;
- }
- return sign == '-' ? -sum : sum;
- }
-}
-
-/*******************************************************************
- * the function be_str2real():
- * >>-+------------+--+-----+--+-digits--+---+--+--------+-+------->
- * '-whitespace-' +- + -+ | '-.-' '-digits-' |
- * '- - -' '-.--digits-----------------'
- *
- * >--+------------------------+----------------------------------><
- * '-+-e-+--+-----+--digits-'
- * '-E-' +- + -+
- * '- - -'
- *******************************************************************/
-BERRY_API breal be_str2real(const char *str, const char **endstr)
-{
- int c, sign;
- breal sum = 0, deci = 0, point = (breal)0.1;
- skip_space(str);
- sign = c = *str++;
- if (c == '+' || c == '-') {
- c = *str++;
- }
- while (is_digit(c)) {
- sum = sum * 10 + c - '0';
- c = *str++;
- }
- if (c == '.') {
- c = *str++;
- while (is_digit(c)) {
- deci = deci + ((breal)c - '0') * point;
- point *= (breal)0.1;
- c = *str++;
- }
- }
- sum = sum + deci;
- if (c == 'e' || c == 'E') {
- int e = 0;
- breal ratio = (c = *str++) == '-' ? (breal)0.1 : 10;
- if (c == '+' || c == '-') {
- c = *str++;
- }
- while (is_digit(c)) {
- e = e * 10 + c - '0';
- c = *str++;
- }
- while (e--) {
- sum *= ratio;
- }
- }
- if (endstr) {
- *endstr = str - 1;
- }
- return sign == '-' ? -sum : sum;
-}
-
-/* convert a string to a number (integer or real).
- * 1. skip \s*[\+\-]?\d*
- * 2. matched [.eE]? yes: real, no: integer.
- **/
-BERRY_API const char *be_str2num(bvm *vm, const char *str)
-{
- const char *sout;
- bint c, vint = be_str2int(str, &sout);
- c = *sout;
- if (c == '.' || c == 'e' || c == 'E') {
- be_pushreal(vm, be_str2real(str, &sout));
- } else {
- be_pushint(vm, vint);
- }
- return sout;
-}
-
-static bstring* string_range(bvm *vm, bstring *str, binstance *range)
-{
- bint lower, upper;
- bint size = str_len(str); /* size of source string */
- /* get index range */
- bvalue temp;
- be_instance_member(vm, range, be_newstr(vm, "__lower__"), &temp);
- lower = var_toint(&temp);
- be_instance_member(vm, range, be_newstr(vm, "__upper__"), &temp);
- upper = var_toint(&temp);
- /* protection scope */
- if (upper < 0) { upper = size + upper; }
- if (lower < 0) { lower = size + lower; }
- upper = upper < size ? upper : size - 1;
- lower = lower < 0 ? 0 : lower;
- if (lower > upper) {
- return be_newstrn(vm, "", 0); /* empty string */
- }
- return be_newstrn(vm, str(str) + lower, upper - lower + 1);
-
-}
-
-/* string subscript operation */
-bstring* be_strindex(bvm *vm, bstring *str, bvalue *idx)
-{
- if (var_isint(idx)) {
- int pos = var_toidx(idx);
- int size = str_len(str);
- if (pos < 0) { pos = size + pos; }
- if ((pos < size) && (pos >= 0)) {
- return be_newstrn(vm, str(str) + pos, 1);
- }
- be_raise(vm, "index_error", "string index out of range");
- } else if (var_isinstance(idx)) {
- binstance * ins = var_toobj(idx);
- const char *cname = str(be_instance_name(ins));
- if (!strcmp(cname, "range")) {
- return string_range(vm, str, ins);
- }
- // str(be_instance_name(i))
- }
- be_raise(vm, "index_error", "string indices must be integers");
- return NULL;
-}
-
-size_t be_strlcpy(char *dst, const char *src, size_t maxlen)
-{
- const size_t srclen = strlen(src);
- if (srclen + 1 < maxlen) {
- memcpy(dst, src, srclen + 1);
- } else if (maxlen != 0) {
- memcpy(dst, src, maxlen - 1);
- dst[maxlen-1] = '\0';
- }
- return srclen;
-}
-
-const char* be_splitpath(const char *path)
-{
- const char *p;
- for (p = path - 1; *path != '\0'; ++path) {
- if (*path == '/') {
- p = path;
- }
- }
- return p + 1; /* return the file name pointer */
-}
-
-const char* be_splitname(const char *path)
-{
- const char *p, *q, *end = path + strlen(path);
- for (p = end; *p != '.' && p > path; --p); /* skip [^\.] */
- for (q = p; *q == '.' && q > path; --q); /* skip \. */
- if ((q == path && *q == '.') || *q == '/') {
- return end;
- }
- return p;
-}
-
-static unsigned escape_length(const char *s, int quote)
-{
- unsigned c, len = 0, step = quote == '"' ? 5 : 3;
- for (; (c = *s) != '\0'; ++s) {
- switch (c) {
- case '\\': case '\n': case '\r': case '\t':
- len += 1;
- break;
- default:
- if (c < 0x20)
- len += step;
- else if (c == (unsigned)quote)
- len += 1;
- break;
- }
- }
- return len;
-}
-
-static unsigned eschex(unsigned num)
-{
- return num <= 9 ? '0' + num : 'a' + num - 10;
-}
-
-/* escape as Berry or JSON */
-static char* escape(char *q, unsigned c, int quote)
-{
- int json = quote == '"';
- switch (c) {
- case '\\': *q++ = '\\'; *q = '\\'; break;
- case '\n': *q++ = '\\'; *q = 'n'; break;
- case '\r': *q++ = '\\'; *q = 'r'; break;
- case '\t': *q++ = '\\'; *q = 't'; break;
- default:
- if (c < 0x20) { /* other characters are escaped using '\uxxxx' */
- *q++ = '\\';
- if (json) {
- *q++ = 'u'; *q++ = '0'; *q++ = '0';
- *q++ = (char)eschex(c >> 4);
- *q = (char)eschex(c & 0x0f);
- } else {
- *q++ = 'x';
- *q++ = (char)eschex(c >> 4);
- *q = (char)eschex(c & 0x0f);
- }
- } else { /* quotes and unescaped characters */
- if (c == (unsigned)quote)
- *q++ = '\\';
- *q = (char)c;
- }
- break;
- }
- return q;
-}
-
-static void toescape(bvm *vm, int index, int quote)
-{
- char *buf, *q;
- const char *p, *s = be_tostring(vm, index);
- size_t len = (size_t)be_strlen(vm, index);
- len += escape_length(s, quote) + 2; /* escape length + quote mark */
- buf = q = be_pushbuffer(vm, len);
- *q++ = (char)quote; /* add first quote */
- /* generate escape string */
- for (p = s; *p != '\0'; ++p, ++q) {
- q = escape(q, *p, quote);
- }
- *q = (char)quote; /* add last quote */
- be_pushnstring(vm, buf, len); /* make escape string from buffer */
- be_moveto(vm, -1, index);
- be_pop(vm, 2); /* remove buffer & top string */
-}
-
-BERRY_API const char* be_toescape(bvm *vm, int index, int mode)
-{
- if (be_isstring(vm, index)) {
- index = be_absindex(vm, index);
- toescape(vm, index, mode == 'u' ? '"' : '\'');
- }
- return be_tostring(vm, index);
-}
-
-#if BE_USE_STRING_MODULE
-
-#define MAX_FORMAT_MODE 32
-#define FLAGES "+- #0"
-
-static const char* skip2dig(const char *s)
-{
- if (is_digit(*s)) {
- ++s;
- }
- if (is_digit(*s)) {
- ++s;
- }
- return s;
-}
-
-static const char* get_mode(const char *str, char *buf, size_t buf_len)
-{
- const char *p = str;
- while (*p && strchr(FLAGES, *p)) { /* skip flags */
- ++p;
- }
- p = skip2dig(p); /* skip width (2 digits at most) */
- if (*p == '.') {
- p = skip2dig(++p); /* skip width (2 digits at most) */
- }
- *(buf++) = '%';
- size_t mode_size = p - str + 1;
- /* Leave 2 bytes for the leading % and the trailing '\0' */
- if (mode_size > buf_len - 2) {
- mode_size = buf_len - 2;
- }
- strncpy(buf, str, mode_size);
- buf[mode_size] = '\0';
- return p;
-}
-
-static void mode_fixlen(char *mode, const char *lenmode)
-{
- size_t l = strlen(mode), lm = strlen(lenmode);
- char spec = mode[l - 1];
- strcpy(mode + l - 1, lenmode);
- mode[l + lm - 1] = spec;
- mode[l + lm] = '\0';
-}
-
-static bbool convert_to_int(bvm *vm, int index, bint *val)
-{
- bbool converted = bfalse;
- if (val == NULL) { return bfalse; }
- if (be_isint(vm, index)) {
- *val = be_toint(vm, index);
- converted = btrue;
- } else {
- be_pushntvfunction(vm, be_baselib_int);
- be_pushvalue(vm, index);
- be_call(vm, 1);
- be_pop(vm, 1);
- if (be_isint(vm, -1)) {
- *val = be_toint(vm, -1);
- converted = btrue;
- }
- be_pop(vm, 1);
- }
- return converted;
-}
-
-static bbool convert_to_real(bvm *vm, int index, breal *val)
-{
- bbool converted = bfalse;
- if (val == NULL) { return bfalse; }
- if (be_isnumber(vm, index)) {
- *val = be_toreal(vm, index);
- converted = btrue;
- } else {
- be_pushntvfunction(vm, be_baselib_real);
- be_pushvalue(vm, index);
- be_call(vm, 1);
- be_pop(vm, 1);
- if (be_isnumber(vm, -1)) {
- *val = be_toreal(vm, -1);
- converted = btrue;
- }
- be_pop(vm, 1);
- }
- return converted;
-}
-
-int be_str_format(bvm *vm)
-{
- int top = be_top(vm);
- if (top > 0 && be_isstring(vm, 1)) {
- int index = 2;
- const char *format = be_tostring(vm, 1);
- pushstr(vm, "", 0);
- for (;;) {
- char mode[MAX_FORMAT_MODE];
- char buf[128];
- const char *p = strchr(format, '%');
- if (p == NULL) {
- break;
- }
- pushstr(vm, format, p - format);
- concat2(vm);
- p = get_mode(p + 1, mode, sizeof(mode));
- buf[0] = '\0';
- if (index > top && *p != '%') {
- be_raise(vm, "runtime_error", be_pushfstring(vm,
- "bad argument #%d to 'format': no value", index));
- }
- switch (*p) {
- case '%':
- be_pushstring(vm, "%");
- --index; /* compensate the future ++index */
- break;
- case 'd': case 'i': case 'o':
- case 'u': case 'x': case 'X':
- {
- bint val;
- if (convert_to_int(vm, index, &val)) {
- mode_fixlen(mode, BE_INT_FMTLEN);
- snprintf(buf, sizeof(buf), mode, val);
- }
- be_pushstring(vm, buf);
- break;
- }
- case 'e': case 'E':
- case 'f': case 'g': case 'G':
- {
- breal val;
- if (convert_to_real(vm, index, &val)) {
- snprintf(buf, sizeof(buf), mode, val);
- }
- be_pushstring(vm, buf);
- break;
- }
- case 'c':
- {
- bint val;
- if (convert_to_int(vm, index, &val)) {
- snprintf(buf, sizeof(buf), "%c", (int)val);
- }
- be_pushstring(vm, buf);
- break;
- }
- case 's': {
- const char *s = be_tostring(vm, index);
- int len = be_strlen(vm, index);
- if (len > 100 && strlen(mode) == 2) {
- be_pushvalue(vm, index);
- } else {
- snprintf(buf, sizeof(buf), mode, s);
- be_pushstring(vm, buf);
- }
- break;
- }
- case 'q': {
- const char *s = be_toescape(vm, index, 'q');
- int len = be_strlen(vm, index);
- if (len > 100 && strlen(mode) == 2) {
- be_pushvalue(vm, index);
- } else {
- snprintf(buf, sizeof(buf), "%s", s);
- be_pushstring(vm, buf);
- }
- break;
- }
- default: /* error */
- be_raise(vm, "runtime_error", be_pushfstring(vm,
- "invalid option '%%%c' to 'format'", *p));
- break;
- }
- concat2(vm);
- format = p + 1;
- ++index;
- }
- pushstr(vm, format, strlen(format));
- concat2(vm);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-/* string.op(s1, s2, begin=0, end=length(s2)) */
-static bint str_operation(bvm *vm, str_opfunc func, bint error)
-{
- int top = be_top(vm);
- /* check the number and type of arguments */
- if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
- /* get the operation string and its length */
- int len1 = be_strlen(vm, 1);
- int len2 = be_strlen(vm, 2);
- const char *s1 = be_tostring(vm, 1);
- const char *s2 = be_tostring(vm, 2);
- /* get begin and end indexes (may use default values) */
- bint begin = top >= 3 && be_isint(vm, 3) ? be_toint(vm, 3) : 0;
- bint end = top >= 4 && be_isint(vm, 4) ? be_toint(vm, 4) : len1;
- /* basic range check:
- * 1. begin position must be greater than 0 and
- * less than the length of the source string.
- * 2. the length of the pattern string cannot be
- * less than the matching range (end - begin).
- **/
- if (begin >= 0 && begin <= len1 && end - begin >= len2) {
- /* call the operation function */
- return func(s1, s2, begin, end - len2);
- }
- }
- return error; /* returns the default error value */
-}
-
-static bint _sfind(const char *s1, const char *s2, bint begin, bint end)
-{
- const char *res = strstr(s1 + begin, s2);
- if (res) {
- bint pos = (bint)(res - s1);
- return pos <= end ? pos : -1;
- }
- return -1;
-}
-
-static int str_find(bvm *vm)
-{
- be_pushint(vm, str_operation(vm, _sfind, -1));
- be_return(vm);
-}
-
-static bint _scount(const char *s1, const char *s2, bint begin, bint end)
-{
- bint count = 0;
- const char *res = s1 + begin, *send = s1 + end;
- while ((res = strstr(res, s2)) != NULL && res <= send) {
- count += 1;
- res += 1;
- }
- return count;
-}
-
-static int str_count(bvm *vm)
-{
- be_pushint(vm, str_operation(vm, _scount, 0));
- be_return(vm);
-}
-
-static bbool _split_string(bvm *vm, int top)
-{
- if (be_isstring(vm, 2)) {
- const char *res;
- int len1 = be_strlen(vm, 1);
- int len2 = be_strlen(vm, 2);
- const char *s1 = be_tostring(vm, 1);
- const char *s2 = be_tostring(vm, 2);
- bint count = len2 /* match when the pattern string is not empty */
- ? top >= 3 && be_isint(vm, 3) ? be_toint(vm, 3) : len1
- : 0; /* cannot match empty pattern string */
- while (count-- && (res = strstr(s1, s2)) != NULL) {
- be_pushnstring(vm, s1, res - s1);
- be_data_push(vm, -2);
- be_pop(vm, 1);
- s1 = res + len2;
- }
- be_pushstring(vm, s1);
- be_data_push(vm, -2);
- be_pop(vm, 1);
- return btrue;
- }
- return bfalse;
-}
-
-static bbool _split_index(bvm *vm)
-{
- if (be_isint(vm, 2)) {
- int len = be_strlen(vm, 1), idx = be_toindex(vm, 2);
- const char *s = be_tostring(vm, 1);
- idx = idx > len ? len : idx < -len ? -len : idx;
- if (idx < 0) {
- idx += len;
- }
- be_pushnstring(vm, s, idx);
- be_data_push(vm, -2);
- be_pop(vm, 1);
- be_pushnstring(vm, s + idx, (size_t)len - idx);
- be_data_push(vm, -2);
- be_pop(vm, 1);
- return btrue;
- }
- return bfalse;
-}
-
-static int str_split(bvm *vm)
-{
- int top = be_top(vm);
- be_newobject(vm, "list");
- if (top >= 2 && be_isstring(vm, 1)) {
- if (!_split_index(vm))
- _split_string(vm, top);
- }
- be_pop(vm, 1);
- be_return(vm);
-}
-
-static int str_i2hex(bvm *vm)
-{
- int top = be_top(vm);
- if (top && be_isint(vm, 1)) {
- bint value = be_toint(vm, 1);
- char fmt[10] = { "%" BE_INT_FMTLEN "X" }, buf[18];
- if (top >= 2 && be_isint(vm, 2)) {
- bint num = be_toint(vm, 2);
- if (num > 0 && num <= 16) {
- snprintf(fmt, sizeof(fmt), "%%.%d" BE_INT_FMTLEN "X", (int)num);
- }
- }
- snprintf(buf, sizeof(buf), fmt, value);
- be_pushstring(vm, buf);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_byte(bvm *vm)
-{
- if (be_top(vm) && be_isstring(vm, 1)) {
- const bbyte *s = (const bbyte *)be_tostring(vm, 1);
- be_pushint(vm, *s);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_char(bvm *vm)
-{
- if (be_top(vm) && be_isint(vm, 1)) {
- char c = be_toint(vm, 1) & 0xFF;
- be_pushnstring(vm, &c, 1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-// boolean to select whether we call toupper() or tolower()
-static int str_touplower(bvm *vm, bbool up)
-{
- if (be_top(vm) && be_isstring(vm, 1)) {
- const char *p, *s = be_tostring(vm, 1);
- size_t len = (size_t)be_strlen(vm, 1);
- char *buf, *q;
- buf = q = be_pushbuffer(vm, len);
- /* convert to lower case */
- for (p = s; *p != '\0'; ++p, ++q) {
- *q = up ? toupper(*p) : tolower(*p);
- }
- be_pushnstring(vm, buf, len); /* make escape string from buffer */
- be_remove(vm, 2); /* remove buffer */
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_tolower(bvm *vm) {
- return str_touplower(vm, bfalse);
-}
-
-static int str_toupper(bvm *vm) {
- return str_touplower(vm, btrue);
-}
-
-static int str_tr(bvm *vm)
-{
- if (be_top(vm) == 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isstring(vm, 3)) {
- const char *p, *s = be_tostring(vm, 1);
- const char *t1 = be_tostring(vm, 2);
- const char *t2 = be_tostring(vm, 3);
- size_t len = (size_t)be_strlen(vm, 1);
- char *buf, *q;
- buf = be_pushbuffer(vm, len);
- /* convert each char */
- for (p = s, q = buf; *p != '\0'; ++p, ++q) {
- const char *p1, *p2;
- *q = *p; /* default to no change */
- for (p1=t1, p2=t2; *p1 != '\0'; ++p1) {
- if (*p == *p1) {
- if (*p2) {
- *q = *p2;
- } else {
- q--; /* remove this char */
- len--;
- }
- break;
- }
- if (*p2) { p2++; }
- }
- }
- be_pushnstring(vm, buf, len); /* make escape string from buffer */
- be_remove(vm, 2); /* remove buffer */
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_replace(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isstring(vm, 3)) {
- be_pushntvfunction(vm, &str_split);
- be_pushvalue(vm, 1);
- be_pushvalue(vm, 2);
- be_call(vm, 2);
- be_pop(vm, 2);
-
- be_getmember(vm, -1, "concat"); /* get `concat` method of list */
- be_pushvalue(vm, -2); /* get list instance as first arg */
- be_pushvalue(vm, 3);
- be_call(vm, 2);
- be_pop(vm, 2);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_escape(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 1 && be_isstring(vm, 1)) {
- int quote = 'u';
- if (top >= 2 && be_isbool(vm, 2)) {
- if (be_tobool(vm, 1)) {
- quote = 'x';
- }
- }
- be_tostring(vm, 1);
- be_toescape(vm, 1, quote);
- be_pushvalue(vm, 1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_startswith(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
- bbool case_insensitive = bfalse;
- if (top >= 3 && be_isbool(vm, 3)) {
- case_insensitive = be_tobool(vm, 3);
- }
- bbool result = bfalse;
- const char *s = be_tostring(vm, 1);
- const char *p = be_tostring(vm, 2);
- size_t len = (size_t)be_strlen(vm, 2);
- if (case_insensitive) {
- if (str_strncasecmp(s, p, len) == 0) {
- result = btrue;
- }
- } else {
- if (strncmp(s, p, len) == 0) {
- result = btrue;
- }
- }
- be_pushbool(vm, result);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int str_endswith(bvm *vm)
-{
- int top = be_top(vm);
- if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
- bbool case_insensitive = bfalse;
- if (top >= 3 && be_isbool(vm, 3)) {
- case_insensitive = be_tobool(vm, 3);
- }
- bbool result = bfalse;
- const char *s = be_tostring(vm, 1);
- const char *p = be_tostring(vm, 2);
- size_t len = (size_t)be_strlen(vm, 2);
- if (case_insensitive) {
- if (str_strncasecmp(s + (int)strlen(s) - (int)len, p, len) == 0) {
- result = btrue;
- }
- } else {
- if (strncmp(s + (int)strlen(s) - (int)len, p, len) == 0) {
- result = btrue;
- }
- }
- be_pushbool(vm, result);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(string) {
- be_native_module_function("format", be_str_format),
- be_native_module_function("count", str_count),
- be_native_module_function("split", str_split),
- be_native_module_function("find", str_find),
- be_native_module_function("hex", str_i2hex),
- be_native_module_function("byte", str_byte),
- be_native_module_function("char", str_char),
- be_native_module_function("tolower", str_tolower),
- be_native_module_function("toupper", str_toupper),
- be_native_module_function("tr", str_tr),
- be_native_module_function("escape", str_escape),
- be_native_module_function("replace", str_replace),
- be_native_module_function("startswith", str_startswith),
- be_native_module_function("endswith", str_endswith),
-};
-
-be_define_native_module(string, NULL);
-#else
-/* @const_object_info_begin
-module string (scope: global, depend: BE_USE_STRING_MODULE) {
- format, func(be_str_format)
- count, func(str_count)
- split, func(str_split)
- find, func(str_find)
- hex, func(str_i2hex)
- byte, func(str_byte)
- char, func(str_char)
- tolower, func(str_tolower)
- toupper, func(str_toupper)
- tr, func(str_tr)
- escape, func(str_escape)
- replace, func(str_replace)
- startswith, func(str_startswith)
- endswith, func(str_endswith)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_string.h"
-#endif
-
-#endif /* BE_USE_STRING_MODULE */
diff --git a/lib/libesp32/Berry/src/be_strlib.h b/lib/libesp32/Berry/src/be_strlib.h
deleted file mode 100644
index 093c37c63877..000000000000
--- a/lib/libesp32/Berry/src/be_strlib.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_STRLIB_H
-#define BE_STRLIB_H
-
-#include "be_object.h"
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bstring* be_strcat(bvm *vm, bstring *s1, bstring *s2);
-int be_strcmp(bstring *s1, bstring *s2);
-bstring* be_num2str(bvm *vm, bvalue *v);
-void be_val2str(bvm *vm, int index);
-int be_char2hex(int c);
-size_t be_strlcpy(char *dst, const char *src, size_t size);
-const char* be_splitpath(const char *path);
-const char* be_splitname(const char *path);
-const char* be_pushvfstr(bvm *vm, const char *format, va_list arg);
-bstring* be_strindex(bvm *vm, bstring *str, bvalue *idx);
-int be_str_format(bvm *vm);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_sys.h b/lib/libesp32/Berry/src/be_sys.h
deleted file mode 100644
index 79a8b3c692e9..000000000000
--- a/lib/libesp32/Berry/src/be_sys.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_SYS_H
-#define BE_SYS_H
-
-#include
-
-/* directory information for directory traversal */
-typedef struct {
- void *dir;
- void *file;
- const char *name;
-} bdirinfo;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void* be_fopen(const char *filename, const char *modes);
-int be_fclose(void *hfile);
-size_t be_fwrite(void *hfile, const void *buffer, size_t length);
-size_t be_fread(void *hfile, void *buffer, size_t length);
-char* be_fgets(void *hfile, void *buffer, int size);
-int be_fseek(void *hfile, long offset);
-long int be_ftell(void *hfile);
-long int be_fflush(void *hfile);
-size_t be_fsize(void *hfile);
-int be_isdir(const char *path);
-int be_isfile(const char *path);
-int be_isexist(const char *path);
-char* be_getcwd(char *buf, size_t size);
-int be_chdir(const char *path);
-int be_mkdir(const char *path);
-int be_unlink(const char *filename);
-int be_dirfirst(bdirinfo *info, const char *path);
-int be_dirnext(bdirinfo *info);
-int be_dirclose(bdirinfo *info);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_syslib.c b/lib/libesp32/Berry/src/be_syslib.c
deleted file mode 100644
index 650db845c445..000000000000
--- a/lib/libesp32/Berry/src/be_syslib.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_object.h"
-
-#if BE_USE_SYS_MODULE
-
-static int m_path(bvm *vm)
-{
- be_getbuiltin(vm, "list");
- be_module_path(vm);
- be_call(vm, 1);
- be_pop(vm, 1);
- be_return(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(sys){
- be_native_module_function("path", m_path)
-};
-
-be_define_native_module(sys, NULL);
-#else
-/* @const_object_info_begin
-module sys (scope: global, depend: BE_USE_SYS_MODULE) {
- path, func(m_path)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_sys.h"
-#endif
-
-#endif /* BE_USE_SYS_MODULE */
diff --git a/lib/libesp32/Berry/src/be_timelib.c b/lib/libesp32/Berry/src/be_timelib.c
deleted file mode 100644
index a7938e4b7669..000000000000
--- a/lib/libesp32/Berry/src/be_timelib.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "berry.h"
-#include
-
-#if BE_USE_TIME_MODULE
-
-static int m_time(bvm *vm)
-{
- be_pushint(vm, (bint)time(NULL));
- be_return(vm);
-}
-
-static void time_insert(bvm *vm, const char *key, int value)
-{
- be_pushstring(vm, key);
- be_pushint(vm, value);
- be_data_insert(vm, -3);
- be_pop(vm, 2);
-}
-
-static int m_dump(bvm *vm)
-{
- if (be_top(vm) >= 1 && be_isint(vm, 1)) {
- time_t ts = be_toint(vm, 1);
- struct tm *t = localtime(&ts);
- be_newobject(vm, "map");
- time_insert(vm, "year", t->tm_year + 1900);
- time_insert(vm, "month", t->tm_mon + 1);
- time_insert(vm, "day", t->tm_mday);
- time_insert(vm, "hour", t->tm_hour);
- time_insert(vm, "min", t->tm_min);
- time_insert(vm, "sec", t->tm_sec);
- time_insert(vm, "weekday", t->tm_wday);
- time_insert(vm, "epoch", ts);
- be_pop(vm, 1);
- be_return(vm);
- }
- be_return_nil(vm);
-}
-
-static int m_clock(bvm *vm)
-{
- be_pushreal(vm, clock() / (breal)CLOCKS_PER_SEC);
- be_return(vm);
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-be_native_module_attr_table(time) {
- be_native_module_function("time", m_time),
- be_native_module_function("dump", m_dump),
- be_native_module_function("clock", m_clock)
-};
-
-be_define_native_module(time, NULL);
-#else
-/* @const_object_info_begin
-module time (scope: global, depend: BE_USE_TIME_MODULE) {
- time, func(m_time)
- dump, func(m_dump)
- clock, func(m_clock)
-}
-@const_object_info_end */
-#include "../generate/be_fixed_time.h"
-#endif
-
-#endif /* BE_USE_TIME_MODULE */
diff --git a/lib/libesp32/Berry/src/be_var.c b/lib/libesp32/Berry/src/be_var.c
deleted file mode 100644
index 1a8e5b18c681..000000000000
--- a/lib/libesp32/Berry/src/be_var.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_var.h"
-#include "be_vm.h"
-#include "be_vector.h"
-#include "be_string.h"
-#include "be_map.h"
-#include "be_gc.h"
-#include "be_class.h"
-#include
-
-#define global(vm) ((vm)->gbldesc.global)
-#define builtin(vm) ((vm)->gbldesc.builtin)
-
-extern BERRY_LOCAL bclass_array be_class_table;
-
-void be_globalvar_init(bvm *vm)
-{
- global(vm).vtab = be_map_new(vm);
- be_gc_fix(vm, gc_object(global(vm).vtab));
- be_vector_init(vm, &global(vm).vlist, sizeof(bvalue));
-#if !BE_USE_PRECOMPILED_OBJECT
- builtin(vm).vtab = be_map_new(vm);
- be_vector_init(vm, &builtin(vm).vlist, sizeof(bvalue));
- be_gc_fix(vm, gc_object(builtin(vm).vtab));
-#endif
-}
-
-void be_globalvar_deinit(bvm *vm)
-{
- global(vm).vtab = NULL;
- be_vector_delete(vm, &global(vm).vlist);
-#if !BE_USE_PRECOMPILED_OBJECT
- builtin(vm).vtab = NULL;
- be_vector_delete(vm, &builtin(vm).vlist);
-#endif
-}
-
-/* This function is called when the global was not found */
-/* If the name looked for matches a static class, a global with the class name is created lazily */
-/* Pre: no global exists with name `name`*/
-/* Returns: idx of newly created global, or -1 if not found */
-static int global_native_class_find(bvm *vm, bstring *name)
-{
- const char* cl_name = str(name);
- bclass_ptr* class_p = &be_class_table[0];
- for (; *class_p; class_p++) {
- const bclass* cl = *class_p;
-
- if (!strcmp(str(cl->name), cl_name)) {
- /* class name matches */
- int idx = be_global_new(vm, name);
- bvalue *v = be_global_var(vm, idx);
- var_setclass(v, (void*) cl);
- return idx;
- }
- }
- return -1;
-}
-
-static int global_find(bvm *vm, bstring *name)
-{
- bvalue *res = be_map_findstr(vm, global(vm).vtab, name);
- if (res) {
- return var_toidx(res) + be_builtin_count(vm);
- }
- return -1; /* not found */
-}
-
-int be_global_find(bvm *vm, bstring *name)
-{
- int res = global_find(vm, name);
- if (res < 0) {
- res = be_builtin_find(vm, name);
- }
- if (res < 0) {
- res = global_native_class_find(vm, name);
- }
- return res;
-}
-
-static int global_new_anonymous(bvm *vm)
-{
- int idx = be_global_count(vm);
- /* allocate space for new variables */
- be_vector_resize(vm, &global(vm).vlist, idx + 1);
- /* set the new variable to nil */
- var_setnil((bvalue *)global(vm).vlist.end);
- return idx;
-}
-
-int be_global_new(bvm *vm, bstring *name)
-{
- int idx = global_find(vm, name);
- if (idx == -1) {
- bvalue *desc;
- idx = global_new_anonymous(vm);
- desc = be_map_insertstr(vm, global(vm).vtab, name, NULL);
- var_setint(desc, idx);
- idx += be_builtin_count(vm);
- }
- return idx;
-}
-
-bvalue* be_global_var(bvm *vm, int index)
-{
- int bcnt = be_builtin_count(vm);
- if (index < bcnt) {
- return be_vector_at(&builtin(vm).vlist, index);
- }
- index -= bcnt;
- return be_vector_at(&global(vm).vlist, index);
-}
-
-void be_global_release_space(bvm *vm)
-{
- be_map_compact(vm, global(vm).vtab);
- be_vector_release(vm, &global(vm).vlist);
-}
-
-int be_builtin_find(bvm *vm, bstring *name)
-{
- bvalue *res = be_map_findstr(vm, builtin(vm).vtab, name);
- if (res) {
- return var_toidx(res);
- }
- return -1; /* not found */
-}
-
-bstring* be_builtin_name(bvm *vm, int index)
-{
- bmap *map = builtin(vm).vtab;
- bmapnode *end, *node = map->slots;
- for (end = node + map->size; node < end; ++node) {
- if (var_isstr(&node->key) && node->value.v.i == index) {
- return node->key.v.s;
- }
- }
- return NULL;
-}
-
-#if !BE_USE_PRECOMPILED_OBJECT
-int be_builtin_new(bvm *vm, bstring *name)
-{
- int idx = be_builtin_find(vm, name);
- if (idx == -1) {
- bvalue *desc;
- idx = be_map_count(builtin(vm).vtab);
- desc = be_map_insertstr(vm, builtin(vm).vtab, name, NULL);
- var_setint(desc, idx);
- be_vector_resize(vm, &builtin(vm).vlist, idx + 1);
- /* set the new variable to nil */
- var_setnil((bvalue*)(builtin(vm).vlist.end));
- }
- return idx;
-}
-
-void be_bulitin_release_space(bvm *vm)
-{
- be_map_compact(vm, builtin(vm).vtab);
- be_vector_release(vm, &builtin(vm).vlist);
-}
-#else
-void be_const_builtin_set(bvm *vm, const bmap *map, const bvector *vec)
-{
- builtin(vm).vtab = cast(bmap*, map);
- builtin(vm).vlist = *vec;
-}
-#endif
diff --git a/lib/libesp32/Berry/src/be_var.h b/lib/libesp32/Berry/src/be_var.h
deleted file mode 100644
index 6b9908a6b7b1..000000000000
--- a/lib/libesp32/Berry/src/be_var.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_VAR_H
-#define BE_VAR_H
-
-#include "be_object.h"
-
-#define be_global_count(vm) \
- be_vector_count(&(vm)->gbldesc.global.vlist)
-
-#define be_builtin_count(vm) \
- be_vector_count(&(vm)->gbldesc.builtin.vlist)
-
-void be_globalvar_init(bvm *vm);
-void be_globalvar_deinit(bvm *vm);
-int be_global_find(bvm *vm, bstring *name);
-int be_global_new(bvm *vm, bstring *name);
-bvalue* be_global_var(bvm *vm, int index);
-void be_global_release_space(bvm *vm);
-int be_builtin_find(bvm *vm, bstring *name);
-bstring* be_builtin_name(bvm *vm, int index);
-int be_builtin_new(bvm *vm, bstring *name);
-void be_bulitin_release_space(bvm *vm);
-void be_const_builtin_set(bvm *vm, const bmap *map, const bvector *vec);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_vector.c b/lib/libesp32/Berry/src/be_vector.c
deleted file mode 100644
index 65ac83350aed..000000000000
--- a/lib/libesp32/Berry/src/be_vector.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_vector.h"
-#include "be_mem.h"
-#include
-
-/* initialize a vector, the vector structure itself is usually allocated
- * on the stack, and the data is allocated from the heap.
- **/
-void be_vector_init(bvm *vm, bvector *vector, int size)
-{
- vector->capacity = 2; /* the default capacity */
- vector->size = size;
- vector->count = 0;
- vector->data = be_malloc(vm, (size_t)vector->capacity * size);
- vector->end = (char*)vector->data - size;
- memset(vector->data, 0, (size_t)vector->capacity * size);
-}
-
-void be_vector_delete(bvm *vm, bvector *vector)
-{
- be_free(vm, vector->data, (size_t)vector->capacity * vector->size);
-}
-
-void* be_vector_at(bvector *vector, int index)
-{
- return (char*)vector->data + (size_t)index * vector->size;
-}
-
-void be_vector_push(bvm *vm, bvector *vector, void *data)
-{
- size_t size = vector->size;
- size_t capacity = vector->capacity;
- size_t count = vector->count++;
- if (count >= capacity) {
- int newcap = be_nextsize(vector->capacity);
- vector->data = be_realloc(vm,
- vector->data, vector->capacity * size, newcap * size);
- vector->end = (char*)vector->data + count * size;
- vector->capacity = newcap;
- } else {
- vector->end = (char*)vector->end + size;
- }
- if (data != NULL) {
- memcpy(vector->end, data, size);
- }
-}
-
-/* clear the expanded portion if the memory expands */
-void be_vector_push_c(bvm *vm, bvector *vector, void *data)
-{
- int capacity = vector->capacity + 1;
- be_vector_push(vm, vector, data);
- if (vector->capacity > capacity) {
- size_t size = ((size_t)vector->capacity - capacity) * vector->size;
- memset(be_vector_at(vector, capacity), 0, size);
- }
-}
-
-void be_vector_remove_end(bvector *vector)
-{
- be_assert(vector->count > 0);
- vector->count--;
- vector->end = (char*)vector->end - vector->size;
-}
-
-void be_vector_resize(bvm *vm, bvector *vector, int count)
-{
- size_t size = vector->size;
- be_assert(count >= 0);
- if (count != be_vector_count(vector)) {
- int newcap = be_nextsize(count);
- if (newcap > vector->capacity) { /* extended capacity */
- vector->data = be_realloc(vm,
- vector->data, vector->capacity * size, newcap * size);
- vector->capacity = newcap;
- }
- vector->count = count;
- if (count == 0) {
- vector->end = (char*)vector->data - size;
- } else {
- vector->end = (char*)vector->data + size * ((size_t)count - 1);
- }
- }
-}
-
-void be_vector_clear(bvector *vector)
-{
- vector->count = 0;
- vector->end = (char*)vector->data - vector->size;
-}
-
-/* free not used */
-void* be_vector_release(bvm *vm, bvector *vector)
-{
- size_t size = vector->size;
- int count = be_vector_count(vector);
- if (count == 0) {
- be_free(vm, vector->data, vector->capacity * size);
- vector->capacity = 0;
- vector->data = NULL;
- vector->end = NULL;
- } else if (count < vector->capacity) {
- vector->data = be_realloc(vm,
- vector->data, vector->capacity * size, count * size);
- vector->end = (char*)vector->data + ((size_t)count - 1) * size;
- vector->capacity = count;
- }
- return vector->data;
-}
-
-/* use binary search to find the vector capacity between 0-1024 */
-static int binary_search(int value)
-{
- static const uint16_t tab[] = {
- 0, 2, 4, 6, 8, 10, 12, 14, 16,
- 20, 24, 28, 32, 40, 48, 64, 96, 128,
- 192, 256, 384, 512, 768, 1024
- };
- const uint16_t *low = tab;
- const uint16_t *high = tab + array_count(tab) - 1;
- while (low <= high) {
- const uint16_t *mid = low + ((high - low) >> 1);
- if (*mid == value) {
- return mid[1];
- }
- if (*mid < value) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- return *low;
-}
-
-static int nextpow(int value)
-{
- value |= value >> 1;
- value |= value >> 2;
- value |= value >> 4;
- value |= value >> 8;
- value |= value >> 16;
- return value + 1;
-}
-
-int be_nextsize(int size)
-{
- if (size < 1024) {
- return binary_search(size);
- }
- return nextpow(size);
-}
diff --git a/lib/libesp32/Berry/src/be_vector.h b/lib/libesp32/Berry/src/be_vector.h
deleted file mode 100644
index 15f399cc6378..000000000000
--- a/lib/libesp32/Berry/src/be_vector.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_VECTOR_H
-#define BE_VECTOR_H
-
-#include "be_object.h"
-
-/* =============================== defines =============================== */
-#define be_vector_data(vector) ((vector)->data)
-#define be_vector_first(vector) ((vector)->data)
-#define be_vector_isend(vector, item) ((item) > (vector)->end)
-#define be_vector_isempty(vector) (!(vector)->count)
-#define be_vector_end(vector) ((vector)->end)
-#define be_vector_count(vector) ((vector)->count)
-#define be_vector_capacity(vector) ((vector)->capacity)
-#define be_stack_init(vm, stack, size) be_vector_init(vm, stack, size)
-#define be_stack_delete(vm, stack) be_vector_delete(vm, stack)
-#define be_stack_clear(stack) be_vector_clear(stack)
-#define be_stack_push(vm, stack, data) be_vector_push(vm, stack, data)
-#define be_stack_pop(stack) be_vector_remove_end(stack)
-#define be_stack_top(stack) be_vector_end(stack)
-#define be_stack_base(stack) be_vector_first(stack)
-#define be_stack_count(stack) be_vector_count(stack)
-#define be_stack_isempty(stack) be_vector_isempty(stack)
-
-/* ========================== function extern ========================== */
-void be_vector_init(bvm *vm, bvector *vector, int size);
-void be_vector_delete(bvm *vm, bvector *vector);
-void* be_vector_at(bvector *vector, int index);
-void be_vector_push(bvm *vm, bvector *vector, void *data);
-void be_vector_push_c(bvm *vm, bvector *vector, void *data);
-void be_vector_remove_end(bvector *vector);
-void be_vector_resize(bvm *vm, bvector *vector, int count);
-void be_vector_clear(bvector *vector);
-void* be_vector_release(bvm *vm, bvector *vector);
-int be_nextsize(int value);
-
-#endif
diff --git a/lib/libesp32/Berry/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c
deleted file mode 100644
index 78fcc486b321..000000000000
--- a/lib/libesp32/Berry/src/be_vm.c
+++ /dev/null
@@ -1,1419 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#include "be_vm.h"
-#include "be_decoder.h"
-#include "be_string.h"
-#include "be_strlib.h"
-#include "be_class.h"
-#include "be_func.h"
-#include "be_vector.h"
-#include "be_list.h"
-#include "be_map.h"
-#include "be_module.h"
-#include "be_mem.h"
-#include "be_var.h"
-#include "be_gc.h"
-#include "be_exec.h"
-#include "be_debug.h"
-#include "be_libs.h"
-#include
-#include
-
-#define NOT_METHOD BE_NONE
-
-#define vm_error(vm, except, ...) \
- be_raise(vm, except, be_pushfstring(vm, __VA_ARGS__))
-
-#define RA() (reg + IGET_RA(ins)) /* Get value of register A */
-#define RKB() ((isKB(ins) ? ktab : reg) + KR2idx(IGET_RKB(ins))) /* Get value of register or constant B */
-#define RKC() ((isKC(ins) ? ktab : reg) + KR2idx(IGET_RKC(ins))) /* Get value of register or constant C */
-
-#define var2cl(_v) cast(bclosure*, var_toobj(_v)) /* cast var to closure */
-#define var2real(_v) (var_isreal(_v) ? (_v)->v.r : (breal)(_v)->v.i) /* get var as real or convert to real if integer */
-#define val2bool(v) ((v) ? btrue : bfalse) /* get var as bool (trur if non zero) */
-#define ibinop(op, a, b) ((a)->v.i op (b)->v.i) /* apply binary operator to both arguments as integers */
-
-#if BE_USE_DEBUG_HOOK
- #define DEBUG_HOOK() \
- if (vm->hookmask & BE_HOOK_LINE) { \
- do_linehook(vm); \
- reg = vm->reg; \
- }
-#else
- #define DEBUG_HOOK()
-#endif
-
-#if BE_USE_PERF_COUNTERS
- #define COUNTER_HOOK() \
- vm->counter_ins++;
-#else
- #define COUNTER_HOOK()
-#endif
-
-#if BE_USE_PERF_COUNTERS
- #define VM_HEARTBEAT() \
- if ((vm->counter_ins & ((1<<(BE_VM_OBSERVABILITY_SAMPLING - 1))-1) ) == 0) { /* call every 2^BE_VM_OBSERVABILITY_SAMPLING instructions */ \
- if (vm->obshook != NULL) \
- (*vm->obshook)(vm, BE_OBS_VM_HEARTBEAT, vm->counter_ins); \
- }
-#else
- #define VM_HEARTBEAT()
-#endif
-
-#define vm_exec_loop() \
- loop: \
- DEBUG_HOOK(); \
- COUNTER_HOOK(); \
- VM_HEARTBEAT(); \
- switch (IGET_OP(ins = *vm->ip++))
-
-#if BE_USE_SINGLE_FLOAT
- #define mathfunc(func) func##f
-#else
- #define mathfunc(func) func
-#endif
-
-#define opcase(opcode) case OP_##opcode
-#define dispatch() goto loop
-
-#define equal_rule(op, iseq) \
- bbool res; \
- be_assert(!var_isstatic(a)); \
- be_assert(!var_isstatic(b)); \
- if (var_isint(a) && var_isint(b)) { \
- res = ibinop(op, a, b); \
- } else if (var_isnumber(a) && var_isnumber(b)) { \
- res = var2real(a) op var2real(b); \
- } else if (var_isinstance(a) && !var_isnil(b)) { \
- res = object_eqop(vm, #op, iseq, a, b); \
- } else if (var_primetype(a) == var_primetype(b)) { /* same types */ \
- if (var_isnil(a)) { /* nil op nil */ \
- res = 1 op 1; \
- } else if (var_isbool(a)) { /* bool op bool */ \
- res = var_tobool(a) op var_tobool(b); \
- } else if (var_isstr(a)) { /* string op string */ \
- res = 1 op be_eqstr(a->v.s, b->v.s); \
- } else if (var_isclass(a) || var_isfunction(a) || var_iscomptr(a)) { \
- res = var_toobj(a) op var_toobj(b); \
- } else { \
- binop_error(vm, #op, a, b); \
- res = bfalse; /* will not be executed */ \
- } \
- } else { /* different types */ \
- res = 1 op 0; \
- } \
- return res
-
-/* when running on ESP32 in IRAM, there is a bug in early chip revision */
-#ifdef ESP32
- #define relop_rule(op) \
- bbool res; \
- if (var_isint(a) && var_isint(b)) { \
- res = ibinop(op, a, b); \
- } else if (var_isnumber(a) && var_isnumber(b)) { \
- /* res = var2real(a) op var2real(b); */ \
- union bvaldata x, y; /* TASMOTA workaround for ESP32 rev0 bug */ \
- x.i = a->v.i;\
- if (var_isint(a)) { x.r = (breal) x.i; }\
- y.i = b->v.i;\
- if (var_isint(b)) { y.r = (breal) y.i; }\
- res = x.r op y.r; \
- } else if (var_isstr(a) && var_isstr(b)) { \
- bstring *s1 = var_tostr(a), *s2 = var_tostr(b); \
- res = be_strcmp(s1, s2) op 0; \
- } else if (var_isinstance(a)) { \
- binstance *obj = var_toobj(a); \
- object_binop(vm, #op, *a, *b); \
- check_bool(vm, obj, #op); \
- res = var_tobool(vm->top); \
- } else { \
- binop_error(vm, #op, a, b); \
- res = bfalse; /* will not be executed */ \
- } \
- return res
-#else // ESP32
- #define relop_rule(op) \
- bbool res; \
- if (var_isint(a) && var_isint(b)) { \
- res = ibinop(op, a, b); \
- } else if (var_isnumber(a) && var_isnumber(b)) { \
- res = var2real(a) op var2real(b); \
- } else if (var_isstr(a) && var_isstr(b)) { \
- bstring *s1 = var_tostr(a), *s2 = var_tostr(b); \
- res = be_strcmp(s1, s2) op 0; \
- } else if (var_isinstance(a)) { \
- binstance *obj = var_toobj(a); \
- object_binop(vm, #op, *a, *b); \
- check_bool(vm, obj, #op); \
- res = var_tobool(vm->top); \
- } else { \
- binop_error(vm, #op, a, b); \
- res = bfalse; /* will not be executed */ \
- } \
- return res
-#endif // ESP32
-
-#define bitwise_block(op) \
- bvalue *dst = RA(), *a = RKB(), *b = RKC(); \
- if (var_isint(a) && var_isint(b)) { \
- var_setint(dst, ibinop(op, a, b)); \
- } else if (var_isinstance(a)) { \
- ins_binop(vm, #op, ins); \
- } else { \
- binop_error(vm, #op, a, b); \
- }
-
-#define push_native(_vm, _f, _ns, _t) { \
- precall(_vm, _f, _ns, _t); \
- _vm->cf->status = PRIM_FUNC; \
-}
-
-static void prep_closure(bvm *vm, int pos, int argc, int mode);
-
-static void attribute_error(bvm *vm, const char *t, bvalue *b, bvalue *c)
-{
- const char *attr = var_isstr(c) ? str(var_tostr(c)) : be_vtype2str(c);
- vm_error(vm, "attribute_error",
- "'%s' value has no %s '%s'", be_vtype2str(b), t, attr);
-}
-
-static void binop_error(bvm *vm, const char *op, bvalue *a, bvalue *b)
-{
- vm_error(vm, "type_error",
- "unsupported operand type(s) for %s: '%s' and '%s'",
- op, be_vtype2str(a), be_vtype2str(b));
-}
-
-static void unop_error(bvm *vm, const char *op, bvalue *a)
-{
- vm_error(vm, "type_error",
- "unsupported operand type(s) for %s: '%s'",
- op, be_vtype2str(a));
-}
-
-static void call_error(bvm *vm, bvalue *v)
-{
- vm_error(vm, "type_error",
- "'%s' value is not callable", be_vtype2str(v));
-}
-
-/* Check that the return value is bool or raise an exception */
-/* `obj` and `method` are only passed for error reporting */
-static void check_bool(bvm *vm, binstance *obj, const char *method)
-{
- if (!var_isbool(vm->top)) {
- const char *name = str(be_instance_name(obj));
- vm_error(vm, "type_error",
- "`%s::%s` return value error, the expected type is 'bool'",
- strlen(name) ? name : "", method);
- }
-}
-
-#if BE_USE_DEBUG_HOOK
-static void do_linehook(bvm *vm)
-{
- bcallframe *cf = vm->cf;
- bclosure *cl = var_toobj(cf->func);
- int pc = cast_int(vm->ip - cl->proto->code);
- if (!pc || pc > cf->lineinfo->endpc) {
- while (pc > cf->lineinfo->endpc)
- cf->lineinfo++;
- be_callhook(vm, BE_HOOK_LINE);
- } else {
- blineinfo *linfo = cf->lineinfo;
- blineinfo *base = cl->proto->lineinfo;
- while (linfo > base && pc <= linfo[-1].endpc)
- linfo--;
- if (cf->lineinfo != linfo) {
- cf->lineinfo = linfo;
- be_callhook(vm, BE_HOOK_LINE);
- }
- }
-}
-#endif
-
-/* Prepare the stack for the function/method call */
-/* `func` is a pointer to the function/method on the stack, it contains the closure before call and the result after the call */
-/* `nstackˋ is the stack depth used by the function (determined by compiler), we add BE_STACK_FREE_MIN as a safety margin */
-static void precall(bvm *vm, bvalue *func, int nstack, int mode)
-{
- bcallframe *cf;
- int expan = nstack + BE_STACK_FREE_MIN; /* `expan` is the minimum required space on the stack */
- if (vm->stacktop < func + expan) { /* do we have too little space left on the stack? */
- size_t fpos = func - vm->stack; /* compute offset of `func` from base stack, in case stack is reallocated and base address changes */
- be_stack_expansion(vm, expan); /* expand stack (vector object), warning stack address changes */
- func = vm->stack + fpos; /* recompute `func` address with new stack address */
- }
- be_stack_push(vm, &vm->callstack, NULL); /* push a NULL value on callstack */
- cf = be_stack_top(&vm->callstack); /* get address of new callframe at top of callstack */
- cf->func = func - mode;
- cf->top = vm->top; /* save previous stack top */
- cf->reg = vm->reg; /* save previous stack base */
- vm->reg = func + 1; /* new stack base is right after function */
- vm->top = vm->reg + nstack; /* new stack top is above the registers used by the function, so we don´t mess with them */
- vm->cf = cf; /* set new current callframe */
-}
-
-/* Prepare call of closure, setting the instruction pointer (ip) */
-static void push_closure(bvm *vm, bvalue *func, int nstack, int mode)
-{
- bclosure *cl = var_toobj(func);
- precall(vm, func, nstack, mode);
- vm->cf->ip = vm->ip;
- vm->cf->status = NONE_FLAG;
- vm->ip = cl->proto->code;
-#if BE_USE_DEBUG_HOOK
- vm->cf->lineinfo = cl->proto->lineinfo;
- be_callhook(vm, BE_HOOK_CALL);
-#endif
-}
-
-static void ret_native(bvm *vm)
-{
- bcallframe *_cf = vm->cf;
- vm->reg = _cf->reg;
- vm->top = _cf->top;
- be_stack_pop(&vm->callstack);
- vm->cf = be_stack_top(&vm->callstack);
-}
-
-static bbool obj2bool(bvm *vm, bvalue *var)
-{
- binstance *obj = var_toobj(var);
- bstring *tobool = str_literal(vm, "tobool");
- /* get operator method */
- int type = be_instance_member(vm, obj, tobool, vm->top);
- if (type != BE_NONE && type != BE_NIL) {
- vm->top[1] = *var; /* move self to argv[0] */
- be_dofunc(vm, vm->top, 1); /* call method 'tobool' */
- /* check the return value */
- check_bool(vm, obj, "tobool");
- return var_tobool(vm->top);
- }
- return btrue;
-}
-
-bbool be_value2bool(bvm *vm, bvalue *v)
-{
- switch (var_basetype(v)) {
- case BE_NIL:
- return bfalse;
- case BE_BOOL:
- return var_tobool(v);
- case BE_INT:
- return val2bool(v->v.i);
- case BE_REAL:
- return val2bool(v->v.r);
- case BE_STRING:
- return str_len(var_tostr(v)) != 0;
- case BE_COMPTR:
- return var_toobj(v) != NULL;
- case BE_COMOBJ:
- return ((bcommomobj*)var_toobj(v))->data != NULL;
- case BE_INSTANCE:
- return obj2bool(vm, v);
- default:
- return btrue;
- }
-}
-
-static void obj_method(bvm *vm, bvalue *o, bstring *attr, bvalue *dst)
-{
- binstance *obj = var_toobj(o);
- int type = be_instance_member_simple(vm, obj, attr, dst);
- if (basetype(type) != BE_FUNCTION) {
- vm_error(vm, "attribute_error",
- "the '%s' object has no method '%s'",
- str(be_instance_name(obj)), str(attr));
- }
-}
-
-static int obj_attribute(bvm *vm, bvalue *o, bstring *attr, bvalue *dst)
-{
- binstance *obj = var_toobj(o);
- int type = be_instance_member(vm, obj, attr, dst);
- if (type == BE_NONE) {
- vm_error(vm, "attribute_error",
- "the '%s' object has no attribute '%s'",
- str(be_instance_name(obj)), str(attr));
- }
- return type;
-}
-
-static int class_attribute(bvm *vm, bvalue *o, bvalue *c, bvalue *dst)
-{
- bstring *attr = var_tostr(c);
- bclass *obj = var_toobj(o);
- int type = be_class_member(vm, obj, attr, dst);
- if (type == BE_NONE || type == BE_INDEX) {
- vm_error(vm, "attribute_error",
- "the '%s' class has no static attribute '%s'",
- str(obj->name), str(attr));
- }
- return type;
-}
-
-static int module_attribute(bvm *vm, bvalue *o, bvalue *c, bvalue *dst)
-{
- bstring *attr = var_tostr(c);
- bmodule *module = var_toobj(o);
- int type = be_module_attr(vm, module, attr, dst);
- if (type == BE_NONE) {
- vm_error(vm, "attribute_error",
- "module '%s' has no member '%s'",
- be_module_name(module), str(attr));
- }
- return type;
-}
-
-static bbool object_eqop(bvm *vm,
- const char *op, bbool iseq, bvalue *a, bvalue *b)
-{
- binstance *o = var_toobj(a);
- bvalue self = *a, other = *b;
- bbool isself = var_isinstance(b) && o == var_toobj(b);
- /* first, try to call the overloaded operator of the object */
- int type = be_instance_member(vm, o, be_newstr(vm, op), vm->top);
- if (basetype(type) == BE_FUNCTION) { /* call method */
- bvalue *top = vm->top;
- top[1] = self; /* move self to argv[0] */
- top[2] = other; /* move other to argv[1] */
- be_incrtop(vm); /* prevent collection results */
- be_dofunc(vm, top, 2); /* call method 'item' */
- be_stackpop(vm, 1);
- check_bool(vm, o, op); /* check return value */
- return var_tobool(vm->top); /* copy result to dst */
- }
- /* the default equal operation rule */
- return iseq == isself; /* check object self */
-}
-
-static void object_binop(bvm *vm, const char *op, bvalue self, bvalue other)
-{
- bvalue *top = vm->top;
- /* get operator method (possible GC) */
- obj_method(vm, &self, be_newstr(vm, op), vm->top);
- top[1] = self; /* move self to argv[0] */
- top[2] = other; /* move other to argv[1] */
- be_incrtop(vm); /* prevent collection results */
- be_dofunc(vm, top, 2); /* call method 'item' */
- be_stackpop(vm, 1);
-}
-
-#define ins_binop(vm, op, ins) { \
- object_binop(vm, op, *RKB(), *RKC()); \
- reg = vm->reg; \
- *RA() = *vm->top; /* copy result to dst */ \
-}
-
-static void ins_unop(bvm *vm, const char *op, bvalue self)
-{
- bvalue *top = vm->top;
- /* get operator method (possible GC) */
- obj_method(vm, &self, be_newstr(vm, op), vm->top);
- top[1] = self; /* move self to argv[0] */
- be_dofunc(vm, top, 1); /* call method 'item' */
-}
-
-bbool be_vm_iseq(bvm *vm, bvalue *a, bvalue *b)
-{
- equal_rule(==, btrue);
-}
-
-bbool be_vm_isneq(bvm *vm, bvalue *a, bvalue *b)
-{
- equal_rule(!=, bfalse);
-}
-
-bbool be_vm_islt(bvm *vm, bvalue *a, bvalue *b)
-{
- relop_rule(<);
-}
-
-bbool be_vm_isle(bvm *vm, bvalue *a, bvalue *b)
-{
- relop_rule(<=);
-}
-
-bbool be_vm_isgt(bvm *vm, bvalue *a, bvalue *b)
-{
- relop_rule(>);
-}
-
-bbool be_vm_isge(bvm *vm, bvalue *a, bvalue *b)
-{
- relop_rule(>=);
-}
-
-static void make_range(bvm *vm, bvalue lower, bvalue upper)
-{
- /* get method 'item' (possible GC) */
- int idx = be_builtin_find(vm, str_literal(vm, "range"));
- bvalue *top = vm->top;
- top[0] = *be_global_var(vm, idx);
- top[1] = lower; /* move lower to argv[0] */
- top[2] = upper; /* move upper to argv[1] */
- vm->top += 3; /* prevent collection results */
- be_dofunc(vm, top, 2); /* call method 'item' */
- vm->top -= 3;
-}
-
-static void connect_str(bvm *vm, bstring *a, bvalue *b)
-{
- bstring *s;
- if (var_isstr(b)) {
- s = be_strcat(vm, a, var_tostr(b));
- var_setstr(vm->top, s);
- } else {
- *vm->top++ = *b;
- be_val2str(vm, -1);
- b = vm->top - 1;
- s = be_strcat(vm, a, var_tostr(b));
- var_setstr(b, s);
- vm->top -= 1;
- }
-}
-
-BERRY_API bvm* be_vm_new(void)
-{
- bvm *vm = be_os_malloc(sizeof(bvm));
- be_assert(vm != NULL);
- memset(vm, 0, sizeof(bvm)); /* clear all members */
- be_gc_init(vm);
- be_string_init(vm);
- be_stack_init(vm, &vm->callstack, sizeof(bcallframe));
- be_stack_init(vm, &vm->refstack, sizeof(binstance*));
- be_stack_init(vm, &vm->exceptstack, sizeof(struct bexecptframe));
- be_stack_init(vm, &vm->tracestack, sizeof(bcallsnapshot));
- vm->stack = be_malloc(vm, sizeof(bvalue) * BE_STACK_START);
- vm->stacktop = vm->stack + BE_STACK_START;
- vm->reg = vm->stack;
- vm->top = vm->reg;
- be_globalvar_init(vm);
- be_gc_setpause(vm, 1);
- be_loadlibs(vm);
- vm->compopt = 0;
- vm->bytesmaxsize = BE_BYTES_MAX_SIZE;
- vm->obshook = NULL;
- vm->ctypefunc = NULL;
-#if BE_USE_PERF_COUNTERS
- vm->counter_ins = 0;
- vm->counter_enter = 0;
- vm->counter_call = 0;
- vm->counter_get = 0;
- vm->counter_set = 0;
- vm->counter_get_global = 0;
- vm->counter_try = 0;
- vm->counter_exc = 0;
- vm->counter_gc_kept = 0;
- vm->counter_gc_freed = 0;
- vm->counter_mem_alloc = 0;
- vm->counter_mem_free = 0;
- vm->counter_mem_realloc = 0;
-#endif
- return vm;
-}
-
-BERRY_API void be_vm_delete(bvm *vm)
-{
- be_gc_deleteall(vm);
- be_string_deleteall(vm);
- be_stack_delete(vm, &vm->callstack);
- be_stack_delete(vm, &vm->refstack);
- be_stack_delete(vm, &vm->exceptstack);
- be_stack_delete(vm, &vm->tracestack);
- be_free(vm, vm->stack, (vm->stacktop - vm->stack) * sizeof(bvalue));
- be_globalvar_deinit(vm);
- be_gc_free_memory_pools(vm);
-#if BE_USE_DEBUG_HOOK
- /* free native hook */
- if (var_istype(&vm->hook, BE_COMPTR))
- be_free(vm, var_toobj(&vm->hook), sizeof(struct bhookblock));
-#endif
- /* free VM structure */
- be_os_free(vm);
-}
-
-static void vm_exec(bvm *vm)
-{
- bclosure *clos;
- bvalue *ktab, *reg;
- binstruction ins;
- vm->cf->status |= BASE_FRAME;
-newframe: /* a new call frame */
- be_assert(var_isclosure(vm->cf->func));
- clos = var_toobj(vm->cf->func); /* `clos` is the current function/closure */
- ktab = clos->proto->ktab; /* `ktab` is the current constant table */
- reg = vm->reg; /* `reg` is the current stack base for the callframe */
-#if BE_USE_PERF_COUNTERS
- vm->counter_enter++;
-#endif
- vm_exec_loop() {
- opcase(LDNIL): {
- var_setnil(RA());
- dispatch();
- }
- opcase(LDBOOL): {
- bvalue *v = RA();
- var_setbool(v, IGET_RKB(ins));
- if (IGET_RKC(ins)) { /* skip next instruction */
- vm->ip += 1;
- }
- dispatch();
- }
- opcase(LDINT): {
- bvalue *v = RA();
- var_setint(v, IGET_sBx(ins));
- dispatch();
- }
- opcase(LDCONST): {
- bvalue *dst = RA();
- *dst = ktab[IGET_Bx(ins)];
- dispatch();
- }
- opcase(GETGBL): {
- bvalue *v = RA();
- int idx = IGET_Bx(ins);
- *v = *be_global_var(vm, idx);
- dispatch();
- }
- opcase(GETNGBL): { /* get Global by name */
-#if BE_USE_PERF_COUNTERS
- vm->counter_get_global++;
-#endif
- bvalue *v = RA();
- bvalue *b = RKB();
- if (var_isstr(b)) {
- bstring *name = var_tostr(b);
- int idx = be_global_find(vm, name);
- if (idx > -1) {
- *v = *be_global_var(vm, idx);
- } else {
- vm_error(vm, "attribute_error", "'%s' undeclared", str(name));
- }
- } else {
- vm_error(vm, "internal_error", "global name must be a string");
- }
- dispatch();
- }
- opcase(SETNGBL): { /* set Global by name */
- bvalue *v = RA();
- bvalue *b = RKB();
- if (var_isstr(b)) {
- bstring *name = var_tostr(b);
- int idx = be_global_new(vm, name);
- *be_global_var(vm, idx) = *v;
- } else {
- vm_error(vm, "internal_error", "global name must be a string");
- }
- dispatch();
- }
- opcase(SETGBL): {
- bvalue *v = RA();
- int idx = IGET_Bx(ins);
- *be_global_var(vm, idx) = *v;
- dispatch();
- }
- opcase(GETUPV): {
- bvalue *v = RA();
- int idx = IGET_Bx(ins);
- be_assert(*clos->upvals != NULL);
- *v = *clos->upvals[idx]->value;
- dispatch();
- }
- opcase(SETUPV): {
- bvalue *v = RA();
- int idx = IGET_Bx(ins);
- be_assert(*clos->upvals != NULL);
- *clos->upvals[idx]->value = *v;
- dispatch();
- }
- opcase(MOVE): {
- bvalue *dst = RA();
- *dst = *RKB();
- dispatch();
- }
- opcase(ADD): {
- bvalue *dst = RA(), *a = RKB(), *b = RKC();
- if (var_isint(a) && var_isint(b)) {
- var_setint(dst, ibinop(+, a, b));
- } else if (var_isnumber(a) && var_isnumber(b)) {
-#ifdef ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
- union bvaldata x, y; // TASMOTA workaround for ESP32 rev0 bug
- x.i = a->v.i;
- if (var_isint(a)) { x.r = (breal) x.i; }
- y.i = b->v.i;
- if (var_isint(b)) { y.r = (breal) y.i; }
- var_setreal(dst, x.r + y.r);
-#else // ESP32
- breal x = var2real(a), y = var2real(b);
- var_setreal(dst, x + y);
-#endif // ESP32
- } else if (var_isstr(a) && var_isstr(b)) { /* strcat */
- bstring *s = be_strcat(vm, var_tostr(a), var_tostr(b));
- reg = vm->reg;
- dst = RA();
- var_setstr(dst, s);
- } else if (var_isinstance(a)) {
- ins_binop(vm, "+", ins);
- } else {
- binop_error(vm, "+", a, b);
- }
- dispatch();
- }
- opcase(SUB): {
- bvalue *dst = RA(), *a = RKB(), *b = RKC();
- if (var_isint(a) && var_isint(b)) {
- var_setint(dst, ibinop(-, a, b));
- } else if (var_isnumber(a) && var_isnumber(b)) {
-#if CONFIG_IDF_TARGET_ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
- union bvaldata x, y; // TASMOTA workaround for ESP32 rev0 bug
- x.i = a->v.i;
- if (var_isint(a)) { x.r = (breal) x.i; }
- y.i = b->v.i;
- if (var_isint(b)) { y.r = (breal) y.i; }
- var_setreal(dst, x.r - y.r);
-#else // CONFIG_IDF_TARGET_ESP32
- breal x = var2real(a), y = var2real(b);
- var_setreal(dst, x - y);
-#endif // CONFIG_IDF_TARGET_ESP32
- } else if (var_isinstance(a)) {
- ins_binop(vm, "-", ins);
- } else {
- binop_error(vm, "-", a, b);
- }
- dispatch();
- }
- opcase(MUL): {
- bvalue *dst = RA(), *a = RKB(), *b = RKC();
- if (var_isint(a) && var_isint(b)) {
- var_setint(dst, ibinop(*, a, b));
- } else if (var_isnumber(a) && var_isnumber(b)) {
-#if CONFIG_IDF_TARGET_ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
- union bvaldata x, y; // TASMOTA workaround for ESP32 rev0 bug
- x.i = a->v.i;
- if (var_isint(a)) { x.r = (breal) x.i; }
- y.i = b->v.i;
- if (var_isint(b)) { y.r = (breal) y.i; }
- var_setreal(dst, x.r * y.r);
-#else // CONFIG_IDF_TARGET_ESP32
- breal x = var2real(a), y = var2real(b);
- var_setreal(dst, x * y);
-#endif // CONFIG_IDF_TARGET_ESP32
- } else if (var_isinstance(a)) {
- ins_binop(vm, "*", ins);
- } else {
- binop_error(vm, "*", a, b);
- }
- dispatch();
- }
- opcase(DIV): {
- bvalue *dst = RA(), *a = RKB(), *b = RKC();
- if (var_isint(a) && var_isint(b)) {
- bint x = var_toint(a), y = var_toint(b);
- if (y == 0) {
- vm_error(vm, "divzero_error", "division by zero");
- } else {
- var_setint(dst, x / y);
- }
- } else if (var_isnumber(a) && var_isnumber(b)) {
-#if CONFIG_IDF_TARGET_ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
- union bvaldata x0, y0; // TASMOTA workaround for ESP32 rev0 bug
- x0.i = a->v.i;
- if (var_isint(a)) { x0.r = (breal) x0.i; }
- y0.i = b->v.i;
- if (var_isint(b)) { y0.r = (breal) y0.i; }
- breal x = x0.r, y = y0.r;
-#else // CONFIG_IDF_TARGET_ESP32
- breal x = var2real(a), y = var2real(b);
-#endif // CONFIG_IDF_TARGET_ESP32
- if (y == cast(breal, 0)) {
- vm_error(vm, "divzero_error", "division by zero");
- } else {
- var_setreal(dst, x / y);
- }
- } else if (var_isinstance(a)) {
- ins_binop(vm, "/", ins);
- } else {
- binop_error(vm, "/", a, b);
- }
- dispatch();
- }
- opcase(MOD): {
- bvalue *dst = RA(), *a = RKB(), *b = RKC();
- if (var_isint(a) && var_isint(b)) {
- bint x = var_toint(a), y = var_toint(b);
- if (y == 0) {
- vm_error(vm, "divzero_error", "division by zero");
- } else {
- var_setint(dst, x % y);
- }
- } else if (var_isnumber(a) && var_isnumber(b)) {
-#if CONFIG_IDF_TARGET_ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
- union bvaldata x0, y0; // TASMOTA workaround for ESP32 rev0 bug
- x0.i = a->v.i;
- if (var_isint(a)) { x0.r = (breal) x0.i; }
- y0.i = b->v.i;
- if (var_isint(b)) { y0.r = (breal) y0.i; }
- breal x = x0.r, y = y0.r;
-#else
- breal x = var2real(a), y = var2real(b);
-#endif
- if (y == cast(breal, 0)) {
- vm_error(vm, "divzero_error", "division by zero");
- } else {
- var_setreal(dst, mathfunc(fmod)(x, y));
- }
- } else if (var_isinstance(a)) {
- ins_binop(vm, "%", ins);
- } else {
- binop_error(vm, "%", a, b);
- }
- dispatch();
- }
- opcase(LT): {
- bbool res = be_vm_islt(vm, RKB(), RKC());
- bvalue *dst;
- reg = vm->reg;
- dst = RA();
- var_setbool(dst, res);
- dispatch();
- }
- opcase(LE): {
- bbool res = be_vm_isle(vm, RKB(), RKC());
- bvalue *dst;
- reg = vm->reg;
- dst = RA();
- var_setbool(dst, res);
- dispatch();
- }
- opcase(EQ): {
- bbool res = be_vm_iseq(vm, RKB(), RKC());
- bvalue *dst;
- reg = vm->reg;
- dst = RA();
- var_setbool(dst, res);
- dispatch();
- }
- opcase(NE): {
- bbool res = be_vm_isneq(vm, RKB(), RKC());
- bvalue *dst;
- reg = vm->reg;
- dst = RA();
- var_setbool(dst, res);
- dispatch();
- }
- opcase(GT): {
- bbool res = be_vm_isgt(vm, RKB(), RKC());
- bvalue *dst;
- reg = vm->reg;
- dst = RA();
- var_setbool(dst, res);
- dispatch();
- }
- opcase(GE): {
- bbool res = be_vm_isge(vm, RKB(), RKC());
- bvalue *dst;
- reg = vm->reg;
- dst = RA();
- var_setbool(dst, res);
- dispatch();
- }
- opcase(CONNECT): {
- bvalue *a = RKB(), *b = RKC();
- if (var_isint(a) && var_isint(b)) {
- make_range(vm, *RKB(), *RKC());
- } else if (var_isstr(a)) {
- connect_str(vm, var_tostr(a), b);
- } else if (var_isinstance(a)) {
- object_binop(vm, "..", *RKB(), *RKC());
- } else {
- binop_error(vm, "..", RKB(), RKC());
- }
- reg = vm->reg;
- *RA() = *vm->top; /* copy result to R(A) */
- dispatch();
- }
- opcase(AND): {
- bitwise_block(&);
- dispatch();
- }
- opcase(OR): {
- bitwise_block(|);
- dispatch();
- }
- opcase(XOR): {
- bitwise_block(^);
- dispatch();
- }
- opcase(SHL): {
- bitwise_block(<<);
- dispatch();
- }
- opcase(SHR): {
- bitwise_block(>>);
- dispatch();
- }
- opcase(NEG): {
- bvalue *dst = RA(), *a = RKB();
- if (var_isint(a)) {
- var_setint(dst, -a->v.i);
- } else if (var_isreal(a)) {
- var_setreal(dst, -a->v.r);
- } else if (var_isinstance(a)) {
- ins_unop(vm, "-*", *RKB());
- reg = vm->reg;
- *RA() = *vm->top; /* copy result to dst */
- } else {
- unop_error(vm, "-", a);
- }
- dispatch();
- }
- opcase(FLIP): {
- bvalue *dst = RA(), *a = RKB();
- if (var_isint(a)) {
- var_setint(dst, ~a->v.i);
- } else if (var_isinstance(a)) {
- ins_unop(vm, "~", *RKB());
- reg = vm->reg;
- *RA() = *vm->top; /* copy result to dst */
- } else {
- unop_error(vm, "~", a);
- }
- dispatch();
- }
- opcase(JMP): {
- vm->ip += IGET_sBx(ins);
- dispatch();
- }
- opcase(JMPT): {
- if (be_value2bool(vm, RA())) {
- vm->ip += IGET_sBx(ins);
- }
- dispatch();
- }
- opcase(JMPF): {
- if (!be_value2bool(vm, RA())) {
- vm->ip += IGET_sBx(ins);
- }
- dispatch();
- }
- opcase(CLOSURE): {
- bvalue *dst;
- bproto *p = clos->proto->ptab[IGET_Bx(ins)];
- bclosure *cl = be_newclosure(vm, p->nupvals);
- cl->proto = p;
- reg = vm->reg;
- dst = RA();
- var_setclosure(dst, cl);
- be_initupvals(vm, cl);
- dispatch();
- }
- opcase(CLASS): {
- bclass *c = var_toobj(ktab + IGET_Bx(ins));
- be_class_upvalue_init(vm, c);
- dispatch();
- }
- opcase(GETMBR): {
-#if BE_USE_PERF_COUNTERS
- vm->counter_get++;
-#endif
- bvalue result; /* copy result to a temp variable because the stack may be relocated in virtual member calls */
- bvalue *b = RKB(), *c = RKC();
- if (var_isinstance(b) && var_isstr(c)) {
- obj_attribute(vm, b, var_tostr(c), &result);
- reg = vm->reg;
- } else if (var_isclass(b) && var_isstr(c)) {
- class_attribute(vm, b, c, &result);
- reg = vm->reg;
- } else if (var_ismodule(b) && var_isstr(c)) {
- module_attribute(vm, b, c, &result);
- reg = vm->reg;
- } else {
- attribute_error(vm, "attribute", b, c);
- result = *RA(); /* avoid gcc warning for uninitialized variable result, this code is never reached */
- }
- bvalue *a = RA();
- *a = result; /* assign the resul to the specified register on the updated stack */
- dispatch();
- }
- opcase(GETMET): {
-#if BE_USE_PERF_COUNTERS
- vm->counter_get++;
-#endif
- bvalue result; /* copy result to a temp variable because the stack may be relocated in virtual member calls */
- bvalue *b = RKB(), *c = RKC();
- if (var_isinstance(b) && var_isstr(c)) {
- binstance *obj = var_toobj(b);
- int type = obj_attribute(vm, b, var_tostr(c), &result);
- reg = vm->reg;
- bvalue *a = RA();
- *a = result;
- if (var_basetype(a) == BE_FUNCTION) {
- if ((type & BE_STATIC) || (type == BE_INDEX)) { /* if instance variable then we consider it's non-method */
- /* static method, don't bother with the instance */
- a[1] = result;
- var_settype(a, NOT_METHOD);
- } else {
- /* this is a real method (i.e. non-static) */
- /* check if the object is a superinstance, if so get the lowest possible subclass */
- while (obj->sub) {
- obj = obj->sub;
- }
- var_setinstance(&a[1], obj); /* replace superinstance by lowest subinstance */
- }
- } else if (var_isclass(a)) {
- /* in this case we have a class in a static or non-static member */
- /* it's always treated like a static function */
- a[1] = result;
- var_settype(a, NOT_METHOD);
- } else {
- vm_error(vm, "attribute_error",
- "class '%s' has no method '%s'",
- str(be_instance_name(obj)), str(var_tostr(c)));
- }
- } else if (var_isclass(b) && var_isstr(c)) {
- class_attribute(vm, b, c, &result);
- reg = vm->reg;
- bvalue *a = RA();
- a[1] = result;
- var_settype(a, NOT_METHOD);
- } else if (var_ismodule(b) && var_isstr(c)) {
- module_attribute(vm, b, c, &result);
- reg = vm->reg;
- bvalue *a = RA();
- a[1] = result;
- var_settype(a, NOT_METHOD);
- } else {
- attribute_error(vm, "method", b, c);
- }
- dispatch();
- }
- opcase(SETMBR): {
-#if BE_USE_PERF_COUNTERS
- vm->counter_set++;
-#endif
- bvalue *a = RA(), *b = RKB(), *c = RKC();
- if (var_isinstance(a) && var_isstr(b)) {
- binstance *obj = var_toobj(a);
- bstring *attr = var_tostr(b);
- bvalue result = *c;
- if (var_isfunction(&result)) {
- var_markstatic(&result);
- }
- if (!be_instance_setmember(vm, obj, attr, &result)) {
- reg = vm->reg;
- vm_error(vm, "attribute_error",
- "class '%s' cannot assign to attribute '%s'",
- str(be_instance_name(obj)), str(attr));
- }
- reg = vm->reg;
- dispatch();
- }
- if (var_isclass(a) && var_isstr(b)) {
- /* if value is a function, we mark it as a static to distinguish from methods */
- bclass *obj = var_toobj(a);
- bstring *attr = var_tostr(b);
- bvalue result = *c;
- if (var_isfunction(&result)) {
- var_markstatic(&result);
- }
- if (!be_class_setmember(vm, obj, attr, &result)) {
- reg = vm->reg;
- vm_error(vm, "attribute_error",
- "class '%s' cannot assign to static attribute '%s'",
- str(be_class_name(obj)), str(attr));
- }
- reg = vm->reg;
- dispatch();
- }
- if (var_ismodule(a) && var_isstr(b)) {
- bmodule *obj = var_toobj(a);
- bstring *attr = var_tostr(b);
- if (be_module_setmember(vm, obj, attr, c)) {
- reg = vm->reg;
- dispatch();
- } else {
- reg = vm->reg;
- // fall through exception below
- }
- }
- attribute_error(vm, "writable attribute", a, b);
- dispatch();
- }
- opcase(GETIDX): {
- bvalue *b = RKB(), *c = RKC();
- if (var_isinstance(b)) {
- bvalue *top = vm->top;
- /* get method 'item' */
- obj_method(vm, b, str_literal(vm, "item"), vm->top);
- top[1] = *b; /* move object to argv[0] */
- top[2] = *c; /* move key to argv[1] */
- vm->top += 3; /* prevent collection results */
- be_dofunc(vm, top, 2); /* call method 'item' */
- vm->top -= 3;
- reg = vm->reg;
- *RA() = *vm->top; /* copy result to R(A) */
- } else if (var_isstr(b)) {
- bstring *s = be_strindex(vm, var_tostr(b), c);
- reg = vm->reg;
- var_setstr(RA(), s);
- } else {
- vm_error(vm, "type_error",
- "value '%s' does not support subscriptable",
- be_vtype2str(b));
- }
- dispatch();
- }
- opcase(SETIDX): {
- bvalue *a = RA(), *b = RKB(), *c = RKC();
- if (var_isinstance(a)) {
- bvalue *top = vm->top;
- /* get method 'setitem' */
- obj_method(vm, a, str_literal(vm, "setitem"), vm->top);
- top[1] = *a; /* move object to argv[0] */
- top[2] = *b; /* move key to argv[1] */
- top[3] = *c; /* move src to argv[2] */
- vm->top += 4;
- be_dofunc(vm, top, 3); /* call method 'setitem' */
- vm->top -= 4;
- reg = vm->reg;
- } else {
- vm_error(vm, "type_error",
- "value '%s' does not support index assignment",
- be_vtype2str(a));
- }
- dispatch();
- }
- opcase(SETSUPER): {
- bvalue *a = RA(), *b = RKB();
- if (var_isclass(a) && var_isclass(b)) {
- bclass *obj = var_toobj(a);
- if (!gc_isconst(obj)) {
- be_class_setsuper(obj, var_toobj(b));
- } else {
- vm_error(vm, "internal_error",
- "cannot change superclass of a read-only class");
- }
- } else {
- vm_error(vm, "type_error",
- "value '%s' does not support set super",
- be_vtype2str(b));
- }
- dispatch();
- }
- opcase(CLOSE): {
- be_upvals_close(vm, RA());
- dispatch();
- }
- opcase(IMPORT): {
- bvalue *b = RKB();
- if (var_isstr(b)) {
- bstring *name = var_tostr(b);
- int res = be_module_load(vm, name);
- reg = vm->reg;
- switch (res) {
- case BE_OK: /* find the module */
- be_stackpop(vm, 1);
- *RA() = *vm->top;
- break;
- case BE_EXCEPTION: /* pop the exception value and message */
- be_pop(vm, 2);
- be_throw(vm, BE_EXCEPTION);
- break;
- default:
- vm_error(vm, "import_error", "module '%s' not found", str(name));
- }
- } else {
- vm_error(vm, "type_error",
- "import '%s' does not support import",
- be_vtype2str(b));
- }
- dispatch();
- }
- opcase(CATCH): {
- bvalue *base = RA(), *top = vm->top;
- int i = 0, ecnt = IGET_RKB(ins), vcnt = IGET_RKC(ins);
- while (i < ecnt && !be_vm_iseq(vm, top, base + i)) {
- ++i;
- }
- if (!ecnt || i < ecnt) { /* exception catched */
- base = RA(), top = vm->top;
- for (i = 0; i < vcnt; ++i) {
- *base++ = *top++;
- }
- vm->ip += 1; /* skip next instruction */
- }
- dispatch();
- }
- opcase(RAISE): {
- if (IGET_RA(ins) < 2) { /* A==2 means no arguments are passed to RAISE, i.e. rethrow with current exception */
- bvalue *top = vm->top;
- top[0] = *RKB(); /* push the exception value to top */
- if (IGET_RA(ins)) { /* has exception argument? */
- top[1] = *RKC(); /* push the exception argument to top + 1 */
- } else {
- var_setnil(top + 1);
- }
- be_save_stacktrace(vm);
- }
- be_throw(vm, BE_EXCEPTION); /* throw / rethrow the exception */
- dispatch();
- }
- opcase(EXBLK): {
-#if BE_USE_PERF_COUNTERS
- vm->counter_try++;
-#endif
- if (!IGET_RA(ins)) {
- be_except_block_setup(vm);
- if (be_setjmp(vm->errjmp->b)) {
- bvalue *top = vm->top;
- bvalue e1 = top[0];
- bvalue e2 = top[1];
- be_except_block_resume(vm);
- top = vm->top;
- top[0] = e1;
- top[1] = e2;
- goto newframe;
- }
- reg = vm->reg;
- } else {
- be_except_block_close(vm, IGET_Bx(ins));
- }
- dispatch();
- }
- opcase(CALL): {
-#if BE_USE_PERF_COUNTERS
- vm->counter_call++;
-#endif
- bvalue *var = RA(); /* `var` is the register for the call followed by arguments */
- int mode = 0, argc = IGET_RKB(ins); /* B contains number of arguments pushed on stack */
- recall: /* goto: instantiation class and call constructor */
- switch (var_type(var)) {
- case NOT_METHOD:
- var[0] = var[1];
- ++var, --argc, mode = 1;
- goto recall;
- case BE_CLASS:
- if (be_class_newobj(vm, var_toobj(var), var - reg, ++argc, mode)) { /* instanciate object and find constructor */
- reg = vm->reg + mode; /* constructor found */
- mode = 0;
- var = RA() + 1; /* to next register */
- reg = vm->reg;
- goto recall; /* call constructor */
- }
- break;
- case BE_INSTANCE: {
- bvalue *v = var + argc++, temp;
- /* load the '()' method to `temp' */
- obj_method(vm, var, str_literal(vm, "()"), &temp);
- for (; v >= var; --v) v[1] = v[0];
- *var = temp;
- goto recall; /* call '()' method */
- }
- case BE_CLOSURE: {
- prep_closure(vm, var - reg, argc, mode);
- reg = vm->reg; /* `reg` has changed, now new base register */
- goto newframe; /* continue execution of the closure */
- }
- case BE_NTVCLOS: {
- bntvclos *f = var_toobj(var);
- push_native(vm, var, argc, mode);
- f->f(vm); /* call C primitive function */
- ret_native(vm);
- break;
- }
- case BE_NTVFUNC: {
- bntvfunc f = var_tontvfunc(var);
- push_native(vm, var, argc, mode);
- f(vm); /* call C primitive function */
- ret_native(vm);
- break;
- }
- case BE_CTYPE_FUNC: {
- if (vm->ctypefunc) {
- push_native(vm, var, argc, mode);
- const void* args = var_toobj(var);
- vm->ctypefunc(vm, args);
- ret_native(vm);
- } else {
- vm_error(vm, "internal_error", "missing ctype_func handler");
- }
- break;
- }
- case BE_MODULE: {
- bvalue attr;
- var_setstr(&attr, str_literal(vm, "()"));
- module_attribute(vm, var, &attr, var); /* exception if not found */
- goto recall; /* call '()' method */
- break;
- }
- default:
- call_error(vm, var);
- }
- reg = vm->reg;
- dispatch();
- }
- opcase(RET): {
- bcallframe *cf;
- bvalue *ret;
-#if BE_USE_DEBUG_HOOK
- be_callhook(vm, BE_HOOK_RET);
-#endif
- cf = vm->cf;
- ret = vm->cf->func;
- /* copy return value */
- if (IGET_RA(ins)) {
- *ret = *RKB();
- } else {
- var_setnil(ret);
- }
- vm->reg = cf->reg;
- vm->top = cf->top;
- vm->ip = cf->ip;
- be_stack_pop(&vm->callstack); /* pop don't delete */
- if (cf->status & BASE_FRAME) { /* entrance function */
- bstack *cs = &vm->callstack;
- if (!be_stack_isempty(cs)) {
- vm->cf = be_stack_top(cs);
- }
- return;
- }
- vm->cf = be_stack_top(&vm->callstack);
- goto newframe;
- }
- }
-}
-
-static void prep_closure(bvm *vm, int pos, int argc, int mode)
-{
- bvalue *v, *end;
- bproto *proto = var2cl(vm->reg + pos)->proto;
- push_closure(vm, vm->reg + pos, proto->nstack, mode);
- end = vm->reg + proto->argc;
- for (v = vm->reg + argc; v <= end; ++v) {
- var_setnil(v);
- }
- int v_offset = v - vm->stack; /* offset from stack base, stack may be reallocated */
- if (proto->varg & BE_VA_VARARG) { /* there are vararg at the last argument, build the list */
- /* code below uses mostly low-level calls for performance */
- be_stack_require(vm, argc + 4); /* make sure we don't overflow the stack */
- int top_save_offset = vm->top - vm->stack; /* save original stack, we need fresh slots to create the 'list' instance */
- vm->top = vm->stack + v_offset; /* move top of stack right after last argument */
- be_newobject(vm, "list"); /* this creates 2 objects on stack: list instance, BE_LIST object */
- blist *list = var_toobj(vm->top-1); /* get low-level BE_LIST structure */
- v = vm->reg + proto->argc - 1; /* last argument */
- for (; v < vm->reg + argc; v++) {
- be_list_push(vm, list, v); /* push all varargs into list */
- }
- *(vm->reg + proto->argc - 1) = *(vm->top-2); /* change the vararg argument to now contain the list instance */
- vm->top = vm->stack + top_save_offset; /* restore top of stack pointer */
- }
-}
-
-static void do_closure(bvm *vm, int pos, int argc)
-{
- // bvalue *v, *end;
- // bproto *proto = var2cl(reg)->proto;
- // push_closure(vm, reg, proto->nstack, 0);
- // v = vm->reg + argc;
- // end = vm->reg + proto->argc;
- // for (; v <= end; ++v) {
- // var_setnil(v);
- // }
- prep_closure(vm, pos, argc, 0);
- vm_exec(vm);
-}
-
-static void do_ntvclos(bvm *vm, int pos, int argc)
-{
- bntvclos *f = var_toobj(vm->reg + pos);
- push_native(vm, vm->reg + pos, argc, 0);
- f->f(vm); /* call C primitive function */
- ret_native(vm);
-}
-
-static void do_ntvfunc(bvm *vm, int pos, int argc)
-{
- bntvfunc f = var_tontvfunc(vm->reg + pos);
- push_native(vm, vm->reg + pos, argc, 0);
- f(vm); /* call C primitive function */
- ret_native(vm);
-}
-
-static void do_cfunc(bvm *vm, int pos, int argc)
-{
- if (vm->ctypefunc) {
- const void* args = var_toobj(vm->reg + pos);
- push_native(vm, vm->reg + pos, argc, 0);
- vm->ctypefunc(vm, args);
- ret_native(vm);
- } else {
- vm_error(vm, "internal_error", "missing ctype_func handler");
- }
-}
-
-static void do_class(bvm *vm, int pos, int argc)
-{
- if (be_class_newobj(vm, var_toobj(vm->reg + pos), pos, ++argc, 0)) {
- be_incrtop(vm);
- be_dofunc(vm, vm->reg + pos + 1, argc);
- be_stackpop(vm, 1);
- }
-}
-
-void be_dofunc(bvm *vm, bvalue *v, int argc)
-{
- be_assert(vm->reg <= v && v < vm->stacktop);
- be_assert(vm->stack <= vm->reg && vm->reg < vm->stacktop);
- int pos = v - vm->reg;
- be_assert(!var_isstatic(v));
- switch (var_type(v)) {
- case BE_CLASS: do_class(vm, pos, argc); break;
- case BE_CLOSURE: do_closure(vm, pos, argc); break;
- case BE_NTVCLOS: do_ntvclos(vm, pos, argc); break;
- case BE_NTVFUNC: do_ntvfunc(vm, pos, argc); break;
- case BE_CTYPE_FUNC: do_cfunc(vm, pos, argc); break;
- default: call_error(vm, v);
- }
-}
-
-/* Default empty constructor */
-int be_default_init_native_function(bvm *vm)
-{
- int argc = be_top(vm);
- if (argc >= 1) {
- be_pushvalue(vm, 1);
- } else {
- be_pushnil(vm);
- }
- be_return(vm);
-}
-
-BERRY_API void be_set_obs_hook(bvm *vm, bobshook hook)
-{
- (void)vm; /* avoid comiler warning */
- (void)hook; /* avoid comiler warning */
-
- vm->obshook = hook;
-}
-
-BERRY_API void be_set_obs_micros(bvm *vm, bmicrosfnct micros)
-{
- vm->microsfnct = micros;
-}
-
-BERRY_API void be_set_ctype_func_hanlder(bvm *vm, bctypefunc handler)
-{
- vm->ctypefunc = handler;
-}
-
-BERRY_API bctypefunc be_get_ctype_func_hanlder(bvm *vm)
-{
- return vm->ctypefunc;
-}
diff --git a/lib/libesp32/Berry/src/be_vm.h b/lib/libesp32/Berry/src/be_vm.h
deleted file mode 100644
index 5953a46251a1..000000000000
--- a/lib/libesp32/Berry/src/be_vm.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/********************************************************************
-** Copyright (c) 2018-2020 Guan Wenliang
-** This file is part of the Berry default interpreter.
-** skiars@qq.com, https://github.com/Skiars/berry
-** See Copyright Notice in the LICENSE file or at
-** https://github.com/Skiars/berry/blob/master/LICENSE
-********************************************************************/
-#ifndef BE_VM_H
-#define BE_VM_H
-
-#include "be_object.h"
-
-#define comp_is_named_gbl(vm) ((vm)->compopt & (1<compopt |= (1<compopt &= ~(1<compopt & (1<compopt |= (1<compopt &= ~(1<compopt & (1<compopt |= (1<compopt &= ~(1<
-#include
-
-#include "berry_conf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @def BERRY_VERSION
- * @brief do not modify the version number!
- *
- */
-#define BERRY_VERSION "1.1.0"
-
-#if BE_STACK_TOTAL_MAX < BE_STACK_FREE_MIN * 2
-#error "The value of the macro BE_STACK_TOTAL_MAX is too small."
-#endif
-
-#if BE_INTGER_TYPE == 0
- #define BE_INTEGER int /**< BE_INTEGER */
- #define BE_INT_FMTLEN "" /**< BE_INT_FMTLEN */
-#elif BE_INTGER_TYPE == 1
- #define BE_INTEGER long /**< BE_INTEGER */
- #define BE_INT_FMTLEN "l" /**< BE_INT_FMTLEN */
-#elif BE_INTGER_TYPE == 2
-#ifdef _WIN32
- #define BE_INTEGER __int64 /**< BE_INTEGER */
- #define BE_INT_FMTLEN "I64" /**< BE_INT_FMTLEN */
- #else
-#define BE_INTEGER long long /**< BE_INTEGER */
-#define BE_INT_FMTLEN "ll" /**< BE_INT_FMTLEN*/
-#endif
-#else
- #error "Unsupported integer type for `bint`."
-#endif
-#define BE_INT_FORMAT "%" BE_INT_FMTLEN "d" /**< BE_INT_FORMAT */
-
-typedef uint8_t bbyte; /**< bbyte */
-typedef BE_INTEGER bint; /**< bint */
-
-#if BE_USE_SINGLE_FLOAT != 0
- typedef float breal; /**< breal */
-#else
-typedef double breal; /**< breal */
-#endif
-
-
-
-#ifndef __cplusplus
-#define bbool _Bool /**< bbool */
-#define bfalse 0 /**< bfalse */
-#define btrue 1 /**< btrue */
-#else
- #define bbool bool /**< bbool */
- #define bfalse false /**< bfalse */
- #define btrue true /**< btrue */
-#endif
-
-/**
- * @enum berrorcode
- * @brief error code definition
- *
- */
-enum berrorcode {
- BE_OK = 0, /**< BE_OK */
- BE_EXIT, /**< BE_EXIT */
- BE_MALLOC_FAIL, /**< BE_MALLOC_FAIL */
- BE_EXCEPTION, /**< BE_EXCEPTION */
- BE_SYNTAX_ERROR, /**< BE_SYNTAX_ERROR */
- BE_EXEC_ERROR, /**< BE_EXEC_ERROR */
- BE_IO_ERROR /**< BE_IO_ERROR */
-};
-
-/**
- * @{ \name native-module member type specifier.
- */
-/**
- * \brief native-module member type specifier.
- *
- */
-#define BE_CNIL 0 /**< BE_CNIL */
-#define BE_CINT 1 /**< BE_CINT */
-#define BE_CREAL 2 /**< BE_CREAL */
-#define BE_CBOOL 3 /**< BE_CBOOL */
-#define BE_CFUNCTION 4 /**< BE_CFUNCTION */
-#define BE_CSTRING 5 /**< BE_CSTRING */
-#define BE_CMODULE 6 /**< BE_CMODULE */
-/**
- * @}
- */
-
-
-/**
- * @def BERRY_API
- * @brief API function mark
- *
- */
-#if defined(_WIN32) || defined(__CYGWIN__) /* in Windows */
- #if defined(BERRY_MODULE) /* berry extension module */
- #define BERRY_API __declspec(dllimport)
- #else /* berry core */
- #define BERRY_API __declspec(dllexport)
- #endif
-#else /* other platforms */
- #define BERRY_API extern
-#endif
-
-/**
- * @{ \name only linux.
- */
-/**
- * \brief only linux
- *
- */
-#if defined(_WIN32) || defined(__CYGWIN__) /* in Windows */
- #define BERRY_LOCAL /**< BERRY_LOCAL */
-#elif defined(__GNUC__) /* in GCC */
-#define BERRY_LOCAL __attribute__ ((visibility ("hidden"))) /**< BERRY_LOCAL */
-#else /* other platforms */
- #define BERRY_LOCAL /**< BERRY_LOCAL */
-#endif
-
-#ifdef __cplusplus
-#ifdef __cpp_constexpr
- #define BE_CONSTEXPR constexpr /**< BE_CONSTEXPR */
-#else
- #define BE_CONSTEXPR /**< BE_CONSTEXPR */
-#endif
-#endif
-
-#ifdef __cplusplus
-#define BE_EXPORT_VARIABLE extern "C" /**< BE_EXPORT_VARIABLE */
-#else
-#define BE_EXPORT_VARIABLE /**< BE_EXPORT_VARIABLE */
-#endif
-/**
- * @}
- */
-
-/**
- * @brief virtual machine structure
- */
-typedef struct bvm bvm;
-
-typedef int (*bntvfunc)(bvm*); /**< native function pointer */
-
-/**
- * @struct bclass
- * @brief bclass
- */
-struct bclass;
-
-/**
- * @struct bnfuncinfo
- * @brief native function information
- *
- */
-typedef struct {
- const char *name; /**< name */
- bntvfunc function; /**< function */
-} bnfuncinfo;
-
-/**
- * @struct bntvmodobj
- * @brief bntvmodobj
- *
- */
-typedef struct bntvmodobj {
- const char *name; /**< name */
- int type; /**< type */
- union value /**< value */
- {
- bint i; /**< i */
- breal r; /**< r */
- bbool b; /**< b */
- bntvfunc f; /**< f */
- const char *s; /**< s */
- const void *o; /**< o */
-#ifdef __cplusplus
- BE_CONSTEXPR value(bint v) : i(v) {} /**< i */
- BE_CONSTEXPR value(breal v) : r(v) {} /**< r */
- BE_CONSTEXPR value(bbool v) : b(v) {} /**< b */
- BE_CONSTEXPR value(bntvfunc v) : f(v) {} /**< f */
- BE_CONSTEXPR value(const char *v) : s(v) {} /**< s */
- BE_CONSTEXPR value(const void *v) : o(v) {} /**< o */
-#endif
- } u; /**< u */
-#ifdef __cplusplus
- BE_CONSTEXPR bntvmodobj(const char *name) :
- name(name), type(BE_CNIL), u(bint(0)) {} /**< bntvmodobj */
- BE_CONSTEXPR bntvmodobj(const char *name, bint v) :
- name(name), type(BE_CINT), u(v) {} /**< bntvmodobj */
- BE_CONSTEXPR bntvmodobj(const char *name, breal v) :
- name(name), type(BE_CREAL), u(v) {} /**< bntvmodobj */
- BE_CONSTEXPR bntvmodobj(const char *name, bbool v) :
- name(name), type(BE_CBOOL), u(v) {} /**< bntvmodobj */
- BE_CONSTEXPR bntvmodobj(const char *name, bntvfunc v) :
- name(name), type(BE_CFUNCTION), u(v) {} /**< bntvmodobj */
- BE_CONSTEXPR bntvmodobj(const char *name, const char *v) :
- name(name), type(BE_CSTRING), u(v) {} /**< bntvmodobj */
- BE_CONSTEXPR bntvmodobj(const char *name, int _tpye, const void *v) :
- name(name), type(_tpye), u(v) {} /**< bntvmodobj */
-#endif
-} bntvmodobj_t; /**< bntvmodobj_t */
-
-/**
- * @struct bntvmodule
- * @brief bntvmodule
- *
- */
-typedef struct bntvmodule {
- const char *name; /**< native module name */
- const bntvmodobj_t *attrs; /**< native module attributes */
- size_t size; /**< native module attribute count */
- const struct bmodule *module; /**< const module object */
-} bntvmodule_t; /**< bntvmodule_t */
-
-/**
- * @struct bclass
- * @brief native class object
- */
-struct bclass;
-
-/**
- * @brief we need only the pointer to `bclass` here
- */
-typedef const struct bclass *bclass_ptr;
-
-/**
- * @brief array of bclass* pointers, NULL terminated
- */
-typedef bclass_ptr bclass_array[];
-
-/**
- * @def be_native_module_nil
- * @brief native module node definition macro
- *
- */
-#ifndef __cplusplus
-#define be_native_module_nil(_name) \
- { .name = (_name), .type = BE_CNIL, .u.i = 0 }
-
-/**
- * @def be_native_module_int
- * @brief be_native_module_int
- *
- */
-#define be_native_module_int(_name, _v) \
- { .name = (_name), .type = BE_CINT, .u.i = (bint)(_v) }
-
-/**
- * @def be_native_module_real
- * @brief be_native_module_real
- *
- */
-#define be_native_module_real(_name, _v) \
- { .name = (_name), .type = BE_CREAL, .u.r = (breal)(_v) }
-
-/**
- * @def be_native_module_bool
- * @brief be_native_module_bool
- *
- */
-#define be_native_module_bool(_name, _b) \
- { .name = (_name), .type = BE_CBOOL, .u.b = (bbool)(_b) }
-
-/**
- * @def be_native_module_function
- * @brief be_native_module_function
- *
- */
-#define be_native_module_function(_name, _f) \
- { .name = (_name), .type = BE_CFUNCTION, .u.f = (_f) }
-
-/**
- * @def be_native_module_str
- * @brief be_native_module_str
- *
- */
-#define be_native_module_str(_name, _s) \
- { .name = (_name), .type = BE_CSTRING, .u.s = (_s) }
-
-/**
- * @def be_native_module_module
- * @brief be_native_module_module
- *
- */
-#define be_native_module_module(_name, _m) \
- { .name = (_name), .type = BE_CMODULE, .u.o = &(_m) }
-#else
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_nil(_name) \
- bntvmodobj(_name)
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_int(_name, _v) \
- bntvmodobj(_name, bint(_v))
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_real(_name, _v) \
- bntvmodobj(_name, breal(_v))
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_bool(_name, _b) \
- bntvmodobj(_name, bbool(_b))
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_function(_name, _f) \
- bntvmodobj(_name, _f)
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_str(_name, _s) \
- bntvmodobj(_name, _s)
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_module(_name, _m) \
- bntvmodobj(_name, BE_CMODULE, &(_m))
-#endif
-
-/**
- * @def be_native_module_attr_table
- * @brief be_native_module_attr_table
- *
- */
-#define be_native_module_attr_table(name) \
- static const bntvmodobj name##_attrs[] =
-
-/**
- * @def be_native_module
- * @brief be_native_module
- *
- */
-#define be_native_module(name) be_native_module_##name
-
-/**
- * @def be_native_class
- * @brief be_native_class
- *
- */
-#define be_native_class(name) be_class_##name
-
-/**
- * @def be_extern_native_module
- * @brief native module declaration macro
- *
- */
-#define be_extern_native_module(name) \
- extern const bntvmodule_t be_native_module(name)
-
-/**
- * @def be_extern_native_class
- * @brief native class declaration macro
- *
- */
-#define be_extern_native_class(name) \
- extern const struct bclass be_native_class(name)
-
-/**
- * @def be_define_native_module
- * @brief native module definition macro
- *
- */
-#ifndef __cplusplus
-#define be_define_native_module(_name, _init) \
- const bntvmodule be_native_module(_name) = { \
- .name = #_name, \
- .attrs = _name##_attrs, \
- .size = sizeof(_name##_attrs) \
- / sizeof(_name##_attrs[0]), \
- .module = NULL, \
- .init = _init \
- }
-#else
-#define be_define_native_module(_name, _init) \
- const bntvmodule be_native_module(_name) = { \
- #_name, _name##_attrs, \
- sizeof(_name##_attrs) \
- / sizeof(_name##_attrs[0]), \
- 0, _init \
- }
-#endif
-
-/**
- * @def be_define_local_const_str
- * @brief support for solidified berry functions
- * native const strings outside of global string hash
- *
- */
-#define be_define_local_const_str(_name, _s, _hash, _len) \
- static const bcstring be_local_const_str_##_name = { \
- .next = (bgcobject *)NULL, \
- .type = BE_STRING, \
- .marked = GC_CONST, \
- .extra = 0, \
- .slen = _len, \
- .hash = 0, \
- .s = _s \
- }
-
-/**
- * @def be_nested_const_str
- * @brief new version for more compact literals
- *
- */
-#define be_nested_const_str(_s, _hash, _len) \
- (bstring*) &(const bcstring) { \
- .next = (bgcobject *)NULL, \
- .type = BE_STRING, \
- .marked = GC_CONST, \
- .extra = 0, \
- .slen = _len, \
- .hash = 0, \
- .s = _s \
- }
-
-/**
- * @def be_local_const_str
- * @brief be_local_const_str
- *
- */
-#define be_local_const_str(_name) (bstring*) &be_local_const_str_##_name
-
-#define BE_IIF(cond) BE_IIF_ ## cond /**< conditional macro see https://stackoverflow.com/questions/11632219/c-preprocessor-macro-specialisation-based-on-an-argument */
-#define BE_IIF_0(t, f) f /**< conditional macro see https://stackoverflow.com/questions/11632219/c-preprocessor-macro-specialisation-based-on-an-argument */
-#define BE_IIF_1(t, f) t /**< conditional macro see https://stackoverflow.com/questions/11632219/c-preprocessor-macro-specialisation-based-on-an-argument */
-
-/**
- * @def be_local_const_upval
- * @brief be_local_const_upval
- *
- */
-#if BE_DEBUG_VAR_INFO
- #define be_local_const_upval(ins, idx) { "", ins, idx }
-#else
- #define be_local_const_upval(ins, idx) { ins, idx }
-#endif
-
-/**
- * @def BE_DEBUG_SOURCE_FILE
- * @brief conditional block in bproto depending on compilation options
- *
- */
-#if BE_DEBUG_SOURCE_FILE
- #define PROTO_SOURCE_FILE(n) \
- ((bstring*) n), /**< source */
- #define PROTO_SOURCE_FILE_STR(n) \
- be_local_const_str(n##_str_source), /**< source */
-#else
- #define PROTO_SOURCE_FILE(n)
- #define PROTO_SOURCE_FILE_STR(n)
-#endif
-
-/**
- * @def PROTO_RUNTIME_BLOCK
- * @brief conditional block in bproto depending on compilation options
- *
- */
-#if BE_DEBUG_RUNTIME_INFO
- #define PROTO_RUNTIME_BLOCK \
- NULL, /**< lineinfo */ \
- 0, /**< nlineinfo */
-#else
- #define PROTO_RUNTIME_BLOCK
-#endif
-
-/**
- * @def PROTO_VAR_INFO_BLOCK
- * @brief PROTO_VAR_INFO_BLOCK
- *
- */
-#if BE_DEBUG_VAR_INFO
- #define PROTO_VAR_INFO_BLOCK \
- NULL, /**< varinfo */ \
- 0, /**< nvarinfo */
-#else
- #define PROTO_VAR_INFO_BLOCK
-#endif
-
-/**
- * @def be_define_local_proto
- * @brief define bproto
- *
- */
-#define be_define_local_proto(_name, _nstack, _argc, _is_const, _is_subproto, _is_upval) \
- static const bproto _name##_proto = { \
- NULL, /**< bgcobject *next */ \
- BE_PROTO, /**< type BE_PROTO */ \
- 0x08, /**< marked outside of GC */ \
- (_nstack), /**< nstack */ \
- BE_IIF(_is_upval)(sizeof(_name##_upvals)/sizeof(bupvaldesc),0), /**< nupvals */ \
- (_argc), /**< argc */ \
- 0, /**< varg */ \
- sizeof(_name##_code)/sizeof(uint32_t), /**< codesize */ \
- BE_IIF(_is_const)(sizeof(_name##_ktab)/sizeof(bvalue),0), /**< nconst */ \
- BE_IIF(_is_subproto)(sizeof(_name##_subproto)/sizeof(bproto*),0), /**< proto */ \
- NULL, /**< bgcobject *gray */ \
- BE_IIF(_is_upval)((bupvaldesc*)&_name##_upvals,NULL), /**< bupvaldesc *upvals */ \
- BE_IIF(_is_const)((bvalue*)&_name##_ktab,NULL), /**< ktab */ \
- BE_IIF(_is_subproto)((struct bproto**)&_name##_subproto,NULL), /**< bproto **ptab */ \
- (binstruction*) &_name##_code, /**< code */ \
- be_local_const_str(_name##_str_name), /**< name */ \
- PROTO_SOURCE_FILE_STR(_name) /**< source */ \
- PROTO_RUNTIME_BLOCK /**< */ \
- PROTO_VAR_INFO_BLOCK /**< */ \
- }
-
-/**
- * @def be_nested_proto
- * @brief new version for more compact literals
- *
- */
-#define be_nested_proto(_nstack, _argc, _varg, _has_upval, _upvals, _has_subproto, _protos, _has_const, _ktab, _fname, _source, _code) \
- & (const bproto) { \
- NULL, /**< bgcobject *next */ \
- BE_PROTO, /**< type BE_PROTO */ \
- 0x08, /**< marked outside of GC */ \
- (_nstack), /**< nstack */ \
- BE_IIF(_has_upval)(sizeof(*_upvals)/sizeof(bupvaldesc),0), /**< nupvals */ \
- (_argc), /**< argc */ \
- (_varg), /**< varg */ \
- sizeof(*_code)/sizeof(binstruction), /**< codesize */ \
- BE_IIF(_has_const)(sizeof(*_ktab)/sizeof(bvalue),0), /**< nconst */ \
- BE_IIF(_has_subproto)(sizeof(*_protos)/sizeof(bproto*),0), /**< proto */ \
- NULL, /**< bgcobject *gray */ \
- (bupvaldesc*) _upvals, /**< bupvaldesc *upvals */ \
- (bvalue*) _ktab, /**< ktab */ \
- (struct bproto**) _protos, /**< bproto **ptab */ \
- (binstruction*) _code, /**< code */ \
- ((bstring*) _fname), /**< name */ \
- PROTO_SOURCE_FILE(_source) /**< source */ \
- PROTO_RUNTIME_BLOCK /**< */ \
- PROTO_VAR_INFO_BLOCK /**< */ \
- }
-
-/**
- * @def be_define_local_closure
- * @brief be_define_local_closure
- *
- */
-#define be_define_local_closure(_name) \
- const bclosure _name##_closure = { \
- NULL, /**< bgcobject *next */ \
- BE_CLOSURE, /**< type BE_CLOSURE */ \
- GC_CONST, /**< marked GC_CONST */ \
- 0, /**< nupvals */ \
- NULL, /**< bgcobject *gray */ \
- (bproto*) &_name##_proto, /**< proto */ \
- { NULL } /**< upvals */ \
- }
-
-/**
- * @def be_local_closure
- * @brief new version for more compact literals
- *
- */
-#define be_local_closure(_name, _proto) \
- static const bclosure _name##_closure = { \
- NULL, /**< bgcobject *next */ \
- BE_CLOSURE, /**< type BE_CLOSURE */ \
- GC_CONST, /**< marked GC_CONST */ \
- 0, /**< nupvals */ \
- NULL, /**< bgcobject *gray */ \
- (bproto*) _proto, /**< proto */ \
- { NULL } /**< upvals */ \
- }
-
-/**
- * @{ \name debug hook typedefs.
- */
-/**
- * \brief debug hook typedefs.
- *
- */
-#define BE_HOOK_LINE 1 /**< BE_HOOK_LINE */
-#define BE_HOOK_CALL 2 /**< BE_HOOK_CALL */
-#define BE_HOOK_RET 4 /**< BE_HOOK_RET */
-#define BE_HOOK_EXCEPT 8 /**< BE_HOOK_EXCEPT */
-/**
- * @}
- */
-
-/**
- * @struct bhookinfo
- * @brief bhookinfo
- *
- */
-typedef struct bhookinfo {
- int type; /**< current hook type */
- int line; /**< current line number */
- const char *source; /**< source path information */
- const char *func_name; /**< current function name */
- void *data; /**< user extended data */
-} bhookinfo_t; /**< bhookinfo_ */
-
-/**
- * @fn void (*bntvhook)(bvm *vm, bhookinfo *info)
- * @brief void (*bntvhook)(bvm *vm, bhookinfo *info)
- *
- * @param vm virtual machine instance
- * @param info
- */
-typedef void (*bntvhook)(bvm *vm, bhookinfo_t *info);
-
-/**
- * @def be_assert
- * @brief the default assert definition
- *
- */
-#if !BE_DEBUG
-#if defined(be_assert)
-#undef be_assert
-#endif
-#define be_assert(expr) ((void)0)
-#endif
-
-/**
- * @fn void (*bobshook)(bvm *vm, int event, ...)
- * @brief Observability hook
- *
- * @param vm virtual machine instance
- * @param event
- */
-typedef void (*bobshook)(bvm *vm, int event, ...);
-typedef uint32_t(*bmicrosfnct)(void);
-
-/**
- * @enum beobshookevents
- * @brief beobshookevents
- *
- */
-enum beobshookevents {
- BE_OBS_PCALL_ERROR, /**< called when be_callp() returned an error, most likely an exception */
- BE_OBS_GC_START, /**< start of GC, arg = allocated size */
- BE_OBS_GC_END, /**< end of GC, arg = allocated size */
- BE_OBS_VM_HEARTBEAT, /**< VM heartbeat called every million instructions */
- BE_OBS_STACK_RESIZE_START, /**< Berry stack resized */
- BE_OBS_MALLOC_FAIL, /**< Memory allocation failed */
-};
-
-typedef int (*bctypefunc)(bvm*, const void*); /**< bctypefunc */
-
-/**
- * @def be_writestring
- * @note FFI function
- * @brief be_writestring
- *
- */
-#define be_writestring(s) be_writebuffer((s), strlen(s))
-
-/**
- * @def be_writenewline
- * @note FFI function
- * @brief be_writenewline
- *
- */
-#define be_writenewline() be_writebuffer("\n", 1)
-
-/**
- * @def be_return
- * @note FFI function
- * @brief be_return
- *
- * @param vm virtual machine instance virtual machine instance
- */
-#define be_return(vm) return be_returnvalue(vm)
-
-/**
- * @def be_return_nil
- * @note FFI function
- * @brief be_return_nil
- *
- * @param vm virtual machine instance virtual machine instance
- */
-#define be_return_nil(vm) return be_returnnilvalue(vm)
-
-/**
- * @def be_loadfile
- * @note FFI function
- * @brief be_loadfile
- *
- * @param vm virtual machine instance virtual machine instance
- * @param name (???)
- */
-#define be_loadfile(vm, name) be_loadmode((vm), (name), 0)
-
-/**
- * @def be_loadmodule
- * @note FFI function
- * @brief be_loadmodule
- *
- * @param vm virtual machine instance virtual machine instance
- * @param name
- *
- */
-#define be_loadmodule(vm, name) be_loadmode((vm), (name), 1)
-
-/**
- * @def be_loadstring
- * @note FFI function
- * @brief be_loadstring
- *
- * @param vm virtual machine instance virtual machine instance
- * @param str (???)
- *
- */
-#define be_loadstring(vm, str) \
- be_loadbuffer((vm), "string", (str), strlen(str))
-
-/**
- * @def be_dostring
- * @note FFI function
- * @brief be_dostring
- *
- * @param vm virtual machine instance virtual machine instance
- * @param s (???)
- *
- */
-#define be_dostring(vm, s) \
- (be_loadstring((vm), (s)) || be_pcall((vm), 0))
-
-/**
- * @fn bint be_str2int(const char*, const char**)
- * @note FFI function
- * @brief (???)
- *
- * @param str (???)
- * @param endstr (???)
- * @return (???)
- */
-BERRY_API bint be_str2int(const char *str, const char **endstr);
-
-/**
- * @fn breal be_str2real(const char*, const char**)
- * @note FFI function
- * @brief (???)
- *
- * @param str
- * @param endstr (???)
- * @return (???)
- */
-BERRY_API breal be_str2real(const char *str, const char **endstr);
-
-/**
- * @fn const char* be_str2num(bvm *vm, const char *str)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance virtual machine instance
- * @param str (???)
- * @return (???)
- */
-BERRY_API const char* be_str2num(bvm *vm, const char *str);
-
-/**
- * @fn int be_top(bvm*)
- * @note FFI function
- * @brief returns the absolute index value of the top element in the virtual stack
- *
- * This function returns the absolute index value of the top element in the virtual stack.
- * This value is also the number of elements in the virtual stack (the capacity of the virtual stack).
- * Call this function before adding or subtracting elements in the virtual stack to get the number of parameters of the native function.
- *
- * @param vm virtual machine instance virtual machine instance
- * @return (???)
- */
-BERRY_API int be_top(bvm *vm);
-
-/**
- * @fn const char* be_typename(bvm *vm, int index)
- * @note FFI function
- * @brief converts the type of the Berry object into a string and returns it
- *
- * This function converts the type of the Berry object into a string and returns it.
- * For example, it returns "int" for an integer object, and "function" for a function object.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index index of the object to be operated
- * @return string corresponding to the parameter type (see: baselib_type)
- */
-BERRY_API const char* be_typename(bvm *vm, int index);
-
-/**
- * @fn const char* be_classname(bvm *vm, int index)
- * @note FFI function
- * @brief converts the type of the Berry object into a string and returns it.
- *
- * This function converts the type of the Berry object into a string and returns it.
- * For example, it returns "int" for an integer object, and "function" for a function object
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index index of the object to be operated
- * @return string corresponding to the parameter type (see: baselib_type)
- */
-BERRY_API const char* be_classname(bvm *vm, int index);
-
-/**
- * @fn bool be_classof(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index (???)
- * @return (???)
- */
-BERRY_API bbool be_classof(bvm *vm, int index);
-
-/**
- * @fn int be_strlen(bvm*, int)
- * @note FFI function
- * @brief length of the specified Berry string
- *
- * This function returns the number of bytes in the string at index
- * (the ’\0’ characters at the end of the Berry string are not counted).
- * If the value of the index position is not a string, the be_strlen function will return 0.
- * Although the Berry string is compatible with the C string format,
- * it is not recommended to use the strlen function of the C standard library to measure the length of the Berry string.
- * For Berry strings, be_strlen is faster than strlen and has better compatibility.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index index of the object to be operated
- * @return length
- */
-BERRY_API int be_strlen(bvm *vm, int index);
-
-/**
- * @fn void be_strconcat(bvm*, int)
- * @note FFI function
- * @brief splice two Berry strings
- *
- * This function will concatenate the string at the parameter position of index with the string at the top position of the stack,
- * and then put the resulting string into the position indexed by index.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index (???)
- */
-BERRY_API void be_strconcat(bvm *vm, int index);
-
-/**
- * @fn void be_pop(bvm*, int)
- * @note FFI function
- * @brief pops the value at the top of the stack
- *
- * Note that the value of n cannot exceed the capacity of the stack.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param n number of values to be popped
- */
-BERRY_API void be_pop(bvm *vm, int n);
-
-/**
- * @fn void be_remove(bvm*, int)
- * @note FFI function
- * @brief remove a value from the stack
- *
- * After the value at index is moved out, the following values will be filled forward,
- * and the stack capacity will be reduced by one.
- * The value of index cannot exceed the capacity of the stack.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index the object to be removed
- */
-BERRY_API void be_remove(bvm *vm, int index);
-
-/**
- * @fn int be_absindex(bvm*, int)
- * @note FFI function
- * @brief absolute index value of a given index value
- *
- * If index is positive, the return value is the value of index.
- * If index is negative, the return value of textttbe_absindex is the absolute index value corresponding to index.
- * When index is a negative value (relative index), its index position cannot be lower than the bottom of the stack.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index index value
- * @return absolute index
- */
-BERRY_API int be_absindex(bvm *vm, int index);
-
-/**
- * @fn bool be_isnil(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is nil
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is nil,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isnil(bvm *vm, int index);
-
-/**
- * @fn bool be_isbool(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is bool
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is bool,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isbool(bvm *vm, int index);
-
-/**
- * @fn bool be_isint(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is int
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is int,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isint(bvm *vm, int index);
-
-/**
- * @fn bool be_isreal(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is real
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is real,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isreal(bvm *vm, int index);
-
-/**
- * @fn bool be_isnumber(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is number
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is number,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isnumber(bvm *vm, int index);
-
-/**
- * @fn bool be_isstring(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is string
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is string,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isstring(bvm *vm, int index);
-
-/**
- * @fn bool be_isclosure(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is closure
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is closure,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isclosure(bvm *vm, int index);
-
-/**
- * @fn bool be_isntvclos(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is primitive closure type
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is primitive closure type,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isntvclos(bvm *vm, int index);
-
-/**
- * @fn bool be_isfunction(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is function
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is function,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isfunction(bvm *vm, int index);
-
-/**
- * @fn bool be_isproto(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is proto
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is proto,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isproto(bvm *vm, int index);
-
-/**
- * @fn bool be_isclass(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is class
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is class,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isclass(bvm *vm, int index);
-
-/**
- * @fn bool be_isinstance(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is instance
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is instance,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isinstance(bvm *vm, int index);
-
-/**
- * @fn bool be_ismapinstance(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is instance
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is
- * an instance of class map (or derived). If it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_ismapinstance(bvm *vm, int index);
-
-/**
- * @fn bool be_ismapinstance(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is instance
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is
- * an instance of class list (or derived). If it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_islistinstance(bvm *vm, int index);
-
-/**
- * @fn bool be_ismodule(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is module
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is module,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_ismodule(bvm *vm, int index);
-
-/**
- * @fn bool be_islist(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is list
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is list,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_islist(bvm *vm, int index);
-
-/**
- * @fn bool be_ismap(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is map
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is map,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_ismap(bvm *vm, int index);
-
-/**
- * @fn bool be_iscomptr(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is universal pointer type
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is universal pointer type,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_iscomptr(bvm *vm, int index);
-
-/**
- * @fn bool be_iscomobj(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_iscomobj(bvm *vm, int index);
-
-/**
- * @fn bool be_isderived(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isderived(bvm *vm, int index);
-
-/**
- * @fn bool be_isbytes(bvm*, int)
- * @note FFI function
- * @brief value in virtual stack is instance or sub-instance of class bytes
- *
- * This function returns whether the value indexed by the parameter index in the virtual stack is instance or sub-instance of class bytes,
- * if it is, it returns 1, otherwise it returns 0
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return true/false
- */
-BERRY_API bbool be_isbytes(bvm *vm, int index);
-
-/**
- * @fn bint be_toint(bvm*, int)
- * @note FFI function
- * @brief virtual stack to integer type
- *
- * Get the value of the index position of index from the virtual stack and return it as an integer type.
- * This function does not check the correctness of the type.
- * If the value is an instance, the method toint() is called if it exists.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index value index
- * @return (???)
- */
-BERRY_API bint be_toint(bvm *vm, int index);
-
-/**
- * @fn breal be_toreal(bvm*, int)
- * @note FFI function
- * @brief virtual stack to floating-point number type
- *
- * Get the value of the index position of index from the virtual stack and return it as an floating-point number type.
- * This function does not check the correctness of the type.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API breal be_toreal(bvm *vm, int index);
-
-/**
- * @fn int be_toindex(bvm*, int)
- * @note FFI function
- * @brief virtual stack to integer type
- *
- * Get the value of the index position of index from the virtual stack and return it as an integer type.
- * This function does not check the correctness of the type.
- * Unlike be_toint, the return value type of be_toindex is int, while the return value of the former is bint.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API int be_toindex(bvm *vm, int index);
-
-/**
- * @fn bool be_tobool(bvm*, int)
- * @note FFI function
- * @brief virtual stack to Boolean type
- *
- * Get the value of the index position of index from the virtual stack and return it as a Boolean type.
- * If the indexed value is not of Boolean type, it will be converted according to the rules in section type_bool,
- * and the conversion process will not cause the indexed value to change.
- * If the value is an instance, the method tobool() is called if it exists.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API bbool be_tobool(bvm *vm, int index);
-
-/**
- * @fn const char* be_tostring(bvm *vm, int index)
- * @note FFI function
- * @brief virtual stack to string
- *
- * Get the value of the index position of index from the virtual stack and return it as a string type.
- * If the indexed value is not a string type, the indexed value will be converted to a string,
- * and the conversion process will replace the value at the indexed position in the virtual stack with the converted string.
- * The string returned by this function always ends with ’\0’ characters.
- * If the value is an instance, the method tostring() is called if it exists.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API const char* be_tostring(bvm *vm, int index);
-
-/**
- * @fn const char* be_toescape(bvm *vm, int index, int mode)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index
- * @param mode
- * @return (???)
- */
-BERRY_API const char* be_toescape(bvm *vm, int index, int mode);
-
-/**
- * @fn void* be_tocomptr(bvm *vm, int index)
- * @note FFI function
- * @brief virtual stack to general pointer
- *
- * Get the value of the index position of index from the virtual stack and return it as a general pointer type.
- * This function does not check the correctness of the type.
- *
- * @param vm virtual machine instance virtual machine instance
- * @param index
- */
-BERRY_API void* be_tocomptr(bvm *vm, int index);
-
-/**
- * @fn void be_moveto(bvm*, int, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance virtual machine instance
- * @param from
- * @param to
- */
-BERRY_API void be_moveto(bvm *vm, int from, int to);
-
-/**
- * @fn void be_pushnil(bvm*)
- * @note FFI function
- * @brief Push a nil value onto the virtual stack.
- *
- * @param vm virtual machine instance
- *
- */
-BERRY_API void be_pushnil(bvm *vm);
-
-/**
- * @fn void be_pushbool(bvm*, int)
- * @note FFI function
- * @brief Push a Boolean value onto the virtual stack
- *
- * Push a Boolean value onto the virtual stack.
- * The parameter b is the boolean value to be pushed onto the stack.
- * When the value is 0, it means false, otherwise it is true.
- *
- * @param vm virtual machine instance
- * @param b
- */
-BERRY_API void be_pushbool(bvm *vm, int b);
-
-/**
- * @fn void be_pushint(bvm*, bint)
- * @note FFI function
- * @brief Push an integer value i onto the virtual stack.
- *
- * @param vm virtual machine instance
- * @param i
- */
-BERRY_API void be_pushint(bvm *vm, bint i);
-
-/**
- * @fn void be_pushreal(bvm*, breal)
- * @note FFI function
- * @brief Push a floating point value r onto the virtual stack.
- *
- * @param vm virtual machine instance
- * @param r
- */
-BERRY_API void be_pushreal(bvm *vm, breal r);
-
-/**
- * @fn void be_pushstring(bvm*, const char*)
- * @note FFI function
- * @brief Push the string str onto the virtual stack.
- *
- * Push the string str onto the virtual stack.
- * The parameter str must point to a C string that ends with a null character ’\0’,
- * and a null pointer cannot be passed in.
- *
- * @param vm virtual machine instance
- * @param str
- */
-BERRY_API void be_pushstring(bvm *vm, const char *str);
-
-/**
- * @fn void be_pushnstring(bvm*, const char*, size_t)
- * @note FFI function
- * @brief Push the string str of length n onto the virtual stack.
- *
- * Push the string str of length n onto the virtual stack.
- * The length of the string is subject to the parameter n,
- * and the null character is not used as the end mark of the string.
- *
- * @param vm virtual machine instance
- * @param str
- * @param n
- */
-BERRY_API void be_pushnstring(bvm *vm, const char *str, size_t n);
-
-/**
- * @fn const char* be_pushfstring(bvm *vm, const char *format, ...)
- * @note FFI function
- * @brief Push the formatted string into the virtual stack.
- *
- * Push the formatted string into the virtual stack.
- * The parameter format is a formatted string, which contains the text to be pushed onto the stack,
- * and the format parameter contains a label,
- * which can be replaced by the value specified by the subsequent additional parameter and formatted as required.
- * According to the label of the format string, a series of additional parameters may be required,
- * and each additional parameter will replace the corresponding % label in the format parameter.
- *
- * @param vm virtual machine instance
- * @param format
- * @return (???)
- */
-BERRY_API const char* be_pushfstring(bvm *vm, const char *format, ...);
-
-/**
- * @fn void* be_pushbuffer(bvm *vm, size_t size)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param size
- */
-BERRY_API void* be_pushbuffer(bvm *vm, size_t size);
-
-/**
- * @fn void be_pushvalue(bvm*, int)
- * @note FFI function
- * @brief Push the value with index index onto the top of the virtual stack.
- *
- * @param vm virtual machine instance
- * @param index
- */
-BERRY_API void be_pushvalue(bvm *vm, int index);
-
-/**
- * @fn void be_pushclosure(bvm*, void*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param cl
- */
-BERRY_API void be_pushclosure(bvm *vm, void *cl);
-
-/**
- * @fn void be_pushntvclosure(bvm*, bntvfunc, int)
- * @note FFI function
- * @brief Push a native closure onto the top of the virtual stack.
- *
- * Push a native closure onto the top of the virtual stack.
- * The parameter f is the C function pointer of the native closure,
- * and nupvals is the upvalue number of the closure.
- *
- * @param vm virtual machine instance
- * @param f
- * @param nupvals
- */
-BERRY_API void be_pushntvclosure(bvm *vm, bntvfunc f, int nupvals);
-
-/**
- * @fn void be_pushntvfunction(bvm*, bntvfunc)
- * @note FFI function
- * @brief Push a native function onto the top of the virtual stack, and the parameter f is the native function pointer.
- *
- * @param vm virtual machine instance
- * @param f
- */
-BERRY_API void be_pushntvfunction(bvm *vm, bntvfunc f);
-
-/**
- * @fn void be_pushclass(bvm*, const char*, const bnfuncinfo*)
- * @note FFI function
- * @brief Push a native class onto the top of the virtual stack
- *
- * Push a native class onto the top of the virtual stack.
- * The parameter name is the name of the native class, and the parameter lib is the attribute description of the native class.
- *
- * @param vm virtual machine instance
- * @param name
- * @param lib
- */
-BERRY_API void be_pushclass(bvm *vm, const char *name, const bnfuncinfo *lib);
-
-/**
- * @fn void be_pushntvclass(bvm*, const struct bclass*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param c
- */
-BERRY_API void be_pushntvclass(bvm *vm, const struct bclass *c);
-
-/**
- * @fn void be_pushcomptr(bvm*, void*)
- * @note FFI function
- * @brief Push a general pointer onto the top of the virtual stack
- *
- * Push a general pointer onto the top of the virtual stack.
- * The general pointer ptr points to a certain C data area.
- * Since the content pointed to by this pointer is not maintained by Berry’s garbage collector,
- * users have to maintain the life cycle of the data themselves.
- *
- * @param vm virtual machine instance
- * @param ptr
- */
-BERRY_API void be_pushcomptr(bvm *vm, void *ptr);
-
-/**
- * @fn bool be_pushiter(bvm*, int)
- * @note FFI function
- * @brief Push an iterator onto the top of the virtual stack.
- *
- * @param vm virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API bbool be_pushiter(bvm *vm, int index);
-
-/**
- * @fn void be_newlist(bvm*)
- * @note FFI function
- * @brief creates a new list value
- *
- * After this function is successfully called, the new list value will be pushed onto the top of the stack.
- * list value is an internal representation of a list, not to be confused with an instance of the list class.
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_newlist(bvm *vm);
-
-/**
- * @fn void be_newmap(bvm*)
- * @note FFI function
- * @brief creates a new map value
- *
- * After this function is successfully called, the new map value will be pushed onto the top of the stack.
- * map value is an internal representation of a list, not to be confused with an instance of the map class.
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_newmap(bvm *vm);
-
-/**
- * @fn void be_newmodule(bvm*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_newmodule(bvm *vm);
-
-/**
- * @fn void be_newcomobj(bvm*, void*, bntvfunc)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param data
- * @param destroy
- */
-BERRY_API void be_newcomobj(bvm *vm, void *data, bntvfunc destroy);
-
-/**
- * @fn void be_newobject(bvm*, const char*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param name
- */
-BERRY_API void be_newobject(bvm *vm, const char *name);
-
-/**
- * @fn bool be_copy(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- * @return
- */
-BERRY_API bbool be_copy(bvm *vm, int index);
-
-/**
- * @fn bool be_setname(bvm*, int, const char*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- * @param name
- * @return (???)
- */
-BERRY_API bbool be_setname(bvm *vm, int index, const char *name);
-
-/**
- * @fn bool be_getglobal(bvm*, const char*)
- * @note FFI function
- * @brief pushes the global variable with the specified name onto the stack
- *
- * After this function is called, the global variable named name will be pushed onto the top of the virtual stack
- *
- * @param vm virtual machine instance
- * @param name
- * @return (???)
- */
-BERRY_API bbool be_getglobal(bvm *vm, const char *name);
-
-/**
- * @fn void be_setglobal(bvm*, const char*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param name
- */
-BERRY_API void be_setglobal(bvm *vm, const char *name);
-
-/**
- * @fn bool be_getbuiltin(bvm*, const char*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param name
- * @return (???)
- */
-BERRY_API bbool be_getbuiltin(bvm *vm, const char *name);
-
-/**
- * @fn bool be_setmember(bvm*, int, const char*)
- * @note FFI function
- * @brief set the value of the member variable of the instance object class
- *
- * This function will copy the value at the top of the stack to the member k of the index position instance.
- * Note that the top element of the stack will not pop up automatically.
- *
- * @param vm virtual machine instance
- * @param index index of the instance object
- * @param k name of the member
- * @return (???)
- */
-BERRY_API bbool be_setmember(bvm *vm, int index, const char *k);
-
-/**
- * @fn bool be_getmember(bvm*, int, const char*)
- * @note FFI function
- * @brief get the value of the member variable of the instance object class
- *
- * This function pushes the value of the member of the index position instance k onto the top of the virtual stack.
- *
- * @param vm virtual machine instance
- * @param index index of the instance object
- * @param k name of the member
- * @return (???)
- */
-BERRY_API bbool be_getmember(bvm *vm, int index, const char *k);
-
-/**
- * @fn bool be_getmethod(bvm*, int, const char*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- * @param k
- * @return (???)
- */
-BERRY_API bbool be_getmethod(bvm *vm, int index, const char *k);
-
-/**
- * @fn bool be_getindex(bvm*, int)
- * @note FFI function
- * @brief get the value of list or map
- *
- * This function is used to get an element from the map or list container (internal values, not instances of map or list classes),
- * and the index of the element is stored at the top of the stack (relative index is − 1).
- * After calling this function, the value obtained from the container will be pushed onto the top of the stack.
- * If there is no subscript pointed to by the container, the value of nil will be pushed onto the top of the stack.
- *
- * @param vm virtual machine instance
- * @param index index of the object to be operated
- * @return (???)
- */
-BERRY_API bbool be_getindex(bvm *vm, int index);
-
-/**
- * @fn bool be_setindex(bvm*, int)
- * @note FFI function
- * @brief set a value in list or map
- *
- * This function is used to write an element of the map or list container.
- * The index of the value to be written in the virtual stack is − 1,
- * and the index of the subscript of the write position in the virtual stack is − 2.
- * If the element with the specified subscript does not exist in the container, the write operation will fail.
- *
- * @param vm virtual machine instance
- * @param index index of the object to be operated
- * @return (???)
- */
-BERRY_API bbool be_setindex(bvm *vm, int index);
-
-/**
- * @fn void be_getupval(bvm*, int, int)
- * @note FFI function
- * @brief read an Up Value of the native closure
- *
- * The read Up Value will be pushed onto the top of the virtual stack.
- *
- * @param vm virtual machine instance
- * @param index the native closure index value of the Up Value to be read
- * @param pos position of the Up Value in the native closure Up Value table (numbering starts from 0)
- */
-BERRY_API void be_getupval(bvm *vm, int index, int pos);
-
-/**
- * @fn bool be_setupval(bvm*, int, int)
- * @note FFI function
- * @brief set an Up Value of the native closure.
- *
- * This function obtains a value from the top of the virtual stack and writes it to the target Up Value.
- * After the operation is completed, the top value of the stack will not be popped from the stack.
- *
- * @param vm virtual machine instance
- * @param index the native closure index value of the Up Value to be read
- * @param pos position of the Up Value in the native closure Up Value table (numbering starts from 0)
- * @return (???)
- */
-BERRY_API bbool be_setupval(bvm *vm, int index, int pos);
-
-/**
- * @fn bool be_setsuper(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API bbool be_setsuper(bvm *vm, int index);
-
-/**
- * @fn void be_getsuper(bvm*, int)
- * @note FFI function
- * @brief get the parent object of the base class or instance of the class.
- *
- * If the value at index is a class with a base class, the function will push its base class onto the top of the stack;
- * if the value at index is an object with a parent object,
- * the function will take its parent The object is pushed onto the top of the stack; otherwise,
- * a value of nil is pushed onto the top of the stack.
- *
- * @param vm virtual machine instance
- * @param index the class or object to be operated
- */
-BERRY_API void be_getsuper(bvm *vm, int index);
-
-/**
- * @fn int be_data_size(bvm*, int)
- * @note FFI function
- * @brief get the number of elements contained in the container
- *
- * If the value at index is a Map value or List value,
- * the function returns the number of elements contained in the container, otherwise it returns -1.
- *
- * @param vm virtual machine instance
- * @param index index of the container object to be operated
- * @return (???)
- */
-BERRY_API int be_data_size(bvm *vm, int index);
-
-/**
- * @fn void be_data_push(bvm*, int)
- * @note FFI function
- * @brief append a new element to the end of the container.
- *
- * The object at index must be a List value.
- * This function gets a value from the top of the stack and appends it to the end of the container.
- * After the operation is completed, the value at the top of the stack will not be popped from the stack.
- *
- * @param vm virtual machine instance
- * @param index index of the container object to be operate
- */
-BERRY_API void be_data_push(bvm *vm, int index);
-
-/**
- * @fn bool be_data_insert(bvm*, int)
- * @note FFI function
- * @brief insert a pair of elements into the container
- *
- * The object at index must be a List value or a Map value.
- * The inserted element forms a pair of key-value pairs.
- * The value is stored at the top of the stack, and the key is stored at the previous index on the top of the stack.
- * It should be noted that the key inserted into the Map container cannot be a nil value,
- * and the key inserted into the List container must be an integer value.
- * If the operation is successful, the function will return bture, otherwise it will return bfalse.
- *
- * @param vm virtual machine instance
- * @param index container object to be operated
- * @return (???)
- */
-BERRY_API bbool be_data_insert(bvm *vm, int index);
-
-/**
- * @fn bool be_data_remove(bvm*, int)
- * @note FFI function
- * @brief remove an element in the container
- *
- * The object at index must be a List value or Map value.
- * For the Map container, the key to delete the element is stored on the top of the virtual stack
- * (need to be pressed before the function call);
- * for the List container, the index of the element to be deleted is stored on the top of the virtual stack
- * (need to be before the function call) push into).
- * If the operation is successful, the function will return bture, otherwise it will return bfalse.
- *
- * @param vm virtual machine instance
- * @param index container object to be operated.
- * @return (???)
- */
-BERRY_API bbool be_data_remove(bvm *vm, int index);
-
-/**
- * @fn bool be_data_merge(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- * @return (???)
- */
-BERRY_API bbool be_data_merge(bvm *vm, int index);
-
-/**
- * @fn void be_data_resize(bvm*, int)
- * @note FFI function
- * @brief reset the capacity of the container
- *
- * This function is only available for List containers, and the new capacity is stored on the top of the virtual stack (must be an integer).
- *
- * @param vm virtual machine instance
- * @param index container object to be operated
- */
-BERRY_API void be_data_resize(bvm *vm, int index);
-
-/**
- * @fn void be_data_reverse(bvm*, int)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- */
-BERRY_API void be_data_reverse(bvm *vm, int index);
-
-/**
- * @fn int be_iter_next(bvm*, int)
- * @note FFI function
- * @brief get the next element of the iterator
- *
- * The iterator object may be an iterator of a List container or a Map container.
- * For the List iterator, this function pushes the iteration result value onto the top of the stack,
- * while for the Map iterator, it pushes the key value into the previous position and the top of the stack respectively.
- * Calling this function will update the iterator.
- * If the function returns 0, the call fails, returning 1 to indicate that the current iterator is a List iterator,
- * and returning 2 to indicate that the current iterator is a Map iterator.
- *
- * @param vm virtual machine instance
- * @param index iterator to be operated
- * @return (???)
- */
-BERRY_API int be_iter_next(bvm *vm, int index);
-
-/**
- * @fn bool be_iter_hasnext(bvm*, int)
- * @note FFI function
- * @brief test whether there is another element in the iterator
- *
- * The iterator object may be an iterator of a List container or a Map container.
- * If there are more iterable elements in the iterator, return 1, otherwise return 0.
- *
- * @param vm virtual machine instance
- * @param index iterator to be operated
- * @return (???)
- */
-BERRY_API bbool be_iter_hasnext(bvm *vm, int index);
-
-/**
- * @fn bool be_refcontains(bvm*, int)
- * @note FFI function
- * @brief test whether there is a reference to the specified object in the reference stack
- *
- * This function is used to test whether there is a reference to the specified object in the reference stack.
- * It must be used in conjunction with be_refpush and be_refpop.
- * This API can avoid recursion when traversing objects that have their own references.
- * This function is used for the value of an instance type.
- * If there is a reference to the object in the reference stack, it returns 1, otherwise it returns 0.
- *
- * @param vm virtual machine instance
- * @param index object to be operated
- * @return (???)
- */
-BERRY_API bbool be_refcontains(bvm *vm, int index);
-
-/**
- * @fn void be_refpush(bvm*, int)
- * @note FFI function
- * @brief Push the reference of the specified object onto the reference stack.
- *
- * This function is used for the value of an instance type.
- *
- * @param vm virtual machine instance
- * @param index object to be operated
- */
-BERRY_API void be_refpush(bvm *vm, int index);
-
-/**
- * @fn void be_refpop(bvm*)
- * @note FFI function
- * @brief Pop the object at the top of the reference stack
- *
- * This function is used in pairs with be_refpush
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_refpop(bvm *vm);
-
-/**
- * @fn void be_stack_require(bvm*, int)
- * @note FFI function
- * @brief tests the amount of free space on the stack and expands the stack space if it is insufficient
- *
- * If the free capacity of the virtual stack allocated by the VM to the native function is lower than this value,
- * an expansion operation will be performed.
- *
- * @param vm virtual machine instance
- * @param count required free stack capacity.
- */
-BERRY_API void be_stack_require(bvm *vm, int count);
-
-/**
- * @fn bool be_getmodule(bvm*, const char*)
- * @note FFI function
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param k
- * @return (???)
- */
-BERRY_API bbool be_getmodule(bvm *vm, const char *k);
-
-/**
- * @fn bool be_iseq(bvm*)
- * @note relop operation API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bbool be_iseq(bvm *vm);
-
-/**
- * @fn bool be_isneq(bvm*)
- * @note relop operation API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bbool be_isneq(bvm *vm);
-
-/**
- * @fn bool be_islt(bvm*)
- * @note relop operation API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bbool be_islt(bvm *vm);
-
-/**
- * @fn bool be_isle(bvm*)
- * @note relop operation API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bbool be_isle(bvm *vm);
-
-/**
- * @fn bool be_isgt(bvm*)
- * @note relop operation API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bbool be_isgt(bvm *vm);
-
-/**
- * @fn bool be_isge(bvm*)
- * @note relop operation API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bbool be_isge(bvm *vm);
-
-/**
- * @fn int be_returnvalue(bvm*)
- * @note Function call/return API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API int be_returnvalue(bvm *vm);
-
-/**
- * @fn int be_returnnilvalue(bvm*)
- * @note Function call/return API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API int be_returnnilvalue(bvm *vm);
-
-/**
- * @fn void be_call(bvm*, int)
- * @note Function call/return API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param argc
- */
-BERRY_API void be_call(bvm *vm, int argc);
-
-/**
- * @fn int be_pcall(bvm*, int)
- * @note Function call/return API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param argc
- * @return (???)
- */
-BERRY_API int be_pcall(bvm *vm, int argc);
-
-/**
- * @fn void be_exit(bvm*, int)
- * @note Function call/return API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param status
- */
-BERRY_API void be_exit(bvm *vm, int status);
-
-/**
- * @fn void be_raise(bvm*, const char*, const char*)
- * @note exception API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param except
- * @param msg
- */
-#ifdef __GNUC__
-__attribute__((noreturn))
-#endif
-BERRY_API void be_raise(bvm *vm, const char *except, const char *msg);
-
-/**
- * @fn int be_getexcept(bvm*, int)
- * @note exception API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param code
- * @return (???)
- */
-BERRY_API int be_getexcept(bvm *vm, int code);
-
-/**
- * @fn void be_dumpvalue(bvm*, int)
- * @note exception API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param index
- */
-BERRY_API void be_dumpvalue(bvm *vm, int index);
-
-/**
- * @fn void be_dumpexcept(bvm*)
- * @note exception API
- * @brief (???)
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_dumpexcept(bvm *vm);
-
-/**
- * @fn void be_stop_iteration(bvm*)
- * @note exception API
- * @brief (???)
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_stop_iteration(bvm *vm);
-
-/**
- * @fn void be_regfunc(bvm*, const char*, bntvfunc)
- * @note exception API
- * @brief register a native function
- *
- * The specific behavior of this function is related to the value of the BE_USE_PRECOMPILED_OBJECT macro
- * (although the FFI is still available when using the compile-time construction technique,
- * it cannot dynamically register the built-in variables.
- * In this case, please refer to the method of registering the built-in objects.
- *
- * @param vm virtual machine instance
- * @param name name of the native function
- * @param f pointer of the native function
- */
-BERRY_API void be_regfunc(bvm *vm, const char *name, bntvfunc f);
-
-/**
- * @fn void be_regclass(bvm*, const char*, const bnfuncinfo*)
- * @note exception API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param name
- * @param lib
- */
-BERRY_API void be_regclass(bvm *vm, const char *name, const bnfuncinfo *lib);
-
-/**
- * @fn bvm* be_vm_new(void)
- * @note VM management API
- * @brief Construct a VM
- *
- * @return (???)
- */
-BERRY_API bvm* be_vm_new(void);
-
-/**
- * @fn void be_vm_delete(bvm*)
- * @note VM management API
- * @brief Destroy a VM
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_vm_delete(bvm *vm);
-
-/**
- * @fn void be_set_obs_hook(bvm*, bobshook)
- * @note Observability hook
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param hook
- */
-BERRY_API void be_set_obs_hook(bvm *vm, bobshook hook);
-BERRY_API void be_set_obs_micros(bvm *vm, bmicrosfnct micros);
-
-
-/**
- * @fn void be_set_ctype_func_hanlder(bvm*, bctypefunc)
- * @note Observability hook
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param handler
- */
-BERRY_API void be_set_ctype_func_hanlder(bvm *vm, bctypefunc handler);
-
-/**
- * @fn bctypefunc be_get_ctype_func_hanlder(bvm*)
- * @note Observability hook
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @return (???)
- */
-BERRY_API bctypefunc be_get_ctype_func_hanlder(bvm *vm);
-
-/**
- * @fn int be_loadbuffer(bvm*, const char*, const char*, size_t)
- * @note code load API
- * @brief load a piece of source code from the buffer and compile it into bytecode
- *
- * f the compilation is successful, be_loadbuffer will compile the source code into a Berry function and place
- * it on the top of the virtual stack. If the compilation encounters an error, be_loadbuffer will return
- * an error value of type berrorcode (Section errorcode), and if possible, will store the
- * specific error message string at the top of the virtual stack.
- *
- * @param vm virtual machine instance
- * @param name string, which is usually used to mark the source of the source code
- * @param buffer buffer for storing the source code
- * @param length length of the buffer
- * @return (???)
- */
-BERRY_API int be_loadbuffer(bvm *vm, const char *name, const char *buffer, size_t length);
-
-/**
- * @fn int be_loadmode(bvm *vm, const char *name, bbool islocal)
- * @note code load API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param name
- * @param islocal
- * @return (???)
- */
-BERRY_API int be_loadmode(bvm *vm, const char *name, bbool islocal);
-
-/**
- * @fn int be_loadlib(bvm*, const char*)
- * @note code load API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param path
- * @return (???)
- */
-BERRY_API int be_loadlib(bvm *vm, const char *path);
-
-/**
- * @fn int be_savecode(bvm*, const char*)
- * @note code load API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param name
- * @return (???)
- */
-BERRY_API int be_savecode(bvm *vm, const char *name);
-
-/**
- * @fn void be_module_path(bvm*)
- * @note module path list API
- * @brief (???)
- *
- * @param vm virtual machine instance
- */
-BERRY_API void be_module_path(bvm *vm);
-
-/**
- * @fn void be_module_path_set(bvm*, const char*)
- * @note module path list API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param path
- */
-BERRY_API void be_module_path_set(bvm *vm, const char *path);
-
-/**
- * @fn void* be_pushbytes(bvm *vm, const void *buf, size_t len)
- * @note bytes operation
- * @brief Push a bytes() buffer
- *
- * @param vm virtual machine instance
- * @param buf starting at position
- * @param len size
- */
-BERRY_API void* be_pushbytes(bvm *vm, const void *buf, size_t len);
-
-/**
- * @fn const void* be_tobytes(bvm *vm, int index, size_t *len)
- * @note bytes operation
- * @brief return virtual stack as a bytes buffer
- *
- * Get the value of the index position of index from the virtual stack and return it as a bytes buffer.
- * The pointer of the buffer is returned, and the size is stored in *len (unless len is NULL).
- * This function works only for instances of the bytes class, or returns NULL.
- *
- * @param vm virtual machine instance
- * @param index index from the virtual stac
- * @param len size
- */
-BERRY_API const void* be_tobytes(bvm *vm, int index, size_t *len);
-
-/**
- * @fn void be_sethook(bvm*, const char*)
- * @note debug API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param mask
- */
-BERRY_API void be_sethook(bvm *vm, const char *mask);
-
-/**
- * @fn void be_setntvhook(bvm*, bntvhook, void*, int)
- * @note debug API
- * @brief (???)
- *
- * @param vm virtual machine instance
- * @param hook
- * @param data
- * @param mask
- */
-BERRY_API void be_setntvhook(bvm *vm, bntvhook hook, void *data, int mask);
-
-/**
- * @fn void be_writebuffer(const char*, size_t)
- * @note basic character IO API
- * @brief implement on berry_port.c
- *
- * Output a piece of data to the standard output device, the parameter
- * `buffer` is the first address of the output data block, and `length` is
- * the length of the output data block. This function outputs to the
- * `stdout` file by default. Inside the interpreter, this function is
- * usually used as a character stream output, not a binary stream.
- *
- * @param buffer
- * @param length
- */
-BERRY_API void be_writebuffer(const char *buffer, size_t length);
-
-/**
- * @fn char* be_readstring(char *buffer, size_t size)
- * @note basic character IO API
- * @brief implement on berry_port.c
- *
- * Input a piece of data from the standard input device, and read at most
- * one row of data each time this function is called. The parameter
- * `buffer` is the data buffer passed in by the caller, and the capacity of
- * the buffer is `size`. This function will stop reading and return when
- * the buffer capacity is used up, otherwise it will return when a newline
- * character or end of file character is read. If the function executes
- * successfully, it will directly use the `buffer` parameter as the return
- * value, otherwise it will return `NULL`.
- *
- * This function will add the read line breaks to the read data, and each
- * time the `be_readstring` function is called, it will continue to read
- * from the current position. This function is only called in the
- * implementation of the native function `input`, and the `be_readstring`
- * function may not be implemented when it is not necessary.
- *
- * @param buffer
- * @param size
- * @return (???)
- */
-BERRY_API char* be_readstring(char *buffer, size_t size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/libesp32/Berry/src/berry_conf.h b/lib/libesp32/Berry/src/berry_conf.h
deleted file mode 100644
index ff5a40419e99..000000000000
--- a/lib/libesp32/Berry/src/berry_conf.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../default/berry_conf.h"
diff --git a/lib/libesp32/Berry/testall.be b/lib/libesp32/Berry/testall.be
deleted file mode 100755
index 57414dbc5bb1..000000000000
--- a/lib/libesp32/Berry/testall.be
+++ /dev/null
@@ -1,44 +0,0 @@
-#! ./berry
-import os
-
-os.system('lcov', '-q -c -i -d . -o init.info')
-
-var exec = './berry'
-var path = 'tests'
-var testcases = os.listdir(path)
-var total = 0, failed = 0
-
-for i : testcases
- if os.path.splitext(i)[1] == '.be'
- print('\033[0;36mrun testcase: ' + i + '\033[0m')
- var ret = os.system(exec, os.path.join(path, i))
- if ret != 0
- print('\033[0;31mreturn code:', ret, '\033[0m')
- failed += 1
- end
- total += 1
- end
-end
-
-print('\033[0;32mtest results: ' +
- str(total) + ' total, ' + str(failed) + ' failed' +
- (failed ? '' : ' (all tests passed)') +
- '.\033[0m')
-
-if failed != 0
- os.exit(-1)
-end
-
-var cmds = [
- 'lcov -q -c -d ./ -o cover.info',
- 'lcov -q -a init.info -a cover.info -o total.info',
- 'lcov --remove total.info */usr/include/* -o final.info',
- 'genhtml -q -o test_report --legend --title "lcov" --prefix=./ final.info',
- 'rm -f init.info cover.info total.info final.info'
-]
-
-for cmd : cmds
- if os.system(cmd)
- os.exit(-1)
- end
-end
diff --git a/lib/libesp32/Berry/tests/assignment.be b/lib/libesp32/Berry/tests/assignment.be
deleted file mode 100644
index 71bb81ebf0a6..000000000000
--- a/lib/libesp32/Berry/tests/assignment.be
+++ /dev/null
@@ -1,34 +0,0 @@
-class Test
- var a
-end
-
-# continuous assignment of global suffix expressions
-o = Test()
-o.a = 100
-assert(o.a == 100)
-o.a += 10
-assert(o.a == 110)
-
-p = Test()
-p.a = Test()
-p.a.a = 50
-assert(p.a.a == 50)
-p.a.a += 10
-assert(p.a.a == 60)
-
-# continuous assignment of local suffix expressions
-def test_func()
- var o = Test()
- o.a = 100
- assert(o.a == 100)
- o.a += 10
- assert(o.a == 110)
-
- var p = Test()
- p.a = Test()
- p.a.a = 50
- assert(p.a.a == 50)
- p.a.a += 10
- assert(p.a.a == 60)
-end
-test_func()
diff --git a/lib/libesp32/Berry/tests/bool.be b/lib/libesp32/Berry/tests/bool.be
deleted file mode 100644
index 2b6bf74746cd..000000000000
--- a/lib/libesp32/Berry/tests/bool.be
+++ /dev/null
@@ -1,53 +0,0 @@
-# test cases for boolean expressions
-
-assert(1 != false && 1 != true)
-assert(0 != false && 0 != true)
-assert(!!1 == true)
-assert(!!0 == false)
-
-a = true
-b = false
-assert(!!list == true)
-assert(a && b == false)
-assert(!(a && b))
-def test(a, b)
- while !(a && b)
- assert(false)
- end
-end
-test(true, true)
-
-# bug in unary
-def f(i)
- var j = !i # bug if i is erroneously modified
- return i
-end
-assert(f(1) == 1)
-
-#- addind bool() function -#
-assert(bool() == false)
-assert(bool(0) == false)
-assert(bool(0.0) == false)
-assert(bool(false) == false)
-assert(bool(nil) == false)
-
-assert(bool(-1) == true)
-assert(bool(3.5) == true)
-assert(bool('') == false) # changed behavior
-assert(bool('a') == true)
-assert(bool(list) == true)
-assert(bool(list()) == false) # changed behavior
-assert(bool([]) == false) # changed behavior
-assert(bool([0]) == true)
-assert(bool(map()) == false) # changed behavior
-assert(bool({}) == false) # changed behavior
-assert(bool({false:false}) == true)
-assert(bool({nil:nil}) == false)# changed behavior - `nil` key is ignored so the map is empty
-
-import introspect
-assert(bool(introspect.toptr(0x1000)) == true)
-assert(bool(introspect.toptr(0)) == false)
-
-# reproduce bug https://github.com/berry-lang/berry/issues/372
-def f() var a = false var b = true || a return a end
-assert(f() == false)
diff --git a/lib/libesp32/Berry/tests/bytes.be b/lib/libesp32/Berry/tests/bytes.be
deleted file mode 100644
index 1f58118e7780..000000000000
--- a/lib/libesp32/Berry/tests/bytes.be
+++ /dev/null
@@ -1,327 +0,0 @@
-def assert_error(f, error_type)
- try
- f()
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == error_type)
- end
-end
-
-#- basic initialization -#
-b=bytes()
-assert(str(b) == "bytes('')")
-b=bytes("")
-assert(str(b) == "bytes('')")
-b=bytes(0)
-assert(str(b) == "bytes('')")
-b=bytes(1)
-assert(str(b) == "bytes('')")
-b=bytes(-1)
-assert(str(b) == "bytes(\'00\')")
-assert(b.size() == 1)
-
-b=bytes("a")
-assert(str(b) == "bytes('')")
-b=bytes(3.5)
-assert(str(b) == "bytes('')")
-b=bytes([])
-assert(str(b) == "bytes('')")
-
-b=bytes("1122AAaaBBbb")
-assert(str(b) == "bytes('1122AAAABBBB')")
-assert(b.size() == 6)
-b=bytes("112")
-assert(str(b) == "bytes('11')")
-b=bytes("++")
-assert(str(b) == "bytes('00')")
-
-#- add -#
-b=bytes()
-b.add(0x22)
-assert(str(b) == "bytes('22')")
-b.add(0x12345678, 0)
-assert(str(b) == "bytes('22')")
-b.add(0x12345678, 1)
-assert(str(b) == "bytes('2278')")
-b.add(0x12345678, 2)
-assert(str(b) == "bytes('22787856')")
-b.add(0x12345678, 4)
-assert(str(b) == "bytes('2278785678563412')")
-b.add(0x12345678, -1) #- big endian -#
-assert(str(b) == "bytes('227878567856341278')")
-b.add(0x12345678, -2)
-assert(str(b) == "bytes('2278785678563412785678')")
-b.add(0x12345678, -4)
-assert(str(b) == "bytes('227878567856341278567812345678')")
-
-#- get -#
-b=bytes("000102030405")
-assert(b.get(0) == 0)
-assert(b.get(-1) == 0x05) #- last byte -#
-assert(b.get(6) == 0)
-assert(b.get(1) == 1)
-assert(b.get(5) == 5)
-assert(b.get(-1000) == 0) # out of range, default to zero
-assert(b.get(1000) == 0) # out of range, default to zero
-
-assert(b.get(1,1) == 0x01)
-assert(b.get(1,2) == 0x0201)
-assert(b.get(1,4) == 0x04030201)
-assert(b.get(1,-1) == 0x01)
-assert(b.get(1,-2) == 0x0102) #- big endian -#
-assert(b.get(1,-4) == 0x01020304)
-assert(b.get(1,0) == 0) # size zero is invalid, returns zero
-assert(b.get(-1000,1) == 0) # out of range, default to zero
-assert(b.get(1000,1) == 0) # out of range, default to zero
-
-#- resize -#
-assert(bytes().size() == 0)
-b=bytes("112233")
-b.resize(2)
-assert(str(b) == "bytes('1122')")
-assert(b.size() == 2)
-b.resize(4)
-assert(str(b) == "bytes('11220000')")
-assert(b.size() == 4)
-b.resize(20)
-assert(str(b) == "bytes('1122000000000000000000000000000000000000')")
-assert(b.size() == 20)
-b.resize(0)
-assert(str(b) == "bytes('')")
-assert(b.size() == 0)
-b=bytes("112233")
-b.resize(-5) # resize negative is equivalent to resize(0)
-assert(str(b) == "bytes('')")
-assert(b.size() == 0)
-
-#- clear -#
-b=bytes("aabb")
-b.clear()
-assert(str(b) == "bytes('')")
-
-#- == != -#
-assert(bytes() == bytes())
-assert(bytes("11") == bytes("11"))
-assert(bytes("11") == bytes()..0x11)
-assert(! (bytes("11") == bytes(0x12)) )
-assert(! (bytes("11") == 0x11) )
-assert(! (bytes("11") != bytes("11")) )
-assert(bytes("11") != bytes("1122"))
-assert(bytes("11") != bytes("12"))
-assert(bytes("11") != bytes())
-
-#- + -#
-b1 = bytes("1122")
-b2 = bytes("334455")
-b = b1 + b2
-assert(str(b1) == "bytes('1122')")
-assert(str(b2) == "bytes('334455')")
-assert(str(b) == "bytes('1122334455')")
-b = b2 + b1
-assert(str(b) == "bytes('3344551122')")
-
-#- + for string -#
-b1 = bytes("AA")
-b = b1 + ''
-assert(str(b) == "bytes('AA')")
-b = b1 + '01'
-assert(str(b) == "bytes('AA3031')")
-
-#- .. and append as synonyms -#
-b1 = bytes("1122")
-b2 = bytes("334455")
-b = b1..b2
-assert(str(b1) == "bytes('1122334455')")
-assert(str(b2) == "bytes('334455')")
-assert(str(b) == "bytes('1122334455')")
-#
-b1 = bytes("1122")
-b2 = bytes("334455")
-b = b1.append(b2)
-assert(str(b1) == "bytes('1122334455')")
-assert(str(b2) == "bytes('334455')")
-assert(str(b) == "bytes('1122334455')")
-
-#- .. with string -#
-b1 = bytes("AA")
-b1 .. ''
-assert(str(b1) == "bytes('AA')")
-b1 .. '01'
-assert(str(b1) == "bytes('AA3031')")
-#
-b1 = bytes("AA")
-b1.append('')
-assert(str(b1) == "bytes('AA')")
-b1.append('01')
-assert(str(b1) == "bytes('AA3031')")
-
-#- item -#
-b = bytes("334455")
-assert(b[0] == 0x33)
-assert(b[1] == 0x44)
-assert(b[2] == 0x55)
-assert(b[-1] == 0x55)
-assert(b[-2] == 0x44)
-assert(b[-3] == 0x33)
-# out of range raises "index_error" exceptions
-assert_error(def () return b[-4] end, 'index_error')
-assert_error(def () return b[4] end, 'index_error')
-
-#- item range -#
-b = bytes("00112233445566778899AABBCCDDEEFF")
-assert(str(b[1..1]) =="bytes('11')")
-assert(str(b[-1..1]) =="bytes('')")
-assert(str(b[0..40]) =="bytes('00112233445566778899AABBCCDDEEFF')")
-assert(str(b[1..0]) =="bytes('')")
-
-#- copy -#
-b=bytes("112233")
-b2=b.copy()
-assert(str(b) =="bytes('112233')")
-assert(str(b2) =="bytes('112233')")
-b2.clear()
-assert(str(b) =="bytes('112233')")
-assert(str(b2) =="bytes('')")
-
-#- setitem -#
-b=bytes("112233")
-assert(str(b) =="bytes('112233')")
-b[1]=0xAA
-assert(str(b) =="bytes('11AA33')")
-b[0]=0xBB
-assert(str(b) =="bytes('BBAA33')")
-b[2]=-1
-assert(str(b) =="bytes('BBAAFF')")
-# negative indices, counting from end
-b[-1]=0xFE
-assert(str(b) =="bytes('BBAAFE')")
-b[-3]=0xBC
-assert(str(b) =="bytes('BCAAFE')")
-# out of range raises "index_error" exceptions
-assert_error(def () b[-4]=0x11 end, 'index_error')
-assert_error(def () b[4]=0x11 end, 'index_error')
-
-#- resize -#
-b=bytes()
-b.resize(20)
-assert(str(b) =="bytes('0000000000000000000000000000000000000000')")
-b2=b.copy()
-assert(str(b2) =="bytes('0000000000000000000000000000000000000000')")
-
-#- asstring -#
-b=bytes()
-assert(b.asstring() == '')
-b=bytes("334455")
-assert(b.asstring() == '3DU')
-b=bytes("33456502")
-assert(b.asstring() == '3Ee\x02')
-
-#- fromstring -#
-b=bytes()
-b.fromstring("Aa0")
-assert(str(b) =="bytes('416130')")
-b=bytes()
-b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
-assert(b.tostring(0) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')")
-assert(size(bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')) == 123)
-
-#- negative index -#
-b=bytes("112233")
-assert(b[0] == 0x11)
-assert(b[-1] == 0x33) #- last element -#
-assert(b[-3] == 0x11)
-
-#- ranges with negative indices -#
-b = bytes("00112233445566778899AABBCCDDEEFF")
-assert(b[0..-1] == b)
-assert(b[1..-2] == bytes("112233445566778899AABBCCDDEE"))
-assert(b[5..10] == bytes("5566778899AA"))
-assert(b[-10..-5] == bytes("66778899AABB"))
-assert(b[5..-10] == bytes("5566"))
-assert(b[7..-12] == bytes())
-
-#- float -#
-b = bytes("00000000")
-b.setfloat(0, 0.33)
-assert(b == bytes('C3F5A83E'))
-b = bytes("0000C03F")
-assert(b.getfloat(0) == 1.5)
-b.addfloat(0.33)
-assert(b == bytes("0000C03FC3F5A83E"))
-b.addfloat(0.33, true) #- Big Endian -#
-assert(b == bytes("0000C03FC3F5A83E3EA8F5C3"))
-b = bytes("")
-b.addfloat(42) #- add integer -#
-assert(b == bytes("00002842"))
-
-#- fromhex -#
-b = bytes("112233")
-b.fromhex("FFFEAABBCC")
-assert(b == bytes("FFFEAABBCC"))
-b.fromhex("")
-assert(b == bytes())
-
-#- tohex -#
-b = bytes("FFFEAABBCC")
-assert(b.tohex() == "FFFEAABBCC")
-assert(bytes().tohex() == "")
-
-# assign buffer to bytes
-var a0 = bytes("112233445566778899")
-b = bytes("aabbccddeeff")
-
-a = a0.copy()
-a.setbytes(0, b) # assign from start
-assert(a == bytes('AABBCCDDEEFF778899'))
-a = a0.copy()
-a.setbytes(0, b, 0, 0) # zero len
-assert(a == a0)
-a = a0.copy()
-a.setbytes(100, b) # index out of range
-assert(a == a0)
-a = a0.copy()
-a.setbytes(6, b) # entire buffer not fitting
-assert(a == bytes('112233445566AABBCC'))
-a = a0.copy()
-a.setbytes(6, b, 2, 2)
-assert(a == bytes('112233445566CCDD99'))
-a = b.copy()
-a.setbytes(0, a0)
-assert(a == bytes('112233445566'))
-
-# reverse
-assert(bytes().reverse() == bytes())
-assert(bytes("AA").reverse() == bytes("AA"))
-assert(bytes("1122334455").reverse() == bytes("5544332211"))
-assert(bytes("11223344").reverse() == bytes("44332211"))
-
-assert(bytes("0011223344").reverse(1) == bytes("0044332211"))
-assert(bytes("0011223344").reverse(3) == bytes("0011224433"))
-assert(bytes("0011223344").reverse(4) == bytes("0011223344"))
-assert(bytes("0011223344").reverse(5) == bytes("0011223344"))
-assert(bytes("0011223344").reverse(15) == bytes("0011223344"))
-assert(bytes("0011223344").reverse(-2) == bytes("0011224433")) # reverse starting 2 from end
-
-assert(bytes("0011223344").reverse(1,3) == bytes("0033221144"))
-assert(bytes("0011223344").reverse(1,0) == bytes("0011223344"))
-assert(bytes("0011223344").reverse(2,2) == bytes("0011332244"))
-assert(bytes("0011223344").reverse(0,2) == bytes("1100223344"))
-assert(bytes("0011223344").reverse(nil,2) == bytes("1100223344"))
-assert(bytes("0011223344").reverse(1, nil) == bytes("0044332211"))
-
-assert(bytes("0011223344").reverse(nil, nil, 2) == bytes("2233001144"))
-assert(bytes("001122334455").reverse(nil, nil, 3) == bytes("334455001122"))
-
-# tobool returns `true` is bytes() is not null, `false` if empty
-assert(bool(bytes()) == false)
-assert(bytes().tobool() == false)
-assert(!bytes())
-
-assert(bool(bytes("00")) == true)
-assert(bytes("01").tobool() == true)
-assert(bytes("02"))
-
-# retrieving 3-bytes little/big endian
-a = bytes("01020304")
-assert(a.get(1, 3) == 0x040302)
-assert(a.get(1, -3) == 0x020304)
diff --git a/lib/libesp32/Berry/tests/bytes_b64.be b/lib/libesp32/Berry/tests/bytes_b64.be
deleted file mode 100644
index a7f57850e0e4..000000000000
--- a/lib/libesp32/Berry/tests/bytes_b64.be
+++ /dev/null
@@ -1,15 +0,0 @@
-#- base64 encode -#
-b=bytes()
-assert(b.tob64() == '')
-b=bytes('00')
-assert(b.tob64() == 'AA==')
-b=bytes('1122334455')
-assert(b.tob64() == 'ESIzRFU=')
-
-#- base64 decode -#
-b=bytes().fromb64('')
-assert(str(b) == str(bytes('')))
-b=bytes().fromb64('AA==')
-assert(str(b) == str(bytes('00')))
-b=bytes().fromb64('ESIzRFU=')
-assert(str(b) == str(bytes('1122334455')))
diff --git a/lib/libesp32/Berry/tests/bytes_fixed.be b/lib/libesp32/Berry/tests/bytes_fixed.be
deleted file mode 100644
index 1f3e5532baad..000000000000
--- a/lib/libesp32/Berry/tests/bytes_fixed.be
+++ /dev/null
@@ -1,68 +0,0 @@
-#- test for bytes with fixed sizes -#
-def assert_attribute_error(f)
- try
- f()
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'attribute_error')
- end
-end
-
-#- simple initialization -#
-b=bytes(-1)
-assert(str(b) == "bytes('00')")
-b=bytes(-5)
-assert(str(b) == "bytes('0000000000')")
-
-#- initialization with hex -#
-b=bytes("11", -1)
-assert(str(b) == "bytes('11')")
-b=bytes("11", -5)
-assert(str(b) == "bytes('1100000000')")
-b=bytes("11223344", -4)
-assert(str(b) == "bytes('11223344')")
-assert(str(bytes(-3).fromb64('RFVm')) == "bytes('445566')")
-
-#- check that get and set still works -#
-b=bytes("11223344",-4)
-assert(b.get(0,2) == 0x2211)
-b.set(0,0x5566,2)
-assert(b.get(0,2) == 0x5566)
-assert(b[0] == 0x66)
-b[0]=12
-assert(b[0] == 12)
-
-#- resize -#
-b=bytes("11223344",-4)
-assert(b.resize(4) == bytes('11223344'))
-
-#- check that changing size raises an exception -#
-b=bytes("112233", -3)
-assert_attribute_error(/-> b.add(1))
-assert_attribute_error(/-> b.add(2,2))
-assert_attribute_error(/-> b.resize(4))
-assert_attribute_error(/-> b.fromstring("aaaaa"))
-assert_attribute_error(/-> b.fromb64('RFVmdw=='))
-assert_attribute_error(/-> b.clear())
-assert_attribute_error(/-> b.bytes())
-
-#- add -#
-b=bytes("112233", -3)
-assert(b+b == bytes("112233112233"))
-
-#- bytes mapped -#
-b1=bytes("112233445566")
-ptr=b1._buffer()
-b2=bytes(ptr, -4)
-assert(b2 == bytes("11223344"))
-b2=bytes(ptr, 4)
-assert(b2 == bytes("11223344"))
-b2=bytes(ptr, 6)
-assert(b2 == bytes("112233445566"))
-assert(b1 == b2)
-
-b2.set(0,0xAABB,2)
-assert(b2 == bytes("BBAA33445566"))
-assert(b1 == bytes("BBAA33445566"))
-assert(b1 == b2)
-assert(b1.ismapped() == false)
\ No newline at end of file
diff --git a/lib/libesp32/Berry/tests/checkspace.be b/lib/libesp32/Berry/tests/checkspace.be
deleted file mode 100644
index 8af1a71d74c5..000000000000
--- a/lib/libesp32/Berry/tests/checkspace.be
+++ /dev/null
@@ -1,35 +0,0 @@
-import os
-
-def strfind(st, char)
- var len = size(st)
- for i : 0 .. len - 1
- if st[i] == char
- return true
- end
- end
- return false
-end
-
-def checkfile(path)
- var subname = os.path.splitext(path)[1]
- if (subname == '.c' || subname == '.h' ||
- subname == '.cpp' || subname == '.be' || subname == '.json')
- var f = open(path)
- assert(!strfind(f.read(), '\t'), 'file \'' + path + '\' has tab character')
- f.close()
- end
-end
-
-def findpath(path)
- var ls = os.listdir(path)
- for name : ls
- var fullname = os.path.join(path, name)
- if os.path.isfile(fullname)
- checkfile(fullname)
- elif fullname != '.' && fullname != '..'
- findpath(fullname)
- end
- end
-end
-
-findpath('.')
diff --git a/lib/libesp32/Berry/tests/class.be b/lib/libesp32/Berry/tests/class.be
deleted file mode 100644
index 06d78ee5dd16..000000000000
--- a/lib/libesp32/Berry/tests/class.be
+++ /dev/null
@@ -1,60 +0,0 @@
-class Test
- var maximum
- def init(maximum)
- self.maximum = maximum
- end
- def iter() # method closure upvalues test
- var i = -1, maximum = self.maximum
- return def ()
- i += 1
- if i > maximum
- raise 'stop_iteration'
- end
- return i
- end
- end
-end
-
-var sum = 0
-for i : Test(10)
- sum += i
-end
-assert(sum == 55, 'iteraion sum is ' + str(sum) + ' (expected 55).')
-
-#- test case for class instanciated from module member #103 -#
-
-m = module()
-g_i = 0 #- detect side effect from init() -#
-class C def init() g_i += 1 end end
-m.C = C
-
-#- normal invocation -#
-assert(type(C()) == 'instance')
-assert(g_i == 1)
-
-#- invoke from module member -#
-assert(type(m.C()) == 'instance')
-assert(g_i == 2)
-
-class C2 var C1 def init(c) self.C1 = c end end
-m.C2 = C2
-c2 = m.C2(m.C)
-
-assert(c2.C1 == C)
-
-c3 = m.C2(m.C())
-assert(type(c3.C1) == 'instance')
-assert(classname(c3.C1) == 'C')
-
-#- an instance member can be a class and called directly -#
-class Test_class
- var c
- def init()
- self.c = map
- end
-end
-c4 = Test_class()
-assert(type(c4.c) == 'class')
-c5 = c4.c()
-assert(type(c5) == 'instance')
-assert(classname(c5) == 'map')
diff --git a/lib/libesp32/Berry/tests/class_const.be b/lib/libesp32/Berry/tests/class_const.be
deleted file mode 100644
index 950ce8b4bb0d..000000000000
--- a/lib/libesp32/Berry/tests/class_const.be
+++ /dev/null
@@ -1,122 +0,0 @@
-def assert_attribute_error(f)
- try
- f()
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'attribute_error')
- end
-end
-
-class A
- static var a
- def init() self.b = 2 end
- def f() end
- var b
- static var c, s, r
-end
-
-assert(A.a == nil)
-assert(A.c == nil)
-assert(A.s == nil)
-assert_attribute_error(/-> A.b)
-assert_attribute_error(/-> A.d)
-
-a = A()
-assert(a.b == 2)
-assert(a.a == nil)
-assert(a.c == nil)
-
-A.a = 1
-A.c = 3
-A.s = "foo"
-A.r = 3.5
-assert(a.a == 1)
-assert(a.c == 3)
-assert(A.a == 1)
-assert(A.c == 3)
-import gc gc.collect()
-assert(A.s == "foo")
-assert(a.s == "foo")
-assert(A.r == 3.5)
-assert(a.r == 3.5)
-
-#- test valid or invalid methods and members -#
-
-def assert_attribute_error(c)
- try
- compile(c)()
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'attribute_error')
- end
-end
-
-class A
- var a, g
- static h
- def init() self.a = 1 end
- def f(x, y) return type(self) end
-end
-a=A()
-a.g = def (x, y) return type(x) end
-A.h = def (x, y) return type(x) end
-
-assert(type(a.g) == 'function')
-assert(type(a.h) == 'function')
-
-assert(a.g(1) == 'int')
-assert(a.h(1) == 'int')
-assert(A.h(1) == 'int')
-
-
-class A
- var a
- static def g(x, y) return [x,y] end
- static h = def (x, y) return [x,y] end
- def init() self.a = 1 end
- def f(x, y) return type(self) end
-end
-a=A()
-assert(type(a.g) == 'function')
-assert(type(a.h) == 'function')
-assert(type(A.g) == 'function')
-assert(type(A.h) == 'function')
-assert(a.g(1,2) == [1,2])
-assert(a.h(1,2) == [1,2])
-assert(A.g(1,2) == [1,2])
-assert(A.h(1,2) == [1,2])
-a.a = def (x,y) return [x,y] end
-assert(a.a(1,2) == [1,2])
-
-
-#- test static initializers -#
-class A
- static a = 1, b, c = 3.5, d = 42, e = "foo", f = [1], g = {}
- var aa,ab
-end
-
-assert(A.a == 1)
-assert(A.b == nil)
-assert(A.c == 3.5)
-assert(A.d == 42)
-assert(A.e == "foo")
-assert(A.f == [1])
-
-a = A()
-assert(a.a == 1)
-assert(a.b == nil)
-assert(a.c == 3.5)
-assert(a.d == 42)
-assert(a.e == "foo")
-assert(a.f == [1])
-assert(a.g == A.g)
-assert(a.aa == nil)
-assert(a.ab == nil)
-
-#- used to fail for subclasses -#
-class A static a=1 end
-class B:A static a=A def f() end static b=1 static c=A end
-assert(A.a == 1)
-assert(B.a == A)
-assert(B.b == 1)
-assert(B.c == A)
diff --git a/lib/libesp32/Berry/tests/closure.be b/lib/libesp32/Berry/tests/closure.be
deleted file mode 100644
index 757c2a94450c..000000000000
--- a/lib/libesp32/Berry/tests/closure.be
+++ /dev/null
@@ -1,16 +0,0 @@
-#- test for issue #105 -#
-
-l=[]
-def tick()
- var start=100
- for i : 1..3
- l.push(def () return [i, start] end)
- end
-end
-tick()
-assert(l[0]() == [1, 100])
-assert(l[1]() == [2, 100])
-assert(l[2]() == [3, 100])
-
-# the following failed to compile #344
-def test() var nv = 1 var f = def() nv += 2*1 print(nv) end end
diff --git a/lib/libesp32/Berry/tests/compiler.be b/lib/libesp32/Berry/tests/compiler.be
deleted file mode 100644
index a2b25640ef56..000000000000
--- a/lib/libesp32/Berry/tests/compiler.be
+++ /dev/null
@@ -1,80 +0,0 @@
-#- test for issue #117 -#
-
-class A var a end
-a=A()
-a.a = ["foo", "bar"]
-
-s = nil
-def fs(m) s = m end
-
-class B
- var b, i
- def nok()
- fs(self.b.a[self.i]) # wrong behavior
- end
- def ok()
- var i = self.i
- fs(self.b.a[i]) # works correctly
- end
-end
-b=B()
-b.i=0
-b.b=a
-
-b.nok()
-assert(s == "foo")
-
-b.ok()
-assert(s == "foo")
-
-# detect a wrong compilation when accessing index
-# Berry compilation problem:
-#
-# ```berry
-# def f(self) print(self.a[128]) end
-# ```
-#
-# Compilation assigns unwanted registers:
-# ```
-# 0x60040001, // 0000 GETGBL R1 G1
-# 0x540A007F, // 0001 LDINT R2 128
-# 0x880C0100, // 0002 GETMBR R3 R0 K0
-# 0x94080602, // 0003 GETIDX R2 R3 R2
-# 0x5C100400, // 0004 MOVE R4 R2 <- PROBLEM
-# 0x7C040200, // 0005 CALL R1 1
-# 0x80000000, // 0006 RET 0
-# ```
-#
-# With the fix, the integer is retrieved in second place, and erroneous register is not allocated:
-# ```
-# 0x60040001, // 0000 GETGBL R1 G1
-# 0x88080100, // 0001 GETMBR R2 R0 K0
-# 0x540E007F, // 0002 LDINT R3 128
-# 0x94080403, // 0003 GETIDX R2 R2 R3
-# 0x7C040200, // 0004 CALL R1 1
-# 0x80000000, // 0005 RET 0
-# ```
-def f(a,b) return b end
-l = [1,2,3,4]
-assert(f(l[-1],l[-2]) == 3)
-
-# Compilation problem:
-# def test()
-# var line = '1234567890'
-# line = line[3..7]
-# # print(line)
-# for n : 1..2 end
-# end
-# test()
-
-# BRY: Exception> 'attribute_error' - the 'range' object has no method '()'
-# stack traceback:
-# :5: in function `test`
-# :7: in function `main`
-def test()
- var line = '1234567890'
- line = line[3..7]
-# print(line)
- for n : 1..2 end
-end
-test()
diff --git a/lib/libesp32/Berry/tests/compound.be b/lib/libesp32/Berry/tests/compound.be
deleted file mode 100644
index b75c2dc523d3..000000000000
--- a/lib/libesp32/Berry/tests/compound.be
+++ /dev/null
@@ -1,28 +0,0 @@
-# test bug in compound statements
-
-a = 0
-assert(a == 0)
-a += 1
-assert(a == 1)
-a += 10/2
-assert(a == 6)
-
-class A var a def init() self.a = 1 end def f(x) self.a+=x/2 end def g(x) self.a = self.a + x/2 end end
-
-a = A()
-assert(a.a == 1)
-a.f(10)
-assert(a.a == 6)
-b=A()
-assert(b.a == 1)
-b.g(10)
-assert(b.a == 6)
-
-# bug in compound assignments
-class A var a,b end
-c=A()
-c.a = {"x": 1, "y": 2}
-c.b = "x"
-assert(c.a[c.b] == 1)
-c.a[c.b] += 2 # this is where the bug happens
-assert(c.a[c.b] == 3)
diff --git a/lib/libesp32/Berry/tests/cond_expr.be b/lib/libesp32/Berry/tests/cond_expr.be
deleted file mode 100644
index dc70fd306788..000000000000
--- a/lib/libesp32/Berry/tests/cond_expr.be
+++ /dev/null
@@ -1,10 +0,0 @@
-assert("" != 0 ? true : false)
-assert(false || !(true ? false : true) && true)
-var t1 = 8, t2 = false
-if t1 ? 7 + t1 : t2
- var a = 'good'
- assert((a == 'good' ? a + '!' : a) == 'good!')
- assert((a == 'good?' ? a + '!' : a) != 'good!')
-else
- assert('condition expression test failed')
-end
diff --git a/lib/libesp32/Berry/tests/debug.be b/lib/libesp32/Berry/tests/debug.be
deleted file mode 100644
index 88b559d8108a..000000000000
--- a/lib/libesp32/Berry/tests/debug.be
+++ /dev/null
@@ -1,29 +0,0 @@
-import debug
-
-class A end
-debug.attrdump(A) #- should not crash -#
-
-# debug.caller()
-def caller_name_chain()
- import debug
- import introspect
- var i = 1
- var ret = []
- var caller = debug.caller(i)
- while caller
- ret.push(introspect.name(caller))
- i += 1
- caller = debug.caller(i)
- end
- return ret
-end
-var chain = caller_name_chain()
-assert(chain[0] == 'caller_name_chain')
-
-def guess_my_name__()
- return caller_name_chain()
-end
-chain = guess_my_name__()
-print(chain)
-assert(chain[0] == 'caller_name_chain')
-assert(chain[1] == 'guess_my_name__')
diff --git a/lib/libesp32/Berry/tests/exceptions.be b/lib/libesp32/Berry/tests/exceptions.be
deleted file mode 100644
index dc2ad54e4b71..000000000000
--- a/lib/libesp32/Berry/tests/exceptions.be
+++ /dev/null
@@ -1,7 +0,0 @@
-
-try
- for k: 0..1 assert({'a':1}.contains('b'), 'failure') end
-except .. as e,m
- assert(e == "assert_failed")
- assert(m == "failure")
-end
diff --git a/lib/libesp32/Berry/tests/for.be b/lib/libesp32/Berry/tests/for.be
deleted file mode 100644
index ec4a910cd0af..000000000000
--- a/lib/libesp32/Berry/tests/for.be
+++ /dev/null
@@ -1,44 +0,0 @@
-var global
-
-global = 0
-for i : 0 .. 10
- global += i
-end
-assert(global == 55)
-
-global = 0
-for i : 0 .. 20
- if i > 10
- break
- end
- global += i
-end
-assert(global == 55)
-
-global = 0
-for i : 0 .. 20
- if i > 10
- continue
- end
- global += i
-end
-assert(global == 55)
-
-assert(def ()
- for i : 0 .. 20
- if i > 10
- return i
- end
- end
- end() == 11)
-
-# test for "stop_iteration" exception as recurrence
-def for_rec(depth)
- for i : 0 .. 10
- if i == 4 && depth < 200
- for_rec(depth + 1)
- end
- end
-end
-
-for_rec(0)
diff --git a/lib/libesp32/Berry/tests/function.be b/lib/libesp32/Berry/tests/function.be
deleted file mode 100644
index 81310408bf42..000000000000
--- a/lib/libesp32/Berry/tests/function.be
+++ /dev/null
@@ -1,12 +0,0 @@
-# CLOSE opcode test
-var gbl
-def func1()
- var a = 'func1_a'
- def func2()
- return a
- end
- gbl = func2
- return 400000 + 500
-end
-assert(func1() == 400500)
-assert(gbl() == 'func1_a')
diff --git a/lib/libesp32/Berry/tests/global.be b/lib/libesp32/Berry/tests/global.be
deleted file mode 100644
index 66135c4e16a7..000000000000
--- a/lib/libesp32/Berry/tests/global.be
+++ /dev/null
@@ -1,43 +0,0 @@
-#- test module global -#
-
-def assert_syntax_error(code)
- try
- var f = compile(code)
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'syntax_error')
- end
-end
-def findinlist(l, e)
- for i: 0..size(l)-1
- if l[i] == e return i end
- end
- return nil
-end
-
-#- set the scene -#
-global_a = 1
-global_b = "bb"
-assert(global_a == 1)
-assert(global_b == "bb")
-
-assert_syntax_error("c") #- compilation fails because c does not exist -#
-
-import global
-
-assert(global.global_a == 1)
-assert(global.global_b == "bb")
-
-global.global_c = 3
-#- now compilation against 'c' global -#
-f = compile("return global_c")
-assert(f() == 3)
-
-#- check that access to non-existent global returns nil (new behavior) -#
-assert(global.d == nil)
-
-#- check the glbal list -#
-assert(findinlist(global(), 'global_a') != nil)
-assert(findinlist(global(), 'global_b') != nil)
-assert(findinlist(global(), 'global_c') != nil)
-assert(findinlist(global(), 'global_d') == nil)
\ No newline at end of file
diff --git a/lib/libesp32/Berry/tests/introspect.be b/lib/libesp32/Berry/tests/introspect.be
deleted file mode 100644
index 1d9c7af293cc..000000000000
--- a/lib/libesp32/Berry/tests/introspect.be
+++ /dev/null
@@ -1,66 +0,0 @@
-#- introspect -#
-import introspect
-
-#- test for modules -#
-m = module("m")
-m.a = 1
-m.b = def () return "foo" end
-
-assert(introspect.members(m) == ['a', 'b'])
-assert(introspect.get(m, 'a') == 1)
-assert(type(introspect.get(m, 'b')) == 'function')
-
-introspect.set(m, 'a', 2)
-assert(m.a == 2)
-
-#- test for instance -#
-class A var a,b static c=1,d=2 def f() end end
-a=A()
-
-assert(introspect.members(A) == ['a', 'f', 'b', 'c', 'd']) #- class members -#
-assert(introspect.members(a) == ['a', 'f', 'b', 'c', 'd']) #- instance members -#
-
-assert(introspect.get(a, 'c') == 1)
-assert(introspect.get(a, 'd') == 2)
-assert(introspect.get(a, 'a') == nil)
-
-introspect.set(a, 'a', 3)
-assert(a.a == 3)
-
-#- load module dynamically -#
-import introspect
-m = introspect.module("math") # load module `math`, assign to `m` and don't create a global variable
-assert(type(m.pi) == 'real')
-
-#- name -#
-import string
-assert(introspect.name(string) == 'string')
-assert(introspect.name(print) == nil) # native C function don't have a registered name
-assert(introspect.name("foo") == nil)
-class A def a() end static def b() end static var c end
-assert(introspect.name(A) == 'A')
-assert(introspect.name(A.a) == 'a')
-assert(introspect.name(A.b) == 'b')
-assert(introspect.name(A.c) == nil)
-
-# test introspect get and set
-# class and instance
-class A
- static var a
- var b
-end
-
-a = A()
-introspect.set(A, "a", 10)
-assert(A.a == 10)
-assert(introspect.get(A, "a") == 10)
-
-introspect.set(a, "b", 20)
-assert(a.b == 20)
-assert(introspect.get(a, "b") == 20)
-
-# module
-m = module('m')
-introspect.set(m, 'c', 30)
-assert(m.c == 30)
-assert(introspect.get(m, 'c') == 30)
diff --git a/lib/libesp32/Berry/tests/json.be b/lib/libesp32/Berry/tests/json.be
deleted file mode 100644
index 2165eda8d736..000000000000
--- a/lib/libesp32/Berry/tests/json.be
+++ /dev/null
@@ -1,95 +0,0 @@
-import json
-import string
-# load tests
-
-def assert_load(text, value)
- var loaded_val = json.load(text)
- var ok = loaded_val == value
- if !ok
- print(string.format('for JSON \'%s\' expected %s [%s] but got %s [%s]', text, str(value), type(value), str(loaded_val), type(loaded_val)))
- end
- assert(ok)
-end
-
-def assert_load_failed(text)
- assert(json.load(text) == nil)
-end
-
-assert_load('null', nil)
-assert_load('true', true)
-assert_load('false', false)
-assert_load('123', 123)
-assert_load('12.3', 12.3)
-assert_load('-0.1', -0.1)
-assert_load('1e2', 1e2)
-assert_load('1e+2', 1e+2)
-assert_load('1e-2', 1e-2)
-assert_load('1E2', 1e2)
-assert_load('1E+2', 1e+2)
-assert_load('1.2e7', 1.2e7)
-assert_load('"abc"', 'abc')
-# strings
-assert_load('"\\"\\\\\\/\\b\\f\\n\\r\\t"', '\"\\/\b\f\n\r\t')
-assert_load('"\\u1234\\u2345\\u04aF\\u003A"', 'ሴ⍅ү:')
-assert_load_failed('"\\u3fr"');
-assert_load_failed('"\\q"');
-assert_load_failed('"123');
-# list
-assert_load('[1, null]', [1, nil])
-assert_load_failed('[x]')
-assert_load_failed('[1, nil]')
-assert_load_failed('[1, null')
-# object
-var o = json.load('{"key": 1}')
-assert(o['key'] == 1 && o.size() == 1)
-
-# parsing an empty string used to cause berry to pass a NULL to strncmp
-# make sure we catch this
-o = json.load('{"key": ""}')
-assert(o['key'] == '' && o.size() == 1)
-
-assert_load_failed('{"ke: 1}')
-assert_load_failed('{"key": 1x}')
-assert_load_failed('{"key"}')
-assert_load_failed('{"key": 1, }')
-# insanely long, nested object
-var text = 'null'
-for i : 0 .. 200
- text = '{"nested":' + text + ', "num": 1, "bool": true, "str": "abc", "n": null, "arr": [1, 2, 3]}'
-end
-json.load(text) # do nothing, just check that it doesn't crash
-
-# dump tests
-
-def assert_dump(value, text, format)
- assert(json.dump(value, format) == text)
-end
-
-assert_dump(nil, 'null');
-assert_dump(true, 'true');
-assert_dump(false, 'false');
-assert_dump(1.23, '1.23');
-assert_dump('String', '"String"');
-assert_dump([1, 'x'], '[1,"x"]');
-assert_dump({1: 'x'}, '{"1":"x"}');
-assert_dump([1, 'x'], '[\n 1,\n "x"\n]', 'format');
-assert_dump({1: 'x'}, '{\n "1": "x"\n}', 'format');
-assert_dump({1: 'x', 'k': 'v'}, '{"k":"v","1":"x"}');
-
-class map2 : map def init() super(self).init() end end
-var m = map2()
-m['key'] = 1
-assert_dump(m, '{"key":1}')
-
-# sweep dumping nested arrays of diffrent sizes
-# this tests for any unexpanded stack conditions
-for count : 10..200
- var arr = [[]]
- var last_arr = arr
- for i : 0..count
- var pushed = [i]
- last_arr.push(pushed)
- last_arr = pushed
- end
- json.dump(arr)
-end
diff --git a/lib/libesp32/Berry/tests/lexer.be b/lib/libesp32/Berry/tests/lexer.be
deleted file mode 100644
index db2945bc7e8e..000000000000
--- a/lib/libesp32/Berry/tests/lexer.be
+++ /dev/null
@@ -1,65 +0,0 @@
-import math
-
-def check(a, b)
- assert(math.abs(a - b) < 1e-6)
-end
-
-def test_source(src, msg)
- try
- compile(src)
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'syntax_error')
- assert(m == 'string:1: ' + msg)
- end
-end
-
-#----
- this is a
- mult-line comment
-----#
-
-compile('x = 5; 0..x')
-assert('\x5a' == 'Z')
-assert('\132' == 'Z')
-assert('\a\b\f\n\r\t\v\\\'\"\?' == '\x07\x08\x0c\x0a\x0d\x09\x0b\x5c\x27\x22\x3f')
-assert(.45 == 0.45)
-assert(0X10 == 16)
-assert(0x10 == 16)
-assert(0X1A == 26)
-assert(0x1a == 26)
-check(45., 45)
-check(45.e-1, 4.5)
-check(45.E-1, 4.5)
-check(45.1e-1, 4.51)
-check(45.1e2, 4510)
-check(45.e2, 4500)
-check(45.e+2, 4500)
-
-# Ensure pathologically long numbers don't crash the lexer (or cause an buffer overflow)
-assert(000000000000000000000000000000000000E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 == 0.0);
-
-
-test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'')
-test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'')
-test_source('0xg', 'invalid hexadecimal number')
-test_source('"\\x5g"', 'invalid hexadecimal number')
-test_source('0x5g', 'malformed number')
-test_source('"\\779"', 'invalid octal number')
-test_source('"\n', 'unfinished string')
-
-var malformed_numbers = [
- '45f',
- '45.f',
- '45.ef',
- '45.e-f',
- '45.e-1f',
- '45.e-1.',
- '45.5.',
- '0x45.',
- '0x45j'
-]
-
-for i : malformed_numbers
- test_source(i, 'malformed number')
-end
diff --git a/lib/libesp32/Berry/tests/lexergc.be b/lib/libesp32/Berry/tests/lexergc.be
deleted file mode 100644
index 155800b95cea..000000000000
--- a/lib/libesp32/Berry/tests/lexergc.be
+++ /dev/null
@@ -1,12 +0,0 @@
-#- check the gc bug fixed in #110 -#
-#- Berry must be compiled with `#define BE_USE_DEBUG_GC 1` -#
-#- for the initial bug to happen -#
-
-code = "()" #- this code triggers a lexer exception -#
-
-try
- compile(code)
- assert(false) #- this should never be reached -#
-except .. as e, m
- assert(m == "string:1: unexpected symbol near ')'")
-end
\ No newline at end of file
diff --git a/lib/libesp32/Berry/tests/list.be b/lib/libesp32/Berry/tests/list.be
deleted file mode 100644
index a2da2ca473ee..000000000000
--- a/lib/libesp32/Berry/tests/list.be
+++ /dev/null
@@ -1,140 +0,0 @@
-l = [1, 2, 3, 4, 5]
-assert(l[0] == 1)
-assert(l[1] == 2)
-assert(l[2] == 3)
-assert(l[3] == 4)
-assert(l[4] == 5)
-assert(str(l) == '[1, 2, 3, 4, 5]')
-
-it = l.iter()
-assert(it() == 1)
-assert(it() == 2)
-assert(it() == 3)
-assert(it() == 4)
-assert(it() == 5)
-
-l.insert(0, 10)
-assert(l[0] == 10)
-assert(l.size() == 6)
-l.remove(0)
-assert(l.size() == 5)
-assert(l[0] == 1)
-l.setitem(0, 42)
-assert(l[0] == 42)
-assert(l.item(2) == 3)
-l.resize(10)
-assert(l.size() == 10)
-assert(l.tostring() == '[42, 2, 3, 4, 5, nil, nil, nil, nil, nil]')
-
-assert(([] == []) == true)
-assert(([] != []) == false)
-assert(([1] == [1]) == true)
-assert(([1] != [1]) == false)
-assert(([1] == [0]) == false)
-assert(([1] != [0]) == true)
-assert(([1, 2, 3] == [1, 2, 3]) == true)
-assert(([1, 2, 3] != [1, 2, 3]) == false)
-assert(([1, 2, 3] == [1, 2, 4]) == false)
-assert(([1, 2, 3] != [1, 2, 4]) == true)
-assert(([1, 2, ['w']] == [1, 2, ['w']]) == true)
-assert(([1, 2, ['w']] != [1, 2, ['w']]) == false)
-assert(([1, 2, ['w']] == [1, 2, ['z']]) == false)
-assert(([1, 2, ['w']] != [1, 2, ['z']]) == true)
-assert(([1, 2, ['w']] == [1, 2, []]) == false)
-assert(([1, 2, ['w']] != [1, 2, []]) == true)
-
-var l = [0, 1, 2, 3]
-assert(l[-1] == 3)
-assert(l[-2] == 2)
-var t = l.copy()
-l.insert(-2, 4)
-assert(t == [0, 1, 2, 3] && t != l)
-assert(l == [0, 1, 4, 2, 3])
-l.remove(-2)
-assert(l == [0, 1, 4, 3])
-assert(l.reverse() == [3, 4, 1, 0])
-assert(l + [5, 6] == [3, 4, 1, 0, 5, 6])
-l = [0]
-assert(l .. '3' == [0, '3'])
-l.push(1)
-assert(l == [0, '3', 1])
-assert(l.concat() == '031')
-l.pop()
-assert(l == [0, '3'])
-l.pop(0)
-assert(l == ['3'])
-
-l1 = [0, 1]
-l2 = [2, 3]
-assert(l1+l2==[0, 1, 2, 3])
-assert(l1 == [0, 1])
-assert(l2 == [2, 3])
-assert(l1+[2] == [0, 1, 2])
-assert([-1]+l1 == [-1, 0, 1])
-assert(l1 == [0, 1])
-
-#- find -#
-#- if no argument return nil -#
-assert([].find() == nil)
-assert([1,2].find() == nil)
-assert([1,1,nil,2].find() == nil)
-
-#- nil if not found -#
-assert([1,2].find(3) == nil)
-assert([1,2].find(true) == nil)
-assert([1,2].find('foo') == nil)
-
-#- if found -#
-assert([1,2,3,4].find(1) == 0)
-assert([1,2,3,4].find(2) == 1)
-assert([1,2,3,4].find(3) == 2)
-assert([1,2,3,4].find(4) == 3)
-assert([1,2,"foo",4].find('foo') == 2)
-
-#- if multiple occurrences -#
-assert([1,1,2,2].find(1) == 0)
-assert([1,1,2,2].find(2) == 2)
-
-#- look for nil -#
-assert([1,1,nil,2].find(nil) == 2)
-
-#- sub-structure -#
-assert([1,[1,nil,2],3,[3]].find(3) == 2)
-assert([1,[1,nil,2],3,[3]].find([3]) == 3)
-assert([1,[1,nil,2],3,[3]].find([1,nil,2]) == 1)
-
-#- keys() -#
-assert(str(["a",'b',0].keys()) == "(0..2)")
-assert(str([nil].keys()) == "(0..0)")
-assert(str([].keys()) == "(0..-1)")
-
-#- concat with delimiter -#
-assert(["foo","bar",0].concat() == "foobar0")
-assert([1,2,3].concat() == "123")
-assert(["foo","bar",0].concat('') == "foobar0")
-assert([1,2,3].concat('') == "123")
-
-assert(["foo","bar",0].concat('-') == "foo-bar-0")
-assert([].concat('<->') == "")
-assert(["foo"].concat('<->') == "foo")
-assert(["foo","bar",0].concat('<->') == "foo<->bar<->0")
-
-assert(["","foo","bar",0].concat('<->') == "<->foo<->bar<->0")
-assert(["","",1,"bar",0].concat('<->') == "<-><->1<->bar<->0")
-assert(["","",1,"bar",0].concat('') == "1bar0")
-
-assert([1,2,3].concat('-') == "1-2-3")
-assert([1,"2",3].concat('-') == "1-2-3")
-
-assert(["",2,3].concat('-') == "-2-3")
-
-#- negative indices -#
-assert([1,2,3,4][0] == 1)
-assert([1,2,3,4][-1] == 4)
-assert([1,2,3,4][-2] == 3)
-
-assert([1,2,3,4][1..10] == [2,3,4])
-assert([1,2,3,4][1..-1] == [2,3,4])
-assert([1,2,3,4][1..-2] == [2,3])
-assert([1,2,3,4][3..2] == [])
-assert([1,2,3,4][2..-3] == [])
\ No newline at end of file
diff --git a/lib/libesp32/Berry/tests/member_indirect.be b/lib/libesp32/Berry/tests/member_indirect.be
deleted file mode 100644
index 046521acdc47..000000000000
--- a/lib/libesp32/Berry/tests/member_indirect.be
+++ /dev/null
@@ -1,75 +0,0 @@
-#- new syntax for indirect members -#
-
-#- module accessor -#
-s_pi = 'pi'
-
-import math
-assert(math.('pi') == math.pi)
-assert(math.(s_pi) == math.pi)
-
-#- module writer -#
-m = module("m")
-
-m.('aa') = 1
-m.('a' + 'b') = 2
-s_ac = 'ac'
-m.(s_ac) = 3
-assert(m.aa == 1)
-assert(m.ab == 2)
-assert(m.ac == 3)
-assert(m.('a'+'a') == 1)
-
-#- class accessor -#
-class A1
- static a = 1, b = 2
- static s = "foo"
- def f() return 0 end
-end
-assert(A1.a == 1)
-assert(A1.b == 2)
-assert(A1.s == "foo")
-assert(type(A1.f) == 'function')
-
-#- instance accessor -#
-class A2
- var a, b
- static s_a = 'a'
- def init(a,b)
- self.(self.('s_a')) = a
- self.('b') = b
- end
- def f(x)
- return x+1
- end
- def g(a,b)
- return A2(a,b)
- end
-end
-a = A2(1,2)
-
-#- reading members -#
-assert(a.a == 1)
-assert(a.b == 2)
-assert(a.(A2.s_a) == 1)
-assert(a.('b') == 2)
-
-#- writing members -#
-a.('a') = 10
-a.('bb'[0]) = 11
-assert(a.a == 10)
-assert(a.b == 11)
-
-#- calling methods -#
-assert(a.f(1) == 2)
-assert(a.('f')(2) == 3)
-
-#- mulit-level -#
-assert(a.('g')(3,4).('a') == 3)
-a.('a') = a.g(3,4)
-assert(a.a.b == 4)
-assert(a.('a').b == 4)
-assert(a.('a').('b') == 4)
-assert(a.a.('b') == 4)
-
-a.('a').('b') += 1
-assert(a.a.b == 5)
diff --git a/lib/libesp32/Berry/tests/os.be b/lib/libesp32/Berry/tests/os.be
deleted file mode 100644
index 58f41c9d0ec8..000000000000
--- a/lib/libesp32/Berry/tests/os.be
+++ /dev/null
@@ -1,51 +0,0 @@
-import os
-
-# os.path.join test
-assert(os.path.join('') == '')
-assert(os.path.join('abc', 'de') == 'abc/de')
-assert(os.path.join('abc', '/de') == '/de')
-assert(os.path.join('a', 'de') == 'a/de')
-assert(os.path.join('abc/', 'de') == 'abc/de')
-assert(os.path.join('abc', 'de', '') == 'abc/de/')
-assert(os.path.join('abc', '', '', 'de') == 'abc/de')
-assert(os.path.join('abc', '/de', 'fghij') == '/de/fghij')
-assert(os.path.join('abc', 'xyz', '/de', 'fghij') == '/de/fghij')
-
-# os.path.split test
-def split(st, lst)
- var res = os.path.split(st)
- assert(res[0] == lst[0] && res[1] == lst[1],
- 'unexpected results: ' .. res .. ', reference value: ' .. lst)
-end
-
-split('/', ['/', ''])
-split('//', ['//', ''])
-split('///', ['///', ''])
-split('a/', ['a', ''])
-split('a//', ['a', ''])
-split('a/b/c', ['a/b', 'c'])
-split('a/b/', ['a/b', ''])
-split('a//b//', ['a//b', ''])
-split('a/../b', ['a/..', 'b'])
-split('abcd////ef/////', ['abcd////ef', ''])
-split('abcd////ef', ['abcd', 'ef'])
-
-# os.path.splitext test
-def splitext(st, lst)
- var res = os.path.splitext(st)
- assert(res[0] == lst[0] && res[1] == lst[1],
- 'unexpected results: ' .. res .. ', reference value: ' .. lst)
-end
-
-splitext('a.b', ['a', '.b'])
-splitext('a..b', ['a.', '.b'])
-splitext('/a..b', ['/a.', '.b'])
-splitext('/.b', ['/.b', ''])
-splitext('/..b', ['/..b', ''])
-splitext('..b', ['..b', ''])
-splitext('...b', ['...b', ''])
-splitext('.b', ['.b', ''])
-splitext('ac..b', ['ac.', '.b'])
-splitext('ac.b', ['ac', '.b'])
-splitext('ac/.b', ['ac/.b', ''])
-splitext('ac/..b', ['ac/..b', ''])
diff --git a/lib/libesp32/Berry/tests/overload.be b/lib/libesp32/Berry/tests/overload.be
deleted file mode 100644
index a9e72081baf5..000000000000
--- a/lib/libesp32/Berry/tests/overload.be
+++ /dev/null
@@ -1,14 +0,0 @@
-class test
- def init()
- self._a = 123
- end
- def +()
- return self._a
- end
- def ()()
- return self._a
- end
- var _a
-end
-
-print(test() + test())
diff --git a/lib/libesp32/Berry/tests/relop.be b/lib/libesp32/Berry/tests/relop.be
deleted file mode 100644
index a9a9805f15d0..000000000000
--- a/lib/libesp32/Berry/tests/relop.be
+++ /dev/null
@@ -1,40 +0,0 @@
-def assert_true(status)
- assert(status == true, 'assert(true) failed!')
-end
-
-def assert_false(status)
- assert(status == false, 'assert(false) failed!')
-end
-
-assert_true(0 == 0)
-assert_false(0 != 0)
-assert_true(0 != 1)
-assert_false(0 == 1)
-
-
-assert_true(0.0 == 0)
-assert_false(0.0 != 0)
-assert_true(0.0 != 1.0)
-assert_false(0.0 == 1.0)
-
-assert_true(nil == nil)
-assert_false(nil != nil)
-assert_true(true != nil)
-assert_false(true == nil)
-assert_true(nil != false)
-assert_false(nil == false)
-
-assert_true(list == list)
-assert_false(list == map)
-
-assert_true([] == [])
-assert_true([true] == [true])
-assert_true([[]] == [[]])
-assert_false([[]] != [[]])
-assert_false([0] == [])
-assert_false([] != [])
-assert_true([] != nil)
-assert_false([] == nil)
-
-assert_true({} != nil)
-assert_false({} == nil)
diff --git a/lib/libesp32/Berry/tests/string.be b/lib/libesp32/Berry/tests/string.be
deleted file mode 100644
index 448ca52157ee..000000000000
--- a/lib/libesp32/Berry/tests/string.be
+++ /dev/null
@@ -1,215 +0,0 @@
-import string as s
-
-assert(s.find('012345', '23') == 2)
-assert(s.find('012345', '23', 1) == 2)
-assert(s.find('012345', '23', 1, 3) == -1)
-assert(s.find('012345', '23', 2, 4) == 2)
-assert(s.find('012345', '23', 3) == -1)
-
-assert(s.find('012345', '') == 0)
-assert(s.find('012345', '', 0, 0) == 0)
-assert(s.find('012345', '', 1) == 1)
-assert(s.find('012345', '', 1, 1) == 1)
-assert(s.find('012345', '', 1, 0) == -1)
-assert(s.find('012345', '', 6) == 6)
-assert(s.find('012345', '', 7) == -1)
-
-assert(s.count('012345', '') == 7)
-assert(s.count('012345', '', 2) == 5)
-assert(s.count('012345', '', 6) == 1)
-
-assert(s.count('121314', '1') == 3)
-assert(s.count('121314', '1', 1) == 2)
-assert(s.count('121314', '1', 2) == 2)
-assert(s.count('121314', '1', 1, 2) == 0)
-assert(s.count('121314', '1', 1, 3) == 1)
-
-assert(s.split('a b c d e f', '1') == ['a b c d e f'])
-assert(s.split('a b c d e f', ' ') == ['a', 'b', 'c', 'd', 'e', 'f'])
-assert(s.split('a b c d e f', ' ', 2) == ['a', 'b', 'c d e f'])
-assert(s.split('a b c d e f', '') == ['a b c d e f'])
-
-assert(s.format("%%") == "%")
-assert(s.format("%i%%", 12) == "12%")
-assert(s.format("%i%%%i", 12, 13) == "12%13")
-assert(s.format("%s%%", "foo") == "foo%")
-assert(s.format("%.1f%%", 3.5) == "3.5%")
-
-s="azerty"
-assert(s[1..2] == "ze")
-assert(s[1..] == "zerty")
-assert(s[1..-1] == "zerty")
-
-#- string ranges -#
-s="azertyuiop"
-assert(s[0] == "a")
-assert(s[0..1] == "az")
-assert(s[0..2] == "aze")
-assert(s[0..10] == s)
-assert(s[0..size(s)] == s)
-assert(s[0..50] == s) #- upper limit is allowed to be out of range -#
-
-#- negative indices start from the end -#
-s="azertyuiop"
-assert(s[-1] == "p")
-assert(s[-2] == "o")
-assert(s[0..-2] == "azertyuio")
-assert(s[-4..-2] == "uio")
-assert(s[-2..-4] == "") #- if range is in wrong order, returns empty string -#
-assert(s[-40..-2] == "azertyuio") #- borders are allowed to be out of range -#
-
-# escape
-import string
-assert(string.escape("A") == '"A"')
-assert(string.escape("A", true) == "'A'")
-assert(string.escape("\"") == '"\\""')
-assert(string.escape("\"", true) == '\'"\'')
-
-var s ='"a\'b"\''
-assert(string.escape(s) == '"\\"a\'b\\"\'"')
-assert(string.escape(s, true) == '\'"a\\\'b"\\\'\'')
-
-# tr
-assert(string.tr("azer", "abcde", "ABCDE") == 'AzEr')
-assert(string.tr("azer", "", "") == 'azer')
-assert(string.tr("azer", "aaa", "ABC") == 'Azer') # only first match works
-assert(string.tr("A_b", "_", " ") == 'A b')
-# tr used to remove characters
-assert(string.tr("qwerty", "qwe", "_") == '_rty')
-
-# the following should not crash
-var s1 = 'A string of more than 128 bytes 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'
-var s2 = string.format("%i, %s", 1, s1)
-
-# replace
-assert(string.replace("hello", "ll", "xx") == "hexxo")
-assert(string.replace("hellollo", "ll", "xx") == "hexxoxxo")
-assert(string.replace("hellollo", "aa", "xx") == "hellollo")
-assert(string.replace("hello", "ll", "") == "heo")
-assert(string.replace("hello", "", "xx") == "hello")
-assert(string.replace("hello", "", "") == "hello")
-
-# multi-line strings
-var s = "a" "b""c"
-assert(s == 'abc')
-
-s = 'a'"b"'''c'
-assert(s == 'abc')
-
-s = "a"
-'b'
- ""
- "c"
-assert(s == 'abc')
-
-s = "a" #- b -# "b" #--# "c"
-assert(s == 'abc')
-
-s = "a"#
- # "z"
- "b" # zz
- "c"
-assert(s == 'abc')
-
-# string.format with automatic conversion
-import string
-
-assert(string.format("%i", 3) == '3')
-assert(string.format("%i", "3") == '3')
-assert(string.format("%i", "03") == '3')
-assert(string.format("%i", nil) == '')
-
-class A def toint() return 42 end end
-a=A()
-class B end
-b=B()
-
-assert(string.format("%i", a) == '42')
-assert(string.format("%i", b) == '')
-
-assert(string.format("%i", nil) == '')
-assert(string.format("%i", true) == '1')
-assert(string.format("%i", false) == '0')
-
-assert(string.format("%c", a) == '*')
-
-assert(string.format("%f", 3.5) == '3.500000')
-assert(string.format("%f", 3) == '3.000000')
-assert(string.format("%.1f", 3) == '3.0')
-assert(string.format("%.1f", nil) == '')
-assert(string.format("%.1f", true) == '')
-assert(string.format("%.1f", false) == '')
-assert(string.format("%.1f", a) == '')
-
-assert(string.format("%s", a) == '')
-assert(string.format("%s", 0) == '0')
-assert(string.format("%s", nil) == 'nil')
-assert(string.format("%s", true) == 'true')
-assert(string.format("%s", false) == 'false')
-
-assert(string.format("%q", "\ntest") == '\'\\ntest\'')
-
-# corrupt format string should not crash the VM
-string.format("%0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", 3.5)
-
-# format is now synonym to string.format
-assert(format == string.format)
-assert(format("%.1f", 3) == '3.0')
-
-# f-strings
-assert(f"" == '')
-assert(f'' == '')
-assert(f"abc\n\r\t" == 'abc\n\r\t')
-assert(f'{{a}}' == '{a}')
-assert(f'\\\\' == '\\\\')
-
-assert(f"A = {1+1}" == 'A = 2')
-assert(f"A = {1+1:s}" == 'A = 2')
-assert(f"A = {1+1:i}" == 'A = 2')
-assert(f"A = {1+1:04i}" == 'A = 0002')
-
-assert(f"P = {3.1415:.2f}" == 'P = 3.14')
-
-var a = 'foobar{0}'
-assert(f"S = {a}" == 'S = foobar{0}')
-assert(f"S = {a:i}" == 'S = 0')
-assert(f"{a=}" == 'a=foobar{0}')
-
-# startswith case sensitive
-assert(string.startswith("", "") == true)
-assert(string.startswith("qwerty", "qw") == true)
-assert(string.startswith("qwerty", "qwerty") == true)
-assert(string.startswith("qwerty", "") == true)
-assert(string.startswith("qwerty", "qW") == false)
-assert(string.startswith("qwerty", "QW") == false)
-assert(string.startswith("qwerty", "qz") == false)
-assert(string.startswith("qwerty", "qwertyw") == false)
-
-# startswith case insensitive
-assert(string.startswith("qwerty", "qw", true) == true)
-assert(string.startswith("qwerty", "qwerty", true) == true)
-assert(string.startswith("qwerty", "", true) == true)
-assert(string.startswith("qwerty", "qW", true) == true)
-assert(string.startswith("qwerty", "QW", true) == true)
-assert(string.startswith("qwerty", "qz", true) == false)
-assert(string.startswith("qwerty", "qwertyw", true) == false)
-
-# endswith case sensitive
-assert(string.endswith("", "") == true)
-assert(string.endswith("qwerty", "ty") == true)
-assert(string.endswith("qwerty", "qwerty") == true)
-assert(string.endswith("qwerty", "") == true)
-assert(string.endswith("qwerty", "tY") == false)
-assert(string.endswith("qwerty", "TY") == false)
-assert(string.endswith("qwerty", "tr") == false)
-assert(string.endswith("qwerty", "qwertyw") == false)
-
-# endswith case insensitive
-assert(string.endswith("", "", true) == true)
-assert(string.endswith("qwerty", "ty", true) == true)
-assert(string.endswith("qwerty", "qwerty", true) == true)
-assert(string.endswith("qwerty", "", true) == true)
-assert(string.endswith("qwerty", "tY", true) == true)
-assert(string.endswith("qwerty", "TY", true) == true)
-assert(string.endswith("qwerty", "tr", true) == false)
-assert(string.endswith("qwerty", "qwertyw", true) == false)
diff --git a/lib/libesp32/Berry/tests/subobject.be b/lib/libesp32/Berry/tests/subobject.be
deleted file mode 100644
index 010e8af2984b..000000000000
--- a/lib/libesp32/Berry/tests/subobject.be
+++ /dev/null
@@ -1,29 +0,0 @@
-class mylist : classof([]) end
-
-assert(issubclass(mylist, list) == true)
-assert(issubclass(mylist, []) == true)
-assert(issubclass(mylist(), list) == false)
-assert(issubclass(mylist(), []) == false)
-
-assert(isinstance(mylist, list) == false)
-assert(isinstance(mylist, []) == false)
-assert(isinstance(mylist(), list) == true)
-assert(isinstance(mylist(), []) == true)
-
-assert(issubclass(list, list) == true)
-assert(issubclass(list, []) == true)
-assert(issubclass(list(), list) == false)
-assert(issubclass(list(), []) == false)
-
-assert(isinstance(list, list) == false)
-assert(isinstance(list, []) == false)
-assert(isinstance(list(), list) == true)
-assert(isinstance(list(), []) == true)
-
-assert(issubclass(list, list) == true)
-assert(issubclass(list, []) == true)
-assert(issubclass(list(), list) == false)
-assert(issubclass(list(), []) == false)
-
-assert(issubclass(list, mylist) == false)
-assert(isinstance([], mylist) == false)
diff --git a/lib/libesp32/Berry/tests/suffix.be b/lib/libesp32/Berry/tests/suffix.be
deleted file mode 100644
index 11f429aa7f70..000000000000
--- a/lib/libesp32/Berry/tests/suffix.be
+++ /dev/null
@@ -1,28 +0,0 @@
-var keys = [ 'key1', 'key2', 'key3', 'key4' ]
-var pairs = {
- keys[0]: 'value1',
- keys[1]: 'value2',
- keys[2]: 'value3',
- keys[3]: 'value4'
-}
-
-for i : 0 .. keys.size() - 1
- assert(pairs[keys[i]] == 'value' .. i + 1)
-end
-
-#- test cases related to #101 -#
-class C var l end
-c=C()
-c.l=[0,1,2]
-
-def t_101_nok_1() return c.l[0..1] end
-def t_101_ok_1() var l2 = c.l return l2[0..1] end
-
-t_i = 0
-def t_101_nok_2() return c.l[t_i] end
-def t_101_ok_2() return c.l[0] end
-
-assert(t_101_nok_1() == [0, 1])
-assert(t_101_ok_1() == [0, 1])
-assert(t_101_nok_2() == 0)
-assert(t_101_ok_2() == 0)
diff --git a/lib/libesp32/Berry/tests/super_auto.be b/lib/libesp32/Berry/tests/super_auto.be
deleted file mode 100644
index 8d7ede85fd6e..000000000000
--- a/lib/libesp32/Berry/tests/super_auto.be
+++ /dev/null
@@ -1,132 +0,0 @@
-#- test for new auto class inference of super() -#
-
-#- test that we can call init() even if it's not defined -#
-class Z end
-z=Z()
-assert(z.init != nil)
-z.init() #- should do nothing -#
-
-#- check the old way still works -#
-class A1
- var a
- def init(a)
- self.a = a
- end
-end
-class B1:A1
- var b
- def init(a,b)
- super(self,A1).init(a)
- self.b = b
- end
-end
-class C1:B1
- var c
- def init(a,b,c)
- super(self,B1).init(a,b)
- self.c = c
- end
-end
-#- -#
-c1=C1(1,2,3)
-assert(c1.a == 1)
-assert(c1.b == 2)
-assert(c1.c == 3)
-
-#- test simple behavior -#
-class A0 var a end
-class B0:A0 var b end
-class C0:B0 end
-c0=C0()
-assert(classof(c0) == C0)
-assert(classof(super(c0)) == B0)
-assert(classof(super(super(c0))) == A0)
-assert(super(super(super(c0))) == nil)
-
-assert(super(C0) == B0)
-assert(super(super(C0)) == A0)
-assert(super(super(super(C0))) == nil)
-
-assert(classof(super(c0,B0)) == B0)
-assert(classof(super(c0,A0)) == A0)
-
-#- test auto inference of target superclass -#
-class A
- var a
- def init(a)
- self.a = a
- end
-end
-class B:A
- var b
- def init(a,b)
- super(self).init(a)
- self.b = b
- end
-end
-class C:B
- var c
- def init(a,b,c)
- super(self).init(a,b)
- self.c = c
- end
-end
-#- -#
-c=C(1,2,3)
-
-assert(c.a == 1)
-assert(c.b == 2)
-assert(c.c == 3)class A
-end
-class B:A
- var b
- def init(a,b) super(self).init(a) self.b = b end
-end
-class C:B
- var c
- def init(a,b,c) super(self).init(a,b) self.c = c end
-end
-c=C(1,2,3)
-
-#- variant if A2 does not have an init() method, still works -#
-class A2
- static a=1
-end
-class B2:A2
- var b
- def init(a,b) super(self).init(a) self.b = b end
-end
-class C2:B2
- var c
- def init(a,b,c) super(self).init(a,b) self.c = c end
-end
-#- -#
-c2=C2(1,2,3)
-assert(c2.a == 1)
-assert(c2.b == 2)
-assert(c2.c == 3)
-
-#- difference in behavior whether the second arg is provided or not -#
-class A3
-end
-class B3:A3
- def b1()
- return super(self)
- end
- def b2(c)
- return super(self, c)
- end
-end
-class C3:B3
-end
-#- -#
-b3=B3()
-c3=C3()
-assert(classof(c3.b1()) == A3)
-assert(classof(b3.b1()) == A3)
-assert(classof(c3.b2(B3)) == B3)
-assert(classof(c3.b2(A3)) == A3)
-
-assert(classof(c3.b2(nil)) == B3) #- testing super(self,nil) in B3::b2() -#
-
-assert(c3.b2(C3) == nil) #- if specifying the current class, can't find any relevant class in supers -#
\ No newline at end of file
diff --git a/lib/libesp32/Berry/tests/super_leveled.be b/lib/libesp32/Berry/tests/super_leveled.be
deleted file mode 100644
index e8891494123b..000000000000
--- a/lib/libesp32/Berry/tests/super_leveled.be
+++ /dev/null
@@ -1,43 +0,0 @@
-#- test for leveled use of super() -#
-
-#- setup -#
-class A def r() return 'a' end def f() return self.r() end end
-class B:A def r() return 'b' end def f() return super(self,A).f() + 'b' end end
-class C:B def r() return 'c' end def f() return super(self,B).f() + 'c' end end
-a=A()
-b=B()
-c=C()
-
-#- regular behavior -#
-assert(classname(a) == 'A')
-assert(classname(b) == 'B')
-assert(classname(c) == 'C')
-assert(a.r() == 'a')
-assert(b.r() == 'b')
-assert(c.r() == 'c')
-assert(a.f() == 'a')
-
-#- standard use of super() -#
-assert(super(a) == nil)
-assert(super(A) == nil)
-assert(classname(super(B)) == 'A')
-assert(classname(super(C)) == 'B')
-assert(classname(super(super(C))) == 'A')
-assert(super(super(super(C))) == nil)
-
-#- super() levele -#
-assert(super(a,A) == nil)
-assert(super(b,B) == nil)
-assert(super(c,C) == nil)
-assert(classname(super(c,B)) == 'B')
-assert(classname(super(c,A)) == 'A')
-assert(super(c,map) == nil) #- not a parent class -#
-
-#- wrapping it all -#
-assert(a.f() == 'a')
-assert(b.f() == 'bb')
-
-#- the last one is tricky:
- c.f() -> calls f() in class B -> calls f() in class A -> calls r() of overall class hence C
--#
-assert(c.f() == 'cbc')
\ No newline at end of file
diff --git a/lib/libesp32/Berry/tests/vararg.be b/lib/libesp32/Berry/tests/vararg.be
deleted file mode 100644
index 7dd3541d3c48..000000000000
--- a/lib/libesp32/Berry/tests/vararg.be
+++ /dev/null
@@ -1,14 +0,0 @@
-#- vararg -#
-def f(a,*b) return b end
-
-assert(f() == [])
-assert(f(1) == [])
-assert(f(1,2) == [2])
-assert(f(1,2,3) == [2, 3])
-
-def g(*a) return a end
-
-assert(g() == [])
-assert(g("foo") == ["foo"])
-assert(g("foo", nil) == ["foo", nil])
-assert(g("foo", nil, 2) == ["foo", nil, 2])
diff --git a/lib/libesp32/Berry/tests/virtual_methods.be b/lib/libesp32/Berry/tests/virtual_methods.be
deleted file mode 100644
index e744dcca84ee..000000000000
--- a/lib/libesp32/Berry/tests/virtual_methods.be
+++ /dev/null
@@ -1,72 +0,0 @@
-#- basic initialization -#
-
-def assert_attribute_error(f)
- try
- f()
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'attribute_error')
- end
-end
-
-class T1
- var a, b
- def init()
- self.a = 1
- self.b = 2
- end
- def f() return true end
- def g() return false end
-end
-t = T1()
-
-#- warm up -#
-assert(t.a == 1)
-assert(t.b == 2)
-assert(t.f() == true)
-assert(t.g() == false)
-
-#- test normal errors when method does not exist -#
-assert_attribute_error(/-> t.h())
-assert_attribute_error(/-> t.c)
-
-class T2 : T1
- def member(n)
- import undefined
- if (n == 'f1') return / n -> n end
- if (n == 'f2') return /-> 4 end
- if (n == 'a1') return 10 end
- if (n == 'h') return undefined end
- end
-end
-t2 = T2()
-
-#- test non-regression -#
-assert(t2.a == 1)
-assert(t2.b == 2)
-assert(t2.f() == true)
-assert(t2.g() == false)
-assert_attribute_error(/-> t2.h())
-
-#- try virtual methods -#
-assert(t2.f1() == t2)
-assert(t2.f2() == 4)
-assert(t2.a1 == 10)
-assert(t2.foo == nil)
-
-#- module -#
-m = module("m")
-
-m.a = 1
-assert(m.a == 1)
-assert_attribute_error(/-> m.b)
-
-m.member = def(n)
- import undefined
- if n == "b" return 2 end
- if n == "c" return undefined end
-end
-
-assert(m.b == 2)
-assert_attribute_error(/-> m.c)
-assert(m.d == nil) #- returns nil if no response -#
diff --git a/lib/libesp32/Berry/tests/virtual_methods2.be b/lib/libesp32/Berry/tests/virtual_methods2.be
deleted file mode 100644
index 10fee905de92..000000000000
--- a/lib/libesp32/Berry/tests/virtual_methods2.be
+++ /dev/null
@@ -1,39 +0,0 @@
-#- virtual attributes -#
-
-def assert_attribute_error(f)
- try
- f()
- assert(false, 'unexpected execution flow')
- except .. as e, m
- assert(e == 'attribute_error')
- end
-end
-
-class Ta
- var a, b, virtual_c
- def init()
- self.a = 1
- self.b = 2
- self.virtual_c = 3
- end
- def member(n)
- if n == 'c' return self.virtual_c end
- return nil
- end
- def setmember(n, v)
- if n == 'c' self.virtual_c = v return true end
- return false
- end
-end
-ta = Ta()
-
-assert(ta.a == 1)
-assert(ta.b == 2)
-assert(ta.c == 3)
-ta.a = 10
-assert(ta.a == 10)
-assert(ta.c == 3)
-ta.c = 30
-assert(ta.c == 30)
-assert(ta.virtual_c == 30)
-assert_attribute_error(def() ta.d = 0 end)
diff --git a/lib/libesp32/Berry/tools/grammar/berry.bytecode b/lib/libesp32/Berry/tools/grammar/berry.bytecode
deleted file mode 100755
index 6b90c2a1d8ae..000000000000
--- a/lib/libesp32/Berry/tools/grammar/berry.bytecode
+++ /dev/null
@@ -1,92 +0,0 @@
--------------------------------------------------------------------------------
--- the Berry's bytecode file structure (version 1)
---
--- description
---
--- a double dash ('--') start a line comment.
--- a: b means that the entity 'a' is realized by the 'b' structure.
--- a: b c 'b' and 'c' are arranged in a compact order (one byte alignment).
--- [a] means that structure 'a' can be repeated 0 to any times.
--- [a](b) means that structure 'a' can be repeated 'b' times.
--- a | b means that the entity can be implemented by structure 'a' or 'b'.
--- N a number indicates the byte count of the field (eg. 'a: 1').
--- .N means the number of bits in the field (eg. 'a: .1').
--- only the first entity is a file entity (the root).
--------------------------------------------------------------------------------
-
-bytecode_file: -- little endian
- header
- global_desc
- main_function
-
-header: 8
- magic_number: 3 -- 0xbecdfe (berry code file)
- version: 1 -- 0x03 update with file structure definition
- integer_size: .1
- float_size: .1
- -- reserved space
-
-main_function -> function
-
-global_desc:
- builtin_count: 4
- global_count: 4 -- excluding builtins
- global_name -> [
- string
- ](global_count)
-
-function:
- information:
- function_name:
- string
- source:
- string
- argc: 1 -- arguments count
- nstack: 1 -- number of stack size by this function
- varg: 1
- extra: 1 -- extra data
- bytecode:
- code_size: 4
- code_array -> [ -- bytecode array
- instruction: 4
- ](code_size)
- constant_table:
- constant_count: 4
- [constant_value](constant_count)
- proto_table:
- proto_count: 4
- [function](proto_count)
- upval_table:
- upval_count: 1
- upvals: [
- instack: 1
- index: 1
- ](upval_count)
- debug_info:
- -- reserved
-
-constant_value:
- type: 1 -- type of value
- integer | float | string | class
-
-string:
- string_size: 2
- byte_array: string_size
-
-class:
- class_name:
- string
- member_count: 4 -- number of member variables
- method_count: 4 -- number of method
- method_table: [
- string -- method name
- function | nil -- method function body or nil (static member) if the first byte is null (which would be an empty func name)
- ](method_count)
- member_index_table -> [
- string -- member name
- ](member_count)
-
-nil: 1
-boolean: 1
-integer: 4 | 8
-float: 4 | 8
diff --git a/lib/libesp32/Berry/tools/grammar/berry.ebnf b/lib/libesp32/Berry/tools/grammar/berry.ebnf
deleted file mode 100644
index 86eef9b58206..000000000000
--- a/lib/libesp32/Berry/tools/grammar/berry.ebnf
+++ /dev/null
@@ -1,49 +0,0 @@
-(* program define *)
-program = block;
-(* block define *)
-block = {statement};
-(* statement define *)
-statement = class_stmt | func_stmt | var_stmt | if_stmt | while_stmt |
- for_stmt | break_stmt | return_stmt | expr_stmt | import_stmt |
- try_stmt | throw_stmt | do_stmt | ';';
-if_stmt = 'if' expr block {'elif' expr block} ['else' block] 'end';
-while_stmt = 'while' expr block 'end';
-do_stmt = 'do' block 'end';
-for_stmt = 'for' ID ':' expr block 'end';
-break_stmt = 'break' | 'continue';
-return_stmt = 'return' [expr];
-(* function define statement *)
-func_stmt = 'def' ID func_body;
-func_body = '(' [arg_field {',' arg_field}] ')' block 'end';
-arg_field = ['*'] ID;
-(* class define statement *)
-class_stmt = 'class' ID [':' ID] class_block 'end';
-class_block = {'var' ID {',' ID} | 'static' ['var'] ID ['=' expr] {',' ID ['=' expr] } | 'static' func_stmt | func_stmt};
-import_stmt = 'import' (ID (['as' ID] | {',' ID}) | STRING 'as' ID);
-(* exceptional handling statement *)
-try_stmt = 'try' block except_block {except_block} 'end';
-except_block = except_stmt block;
-except_stmt = 'except' (expr {',' expr} | '..') ['as' ID [',' ID]];
-throw_stmt = 'raise' expr [',' expr];
-(* variable define statement *)
-var_stmt = 'var' ID ['=' expr] {',' ID ['=' expr]};
-(* expression define *)
-expr_stmt = expr [assign_op expr];
-expr = suffix_expr | unop expr | expr binop expr | range_expr | cond_expr | walrus_expr;
-cond_expr = expr '?' expr ':' expr; (* conditional expression *)
-assign_op = '=' | '+=' | '-=' | '*=' | '/=' |
- '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=';
-binop = '<' | '<=' | '==' | '!=' | '>' | '>=' | '||' | '&&' |
- '<<' | '>>' | '&' | '|' | '^' | '+' | '-' | '*' | '/' | '%';
-range_expr = expr '..' [expr]
-unop = '-' | '!' | '~';
-walrus_expr = expr ':=' expr
-suffix_expr = primary_expr {call_expr | ('.' ID) | '[' expr ']'};
-primary_expr = '(' expr ')' | simple_expr | list_expr | map_expr | anon_func | lambda_expr;
-simple_expr = INTEGER | REAL | STRING | ID | 'true' | 'false' | 'nil' | f_string;
-f_string = 'f' STRING
-call_expr = '(' [expr {',' expr}] ')';
-list_expr = '[' {expr ','} [expr] ']';
-map_expr = '{' {expr ':' expr ','} [expr ':' expr] '}';
-anon_func = 'def' func_body; (* anonymous function *)
-lambda_expr = '/' [arg_field {',' arg_field}] | {arg_field}] '->' expr;
diff --git a/lib/libesp32/Berry/tools/grammar/const_obj.ebnf b/lib/libesp32/Berry/tools/grammar/const_obj.ebnf
deleted file mode 100755
index 6c38a42624ac..000000000000
--- a/lib/libesp32/Berry/tools/grammar/const_obj.ebnf
+++ /dev/null
@@ -1,11 +0,0 @@
-block = type name ['(' {attributes} ')'] '{' {data_fields} '}';
-type = 'map' | 'class' | 'module' | 'vartab';
-
-attributes = name ':' name [','];
-data_fields = data_name ',' data_value [':' depend_macro] '\n';
-
-(* regular expression *)
-name = [_a-zA-Z]\w*;
-data_name = [\._a-zA-Z]\w*;
-data_value = [\w\()]+;
-depend_macro = [_a-zA-Z]\w*;
diff --git a/lib/libesp32/Berry/tools/grammar/json.ebnf b/lib/libesp32/Berry/tools/grammar/json.ebnf
deleted file mode 100644
index 47c317193989..000000000000
--- a/lib/libesp32/Berry/tools/grammar/json.ebnf
+++ /dev/null
@@ -1,5 +0,0 @@
-json = value;
-value = object | array |
- string | number | 'true' | 'false' | 'null';
-object = '{' [ string ':' value ] { ',' string ':' value } '}';
-array = '[' [json] { ',' json } ']';