interpreters/berry: Add Berry scripting language

Add an optional Berry interpreter under apps/interpreters.

Fetch the pinned upstream source and apply the NuttX default-port patch.

Generate Berry constant objects and build the NSH command through Kconfig.

Make and CMake build paths are included for normal app integration.

Signed-off-by: Frederick Blais <fred_blais5@hotmail.com>
This commit is contained in:
Frederick Blais 2026-06-26 09:12:29 -04:00 committed by Xiang Xiao
parent 253f1d40c3
commit a2b1cc16da
6 changed files with 426 additions and 0 deletions

View file

@ -0,0 +1,27 @@
diff --git a/default/berry.c b/default/berry.c
index d6ea5d1..bb95fc7 100644
--- a/default/berry.c
+++ b/default/berry.c
@@ -22 +22,3 @@
-#if defined(__linux)
+#if defined(__NuttX__)
+ #define OS_NAME "NuttX"
+#elif defined(__linux)
@@ -103 +105 @@
- const char *optarg;
+ const char *optvalue;
@@ -148 +150 @@
- opt->optarg = argv[opt->idx++]; /* save the argument */
+ opt->optvalue = argv[opt->idx++]; /* save the argument */
@@ -151 +153 @@
- opt->optarg = NULL;
+ opt->optvalue = NULL;
@@ -272 +274 @@
- opt->modulepath = opt->optarg;
+ opt->modulepath = opt->optvalue;
@@ -277 +279 @@
- opt->src = opt->optarg;
+ opt->src = opt->optvalue;
@@ -281 +283 @@
- opt->dst = opt->optarg;
+ opt->dst = opt->optvalue;

View file

