From 02c6985be9ffc92868a61c5c66afb0a603b3c472 Mon Sep 17 00:00:00 2001 From: Frederick Blais Date: Fri, 26 Jun 2026 09:12:29 -0400 Subject: [PATCH] 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 --- ...001-Fix-Berry-default-port-for-NuttX.patch | 27 ++++ interpreters/berry/CMakeLists.txt | 148 ++++++++++++++++++ interpreters/berry/Kconfig | 43 +++++ interpreters/berry/Make.defs | 25 +++ interpreters/berry/Makefile | 97 ++++++++++++ interpreters/berry/include/berry_conf.h | 86 ++++++++++ 6 files changed, 426 insertions(+) create mode 100644 interpreters/berry/0001-Fix-Berry-default-port-for-NuttX.patch create mode 100644 interpreters/berry/CMakeLists.txt create mode 100644 interpreters/berry/Kconfig create mode 100644 interpreters/berry/Make.defs create mode 100644 interpreters/berry/Makefile create mode 100644 interpreters/berry/include/berry_conf.h diff --git a/interpreters/berry/0001-Fix-Berry-default-port-for-NuttX.patch b/interpreters/berry/0001-Fix-Berry-default-port-for-NuttX.patch new file mode 100644 index 00000000000..39fc4972e30 --- /dev/null +++ b/interpreters/berry/0001-Fix-Berry-default-port-for-NuttX.patch @@ -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; diff --git a/interpreters/berry/CMakeLists.txt b/interpreters/berry/CMakeLists.txt new file mode 100644 index 00000000000..5e30aa8c803 --- /dev/null +++ b/interpreters/berry/CMakeLists.txt @@ -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/Skiars/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() diff --git a/interpreters/berry/Kconfig b/interpreters/berry/Kconfig new file mode 100644 index 00000000000..805c618669a --- /dev/null +++ b/interpreters/berry/Kconfig @@ -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 diff --git a/interpreters/berry/Make.defs b/interpreters/berry/Make.defs new file mode 100644 index 00000000000..48a5e64efaa --- /dev/null +++ b/interpreters/berry/Make.defs @@ -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 diff --git a/interpreters/berry/Makefile b/interpreters/berry/Makefile new file mode 100644 index 00000000000..21415b8b776 --- /dev/null +++ b/interpreters/berry/Makefile @@ -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/Skiars/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 diff --git a/interpreters/berry/include/berry_conf.h b/interpreters/berry/include/berry_conf.h new file mode 100644 index 00000000000..633d9cdc975 --- /dev/null +++ b/interpreters/berry/include/berry_conf.h @@ -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 + +#include +#include + +/**************************************************************************** + * 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 */