@ -0,0 +1,148 @@
# ##############################################################################
# apps/interpreters/berry/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
if(CONFIG_INTERPRETERS_BERRY)
set(BERRY_COMMIT_ID 4db341475df9e9ad18e6741ef978b4c467690e09)
set(BERRY_DIR ${CMAKE_CURRENT_LIST_DIR}/berry)
if(NOT EXISTS ${BERRY_DIR})
set(BERRY_URL_BASE https://github.com/berry-lang/berry/archive/)
FetchContent_Declare(
berry_fetch
URL ${BERRY_URL_BASE}/${BERRY_COMMIT_ID}.zip SOURCE_DIR
${CMAKE_CURRENT_LIST_DIR}/berry BINARY_DIR
${CMAKE_BINARY_DIR}/apps/interpreters/berry/berry
PATCH_COMMAND
patch -l -p1 -d ${CMAKE_CURRENT_LIST_DIR}/berry -i
${CMAKE_CURRENT_LIST_DIR}/0001-Fix-Berry-default-port-for-NuttX.patch
DOWNLOAD_NO_PROGRESS true
TIMEOUT 30)
FetchContent_GetProperties(berry_fetch)
if(NOT berry_fetch_POPULATED)
FetchContent_Populate(berry_fetch)
endif()
endif()
find_package(
Python3
COMPONENTS Interpreter
REQUIRED)
set(BERRY_CONFIG_DIR ${CMAKE_CURRENT_LIST_DIR}/include)
set(BERRY_CONFIG ${BERRY_CONFIG_DIR}/berry_conf.h)
set(BERRY_GENERATE ${BERRY_DIR}/generate)
set(BERRY_GEN_STAMP ${BERRY_GENERATE}/.generated)
set(BERRY_FLAGS -Wno-unused-but-set-variable)
set(BERRY_INCDIR ${BERRY_CONFIG_DIR} ${BERRY_DIR}/src ${BERRY_DIR}/default)
set(BERRY_CSRCS
${BERRY_DIR}/src/be_api.c
${BERRY_DIR}/src/be_baselib.c
${BERRY_DIR}/src/be_bytecode.c
${BERRY_DIR}/src/be_byteslib.c
${BERRY_DIR}/src/be_class.c
${BERRY_DIR}/src/be_code.c
${BERRY_DIR}/src/be_debug.c
${BERRY_DIR}/src/be_debuglib.c
${BERRY_DIR}/src/be_exec.c
${BERRY_DIR}/src/be_filelib.c
${BERRY_DIR}/src/be_func.c
${BERRY_DIR}/src/be_gc.c
${BERRY_DIR}/src/be_gclib.c
${BERRY_DIR}/src/be_globallib.c
${BERRY_DIR}/src/be_introspectlib.c
${BERRY_DIR}/src/be_jsonlib.c
${BERRY_DIR}/src/be_lexer.c
${BERRY_DIR}/src/be_libs.c
${BERRY_DIR}/src/be_list.c
${BERRY_DIR}/src/be_listlib.c
${BERRY_DIR}/src/be_map.c
${BERRY_DIR}/src/be_maplib.c
${BERRY_DIR}/src/be_mathlib.c
${BERRY_DIR}/src/be_mem.c
${BERRY_DIR}/src/be_module.c
${BERRY_DIR}/src/be_object.c
${BERRY_DIR}/src/be_oslib.c
${BERRY_DIR}/src/be_parser.c
${BERRY_DIR}/src/be_rangelib.c
${BERRY_DIR}/src/be_repl.c
${BERRY_DIR}/src/be_solidifylib.c
${BERRY_DIR}/src/be_strictlib.c
${BERRY_DIR}/src/be_string.c
${BERRY_DIR}/src/be_strlib.c
${BERRY_DIR}/src/be_syslib.c
${BERRY_DIR}/src/be_timelib.c
${BERRY_DIR}/src/be_undefinedlib.c
${BERRY_DIR}/src/be_var.c
${BERRY_DIR}/src/be_vector.c
${BERRY_DIR}/src/be_vm.c
${BERRY_DIR}/default/be_modtab.c
${BERRY_DIR}/default/be_port.c)
add_custom_command(
OUTPUT ${BERRY_GEN_STAMP}
COMMAND ${CMAKE_COMMAND} -E make_directory ${BERRY_GENERATE}
COMMAND
${Python3_EXECUTABLE} ${BERRY_DIR}/tools/coc/coc -o ${BERRY_GENERATE}
${BERRY_DIR}/src ${BERRY_DIR}/default -c ${BERRY_CONFIG}
COMMAND ${CMAKE_COMMAND} -E touch ${BERRY_GEN_STAMP}
DEPENDS ${BERRY_CSRCS} ${BERRY_CONFIG}
WORKING_DIRECTORY ${BERRY_DIR}
COMMENT "Generating Berry constant objects")
add_custom_target(berry_coc DEPENDS ${BERRY_GEN_STAMP})
nuttx_add_library(libberry)
target_sources(libberry PRIVATE ${BERRY_CSRCS})
target_include_directories(libberry PRIVATE ${BERRY_INCDIR})
target_compile_options(libberry PRIVATE ${BERRY_FLAGS})
add_dependencies(libberry berry_coc)
nuttx_export_header(TARGET libberry INCLUDE_DIRECTORIES ${BERRY_DIR}/src)
set_property(
TARGET nuttx
APPEND
PROPERTY NUTTX_INCLUDE_DIRECTORIES ${BERRY_DIR}/src)
nuttx_add_application(
MODULE
${CONFIG_INTERPRETERS_BERRY}
NAME
${CONFIG_INTERPRETERS_BERRY_PROGNAME}
STACKSIZE
${CONFIG_INTERPRETERS_BERRY_STACKSIZE}
PRIORITY
${CONFIG_INTERPRETERS_BERRY_PRIORITY}
SRCS
${BERRY_DIR}/default/berry.c
INCLUDE_DIRECTORIES
${BERRY_INCDIR}
COMPILE_FLAGS
${BERRY_FLAGS}
DEPENDS
libberry
berry_coc)
endif()

View file

@ -0,0 +1,43 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config INTERPRETERS_BERRY
tristate "Berry scripting language"
default n
depends on ARCH_SETJMP_H
depends on LIBC_FLOATINGPOINT
depends on SYSTEM_SYSTEM
---help---
Enable the Berry embedded scripting language as an NSH built-in
command. Berry provides a small ANSI C99 compiler, register-based
virtual machine, garbage collector, file I/O, bytecode loading and
saving, and built-in modules.
The default NuttX configuration keeps Berry shared-library loading
disabled so boards do not need CONFIG_LIBC_DLFCN. The math module
is enabled, so select a NuttX math library or provide one from the
toolchain.
if INTERPRETERS_BERRY
config INTERPRETERS_BERRY_PROGNAME
string "Berry program name"
default "berry"
---help---
The command name used to start the Berry interpreter.
config INTERPRETERS_BERRY_PRIORITY
int "Berry interpreter priority"
default 100
---help---
Task priority of the Berry interpreter main task.
config INTERPRETERS_BERRY_STACKSIZE
int "Berry interpreter stack size"
default 12288
---help---
Size of the stack allocated for the Berry interpreter main task.
endif # INTERPRETERS_BERRY

View file

@ -0,0 +1,25 @@
############################################################################
# apps/interpreters/berry/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_INTERPRETERS_BERRY),)
CONFIGURED_APPS += $(APPDIR)/interpreters/berry
endif

View file

@ -0,0 +1,97 @@
############################################################################
# apps/interpreters/berry/Makefile
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(APPDIR)/Make.defs
BERRY_COMMIT_ID = 4db341475df9e9ad18e6741ef978b4c467690e09
BERRY_UNPACK = berry
BERRY_ARCHIVE = berry-$(BERRY_COMMIT_ID).zip
BERRY_URL_BASE = https://github.com/berry-lang/berry/archive/
BERRY_URL = $(BERRY_URL_BASE)/$(BERRY_COMMIT_ID).zip
BERRY_CONFIG = include$(DELIM)berry_conf.h
BERRY_COC = $(BERRY_UNPACK)$(DELIM)tools$(DELIM)coc$(DELIM)coc
BERRY_GENERATE = $(BERRY_UNPACK)$(DELIM)generate
BERRY_GEN_STAMP = $(BERRY_GENERATE)$(DELIM).generated
BERRY_SRCS = be_api.c be_baselib.c be_bytecode.c be_byteslib.c
BERRY_SRCS += be_class.c be_code.c be_debug.c be_debuglib.c be_exec.c
BERRY_SRCS += be_filelib.c be_func.c be_gc.c be_gclib.c be_globallib.c
BERRY_SRCS += be_introspectlib.c be_jsonlib.c be_lexer.c be_libs.c
BERRY_SRCS += be_list.c be_listlib.c be_map.c be_maplib.c be_mathlib.c
BERRY_SRCS += be_mem.c be_module.c be_object.c be_oslib.c be_parser.c
BERRY_SRCS += be_rangelib.c be_repl.c be_solidifylib.c be_strictlib.c
BERRY_SRCS += be_string.c be_strlib.c be_syslib.c be_timelib.c
BERRY_SRCS += be_undefinedlib.c be_var.c be_vector.c be_vm.c
CSRCS = $(BERRY_SRCS)
CSRCS += be_modtab.c be_port.c
MAINSRC = berry.c
VPATH += $(BERRY_UNPACK)$(DELIM)src
VPATH += $(BERRY_UNPACK)$(DELIM)default
DEPPATH += --dep-path $(BERRY_UNPACK)$(DELIM)src
DEPPATH += --dep-path $(BERRY_UNPACK)$(DELIM)default
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)$(DELIM)interpreters$(DELIM)berry$(DELIM)include
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)$(DELIM)interpreters$(DELIM)berry$(DELIM)$(BERRY_UNPACK)$(DELIM)src
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)$(DELIM)interpreters$(DELIM)berry$(DELIM)$(BERRY_UNPACK)$(DELIM)default
CFLAGS += -Wno-unused-but-set-variable
PROGNAME = $(CONFIG_INTERPRETERS_BERRY_PROGNAME)
PRIORITY = $(CONFIG_INTERPRETERS_BERRY_PRIORITY)
STACKSIZE = $(CONFIG_INTERPRETERS_BERRY_STACKSIZE)
MODULE = $(CONFIG_INTERPRETERS_BERRY)
$(BERRY_ARCHIVE):
$(Q) echo "Downloading $(BERRY_ARCHIVE)"
$(Q) curl -L $(BERRY_URL) -o $(BERRY_ARCHIVE)
$(BERRY_UNPACK): $(BERRY_ARCHIVE)
$(Q) echo "Unpacking $(BERRY_ARCHIVE) to $(BERRY_UNPACK)"
$(Q) unzip -q -o $(BERRY_ARCHIVE)
$(call DELDIR, $(BERRY_UNPACK))
$(Q) mv berry-$(BERRY_COMMIT_ID) $(BERRY_UNPACK)
$(Q) patch -l -d $(BERRY_UNPACK) -p1 < 0001-Fix-Berry-default-port-for-NuttX.patch
$(BERRY_GEN_STAMP): $(BERRY_UNPACK) $(BERRY_CONFIG)
$(Q) echo "Generating Berry constant objects"
$(Q) mkdir -p $(BERRY_GENERATE)
$(Q) python3 $(BERRY_COC) -o $(BERRY_GENERATE) \
$(BERRY_UNPACK)$(DELIM)src \
$(BERRY_UNPACK)$(DELIM)default \
-c $(BERRY_CONFIG)
$(Q) touch $(BERRY_GEN_STAMP)
ifeq ($(wildcard $(BERRY_UNPACK)/.git),)
context:: $(BERRY_GEN_STAMP)
endif
depend:: $(BERRY_GEN_STAMP)
distclean::
ifeq ($(wildcard $(BERRY_UNPACK)/.git),)
$(call DELDIR, $(BERRY_UNPACK))
$(call DELFILE, $(BERRY_ARCHIVE))
endif
include $(APPDIR)/Application.mk

View file

@ -0,0 +1,86 @@
/****************************************************************************
* apps/interpreters/berry/include/berry_conf.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_INTERPRETERS_BERRY_INCLUDE_BERRY_CONF_H
#define __APPS_INTERPRETERS_BERRY_INCLUDE_BERRY_CONF_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <stdlib.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BE_DEBUG 0
#define BE_INTGER_TYPE 2
#define BE_USE_SINGLE_FLOAT 0
#define BE_BYTES_MAX_SIZE (32 * 1024)
#define BE_USE_PRECOMPILED_OBJECT 1
#define BE_DEBUG_SOURCE_FILE 1
#define BE_DEBUG_RUNTIME_INFO 1
#define BE_DEBUG_VAR_INFO 1
#define BE_USE_PERF_COUNTERS 1
#define BE_VM_OBSERVABILITY_SAMPLING 20
#define BE_STACK_TOTAL_MAX 20000
#define BE_STACK_FREE_MIN 10
#define BE_STACK_START 50
#define BE_CONST_SEARCH_SIZE 50
#define BE_USE_STR_HASH_CACHE 0
#define BE_USE_FILE_SYSTEM 1
#define BE_USE_SCRIPT_COMPILER 1
#define BE_USE_BYTECODE_SAVER 1
#define BE_USE_BYTECODE_LOADER 1
#define BE_USE_SHARED_LIB 0
#define BE_USE_OVERLOAD_HASH 1
#define BE_USE_DEBUG_HOOK 0
#define BE_USE_DEBUG_GC 0
#define BE_USE_DEBUG_STACK 0
#define BE_USE_MEM_ALIGNED 0
#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
#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
#define be_assert(expr) assert(expr)
#endif /* __APPS_INTERPRETERS_BERRY_INCLUDE_BERRY_CONF_H */