├── ChangeLog ├── LICENSE ├── LICENSE.GPL ├── Makefile ├── README.md ├── configure ├── dist ├── boron.spec └── control ├── doc ├── Doxyfile ├── Makefile ├── UserManual.md ├── boron.troff ├── boron.vim ├── boron_logo2.jpg ├── copr.md ├── css │ └── lsr-doc.css ├── dev_manual.dox ├── extra_style.css └── func_ref_head.html ├── eval ├── asm.c ├── boot.b ├── boot.c ├── boron.c ├── boron_internal.h ├── boron_types.c ├── cfunc.c ├── cfunc_table.c ├── checksum.c ├── compress.c ├── construct.c ├── encode.c ├── eval.c ├── format.c ├── main.c ├── mkboot ├── os_file.h ├── port_file.c ├── port_socket.c ├── port_ssl.c ├── port_thread.c ├── random.c ├── sort.c ├── thread.c └── wait.c ├── examples ├── boron_mini.c ├── calculator.c └── project.b ├── include ├── boron.h ├── urlan.h └── urlan_atoms.h ├── jni ├── Android.mk └── Application.mk ├── project.b ├── qt ├── UTreeModel.cpp ├── UTreeModel.h ├── boron-qt.cpp ├── boron-qt.h ├── examples │ ├── hello.b │ ├── layout1.b │ ├── progress.b │ └── widgets.b ├── main.cpp └── project.b ├── scripts ├── bump_dev.b ├── bump_version.b ├── c_binary.b ├── c_string.b ├── cfunc_docs.b ├── cfunc_table.b ├── copr.b ├── ctx_header.b ├── m2 │ ├── m2 │ ├── m2_linux.b │ ├── m2_macx.b │ ├── m2_mingw.b │ ├── m2_sun.b │ ├── m2_visualc.b │ ├── test.b │ └── version-up.b ├── mkdef.b ├── parse_blk_compile.b └── vm-summary.b ├── support ├── cpuCounter.h ├── fpconv.c ├── linenoise.c ├── linenoise.h ├── mem_util.c ├── mem_util.h ├── quickSortIndex.c ├── quickSortIndex.h ├── sha1.c ├── str.c ├── str.h ├── trim_string.c ├── url_encoding.c ├── well512.c └── well512.h ├── test ├── Makefile ├── binary.b ├── binary.good ├── bind.b ├── bind.good ├── bitset.b ├── bitset.good ├── block.b ├── block.good ├── char.b ├── char.good ├── compare.b ├── compare.good ├── conditional.b ├── conditional.good ├── construct.b ├── construct.good ├── context.b ├── context.good ├── coord.b ├── coord.good ├── data-104 ├── datatype.b ├── datatype.good ├── date.b_ ├── date.good ├── error.b ├── error.good ├── eval.b ├── eval.good ├── exception.b ├── exception.good ├── execute.b ├── execute.good ├── execute_child ├── file.b ├── file.good ├── format.b ├── format.good ├── func.b ├── func.good ├── grind ├── hash-map.b ├── hash-map.good ├── helpers.b ├── helpers.good ├── int.b ├── int.good ├── iterate.b ├── iterate.good ├── logic.b ├── logic.good ├── loop.b ├── loop.good ├── math.b ├── math.good ├── none.b ├── none.good ├── parse.b ├── parse.good ├── path.b ├── path.good ├── random.b ├── random.good ├── read.b ├── read.good ├── reduce.b ├── reduce.good ├── run_test ├── serialize.b ├── serialize.good ├── series.b ├── series.good ├── sort.b ├── sort.good ├── speed ├── speed.results ├── split.b ├── split.good ├── string.b ├── string.good ├── thread.b ├── thread.good ├── time.b ├── time.good ├── utf8.b ├── utf8.good ├── vec3.b ├── vec3.good ├── vector.b ├── vector.good ├── word.b └── word.good ├── unix └── os.c ├── urlan ├── array.c ├── atoms.c ├── binary.c ├── block.c ├── context.c ├── coord.c ├── datatypes.c ├── date.c ├── env.c ├── env.h ├── gc.c ├── hashmap.c ├── hashmap.h ├── i_parse_blk.c ├── i_parse_blk.h ├── memtrack.c ├── os.h ├── parse_block.c ├── parse_string.c ├── path.c ├── project.b ├── serialize.c ├── string.c ├── tokenize.c ├── ucs2_case.c ├── unset.h └── vector.c ├── util ├── CBParser.c └── CBParser.h └── win32 ├── boron.def ├── os.c ├── redef.b └── win32console.c /ChangeLog: -------------------------------------------------------------------------------- 1 | Boron Change Log 2 | 3 | 4 | V2.0.8 - 25 Apr 2022 5 | 6 | * Parse 'into accepts any block type. 7 | * Add appair function. 8 | * Add boron_random() & boron_randomSeed() for access to UThread RNG. 9 | * Checksum returns int! values with HEX flag set. 10 | * Construct binary! handles coord! values. 11 | * Execute treats \" as a literal double quote on Unix. 12 | * Fix a couple bugs. 13 | 14 | 15 | V2.0.6 - 17 Feb 2021 16 | 17 | * Add continue, ge?, and le? functions. 18 | * Bitset! pick changed to return logic!. Poking 0 or 0.0 will clear bits. 19 | * Charset interprets dash as a range indicator. 20 | * Fix hash-map! to accept file! keys. 21 | * Fix info? timestamps on Windows. 22 | * Automatically join threads when a thread port! is closed. 23 | * Some bugfixes. 24 | 25 | 26 | V2.0.4 - 16 Nov 2020 27 | 28 | * Replace parse /binary option with 'bits command. 29 | * Implement swap for block!. 30 | * Add split function. 31 | * Add boron_tempBinary() function & ur_stackTop() macro. 32 | * Fix small memory leak in ur_freezeEnv(). 33 | * Some bugfixes. 34 | 35 | 36 | V2.0.2 - 7 Mar 2020 37 | 38 | * Update Boron-GL to use OpenGL 3.3 & ES 3.1 and support Android. 39 | * On Android environs/os is set to 'Android. 40 | * Add bind /secure option. 41 | * Atan accepts coord!/vec3! to return result in the range -PI to PI. 42 | * Math operators accept (coord! int!) arguments. 43 | * Parse with binary! value handles to & thru rules. 44 | * Fix save to append newline. 45 | * Fix recycle bugs. 46 | * User defined C function specification can type check user defined types. 47 | 48 | 49 | V2.0.0 - 1 Feb 2019 50 | 51 | * Evaluator rewritten to use the stack more efficiently. 52 | * Func creates local variables for set-word! values. Added /extern option 53 | to preserve any external bindings. 54 | * Changed int! datatype to be 64 bits. 55 | * Renamed decimal! datatype to double!. 56 | * Added multiple brace string! syntax to more easily deal with embedded text. 57 | * Added hash-map! datatype. 58 | * Added format & setenv functions. 59 | * Removed big-num! datatype. The type slot is kept so a full implementation 60 | could be added in the future. 61 | * Change serialized format ID to BOR2. This handles 64-bit int!, hash-map!, 62 | and stores logic! with one less byte. 63 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Boron Makefile for UNIX systems. 2 | 3 | VER=2.0.8 4 | 5 | DESTDIR ?= /usr/local 6 | BIN_DIR=$(DESTDIR)/bin 7 | LIB_DIR=$(DESTDIR)/lib 8 | INC_DIR=$(DESTDIR)/include/boron 9 | MAN_DIR=$(DESTDIR)/share/man/man1 10 | VIM_DIR=$(DESTDIR)/share/vim/vimfiles/syntax 11 | 12 | OS := $(shell uname) 13 | 14 | CFLAGS = -pipe -pedantic -Wall -W -Iinclude -Iurlan -Ieval -Isupport 15 | CFLAGS += -O3 -DNDEBUG 16 | #CFLAGS += -g -DDEBUG 17 | 18 | ifeq ($(OS), Darwin) 19 | CFLAGS += -std=c99 20 | AR_LIB = libtool -static -o 21 | else 22 | CFLAGS += -std=gnu99 -fPIC 23 | AR_LIB = ar rc 24 | ifneq (,$(wildcard /usr/lib64/libc.so)) 25 | LIB_DIR=$(DESTDIR)/lib64 26 | else ifneq (,$(wildcard /usr/lib/x86_64-linux-gnu/.)) 27 | LIB_DIR=$(DESTDIR)/lib/x86_64-linux-gnu 28 | endif 29 | endif 30 | 31 | CONFIG := $(shell cat config.opt) 32 | ifneq (,$(findstring _STATIC,$(CONFIG))) 33 | STATIC_LIB = true 34 | endif 35 | 36 | LIBS := -lm 37 | 38 | ODIR = .obj 39 | OBJ_FN = env.o array.o binary.o block.o coord.o date.o path.o \ 40 | string.o context.o gc.o serialize.o tokenize.o \ 41 | vector.o parse_block.o parse_string.o 42 | OBJ_FN += str.o mem_util.o quickSortIndex.o fpconv.o 43 | OBJ_FN += os.o boron.o port_file.o wait.o 44 | ifneq (,$(findstring _HASHMAP,$(CONFIG))) 45 | OBJ_FN += hashmap.o 46 | endif 47 | ifneq (,$(findstring _RANDOM,$(CONFIG))) 48 | OBJ_FN += well512.o random.o 49 | endif 50 | ifneq (,$(findstring _SOCKET,$(CONFIG))) 51 | OBJ_FN += port_socket.o 52 | endif 53 | ifneq (,$(findstring _THREAD,$(CONFIG))) 54 | OBJ_FN += port_thread.o 55 | ifeq ($(OS), Linux) 56 | LIBS += -lpthread 57 | endif 58 | endif 59 | LIB_OBJS = $(addprefix $(ODIR)/,$(OBJ_FN)) 60 | 61 | 62 | MAIN_FN = main.o 63 | ifneq (,$(findstring _LINENOISE,$(CONFIG))) 64 | MAIN_FN += linenoise.o 65 | else 66 | EXE_LIBS += -lreadline -lhistory 67 | endif 68 | ifneq (,$(findstring _COMPRESS=1,$(CONFIG))) 69 | LIBS += -lz 70 | endif 71 | ifneq (,$(findstring _COMPRESS=2,$(CONFIG))) 72 | LIBS += -lbz2 73 | endif 74 | EXE_OBJS = $(addprefix $(ODIR)/,$(MAIN_FN)) 75 | 76 | ifdef STATIC_LIB 77 | BORON_LIB = libboron.a 78 | EXE_LIBS += $(LIBS) 79 | else ifeq ($(OS), Darwin) 80 | BORON_LIB = libboron.dylib 81 | else 82 | BORON_LIB = libboron.so.$(VER) 83 | endif 84 | 85 | 86 | $(ODIR)/%.o: urlan/%.c 87 | cc -c $(CFLAGS) $(CONFIG) $< -o $@ 88 | $(ODIR)/%.o: support/%.c 89 | cc -c $(CFLAGS) $(CONFIG) $< -o $@ 90 | $(ODIR)/%.o: eval/%.c 91 | cc -c $(CFLAGS) $(CONFIG) $< -o $@ 92 | 93 | boron: $(EXE_OBJS) $(BORON_LIB) 94 | cc $^ -o $@ $(EXE_LIBS) 95 | 96 | $(ODIR)/os.o: unix/os.c 97 | cc -c $(CFLAGS) $(CONFIG) $< -o $@ 98 | 99 | $(EXE_OBJS): | $(ODIR) 100 | $(LIB_OBJS): | $(ODIR) 101 | $(ODIR): 102 | mkdir -p $@ 103 | 104 | $(BORON_LIB): $(LIB_OBJS) 105 | ifdef STATIC_LIB 106 | $(AR_LIB) $@ $^ 107 | ranlib $@ 108 | else ifeq ($(OS), Darwin) 109 | libtool -dynamiclib -o $@ $^ -install_name @rpath/$(BORON_LIB) $(LIBS) 110 | else 111 | cc -o $@ -shared -Wl,-soname,libboron.so.2 $^ $(LIBS) 112 | ln -sf $(BORON_LIB) libboron.so.2 113 | ln -sf $(BORON_LIB) libboron.so 114 | endif 115 | 116 | .PHONY: clean install uninstall install-dev uninstall-dev 117 | 118 | clean: 119 | rm -f boron $(BORON_LIB) $(LIB_OBJS) $(EXE_OBJS) 120 | ifndef STATIC_LIB 121 | rm -f libboron.so* 122 | endif 123 | rmdir $(ODIR) 124 | 125 | install: 126 | mkdir -p $(BIN_DIR) $(LIB_DIR) $(MAN_DIR) 127 | ifndef STATIC_LIB 128 | ifeq ($(OS), Darwin) 129 | install_name_tool -id $(LIB_DIR)/libboron.dylib libboron.dylib 130 | install_name_tool -change libboron.dylib $(LIB_DIR)/libboron.dylib boron 131 | install -m 644 libboron.dylib $(LIB_DIR) 132 | else 133 | install -m 755 -s $(BORON_LIB) $(LIB_DIR) 134 | ln -s $(BORON_LIB) $(LIB_DIR)/libboron.so.2 135 | endif 136 | endif 137 | install -s -m 755 boron $(BIN_DIR) 138 | gzip -c -n doc/boron.troff > doc/boron.1.gz 139 | install -m 644 doc/boron.1.gz $(MAN_DIR) 140 | 141 | uninstall: 142 | rm -f $(BIN_DIR)/boron $(MAN_DIR)/boron.1 143 | ifndef STATIC_LIB 144 | rm -f $(LIB_DIR)/$(BORON_LIB) 145 | ifneq ($(OS), Darwin) 146 | rm -f $(LIB_DIR)/libboron.so.2 147 | endif 148 | endif 149 | 150 | install-dev: 151 | mkdir -p $(INC_DIR) $(LIB_DIR) 152 | sed -e 's~"urlan.h"~~' include/boron.h >boron.tmp 153 | install -m 644 boron.tmp $(INC_DIR)/boron.h 154 | rm boron.tmp 155 | install -m 644 include/urlan.h $(INC_DIR) 156 | install -m 644 include/urlan_atoms.h $(INC_DIR) 157 | # install -m 755 scripts/copr.b $(BIN_DIR)/copr 158 | ifdef STATIC_LIB 159 | install -m 644 $(BORON_LIB) $(LIB_DIR) 160 | endif 161 | ifneq ($(OS), Darwin) 162 | mkdir -p $(VIM_DIR) 163 | install -m 644 doc/boron.vim $(VIM_DIR) 164 | ifndef STATIC_LIB 165 | ln -s $(BORON_LIB) $(LIB_DIR)/libboron.so 166 | endif 167 | endif 168 | 169 | uninstall-dev: 170 | ifdef STATIC_LIB 171 | rm -f $(LIB_DIR)/$(BORON_LIB) 172 | endif 173 | ifneq ($(OS), Darwin) 174 | ifndef STATIC_LIB 175 | rm -f $(LIB_DIR)/libboron.so 176 | endif 177 | rm -f $(VIM_DIR)/boron.vim 178 | endif 179 | # rm -f $(BIN_DIR)/copr 180 | rm -f $(INC_DIR)/boron.h $(INC_DIR)/urlan.h $(INC_DIR)/urlan_atoms.h 181 | rmdir $(INC_DIR) 182 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | About Boron 2 | =========== 3 | 4 | Boron is an interpreted, prototype-based, scripting language similar to Rebol. 5 | The interpreter and datatype system is a C library useful for building 6 | domain-specific languages (DSLs) embedded in C/C++ applications. 7 | 8 | It is a smaller language than Rebol with fewer built-in data types, no infix 9 | operators, and no built-in internet protocols. It does add the capability to 10 | slice series values and store data in a serialized binary format. 11 | 12 | The library may be copied under the terms of the LGPLv3, which is included in 13 | the LICENSE file. 14 | 15 | 16 | How to compile 17 | ============== 18 | 19 | These commands can be used to build the shared library and interpreter program 20 | on UNIX systems: 21 | 22 | ./configure 23 | make 24 | 25 | To see the configure options run: 26 | 27 | ./configure -h 28 | 29 | Use the make `install` & `install-dev` targets to copy files into the local 30 | system directories. If the DESTDIR is not provided then the files will be 31 | placed under `/usr/local`. 32 | 33 | sudo make install DESTDIR=/usr 34 | sudo make install-dev DESTDIR=/usr 35 | 36 | 37 | Boron links 38 | =========== 39 | 40 | Home Page 41 | http://urlan.sourceforge.net/boron/ 42 | 43 | Git Repository 44 | https://git.code.sf.net/p/urlan/boron/code 45 | 46 | Author Email 47 | wickedsmoke@users.sf.net 48 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then 4 | echo "Configuration Options:" 5 | echo " -h, --help Display this help and exit" 6 | echo -e "\nRemove Standard Features:" 7 | echo " --no-checksum Remove the checksum function" 8 | echo " --no-compress Remove the compress function" 9 | echo " --no-execute Remove the execute function" 10 | echo " --no-random Remove the random function" 11 | echo " --no-readline Remove console editing and history" 12 | echo " --no-socket Remove the socket port" 13 | echo -e "\nAdd Optional Features:" 14 | echo " --assemble Enable assemble function (requires libjit)" 15 | echo " --bzip2 Use bzip2 for compress instead of zlib" 16 | echo " --gnu-readline Use GNU Readline for console editing and history" 17 | echo " --static Build static library and stand-alone executable" 18 | echo " --timecode Enable timecode! datatype" 19 | echo " --thread Enable thread functions" 20 | echo -e "\nSet Default Limits:" 21 | echo " --atom-limit Maximum number of atoms" 22 | echo " --atom-names Atom names buffer size" 23 | exit 24 | fi 25 | 26 | 27 | CFG_ASSEM=0 28 | CFG_CHECKSUM=1 29 | CFG_COMPRESS=zlib 30 | CFG_EXECUTE=1 31 | CFG_RANDOM=1 32 | CFG_READLINE=linenoise 33 | CFG_SOCKET=1 34 | CFG_STATIC=0 35 | CFG_TIMECODE=0 36 | CFG_THREAD=0 37 | CFG_ATOM_LIMIT=none 38 | CFG_ATOM_NAMES=none 39 | 40 | while [ "$1" != "" ]; do 41 | case $1 in 42 | --no-checksum) 43 | CFG_CHECKSUM=0 ;; 44 | --no-compress) 45 | CFG_COMPRESS=0 ;; 46 | --no-execute) 47 | CFG_EXECUTE=0 ;; 48 | --no-random) 49 | CFG_RANDOM=0 ;; 50 | --no-readline) 51 | CFG_READLINE=0 ;; 52 | --no-socket) 53 | CFG_SOCKET=0 ;; 54 | --assemble) 55 | CFG_ASSEM=1 ;; 56 | --bzip2) 57 | CFG_COMPRESS=bzip2 ;; 58 | --gnu-readline) 59 | CFG_READLINE=gnu ;; 60 | --static) 61 | CFG_STATIC=1 ;; 62 | --timecode) 63 | CFG_TIMECODE=1 ;; 64 | --thread) 65 | CFG_THREAD=1 ;; 66 | --atom-limit) 67 | shift 68 | CFG_ATOM_LIMIT=$1 ;; 69 | --atom-names) 70 | shift 71 | CFG_ATOM_NAMES=$1 ;; 72 | *) 73 | echo "Invalid option $opt" 74 | exit 1 75 | ;; 76 | esac 77 | shift 78 | done 79 | 80 | 81 | echo "Generating config.opt & project.config" 82 | rm -f config.opt project.config 83 | 84 | function m2-word { 85 | if [ $2 = 0 ]; then 86 | echo "$1: false" >> project.config 87 | else 88 | echo "$1: '$2" >> project.config 89 | case $2 in 90 | gnu) 91 | echo -n " -DCONFIG_READLINE" >> config.opt ;; 92 | linenoise) 93 | echo -n " -DCONFIG_LINENOISE" >> config.opt ;; 94 | zlib) 95 | echo -n " -DCONFIG_COMPRESS=1" >> config.opt ;; 96 | bzip2) 97 | echo -n " -DCONFIG_COMPRESS=2" >> config.opt ;; 98 | esac 99 | fi 100 | } 101 | function m2-logic { 102 | if [ $2 = 0 ]; then 103 | echo "$1: false" >> project.config 104 | else 105 | echo "$1: true" >> project.config 106 | echo -n " -DCONFIG_$(tr '[:lower:]' '[:upper:]' <<< $1)" >> config.opt 107 | fi 108 | } 109 | function m2-int { 110 | if [ $2 != 'none' ]; then 111 | echo "$1: $2" >> project.config 112 | echo -n " -DCONFIG_$(tr '[:lower:]' '[:upper:]' <<< $1)=$2" >> config.opt 113 | fi 114 | } 115 | 116 | m2-logic "assemble" $CFG_ASSEM 117 | m2-logic "checksum" $CFG_CHECKSUM 118 | m2-word "compress" $CFG_COMPRESS 119 | m2-logic "hashmap" 1 120 | m2-logic "execute" $CFG_EXECUTE 121 | m2-logic "random" $CFG_RANDOM 122 | m2-word "readline" $CFG_READLINE 123 | m2-logic "socket" $CFG_SOCKET 124 | m2-logic "static" $CFG_STATIC 125 | m2-logic "timecode" $CFG_TIMECODE 126 | m2-logic "thread" $CFG_THREAD 127 | m2-int "atom-limit" $CFG_ATOM_LIMIT 128 | m2-int "atom-names" $CFG_ATOM_NAMES 129 | -------------------------------------------------------------------------------- /dist/boron.spec: -------------------------------------------------------------------------------- 1 | Summary: Scripting language and C library useful for building DSLs 2 | Name: boron 3 | Version: 2.0.8 4 | #Release: 1%{?dist} 5 | Release: 1 6 | License: LGPLv3+ 7 | URL: http://urlan.sf.net/boron 8 | Group: Development/Languages 9 | Source: https://sourceforge.net/projects/urlan/files/Boron/boron-%{version}.tar.gz 10 | BuildRoot: %{_tmppath}/%{name}-%{version}-build 11 | BuildRequires: gcc, make, zlib-devel 12 | 13 | %global debug_package %{nil} 14 | 15 | %description 16 | Boron is an interpreted, prototype-based, scripting language similar to Rebol. 17 | The interpreter and datatype system is a C library useful for building 18 | domain specific languages embedded in C/C++ applications. 19 | 20 | %package devel 21 | Summary: Development files for Boron 22 | Requires: %{name}%{?_isa} = %{version}-%{release} 23 | 24 | %description devel 25 | This package contains the header files and libraries needed to build 26 | C/C++ programs that use the Boron interpreter. 27 | 28 | %prep 29 | %setup -q -n %{name}-%{version} 30 | 31 | %build 32 | ./configure --thread 33 | make 34 | 35 | %check 36 | export LD_LIBRARY_PATH=$(pwd) 37 | make -C test 38 | 39 | %install 40 | make DESTDIR="$RPM_BUILD_ROOT/usr" install install-dev 41 | 42 | %clean 43 | rm -rf $RPM_BUILD_ROOT 44 | 45 | %files 46 | %doc ChangeLog 47 | %license LICENSE 48 | %defattr(-,root,root) 49 | %{_bindir}/boron 50 | %{_mandir}/man1/boron.1* 51 | %{_libdir}/libboron.so.2 52 | %{_libdir}/libboron.so.%{version} 53 | 54 | %files devel 55 | %defattr(-,root,root) 56 | %dir %{_includedir}/boron 57 | %{_libdir}/libboron.so 58 | %{_includedir}/boron/boron.h 59 | %{_includedir}/boron/urlan.h 60 | %{_includedir}/boron/urlan_atoms.h 61 | %{_datadir}/vim/vimfiles/syntax/boron.vim 62 | 63 | %changelog 64 | * Sun Dec 27 2020 Karl Robillard 2.0.4-1 65 | - Update to 2.0.4 66 | - Fix rpmlint warnings, meet Fedora guidelines, remove mandriva lines. 67 | * Fri Feb 1 2019 Karl Robillard 68 | - Update to 2.0.0 69 | * Fri Mar 16 2012 Karl Robillard 70 | - No longer using cmake. 71 | * Fri Dec 4 2009 Karl Robillard 72 | - Initial package release. 73 | -------------------------------------------------------------------------------- /dist/control: -------------------------------------------------------------------------------- 1 | Package: boron 2 | Version: 2.0.8-1 3 | Section: interpreters 4 | Priority: optional 5 | Architecture: amd64 6 | Depends: libc6 (>= 2.2.5), zlib1g 7 | Maintainer: Karl Robillard 8 | Description: Scripting language and C library useful for building DSLs 9 | Boron is an interpreted, prototype-based, scripting language similar to Rebol. 10 | The interpreter and datatype system is a C library useful for building 11 | domain specific languages embedded in C/C++ applications. 12 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | STYLE = css/lsr-doc.css 2 | PDOPT = -s -N -f markdown 3 | 4 | 5 | dox: 6 | doxygen 7 | 8 | html: UserManual.html copr.html 9 | 10 | pdf: UserManual.pdf 11 | 12 | 13 | UserManual.html: UserManual.md $(STYLE) 14 | pandoc $(PDOPT) --self-contained --toc --css=$(STYLE) -o $@ UserManual.md 15 | 16 | UserManual.pdf: UserManual.md 17 | pandoc $(PDOPT) --toc -o $@ $^ 18 | 19 | copr.html: copr.md $(STYLE) 20 | pandoc $(PDOPT) --css=$(STYLE) -o $@ $< 21 | 22 | clean: 23 | rm -rf func_ref.html *.pdf *.aux *.log *.tex *.toc *.out 24 | rm -rf ./html ./latex 25 | -------------------------------------------------------------------------------- /doc/boron.troff: -------------------------------------------------------------------------------- 1 | .\" Manpage for boron. 2 | .TH BORON 1 "25 Apr 2022" "Version 2.0.8" "boron 2.0.8" 3 | .SH NAME 4 | boron \- The Boron language interpreter 5 | .SH SYNOPSIS 6 | .B boron 7 | [OPTIONS] [SCRIPT [ARGUMENTS]] 8 | .SH DESCRIPTION 9 | Boron is an interpreted, prototype-based, scripting language similar to Rebol. 10 | .PP 11 | If no script filename or \fB\-e\fR argument is given then an interactive 12 | command prompt is shown. 13 | .SH OPTIONS 14 | .TP 15 | \fB\-e\fR exp 16 | Evaluate an expression. 17 | .TP 18 | .B \-h 19 | Show help and exit. 20 | .TP 21 | .B \-p 22 | Disable the command prompt and exit when an exception is thrown. 23 | .TP 24 | .B \-s 25 | Disable security checks and allow full system access to scripts. 26 | By default the program will prompt the user when scripts write to files or 27 | open network sockets. 28 | .SH SEE ALSO 29 | User Guide 30 | .RS 31 | http://urlan.sourceforge.net/boron/doc/UserManual.html 32 | .RE 33 | Function Reference 34 | .RS 35 | http://urlan.sourceforge.net/boron/doc/func_ref.html 36 | .RE 37 | .SH AUTHOR 38 | Karl Robillard 39 | -------------------------------------------------------------------------------- /doc/boron_logo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0branch/boron/e98ed6cbc7911cf31a6e4ac8a0b00fd7c224e807/doc/boron_logo2.jpg -------------------------------------------------------------------------------- /doc/css/lsr-doc.css: -------------------------------------------------------------------------------- 1 | /* 2 | Modified version of Peter Parente's public domain reST style (2008/01/22) 3 | 4 | font-face snippets from 5 | https://fonts.googleapis.com/css2?family=Roboto:wght@700 6 | https://fonts.googleapis.com/css2?family=Merriweather:wght@400 7 | */ 8 | 9 | @font-face { 10 | font-family: 'Roboto'; 11 | font-style: normal; 12 | font-weight: 700; 13 | src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmWUlvAw.ttf) format('truetype') 14 | } 15 | 16 | @font-face { 17 | font-family: 'Merriweather'; 18 | font-style: normal; 19 | font-weight: 400; 20 | src: local('Merriweather'), url(https://fonts.gstatic.com/s/merriweather/v22/u-440qyriQwlOrhSvowK_l5-fCZM.woff2) format('woff2') 21 | } 22 | 23 | body { 24 | font-family: sans-serif; 25 | background: #ffffff; 26 | color: black; 27 | margin: 2em; 28 | padding: 0em 2em; 29 | } 30 | 31 | p.topic-title { 32 | font-weight: bold; 33 | } 34 | 35 | table.docinfo { 36 | text-align: left; 37 | margin: 2em 0em; 38 | } 39 | 40 | a[href] { 41 | color: #436976; 42 | background-color: transparent; 43 | } 44 | 45 | a.toc-backref { 46 | text-decoration: none; 47 | } 48 | 49 | h1 a[href] { 50 | color: #003a6b; 51 | text-decoration: none; 52 | background-color: transparent; 53 | } 54 | 55 | a.strong { 56 | font-weight: bold; 57 | } 58 | 59 | img { 60 | margin: 0; 61 | border: 0; 62 | } 63 | 64 | p { 65 | font-family: Merriweather, serif; 66 | margin: 0.5em 0 1em 0; 67 | line-height: 1.5em; 68 | } 69 | 70 | p a:visited { 71 | color: purple; 72 | background-color: transparent; 73 | } 74 | 75 | p a:active { 76 | color: red; 77 | background-color: transparent; 78 | } 79 | 80 | a:hover { 81 | text-decoration: none; 82 | } 83 | 84 | p img { 85 | border: 0; 86 | margin: 0; 87 | } 88 | 89 | p.rubric { 90 | font-weight: bold; 91 | font-style: italic; 92 | } 93 | 94 | p.date { 95 | text-align: center; 96 | } 97 | 98 | h1.title { 99 | color: #003a6b; 100 | font-size: 250%; 101 | margin-bottom: 0em; 102 | text-align: center; 103 | border-bottom: 0; 104 | } 105 | 106 | h2.subtitle { 107 | color: #003a6b; 108 | border-bottom: 0px; 109 | } 110 | 111 | h1, h2, h3, h4, h5, h6 { 112 | font-family: "Roboto"; 113 | color: #436976; 114 | background-color: transparent; 115 | margin: 0em; 116 | padding-top: 0.5em; 117 | } 118 | 119 | h1 { 120 | color: #003a6b; 121 | font-size: 160%; 122 | margin-bottom: 0.5em; 123 | border-bottom: 2px solid #aaa; 124 | //text-transform: uppercase; 125 | } 126 | 127 | h2 { 128 | font-size: 140%; 129 | margin-bottom: 0.5em; 130 | //border-bottom: 1px solid #aaa; 131 | } 132 | 133 | h3 { 134 | font-size: 130%; 135 | margin-bottom: 0.5em; 136 | } 137 | 138 | h4 { 139 | font-size: 110%; 140 | font-weight: bold; 141 | margin-bottom: 0.5em; 142 | } 143 | 144 | h5 { 145 | font-size: 105%; 146 | font-weight: bold; 147 | margin-bottom: 0.5em; 148 | } 149 | 150 | h6 { 151 | font-size: 100%; 152 | font-weight: bold; 153 | margin-bottom: 0.5em; 154 | } 155 | 156 | dl { 157 | margin-left: 2em; 158 | } 159 | 160 | dt { 161 | font-style: italic; 162 | } 163 | 164 | dd { 165 | margin-bottom: 1.5em; 166 | } 167 | 168 | table { 169 | text-align: left; 170 | border: 1px solid gray; 171 | border-collapse: collapse; 172 | width: 60%; 173 | margin: 1.5em 0em; 174 | } 175 | 176 | table caption { 177 | font-style: italic; 178 | } 179 | 180 | table td, table th { 181 | border: 1px solid gray; 182 | padding: 0.25em 0.5em; 183 | } 184 | 185 | table th { 186 | background-color: #dddddd; 187 | } 188 | 189 | div.sidebar { 190 | width: 33%; 191 | float: right; 192 | margin: 0em 2em; 193 | padding: 0em 1em; 194 | border-top: 1px solid #aaa; 195 | border-left: 1px solid #aaa; 196 | border-bottom: 2px solid #555; 197 | border-right: 2px solid #555; 198 | } 199 | 200 | p.sidebar-title { 201 | margin-bottom: 0em; 202 | color: #003a6b; 203 | border-bottom: 1px solid #aaa; 204 | font-weight: bold; 205 | } 206 | 207 | p.sidebar-subtitle { 208 | margin-top: 0em; 209 | font-style: italic; 210 | color: #003a6b; 211 | } 212 | 213 | pre { 214 | font-family: monospace; 215 | padding: 0.5em 0.5em 0.5em 0.5em; 216 | margin-left: 1.5em; 217 | margin-right: 1.5em; 218 | width: 70%; 219 | background: #f7f7f7; 220 | border: 1px solid #cccccc 221 | } 222 | 223 | code { 224 | display: inline-block; 225 | border: 1px solid #EAEAEA; 226 | background: #f8f8f8; 227 | color: #444; 228 | padding: 0 2px; 229 | } 230 | 231 | pre code { 232 | border: 0 233 | } 234 | -------------------------------------------------------------------------------- /doc/extra_style.css: -------------------------------------------------------------------------------- 1 | /* Conceal header projectname as the logo is the name. */ 2 | #projectname { 3 | font-size: 20%; 4 | color: #FFFFFF; 5 | } 6 | #projectnumber { 7 | font-size: 10em; 8 | color: #000000; 9 | } 10 | -------------------------------------------------------------------------------- /doc/func_ref_head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $TITLE 7 | 220 | 221 | 222 | 223 |
224 |

$TITLE

225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
Version: $VERSION
Date: $DATE
234 | -------------------------------------------------------------------------------- /eval/boot.b: -------------------------------------------------------------------------------- 1 | environs: make context! [ 2 | version: 2,0,8 3 | os: arch: big-endian: none 4 | ] 5 | 6 | q: :quit yes: true no: false 7 | eq?: :equal? 8 | tail?: :empty? 9 | close: :free 10 | context: func [b block!] [make context! b] 11 | charset: func [s char!/string!] [construct bitset! s] 12 | error: func [s string! /no-trace] [throw make error! s] 13 | 14 | join: func [a b] [ 15 | a: either series? a [copy a][to-text a] 16 | append a reduce b 17 | ] 18 | 19 | rejoin: func [b block!] [ 20 | if empty? b: reduce b [return b] 21 | append either series? first b 22 | [copy first b] 23 | [to-text first b] 24 | next b 25 | ] 26 | 27 | replace: func [series pat rep /all] [ 28 | size: either series? pat [size? pat][1] 29 | either all [ 30 | f: series 31 | while [f: find f pat] [f: change/part f rep size] 32 | ][ 33 | if f: find series pat [change/part f rep size] 34 | ] 35 | series 36 | ] 37 | 38 | split-path: func [path] [ 39 | either end: find/last path '/' 40 | [++ end reduce [slice path end end]] 41 | [reduce [none path]] 42 | ] 43 | 44 | term-dir: func [path] [terminate/dir path '/'] 45 | -------------------------------------------------------------------------------- /eval/boron_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef BORON_INTERNAL_H 2 | #define BORON_INTERNAL_H 3 | 4 | 5 | #include "env.h" 6 | 7 | #ifdef CONFIG_RANDOM 8 | #include "well512.h" 9 | #endif 10 | #ifdef CONFIG_ASSEMBLE 11 | #include 12 | #endif 13 | 14 | 15 | #define MAX_OPT 8 // LIMIT: 8 options per func/cfunc. 16 | #define OPT_BITS(c) (c)->id._pad0 17 | 18 | #define PORT_SITE(dev,pbuf,portC) \ 19 | UBuffer* pbuf = ur_buffer( portC->port.buf ); \ 20 | UPortDevice* dev = (pbuf->form == UR_PORT_SIMPLE) ? \ 21 | (UPortDevice*) pbuf->ptr.v : \ 22 | (pbuf->ptr.v ? *((UPortDevice**) pbuf->ptr.v) : 0) 23 | 24 | 25 | typedef struct 26 | { 27 | UEnv env; 28 | UBuffer ports; 29 | UStatus (*funcRead)( UThread*, UCell*, UCell* ); 30 | UAtom compileAtoms[5]; 31 | } 32 | BoronEnv; 33 | 34 | #define BENV ((BoronEnv*) ut->env) 35 | 36 | 37 | typedef struct BoronThread 38 | { 39 | UThread thread; 40 | UBuffer tbin; // Temporary binary buffer. 41 | int (*requestAccess)( UThread*, const char* ); 42 | UCell* stackLimit; 43 | UBuffer frames; // Function body & locals stack position. 44 | UCell optionCell; 45 | #ifdef CONFIG_RANDOM 46 | Well512 rand; 47 | #endif 48 | #ifdef CONFIG_ASSEMBLE 49 | jit_context_t jit; 50 | UAtomEntry* insTable; 51 | #endif 52 | } 53 | BoronThread; 54 | 55 | #define BT ((BoronThread*) ut) 56 | #define RESULT (BT->evalData + BT_RESULT) 57 | 58 | 59 | extern UIndex boron_seriesEnd( UThread* ut, const UCell* cell ); 60 | 61 | 62 | #endif // BORON_INTERNAL_H 63 | -------------------------------------------------------------------------------- /eval/format.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015,2019 Karl Robillard 3 | 4 | This file is part of the Boron programming language. 5 | 6 | Boron is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Boron is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Boron. If not, see . 18 | */ 19 | 20 | 21 | /*-cf- 22 | format 23 | fmt block! 24 | data 25 | return: string! 26 | group: io 27 | 28 | Convert values to formatted string. 29 | 30 | The format specification rules are: 31 | int! Field width of the next data item. 32 | If negative then right align the item in the field. 33 | coord! Field width and limit of the next data item. 34 | char!/string! Literal output to string. 35 | 'pad char! Set pad character for the following fields. 36 | */ 37 | CFUNC(cfunc_format) 38 | { 39 | static const char* padStr = "pad"; 40 | UBlockIt fi; 41 | UBlockIt di; 42 | USeriesIter si; 43 | UBuffer tmp; 44 | UBuffer* str; 45 | const UCell* data = a1+1; 46 | UAtom atomPad = 0; 47 | int pad = ' '; 48 | int plen; 49 | int dlen; 50 | int colWidth; 51 | int limit; 52 | 53 | ur_makeStringCell( ut, UR_ENC_LATIN1, 32, res ); // gc! 54 | 55 | if( ur_is(data, UT_BLOCK) || ur_is(data, UT_PAREN) ) 56 | { 57 | UCell* rv = boron_reduceBlock( ut, a2, ur_push(ut, UT_UNSET) ); // gc! 58 | ur_pop(ut); 59 | if( ! rv ) 60 | return UR_THROW; 61 | ur_blockIt( ut, &di, rv ); 62 | } 63 | else 64 | { 65 | di.it = data; 66 | di.end = di.it + 1;; 67 | } 68 | 69 | ur_blockIt( ut, &fi, a1 ); 70 | ur_strInit( &tmp, UR_ENC_LATIN1, 0 ); 71 | str = ur_buffer( res->series.buf ); 72 | 73 | ur_foreach( fi ) 74 | { 75 | switch( ur_type(fi.it) ) 76 | { 77 | case UT_INT: 78 | colWidth = ur_int(fi.it); 79 | limit = INT32_MAX; 80 | emit_column: 81 | if( di.it >= di.end ) 82 | { 83 | si.buf = &tmp; // Required by ur_strAppend. 84 | si.it = si.end = 0; 85 | dlen = tmp.used = 0; 86 | } 87 | else if( ur_isStringType( ur_type(di.it) ) ) 88 | { 89 | ur_seriesSlice( ut, &si, di.it++ ); 90 | } 91 | else 92 | { 93 | si.buf = &tmp; 94 | tmp.used = si.it = 0; 95 | ur_toText( ut, di.it++, &tmp ); 96 | si.end = tmp.used; 97 | } 98 | 99 | dlen = si.end - si.it; 100 | if( dlen > limit ) 101 | { 102 | dlen = limit; 103 | si.end = si.it + limit; 104 | } 105 | 106 | if( colWidth < 0 ) 107 | { 108 | for( plen = -colWidth - dlen; plen > 0; --plen ) 109 | ur_strAppendChar( str, pad ); 110 | ur_strAppend( str, si.buf, si.it, si.end ); 111 | } 112 | else 113 | { 114 | ur_strAppend( str, si.buf, si.it, si.end ); 115 | for( plen = colWidth - dlen; plen > 0; --plen ) 116 | ur_strAppendChar( str, pad ); 117 | } 118 | break; 119 | 120 | case UT_COORD: 121 | colWidth = fi.it->coord.n[0]; 122 | limit = fi.it->coord.n[1]; 123 | goto emit_column; 124 | 125 | case UT_CHAR: 126 | ur_strAppendChar( str, ur_int(fi.it) ); 127 | break; 128 | 129 | case UT_STRING: 130 | ur_seriesSlice( ut, &si, fi.it ); 131 | ur_strAppend( str, si.buf, si.it, si.end ); 132 | break; 133 | 134 | case UT_WORD: 135 | if( ! atomPad ) 136 | atomPad = ur_intern( ut, padStr, strlen(padStr) ); 137 | if( ur_atom(fi.it) == atomPad ) 138 | { 139 | if( ++fi.it == fi.end ) 140 | goto cleanup; 141 | if( ur_is(fi.it, UT_CHAR) ) 142 | pad = ur_int(fi.it); 143 | else if( ur_is(fi.it, UT_INT) ) 144 | pad = ur_int(fi.it) + '0'; 145 | } 146 | break; 147 | } 148 | } 149 | 150 | cleanup: 151 | ur_strFree( &tmp ); 152 | return UR_OK; 153 | } 154 | 155 | 156 | //EOF 157 | -------------------------------------------------------------------------------- /eval/mkboot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | ../boron -s -e 'write %boot.bin serialize unbind load %boot.b' 3 | ../scripts/c_binary.b boot.bin >boot.c 4 | rm boot.bin 5 | -------------------------------------------------------------------------------- /eval/os_file.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_FILE_H 2 | #define OS_FILE_H 3 | /* 4 | Operating system file interface. 5 | */ 6 | 7 | 8 | enum OSFileInfoMask 9 | { 10 | FI_Size = 0x01, 11 | FI_Time = 0x02, 12 | FI_Type = 0x04 13 | }; 14 | 15 | 16 | enum OSFileType 17 | { 18 | FI_File, 19 | FI_Link, 20 | FI_Dir, 21 | FI_Socket, 22 | FI_OtherType 23 | }; 24 | 25 | 26 | enum OSFilePerm 27 | { 28 | FI_User, 29 | FI_Group, 30 | FI_Other, 31 | FI_Misc, 32 | 33 | FI_Read = 4, // FI_User, FI_Group, FI_Other 34 | FI_Write = 2, 35 | FI_Exec = 1, 36 | 37 | FI_SetUser = 4, // FI_Misc 38 | FI_SetGroup = 2 39 | }; 40 | 41 | 42 | typedef struct 43 | { 44 | int64_t size; 45 | double accessed; 46 | double modified; 47 | int16_t perm[4]; 48 | uint8_t type; 49 | } 50 | OSFileInfo; 51 | 52 | 53 | extern int ur_fileInfo( const char* path, OSFileInfo* info, int mask ); 54 | 55 | 56 | #endif /* OS_FILE_H */ 57 | -------------------------------------------------------------------------------- /eval/random.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2009-2010,2013 Karl Robillard 3 | 4 | This file is part of the Boron programming language. 5 | 6 | Boron is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Boron is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Boron. If not, see . 18 | */ 19 | 20 | 21 | #include 22 | #include "boron.h" 23 | #include "boron_internal.h" 24 | 25 | 26 | #define genrand_int32() well512_genU32( &BT->rand ) 27 | #define genrand_real2() well512_genReal( &BT->rand ) 28 | 29 | 30 | static unsigned long _clockSeed() 31 | { 32 | unsigned long seed; 33 | seed = time(NULL); 34 | seed += clock(); 35 | return seed; 36 | } 37 | 38 | 39 | /** 40 | Seed the thread RNG. 41 | 42 | \ingroup boron 43 | */ 44 | void boron_randomSeed( UThread* ut, uint32_t seed ) 45 | { 46 | well512_init( &BT->rand, seed ); 47 | } 48 | 49 | 50 | /** 51 | Get the next number from the thread RNG. 52 | 53 | \return Value from 0 to 0xffffffff. 54 | \ingroup boron 55 | */ 56 | uint32_t boron_random( UThread* ut ) 57 | { 58 | return genrand_int32(); 59 | } 60 | 61 | 62 | /*-cf- 63 | random 64 | data logic!/int!/double!/coord!/vec3! or series. 65 | /seed Use data as generator seed. 66 | return: Random number, series position, or seed if /seed option used. 67 | group: data 68 | 69 | If data is a number, then a number from 1 through data will be returned. 70 | 71 | A call to random/seed must be done before random values will be generated. 72 | If seed data is is not an int! then a clock-based seed is used. 73 | */ 74 | CFUNC_PUB(cfunc_random) 75 | { 76 | #define OPT_RANDOM_SEED 1 77 | int type = ur_type(a1); 78 | 79 | if( CFUNC_OPTIONS & OPT_RANDOM_SEED ) 80 | { 81 | ur_setId(res, UT_INT); 82 | ur_int(res) = (type == UT_INT) ? ur_int(a1) : (int32_t) _clockSeed(); 83 | well512_init( &BT->rand, (uint32_t) ur_int(res) ); 84 | return UR_OK; 85 | } 86 | 87 | if( ur_isSeriesType(type) ) 88 | { 89 | int len = boron_seriesEnd( ut, a1 ); 90 | *res = *a1; 91 | if( len > 0 ) 92 | res->series.it += genrand_int32() % (len - a1->series.it); 93 | return UR_OK; 94 | } 95 | 96 | switch( type ) 97 | { 98 | case UT_LOGIC: 99 | ur_setId(res, UT_LOGIC); 100 | ur_logic(res) = genrand_int32() & 1; 101 | break; 102 | 103 | case UT_INT: 104 | if( ur_int(a1) == 0 ) 105 | { 106 | *res = *a1; 107 | } 108 | else 109 | { 110 | ur_setId(res, UT_INT); 111 | ur_int(res) = (genrand_int32() % ur_int(a1)) + 1; 112 | } 113 | break; 114 | 115 | case UT_DOUBLE: 116 | ur_setId(res, UT_DOUBLE); 117 | ur_double(res) = ur_double(a1) * genrand_real2(); 118 | break; 119 | 120 | case UT_COORD: 121 | { 122 | int i, n; 123 | ur_setId(res, UT_COORD); 124 | res->coord.len = a1->coord.len; 125 | for( i = 0; i < a1->coord.len; ++i ) 126 | { 127 | n = a1->coord.n[ i ]; 128 | res->coord.n[ i ] = n ? (genrand_int32() % n) + 1 : 0; 129 | } 130 | } 131 | break; 132 | 133 | case UT_VEC3: 134 | { 135 | int i; 136 | float n; 137 | ur_setId(res, UT_VEC3); 138 | for( i = 0; i < 3; ++i ) 139 | { 140 | n = a1->vec3.xyz[ i ]; 141 | res->vec3.xyz[ i ] = n ? genrand_real2() * n : 0.0f; 142 | } 143 | } 144 | break; 145 | 146 | default: 147 | return ur_error( ut, UR_ERR_TYPE, "random does not handle %s", 148 | ur_atomCStr( ut, type ) ); 149 | } 150 | return UR_OK; 151 | } 152 | 153 | 154 | //EOF 155 | -------------------------------------------------------------------------------- /eval/thread.c: -------------------------------------------------------------------------------- 1 | /* Boron Thread */ 2 | 3 | 4 | #include 5 | #include 6 | 7 | 8 | #ifdef _WIN32 9 | static DWORD WINAPI threadRoutine( LPVOID arg ) 10 | #else 11 | static void* threadRoutine( void* arg ) 12 | #endif 13 | { 14 | UThread* ut = (UThread*) arg; 15 | UBuffer* bin = &BT->tbin; 16 | if( ! boron_evalUtf8( ut, bin->ptr.c, bin->used ) ) 17 | { 18 | UBuffer str; 19 | UCell* ex = ur_exception( ut ); 20 | if( ! ur_is(ex, UT_WORD) || ur_atom(ex) != UR_ATOM_QUIT ) 21 | { 22 | ur_strInit( &str, UR_ENC_UTF8, 0 ); 23 | ur_toText( ut, ex, &str ); 24 | ur_strTermNull( &str ); 25 | puts( str.ptr.c ); 26 | ur_strFree( &str ); 27 | } 28 | } 29 | ur_destroyThread( ut ); 30 | return 0; 31 | } 32 | 33 | 34 | extern void boron_installThreadPort( UThread*, const UCell*, UThread* ); 35 | extern void boron_setJoinThread( UThread*, const UCell*, OSThread ); 36 | 37 | /*-cf- 38 | thread 39 | routine string!/block! 40 | /port Create thread port. 41 | return: Thread port or unset! 42 | 43 | Create a new thread to run a routine. 44 | 45 | A string! routine argument is preferred as a block! will be converted to 46 | a string! before it can be passed to the thread. 47 | 48 | If the /port option is used the new thread will have a port! bound to the 49 | 'thread-port word that is connected to the one returned from the function. 50 | This can be used for bi-directional communication. 51 | 52 | Each thread has it's own data store, so series values passed through the 53 | port will become empty on write as ownership is transferred. 54 | Only one series can be sent through the port on each write, so writing a 55 | block! that contains series values will throw an error. 56 | Words not bound to the shared environment will become unbound in the 57 | reading thread. 58 | */ 59 | CFUNC( cfunc_thread ) 60 | { 61 | #define OPT_THREAD_PORT 0x01 62 | OSThread osThr; 63 | UThread* child; 64 | UBuffer code; 65 | #ifdef _WIN32 66 | DWORD winId; 67 | #endif 68 | 69 | ur_strInit( &code, UR_ENC_UTF8, 0 ); 70 | 71 | if( ur_is(a1, UT_STRING) ) 72 | { 73 | USeriesIter si; 74 | ur_seriesSlice( ut, &si, a1 ); 75 | ur_strAppend( &code, si.buf, si.it, si.end ); 76 | } 77 | else if( ur_is(a1, UT_BLOCK) ) 78 | { 79 | ur_toStr( ut, a1, &code, -1 ); 80 | } 81 | else 82 | return ur_error( ut, UR_ERR_TYPE, "thread expected string!/block!" ); 83 | 84 | child = ur_makeThread( ut ); 85 | if( ! child ) 86 | { 87 | ur_strFree( &code ); 88 | return ur_error( ut, UR_ERR_INTERNAL, "No memory for thread" ); 89 | } 90 | 91 | // Copy code to child temp. binary. 92 | { 93 | UBuffer* bin = &((BoronThread*) child)->tbin; 94 | bin->used = 0; 95 | ur_binAppendData( bin, code.ptr.b, code.used ); 96 | ur_strFree( &code ); 97 | } 98 | 99 | ur_setId(res, UT_UNSET); 100 | 101 | if( CFUNC_OPTIONS & OPT_THREAD_PORT ) 102 | { 103 | if( ! port_thread.open( ut, &port_thread, res, 0, res ) ) 104 | return UR_THROW; 105 | boron_installThreadPort( ut, res, child ); 106 | } 107 | 108 | #ifdef _WIN32 109 | osThr = CreateThread( NULL, 0, threadRoutine, child, 0, &winId ); 110 | if( osThr == NULL ) 111 | #else 112 | if( pthread_create( &osThr, 0, threadRoutine, child ) != 0 ) 113 | #endif 114 | { 115 | return ur_error( ut, UR_ERR_INTERNAL, "Could not create thread" ); 116 | } 117 | 118 | if( CFUNC_OPTIONS & OPT_THREAD_PORT ) 119 | { 120 | // Will pthread_join() when port closed. 121 | boron_setJoinThread( ut, res, osThr ); 122 | } 123 | #ifndef _WIN32 124 | else 125 | { 126 | // Detach to automatically release thread memory when it exits. 127 | pthread_detach( osThr ); 128 | } 129 | #endif 130 | 131 | return UR_OK; 132 | } 133 | 134 | 135 | /*EOF*/ 136 | -------------------------------------------------------------------------------- /examples/boron_mini.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "boron.h" 3 | 4 | 5 | CFUNC(printHello) 6 | { 7 | int i; 8 | int count = ur_is(a1, UT_INT) ? ur_int(a1) : 1; 9 | (void) ut; 10 | 11 | for( i = 0; i < count; ++i ) 12 | printf( "Hello World\n" ); 13 | 14 | ur_setId(res, UT_UNSET); 15 | return UR_OK; 16 | } 17 | 18 | static const BoronCFunc myFuncs[] = { printHello }; 19 | static const char myFuncSpecs[] = "hello n"; 20 | 21 | int main() 22 | { 23 | UEnvParameters param; 24 | UThread* ut = boron_makeEnv( boron_envParam(¶m) ); // Startup. 25 | if( ! ut ) 26 | return 255; 27 | 28 | boron_defineCFunc( ut, UR_MAIN_CONTEXT, myFuncs, myFuncSpecs, 29 | sizeof(myFuncSpecs)-1 ); // Add our cfunc!. 30 | boron_evalUtf8( ut, "hello 3", -1 ); // Invoke it. 31 | boron_freeEnv( ut ); // Cleanup. 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /examples/project.b: -------------------------------------------------------------------------------- 1 | project: "examples" 2 | 3 | default [ 4 | debug 5 | ;release 6 | 7 | objdir %obj 8 | 9 | include_from [%../include %../urlan] 10 | libs_from %.. %boron 11 | 12 | macx [ 13 | cflags {-std=c99} 14 | cflags {-pedantic} 15 | libs [%m %z] 16 | universal 17 | ] 18 | unix [ 19 | cflags {-std=c99} 20 | ;cflags {-std=gnu99} ; Try this if c99 fails. 21 | cflags {-pedantic} 22 | libs [%m %z %pthread] 23 | ] 24 | win32 [ 25 | include_from %../win32 26 | console 27 | ] 28 | ] 29 | 30 | exe %calculator [ 31 | sources [%calculator.c] 32 | ] 33 | 34 | exe %boron_mini [ 35 | sources [%boron_mini.c] 36 | ] 37 | -------------------------------------------------------------------------------- /include/boron.h: -------------------------------------------------------------------------------- 1 | #ifndef BORON_H 2 | #define BORON_H 3 | /* 4 | Copyright 2009-2015 Karl Robillard 5 | 6 | This file is part of the Boron programming language. 7 | 8 | Boron is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | Boron is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with Boron. If not, see . 20 | */ 21 | 22 | 23 | #include "urlan.h" 24 | 25 | 26 | #define BORON_VERSION_STR "2.0.8" 27 | #define BORON_VERSION 0x020008 28 | 29 | 30 | enum BoronDataType 31 | { 32 | UT_FUNC = UT_BI_COUNT, 33 | UT_CFUNC, 34 | UT_AFUNC, 35 | UT_PORT, 36 | UT_BORON_COUNT 37 | }; 38 | 39 | 40 | enum BoronWordBindings 41 | { 42 | BOR_BIND_FUNC = UR_BIND_USER, 43 | BOR_BIND_OPTION, 44 | BOR_BIND_OPTION_ARG 45 | }; 46 | 47 | 48 | typedef UStatus (*BoronCFunc)(UThread*,UCell*,UCell*); 49 | #define CFUNC(name) static UStatus name( UThread* ut, UCell* a1, UCell* res ) 50 | #define CFUNC_PUB(name) UStatus name( UThread* ut, UCell* a1, UCell* res ) 51 | #define CFUNC_OPTIONS a1[-1].id.ext 52 | #define CFUNC_OPT_ARG(opt) (a1 + ((uint8_t*)a1)[-opt]) 53 | 54 | 55 | typedef struct 56 | { 57 | UCellId id; 58 | UIndex avail; // End cell is pos + avail. 59 | const UCell* pos; 60 | } 61 | UCellCFuncEval; 62 | 63 | #define boron_evalPos(a1) ((UCellCFuncEval*) a1)->pos 64 | #define boron_evalAvail(a1) ((UCellCFuncEval*) a1)->avail 65 | 66 | 67 | enum UserAccess 68 | { 69 | UR_ACCESS_DENY, 70 | UR_ACCESS_ALLOW, 71 | UR_ACCESS_ALWAYS 72 | }; 73 | 74 | 75 | enum PortForm 76 | { 77 | UR_PORT_SIMPLE, // buf->ptr.v is UPortDevice*. 78 | UR_PORT_EXT, // buf->ptr.v is UPortDevice**. 79 | }; 80 | 81 | 82 | enum PortOpenOptions 83 | { 84 | UR_PORT_READ = 0x01, 85 | UR_PORT_WRITE = 0x02, 86 | UR_PORT_NEW = 0x04, 87 | UR_PORT_NOWAIT = 0x08 88 | }; 89 | 90 | 91 | enum PortSeek 92 | { 93 | UR_PORT_HEAD, 94 | UR_PORT_TAIL, 95 | UR_PORT_SKIP 96 | }; 97 | 98 | 99 | #ifdef _WIN32 100 | #define UR_PORT_HANDLE 0x7fffffff 101 | #endif 102 | 103 | typedef struct UPortDevice UPortDevice; 104 | 105 | struct UPortDevice 106 | { 107 | int (*open) ( UThread*, const UPortDevice*, const UCell* from, int opt, 108 | UCell* res ); 109 | void (*close)( UBuffer* ); 110 | int (*read) ( UThread*, UBuffer*, UCell*, int len ); 111 | int (*write)( UThread*, UBuffer*, const UCell* ); 112 | int (*seek) ( UThread*, UBuffer*, UCell*, int where ); 113 | #ifdef _WIN32 114 | int (*waitFD)( UBuffer*, void** ); 115 | #else 116 | int (*waitFD)( UBuffer* ); 117 | #endif 118 | int defaultReadLen; 119 | }; 120 | 121 | 122 | #ifdef __cplusplus 123 | extern "C" { 124 | #endif 125 | 126 | UEnvParameters* boron_envParam( UEnvParameters* ); 127 | UThread* boron_makeEnv( UEnvParameters* ); 128 | void boron_freeEnv( UThread* ); 129 | UStatus boron_defineCFunc( UThread*, UIndex ctxN, const BoronCFunc* funcs, 130 | const char* spec, int slen ); 131 | void boron_overrideCFunc( UThread*, const char* name, BoronCFunc func ); 132 | void boron_addPortDevice( UThread*, const UPortDevice*, UAtom name ); 133 | UBuffer* boron_makePort( UThread*, const UPortDevice*, void* ext, UCell* res ); 134 | void boron_setAccessFunc( UThread*, int (*func)( UThread*, const char* ) ); 135 | UStatus boron_requestAccess( UThread*, const char* msg, ... ); 136 | void boron_bindDefault( UThread*, UIndex blkN ); 137 | UStatus boron_load( UThread*, const char* file, UCell* res ); 138 | const UCell* 139 | boron_eval1(UThread*, const UCell* it, const UCell* end, UCell* res); 140 | UStatus boron_doBlock( UThread* ut, const UCell* blkC, UCell* res ); 141 | UCell* boron_reduceBlock( UThread* ut, const UCell* blkC, UCell* res ); 142 | UCell* boron_evalUtf8( UThread*, const char* script, int len ); 143 | void boron_reset( UThread* ); 144 | UStatus boron_throwWord( UThread*, UAtom atom, UIndex stackPos ); 145 | int boron_catchWord( UThread*, UAtom atom ); 146 | char* boron_cstr( UThread*, const UCell* strC, UBuffer* bin ); 147 | char* boron_cpath( UThread*, const UCell* strC, UBuffer* bin ); 148 | UBuffer* boron_tempBinary( const UThread* ); 149 | UStatus boron_badArg( UThread*, UIndex atom, int argN ); 150 | void boron_randomSeed( UThread*, uint32_t ); 151 | uint32_t boron_random( UThread* ); 152 | 153 | #ifdef __cplusplus 154 | } 155 | #endif 156 | 157 | 158 | #endif /*EOF*/ 159 | -------------------------------------------------------------------------------- /include/urlan_atoms.h: -------------------------------------------------------------------------------- 1 | #ifndef URLAN_ATOMS_H 2 | #define URLAN_ATOMS_H 3 | 4 | enum UrlanFixedAtoms 5 | { 6 | UR_ATOM_I8 = 64, 7 | UR_ATOM_U8, 8 | UR_ATOM_I16, 9 | UR_ATOM_U16, 10 | UR_ATOM_I32, 11 | UR_ATOM_U32, 12 | UR_ATOM_F32, 13 | UR_ATOM_F64, 14 | UR_ATOM_I64, 15 | UR_ATOM_U64, 16 | 17 | UR_ATOM_NONE, 18 | UR_ATOM_TRUE, 19 | UR_ATOM_FALSE, 20 | UR_ATOM_ON, 21 | UR_ATOM_OFF, 22 | UR_ATOM_YES, 23 | UR_ATOM_NO, 24 | 25 | UR_ATOM_QUIT, 26 | UR_ATOM_HALT, 27 | UR_ATOM_RETURN, 28 | UR_ATOM_BREAK, 29 | UR_ATOM_CONTINUE, 30 | UR_ATOM_EXTERN, 31 | UR_ATOM_LOCAL, 32 | UR_ATOM_SELF, 33 | 34 | UR_ATOM_LATIN1, 35 | UR_ATOM_UTF8, 36 | UR_ATOM_UCS2, 37 | UR_ATOM_URL, 38 | 39 | UR_ATOM_PLUS, 40 | UR_ATOM_MINUS, 41 | UR_ATOM_SLASH, 42 | UR_ATOM_ASTERISK, 43 | UR_ATOM_EQUAL, 44 | UR_ATOM_LT, 45 | UR_ATOM_GT, 46 | UR_ATOM_LTE, 47 | UR_ATOM_GTE, 48 | 49 | UR_ATOM_X, 50 | UR_ATOM_Y, 51 | UR_ATOM_Z, 52 | UR_ATOM_R, 53 | UR_ATOM_G, 54 | UR_ATOM_B, 55 | UR_ATOM_A, 56 | 57 | UR_ATOM_BAR, 58 | UR_ATOM_OPT, 59 | UR_ATOM_SOME, 60 | UR_ATOM_ANY, 61 | UR_ATOM_SKIP, 62 | UR_ATOM_SET, 63 | UR_ATOM_COPY, 64 | UR_ATOM_TO, 65 | UR_ATOM_THRU, 66 | UR_ATOM_INTO, 67 | UR_ATOM_PLACE, 68 | UR_ATOM_BITS, 69 | 70 | UR_ATOM_BIG_ENDIAN, 71 | UR_ATOM_LITTLE_ENDIAN 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := . 2 | 3 | include $(CLEAR_VARS) 4 | LOCAL_MODULE := libboron 5 | LOCAL_CFLAGS := -DCONFIG_CHECKSUM -DCONFIG_COMPRESS=1 -DCONFIG_HASHMAP -DCONFIG_EXECUTE -DCONFIG_RANDOM -DCONFIG_SOCKET -DCONFIG_THREAD 6 | LOCAL_C_INCLUDES := include urlan eval support 7 | LOCAL_EXPORT_LDLIBS := -lz 8 | LOCAL_SRC_FILES := urlan/hashmap.c \ 9 | support/well512.c \ 10 | eval/random.c \ 11 | eval/port_socket.c \ 12 | urlan/env.c \ 13 | urlan/array.c \ 14 | urlan/binary.c \ 15 | urlan/block.c \ 16 | urlan/coord.c \ 17 | urlan/date.c \ 18 | urlan/path.c \ 19 | urlan/string.c \ 20 | urlan/context.c \ 21 | urlan/gc.c \ 22 | urlan/serialize.c \ 23 | urlan/tokenize.c \ 24 | urlan/vector.c \ 25 | urlan/parse_block.c \ 26 | urlan/parse_string.c \ 27 | support/str.c \ 28 | support/mem_util.c \ 29 | support/quickSortIndex.c \ 30 | support/fpconv.c \ 31 | eval/boron.c \ 32 | eval/port_file.c \ 33 | eval/port_thread.c \ 34 | eval/wait.c \ 35 | unix/os.c 36 | include $(BUILD_STATIC_LIBRARY) 37 | 38 | 39 | include $(CLEAR_VARS) 40 | LOCAL_MODULE := boron2 41 | LOCAL_C_INCLUDES := include support 42 | LOCAL_SRC_FILES := eval/main.c 43 | LOCAL_STATIC_LIBRARIES := boron 44 | include $(BUILD_EXECUTABLE) 45 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_MODULES := libboron boron2 2 | APP_ABI := armeabi-v7a arm64-v8a x86_64 3 | APP_OPTIM := release 4 | APP_PLATFORM := android-24 5 | -------------------------------------------------------------------------------- /project.b: -------------------------------------------------------------------------------- 1 | project: "boron" 2 | 3 | options [ 4 | -debug: false "Compile for debugging" 5 | assemble: false "Enable assemble function (requires libjit)" 6 | checksum: true "Enable checksum function" 7 | compress: 'zlib "Include compressor ('zlib/'bzip2/none)" 8 | hashmap: true "Enable hash-map! datatype" 9 | execute: true "Enable execute function" 10 | random: true "Include random number generator" 11 | readline: 'linenoise "Console editing ('linenoise/'gnu/none)" 12 | socket: true "Enable socket port!" 13 | ssl: false "Enable SSL/TLS port! (requires mbedtls)" 14 | static: false "Build static library and stand-alone executable" 15 | thread: false "Enable thread functions" 16 | timecode: false "Enable timecode! datatype" 17 | atom-limit: 2048 "Set maximum number of words" 18 | atom-names: mul atom-limit 16 "Set byte size of word name buffer" 19 | ] 20 | 21 | default [ 22 | either -debug [debug] [release] 23 | 24 | objdir %obj 25 | include_from [%include %urlan %eval %support] 26 | 27 | macx [ 28 | cflags {-std=c99} 29 | cflags {-pedantic} 30 | ;universal 31 | ] 32 | unix [ 33 | ;cflags {-std=c99} 34 | cflags {-std=gnu99} ; Try this if c99 fails. 35 | cflags {-pedantic} 36 | ] 37 | win32 [ 38 | if thread [cflags {-D_WIN32_WINNT=0x0600}] 39 | ] 40 | ] 41 | 42 | lib-spec: [ 43 | cflags rejoin [ 44 | {-DCONFIG_ATOM_LIMIT=} atom-limit 45 | { -DCONFIG_ATOM_NAMES=} atom-names 46 | ] 47 | if checksum [ 48 | cflags {-DCONFIG_CHECKSUM} 49 | ] 50 | if eq? compress 'zlib [ 51 | cflags {-DCONFIG_COMPRESS=1} 52 | win32 [libs either msvc [%zdll] [%z]] 53 | macx [libs %z] 54 | unix [libs %z] 55 | ] 56 | if eq? compress 'bzip2 [ 57 | cflags {-DCONFIG_COMPRESS=2} 58 | win32 [libs %libbz2] 59 | macx [libs %bz2] 60 | unix [libs %bz2] 61 | ] 62 | if hashmap [ 63 | cflags {-DCONFIG_HASHMAP} 64 | sources [%urlan/hashmap.c] 65 | ] 66 | if execute [ 67 | cflags {-DCONFIG_EXECUTE} 68 | ] 69 | if random [ 70 | cflags {-DCONFIG_RANDOM} 71 | sources [ 72 | %support/well512.c 73 | %eval/random.c 74 | ] 75 | ] 76 | if ssl [ 77 | socket: true 78 | cflags {-DCONFIG_SSL} 79 | libs %mbedtls 80 | ] 81 | if socket [ 82 | cflags {-DCONFIG_SOCKET} 83 | sources [%eval/port_socket.c] 84 | ] 85 | if timecode [ 86 | cflags {-DCONFIG_TIMECODE} 87 | ] 88 | if thread [ 89 | cflags {-DCONFIG_THREAD} 90 | linux [libs %pthread] 91 | sources [%eval/port_thread.c] 92 | ] 93 | if assemble [ 94 | cflags {-DCONFIG_ASSEMBLE} 95 | libs %jit 96 | ] 97 | ;cflags {-DTRACK_MALLOC} sources [%urlan/memtrack.c] 98 | 99 | sources_from %urlan [ 100 | %env.c 101 | %array.c 102 | %binary.c 103 | %block.c 104 | %coord.c 105 | %date.c 106 | %path.c 107 | %string.c 108 | %context.c 109 | %gc.c 110 | %serialize.c 111 | %tokenize.c 112 | %vector.c 113 | 114 | %parse_block.c 115 | %parse_string.c 116 | ] 117 | 118 | sources [ 119 | %support/str.c 120 | %support/mem_util.c 121 | %support/quickSortIndex.c 122 | %support/fpconv.c 123 | 124 | %eval/boron.c 125 | %eval/port_file.c 126 | %eval/wait.c 127 | ] 128 | 129 | macx [sources [%unix/os.c]] 130 | unix [ 131 | sources [%unix/os.c] 132 | libs %m 133 | ] 134 | win32 [ 135 | sources [%win32/os.c] 136 | ifn static [ 137 | lflags either msvc ["/def:win32\boron.def"]["win32/boron.def"] 138 | ] 139 | libs %ws2_32 140 | ] 141 | ] 142 | 143 | either static [ 144 | exe-libs: [] 145 | lib %boron bind lib-spec context [ 146 | libs: func [l] [append exe-libs l] 147 | ] 148 | ][ 149 | shlib [%boron 2,0,8] lib-spec 150 | ] 151 | 152 | exe %boron [ 153 | win32 [ 154 | console 155 | libs %ws2_32 156 | readline: false 157 | ] 158 | libs_from %. %boron 159 | if static [ 160 | foreach l exe-libs [libs l] 161 | ] 162 | switch readline [ 163 | linenoise [ 164 | cflags {-DCONFIG_LINENOISE} 165 | sources [%support/linenoise.c] 166 | ] 167 | gnu [ 168 | cflags {-DCONFIG_READLINE} 169 | libs [%readline %history] 170 | ] 171 | ] 172 | sources [ 173 | %eval/main.c 174 | ] 175 | ] 176 | -------------------------------------------------------------------------------- /qt/UTreeModel.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "UTreeModel.h" 4 | #include "boron-qt.h" 5 | 6 | 7 | extern QString qstring( const UCell* cell ); 8 | 9 | 10 | UTreeModel::UTreeModel( QObject* parent, const UCell* hdr, const UCell* data ) 11 | : QAbstractItemModel( parent ) 12 | { 13 | UThread* ut = qEnv.ut; 14 | 15 | _blkN = UR_INVALID_BUF; 16 | _hold = UR_INVALID_HOLD; 17 | _rows = 0; 18 | _cols = 1; 19 | 20 | if( ur_is(hdr, UT_BLOCK ) ) 21 | { 22 | UBlockIter bi; 23 | ur_blkSlice( ut, &bi, hdr ); 24 | ur_foreach( bi ) 25 | { 26 | _hdr.append( qstring( bi.it ) ); 27 | } 28 | if( _hdr.size() ) 29 | _cols = _hdr.size(); 30 | } 31 | 32 | if( data ) 33 | setData( data ); 34 | } 35 | 36 | 37 | UTreeModel::~UTreeModel() 38 | { 39 | if( _hold != UR_INVALID_HOLD ) 40 | { 41 | UThread* ut = qEnv.ut; 42 | ur_release( _hold ); 43 | } 44 | } 45 | 46 | 47 | static QVariant cellToVariant( const UCell* cell ) 48 | { 49 | switch( ur_type(cell) ) 50 | { 51 | case UT_CHAR: 52 | return QChar( int(ur_int(cell)) ); 53 | case UT_INT: 54 | return qlonglong(ur_int(cell)); 55 | case UT_DOUBLE: 56 | return ur_double(cell); 57 | default: 58 | return qstring( cell ); 59 | } 60 | } 61 | 62 | 63 | QVariant UTreeModel::data( const QModelIndex& index, int role ) const 64 | { 65 | if( index.isValid() ) 66 | { 67 | if( role == Qt::DisplayRole ) 68 | { 69 | UThread* ut = qEnv.ut; 70 | const UBuffer* blk = ur_buffer( _blkN ); 71 | int i = (_cols * index.row()) + index.column(); 72 | if( i < blk->used ) 73 | return cellToVariant( blk->ptr.cell + i ); 74 | } 75 | } 76 | return QVariant(); 77 | } 78 | 79 | 80 | QVariant UTreeModel::headerData( int section, Qt::Orientation /*orientation*/, 81 | int role ) const 82 | { 83 | switch( role ) 84 | { 85 | case Qt::DisplayRole: 86 | return _hdr.value( section ); 87 | } 88 | return QVariant(); 89 | } 90 | 91 | 92 | QModelIndex UTreeModel::index( int row, int column, 93 | const QModelIndex& /*parent*/ ) const 94 | { 95 | return createIndex( row, column ); 96 | } 97 | 98 | 99 | QModelIndex UTreeModel::parent( const QModelIndex& /*index*/ ) const 100 | { 101 | return QModelIndex(); 102 | } 103 | 104 | 105 | int UTreeModel::rowCount( const QModelIndex& parent ) const 106 | { 107 | if( parent.isValid() ) 108 | return 0; 109 | return _rows; 110 | } 111 | 112 | 113 | int UTreeModel::columnCount( const QModelIndex& parent ) const 114 | { 115 | if( parent.isValid() ) 116 | return 0; 117 | return _cols; 118 | } 119 | 120 | 121 | void UTreeModel::setData( const UCell* data ) 122 | { 123 | UThread* ut = qEnv.ut; 124 | 125 | #if QT_VERSION >= 0x040600 126 | beginResetModel(); 127 | #endif 128 | 129 | if( _hold != UR_INVALID_HOLD ) 130 | ur_release( _hold ); 131 | 132 | if( ur_is(data, UT_BLOCK ) ) 133 | { 134 | _blkN = data->series.buf; 135 | _hold = ur_hold( _blkN ); 136 | 137 | const UBuffer* blk = ur_buffer( _blkN ); 138 | _rows = blk->used / _cols; 139 | } 140 | else 141 | { 142 | _blkN = UR_INVALID_BUF; 143 | _hold = UR_INVALID_HOLD; 144 | _rows = 0; 145 | } 146 | 147 | #if QT_VERSION >= 0x040600 148 | endResetModel(); 149 | #else 150 | reset(); 151 | #endif 152 | } 153 | 154 | 155 | void UTreeModel::blockSlice( const QModelIndex& index, UCell* res ) 156 | { 157 | if( index.isValid() ) 158 | { 159 | //UThread* ut = qEnv.ut; 160 | //const UBuffer* blk = ur_buffer( _blkN ); 161 | int i = _cols * index.row(); // + index.column(); 162 | //if( i < blk->used ) 163 | { 164 | ur_setId(res, UT_BLOCK); 165 | ur_setSlice(res, _blkN, i, i + _cols ); 166 | } 167 | } 168 | else 169 | { 170 | ur_setId(res, UT_NONE); 171 | } 172 | } 173 | 174 | 175 | //EOF 176 | -------------------------------------------------------------------------------- /qt/UTreeModel.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "urlan.h" 4 | #include 5 | #include 6 | 7 | 8 | class UTreeModel : public QAbstractItemModel 9 | { 10 | public: 11 | 12 | UTreeModel( QObject* parent, const UCell* hdr, const UCell* data = 0 ); 13 | ~UTreeModel(); 14 | 15 | QVariant data( const QModelIndex& , int role ) const; 16 | QVariant headerData( int section, Qt::Orientation, int role ) const; 17 | QModelIndex index( int row, int column, const QModelIndex& parent ) const; 18 | QModelIndex parent( const QModelIndex& index ) const; 19 | int rowCount( const QModelIndex& parent ) const; 20 | int columnCount( const QModelIndex& parent ) const; 21 | 22 | void setData( const UCell* data ); 23 | void blockSlice( const QModelIndex& index, UCell* res ); 24 | 25 | private: 26 | 27 | UIndex _blkN; 28 | UIndex _hold; 29 | int _rows; 30 | int _cols; 31 | QStringList _hdr; 32 | }; 33 | 34 | 35 | -------------------------------------------------------------------------------- /qt/boron-qt.h: -------------------------------------------------------------------------------- 1 | #ifndef QBORON_H 2 | #define QBORON_H 3 | /*============================================================================ 4 | Boron Qt Module 5 | Copyright (C) 2005-2009 Karl Robillard 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 | 02110-1301, USA. 21 | ============================================================================*/ 22 | 23 | 24 | #include "boron.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | 40 | enum eWidgetType 41 | { 42 | WT_Null, 43 | WT_Button, 44 | WT_Dialog, 45 | WT_Label, 46 | WT_LineEdit, 47 | WT_CheckBox, 48 | WT_SpinBox, 49 | WT_Combo, 50 | WT_Tab, 51 | WT_TextEdit, 52 | WT_TreeView, 53 | WT_Group, 54 | WT_Progress, 55 | WT_Watcher, 56 | WT_Widget 57 | }; 58 | 59 | 60 | class WIDPool 61 | { 62 | public: 63 | 64 | enum eRecFlags 65 | { 66 | DeleteObject = 0x0001 67 | }; 68 | 69 | struct REC 70 | { 71 | short type; 72 | short flags; 73 | union 74 | { 75 | QObject* object; 76 | QWidget* widget; 77 | }; 78 | }; 79 | 80 | WIDPool() : _freeCount(0), _freeIndex(-1) {} 81 | 82 | int add( QObject*, int type, int flags = 0 ); 83 | void remove( int id ); 84 | REC* record( int id ); 85 | 86 | typedef QVector::iterator iterator; 87 | iterator begin() { return _records.begin(); } 88 | iterator end() { return _records.end(); } 89 | 90 | private: 91 | 92 | int _freeCount; 93 | int _freeIndex; 94 | QVector _records; 95 | }; 96 | 97 | 98 | struct QtEnv 99 | { 100 | UThread* ut; 101 | 102 | UAtom atom_close; 103 | UAtom atom_exec_exit; 104 | UAtom atom_ready; 105 | UAtom atom_removed; 106 | UAtom atom_created; 107 | UAtom atom_changed; 108 | 109 | UIndex layoutRules; 110 | UIndex comboCtxN; 111 | 112 | QWidget* curWidget; 113 | QDialog* dialog; 114 | QString filePath; // Saves directory selected in last request-file. 115 | WIDPool pool; 116 | 117 | QEventLoop* loop; 118 | }; 119 | 120 | 121 | class BoronApp : public QApplication 122 | { 123 | Q_OBJECT 124 | 125 | public: 126 | 127 | BoronApp( int& argc, char** argv ); 128 | }; 129 | 130 | 131 | class ExeBlock 132 | { 133 | public: 134 | ExeBlock() : n(0), hold(UR_INVALID_HOLD) {} 135 | ~ExeBlock(); 136 | 137 | void setBlock( const UCell* ); 138 | void switchWord( UAtom ); 139 | 140 | UIndex n; 141 | UIndex index; 142 | UIndex hold; 143 | }; 144 | 145 | 146 | class SButton : public QPushButton 147 | { 148 | Q_OBJECT 149 | 150 | public: 151 | 152 | SButton(); 153 | ~SButton(); 154 | 155 | int _wid; 156 | 157 | void setBlock( const UCell* v ); 158 | 159 | public slots: 160 | 161 | void slotDo(); 162 | 163 | private: 164 | 165 | ExeBlock _blk; 166 | }; 167 | 168 | 169 | class SCombo : public QComboBox 170 | { 171 | Q_OBJECT 172 | 173 | public: 174 | 175 | SCombo(); 176 | ~SCombo(); 177 | 178 | int _wid; 179 | 180 | void setBlock( const UCell* ); 181 | 182 | public slots: 183 | 184 | void slotDo( int ); 185 | 186 | private: 187 | 188 | ExeBlock _blk; 189 | }; 190 | 191 | 192 | class STreeView : public QTreeView 193 | { 194 | Q_OBJECT 195 | 196 | public: 197 | 198 | STreeView(); 199 | ~STreeView(); 200 | 201 | int _wid; 202 | 203 | void setBlock( const UCell* ); 204 | 205 | public slots: 206 | 207 | void slotDo( const QModelIndex& ); 208 | 209 | private: 210 | 211 | ExeBlock _blk; 212 | }; 213 | 214 | 215 | class SWidget : public QWidget 216 | { 217 | Q_OBJECT 218 | 219 | public: 220 | 221 | SWidget(); 222 | ~SWidget(); 223 | 224 | int _wid; 225 | 226 | void setEventBlock( const UCell* ); 227 | 228 | protected: 229 | 230 | void closeEvent( QCloseEvent* ); 231 | 232 | private: 233 | 234 | ExeBlock _blk; 235 | }; 236 | 237 | 238 | #define DEF_WIDGET(oo,qo) \ 239 | class oo : public qo { public: oo(); ~oo(); int _wid; } 240 | 241 | 242 | DEF_WIDGET(SCheck,QCheckBox); 243 | DEF_WIDGET(SSpinBox,QSpinBox); 244 | DEF_WIDGET(SDialog,QDialog); 245 | DEF_WIDGET(SGroup,QGroupBox); 246 | DEF_WIDGET(SLabel,QLabel); 247 | DEF_WIDGET(SLineEdit,QLineEdit); 248 | DEF_WIDGET(STabWidget,QTabWidget); 249 | DEF_WIDGET(STextEdit,QTextEdit); 250 | DEF_WIDGET(SProgress,QProgressBar); 251 | 252 | 253 | extern QtEnv qEnv; 254 | 255 | extern void boron_initQt( UThread* ); 256 | extern void boron_freeQt(); 257 | extern void boron_doBlockQt( UThread*, const UCell* blkC ); 258 | 259 | 260 | #endif /*QBORON_H*/ 261 | -------------------------------------------------------------------------------- /qt/examples/hello.b: -------------------------------------------------------------------------------- 1 | exec widget [ 2 | vbox [ button "Hello World" [quit] ] 3 | ] 4 | -------------------------------------------------------------------------------- /qt/examples/layout1.b: -------------------------------------------------------------------------------- 1 | /* 2 | A simple layout example. 3 | */ 4 | 5 | print exec widget [ 6 | vbox [ 7 | grid 3 [ 8 | label "Input Folder" if: line-edit button "..." [print "A"] 9 | label "Config File" cf: line-edit button "..." [print "B"] 10 | label "Log File" lf: line-edit button "..." [print "C"] 11 | ] 12 | spacer 13 | hbox [ 14 | spacer 15 | button "OK" [close yes] 16 | button "Cancel" [close no ] 17 | ] 18 | ] 19 | ] 20 | -------------------------------------------------------------------------------- /qt/examples/progress.b: -------------------------------------------------------------------------------- 1 | done: 0 2 | exec widget [ 3 | vbox [ 4 | label "Progress Demo" 5 | prog-bar: progress 10 6 | spacer 7 | hbox [ 8 | spacer 9 | button "Increment" [ 10 | set-widget-value prog-bar either equal? done 10 [0] [++ done] 11 | ] 12 | button "Quit" [quit] 13 | ] 14 | ] 15 | ] 16 | -------------------------------------------------------------------------------- /qt/examples/widgets.b: -------------------------------------------------------------------------------- 1 | /* 2 | Show all widgets. 3 | */ 4 | 5 | text: 6 | {

Text-Edit Widget

7 |

Text-edit can show basic HTML.

8 |
9 |

A List

10 |
    11 |
  • Item one
  • 12 |
  • Item two
  • 13 |
14 | } 15 | 16 | exec widget [ 17 | vbox [ 18 | tab [ 19 | "Basic" [ 20 | vbox [ 21 | hbox [button "Button" [print "Button pressed"] spacer] 22 | hbox [ 23 | label "Combo" 24 | combo ["Item one" "Item two" "Last Item"] 25 | [print ["Combo activated:" index]] ; Optional 26 | spacer 27 | ] 28 | checkbox "Checkbox" 29 | list ["Name" "Age"] [ 30 | "Chris" 32 31 | "Abe" 51 32 | "Sara" 28 33 | ] 34 | [print ["List activated:" index]] ; Optional 35 | spacer 36 | ] 37 | ] 38 | "Text" [ 39 | vbox [ 40 | hbox [label "Line-edit" line-edit] 41 | text-edit :text 42 | ] 43 | ] 44 | "Grouping" [vbox [ 45 | group "Group" [vbox [ 46 | button "Checked Status" [ 47 | print [ 48 | "Checked Status^/ Group 1:" widget-value grp1 49 | "^/ Group 2:" widget-value grp2 50 | ] 51 | ] tip "Print checkable group status." 52 | ]] 53 | grp1: group true "Checkable Group 1" [vbox [ 54 | label "Checked by default" 55 | ]] 56 | grp2: group false "Checkable Group 2" [vbox [ 57 | label "Unchecked by default" 58 | ]] 59 | spacer 60 | ]] 61 | "Dialogs" [ 62 | vbox [ 63 | button "Message" [ 64 | message "Message" 65 | "This was invoked by the 'message word." 66 | ] 67 | 68 | button "Question" [ 69 | answer: question "Question" 70 | "Do you like vanilla yogurt?" 71 | "Yes" "Umm, not so much" 72 | message "Answer" join "Question returned: " answer 73 | ] 74 | 75 | button "Request-file" [ 76 | file: request-file "Select a file" 77 | message "File Selected" file 78 | ] 79 | 80 | spacer 81 | ] 82 | ] 83 | ] 84 | 85 | spacer 86 | hbox [spacer button "Quit" [quit]] 87 | ] 88 | ] 89 | -------------------------------------------------------------------------------- /qt/project.b: -------------------------------------------------------------------------------- 1 | 2 | exe %boron-qt [ 3 | warn 4 | debug 5 | ;release 6 | objdir %obj 7 | 8 | qt [widgets] 9 | include_from [%. %../include %../urlan %../support %../util] 10 | libs_from %.. %boron 11 | 12 | macx [ 13 | libs %bz2 14 | ] 15 | linux [ 16 | libs %bz2 17 | ] 18 | win32 [ 19 | include_from %../win32 20 | sources_from %../win32 [%win32console.c] 21 | libs %ws2_32 22 | ] 23 | 24 | sources [ 25 | %main.cpp 26 | %boron-qt.cpp 27 | %UTreeModel.cpp 28 | %../util/CBParser.c 29 | ] 30 | ] 31 | 32 | -------------------------------------------------------------------------------- /scripts/bump_dev.b: -------------------------------------------------------------------------------- 1 | old: 2,0,6 2 | new: 2,0,7 3 | files: [ 4 | %Makefile ["VER=$v"] 5 | %project.b ["%boron $c"] 6 | %eval/boot.b ["version: $c"] 7 | %include/boron.h [ 8 | {BORON_VERSION_STR "$v"} 9 | {BORON_VERSION 0x0$m0$i0$r} 10 | ] 11 | ] 12 | finish: [ 13 | print "Now run eval/mkboot." 14 | ] 15 | -------------------------------------------------------------------------------- /scripts/bump_version.b: -------------------------------------------------------------------------------- 1 | #!/usr/bin/boron -s 2 | ; Bump Version v1.1 3 | 4 | usage: {{ 5 | Usage: bump-version [OPTIONS] 6 | 7 | Options: 8 | -b Use built-in specification. 9 | -f Use version specification file. (default: ./version-up.b) 10 | -h Print this help and quit. 11 | -r Revert to old version; reverse mapping of old to new. 12 | }} 13 | 14 | spec-file: %version-up.b 15 | finish: none 16 | vorder: [old new] 17 | 18 | forall args [ 19 | switch first args [ 20 | "-b" [spec-file: none] 21 | "-f" [spec-file: to-file second ++ args] 22 | "-h" [print usage quit] 23 | "-r" [swap vorder] 24 | ] 25 | ] 26 | 27 | either spec-file [ 28 | do spec-file 29 | ][ 30 | old: 2,0,6 31 | new: 2,0,8 32 | files: [ 33 | %Makefile ["VER=$v"] 34 | %dist/boron.spec ["Version: $v"] 35 | %dist/control ["Version: $v"] 36 | %project.b ["%boron $c"] 37 | %eval/boot.b ["version: $c"] 38 | %doc/UserManual.md ["Version $v, "] 39 | %doc/boron.troff ["Version $v" "boron $v"] 40 | %include/boron.h [ 41 | {BORON_VERSION_STR "$v"} 42 | {BORON_VERSION 0x0$m0$i0$r} 43 | ] 44 | %include/urlan.h [ 45 | {UR_VERSION_STR "$v"} 46 | {UR_VERSION 0x0$m0$i0$r} 47 | ] 48 | ] 49 | finish: [ 50 | print "Now run eval/mkboot, adjust manual dates, and make docs." 51 | ] 52 | ] 53 | 54 | mrule: func [version coord!] [ 55 | replace: reduce [ 56 | str: mold version ; $c Coordinate version "1,2,3" 57 | construct str [',' '.'] ; $v Program version "1.2.3" 58 | first version ; $m Major version "1" 59 | second version ; $i Minor version "2" 60 | third version ; $r Revision "3" 61 | ] 62 | blk: make block! 10 63 | foreach it "cvmir" [ 64 | append append blk join '$' it first ++ replace 65 | ] 66 | blk 67 | ] 68 | 69 | 70 | old-rules: mrule get first vorder 71 | new-rules: mrule get second vorder 72 | 73 | crule: func [spec] [ 74 | blk: make block! 4 75 | foreach it spec [ 76 | append blk construct it old-rules 77 | append blk construct it new-rules 78 | ] 79 | blk 80 | ] 81 | 82 | foreach [f mod] files [ 83 | ;probe crule mod 84 | write f construct read/text f crule mod 85 | ] 86 | do finish 87 | -------------------------------------------------------------------------------- /scripts/c_binary.b: -------------------------------------------------------------------------------- 1 | #!/usr/bin/boron 2 | 3 | contents-only: ser: false 4 | parse args [some[ 5 | "-c" contents-only: 6 | | "-s" ser: 7 | | set file skip 8 | ]] 9 | 10 | bin: either ser [serialize load file] [read file] 11 | 12 | ifn contents-only [ 13 | parse file [some ['/' file: | '.' -1 skip :file break | skip]] 14 | prin rejoin [ 15 | "#define " file "_len^-" size? bin 16 | "^/static const unsigned char " file "_data[] = {" 17 | ] 18 | ] 19 | 20 | n: 0 21 | foreach c bin [ 22 | if zero? and 7 ++ n [prin "^/ "] 23 | prin to-hex c 24 | prin ',' 25 | ] 26 | 27 | prin either contents-only ['^/']["^/};^/"] 28 | -------------------------------------------------------------------------------- /scripts/c_string.b: -------------------------------------------------------------------------------- 1 | ; Convert Boron data to C string. 2 | 3 | replace-quotes: func [str] [ 4 | replace/all copy str '"' {\"} 5 | ] 6 | 7 | forall args [ 8 | str: to-string load first args 9 | str: copy trim/indent slice str 1,-1 ; Remove first & last bracket. 10 | append str '^/' 11 | parse str [some[ 12 | tok: to '^/' :tok skip ( 13 | ifn empty? tok [prin { "} prin replace-quotes tok print {\n"}] 14 | ) 15 | ]] 16 | ] 17 | -------------------------------------------------------------------------------- /scripts/cfunc_table.b: -------------------------------------------------------------------------------- 1 | ; Make _cfuncTable and serialized signatures from individual addCFunc calls. 2 | 3 | ft: make string! 1024 4 | sig: make block! 512 5 | s2: empty: "" 6 | 7 | append ft "BoronCFunc _cfuncTable[] =^/{^/" 8 | parse read/text %boron.c [ 9 | thru "CFUNC_TABLE_START^/" 10 | some [ 11 | " addCFunc(" f: thru ',' :f thru '"' s: to '"' :s thru '^/' 12 | opt [some ' ' '"' s2: to '"' :s2 thru '^/'] 13 | ( 14 | append ft rejoin [" " f '^/'] 15 | 16 | blk: probe to-block rejoin ["^/" s s2] 17 | blk/1: to-set-word blk/1 18 | append sig blk 19 | s2: empty 20 | ) 21 | ] 22 | ] 23 | append ft "};^/^/" 24 | 25 | c-array: func [name bin | out] [ 26 | out: make string! 1024 27 | append out rejoin ["uint8_t " name "[] =^/{^/ // " size? bin " bytes"] 28 | forall bin [ 29 | if eq? 1 and index? bin 15 [append out "^/ "] 30 | append out first bin 31 | append out ',' 32 | ] 33 | append out "^/};^/" 34 | out 35 | ] 36 | 37 | append ft c-array "_cfuncSigs" serialize sig 38 | write %cfuncTable.c ft 39 | -------------------------------------------------------------------------------- /scripts/ctx_header.b: -------------------------------------------------------------------------------- 1 | #!/usr/bin/boron 2 | /* 3 | Print C enum statements for each context in input. 4 | */ 5 | 6 | hdr: make string! 1024 7 | 8 | cc: func [word] [ 9 | word: replace/all to-text word '-' '_' 10 | word/1: uppercase word/1 11 | word 12 | ] 13 | 14 | uc: func [word] [ 15 | replace/all uppercase to-text word '-' '_' 16 | ] 17 | 18 | code: load args/1 19 | parse code [some[ 20 | tok: set-word! 'context block! ( 21 | prefix: uc tok/1 22 | append hdr rejoin ["enum Context" cc tok/1 "^/{^/"] 23 | foreach v tok/3 [ 24 | if set-word? v [ 25 | append hdr rejoin [" " prefix '_' uc v ",^/"] 26 | ] 27 | ] 28 | append hdr "};^/" 29 | ) 30 | | skip 31 | ]] 32 | 33 | prin hdr 34 | -------------------------------------------------------------------------------- /scripts/m2/test.b: -------------------------------------------------------------------------------- 1 | #!/usr/bin/boron -s 2 | ; Test m2 on various project files. 3 | ; Must be run from the boron/scripts/m2/ directory. 4 | 5 | odir: %/tmp/m2-test 6 | mdir: current-dir 7 | home: to-file terminate getenv "HOME" '/' 8 | 9 | targets: [ 10 | %m2_linux.b 11 | %m2_macx.b 12 | %m2_mingw.b 13 | ; %m2_sun.b Not updated for Qt 5. 14 | %m2_visualc.b 15 | ] 16 | 17 | projects: reduce [ 18 | join home %src/primal 19 | join home %src/boron 20 | join home %src/bgl 21 | ] 22 | 23 | make-dir odir 24 | foreach proj projects [ 25 | change-dir proj 26 | projbase: next find/last proj '/' 27 | foreach t targets [ 28 | mf: construct to-string t ["m2" projbase ".b" none] 29 | execute rejoin [ 30 | {boron -s } mdir {m2 -t } mdir t { -o } odir '/' mf 31 | ] 32 | ] 33 | ] 34 | -------------------------------------------------------------------------------- /scripts/m2/version-up.b: -------------------------------------------------------------------------------- 1 | old: 2,0,2 2 | new: 2,0,3 3 | target_up: ["m2 $v"] 4 | files: reduce [ 5 | %m2 ["ersion $v"] 6 | %m2_linux.b target_up 7 | %m2_macx.b target_up 8 | %m2_mingw.b target_up 9 | %m2_sun.b target_up 10 | %m2_visualc.b target_up 11 | ] 12 | -------------------------------------------------------------------------------- /scripts/mkdef.b: -------------------------------------------------------------------------------- 1 | ; Create win32/boron.def 2 | ; Run from repository root. 3 | 4 | n: 1 5 | type-char: make bitset! "cilsvuU" 6 | def-format: func [sym] [ 7 | append def format [" " 26 '@' 1 '^/'] [sym ++ n] 8 | ] 9 | process-header: func [f file! prefix string!] [ 10 | parse read/text f [ 11 | thru {extern "C"} 12 | thru {#endif} 13 | some [ 14 | "#define" thru '^/' 15 | | '^/' 16 | | type-char to prefix tok: to '(' :tok thru ");^/" (def-format tok) 17 | ] 18 | ] 19 | ] 20 | 21 | def: make string! 8192 22 | append def 23 | {LIBRARY boron.dll 24 | EXPORTS 25 | } 26 | process-header %include/boron.h "boron_" 27 | process-header %include/urlan.h "ur_" 28 | foreach sym [ 29 | find_uint8_t 30 | find_uint16_t 31 | find_uint32_t 32 | find_pattern_8 33 | find_pattern_ic_8 34 | find_pattern_16 35 | find_pattern_ic_16 36 | unset_bind 37 | unset_compare 38 | unset_copy 39 | unset_destroy 40 | unset_make 41 | unset_mark 42 | unset_operate 43 | unset_select 44 | unset_toShared 45 | unset_toString 46 | binary_copy 47 | binary_mark 48 | binary_toShared 49 | block_markBuf 50 | cfunc_free 51 | vec3_toString 52 | ][ 53 | def-format sym 54 | ] 55 | append def ';' def-format 'ur_stringToTimeCode 56 | write %win32/boron.def def 57 | -------------------------------------------------------------------------------- /scripts/vm-summary.b: -------------------------------------------------------------------------------- 1 | #!/usr/bin/boron 2 | ; Summarize Valgrind Massif files. 3 | 4 | eol: '^/' 5 | heap: 0 6 | 7 | parse read/text first args [ 8 | thru "cmd: " cmd: to eol :cmd 9 | some [ 10 | thru "time=" t: to eol :t ( 11 | time: to-int t time 12 | ) 13 | thru "mem_heap_B=" t: to eol :t ( 14 | hb: to-int t 15 | ) 16 | thru "mem_heap_extra_B=" t: to eol :t ( 17 | hb: add hb to-int t 18 | if gt? hb heap [heap: hb] 19 | ) 20 | ] 21 | ] 22 | 23 | pad: func [v] [ 24 | v: to-string v 25 | rejoin [skip " " size? v v] 26 | ] 27 | 28 | print [pad time pad heap cmd] 29 | -------------------------------------------------------------------------------- /support/cpuCounter.h: -------------------------------------------------------------------------------- 1 | #ifndef CPUCOUNTER_H 2 | #define CPUCOUNTER_H 3 | 4 | 5 | #include 6 | 7 | 8 | #if defined(__GNUC__) 9 | #if defined(__x86_64__) 10 | #define HAVE_CPU_COUNTER 11 | static __inline__ uint64_t cpuCounter() 12 | { 13 | uint32_t lo, hi; 14 | /* We cannot use "=A", since this would use %rax on x86_64 */ 15 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); 16 | return (uint64_t) hi << 32 | lo; 17 | } 18 | #elif defined(__i386__) 19 | #define HAVE_CPU_COUNTER 20 | static __inline__ uint64_t cpuCounter() 21 | { 22 | uint64_t c; 23 | __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (c)); 24 | return c; 25 | } 26 | #elif defined(__powerpc__) 27 | #define HAVE_CPU_COUNTER 28 | static __inline__ uint64_t cpuCounter() 29 | { 30 | uint32_t lo, hi, t; 31 | __asm__ __volatile__ ( 32 | "0:\n" 33 | "\tmftbu %0\n" 34 | "\tmftb %1\n" 35 | "\tmftbu %2\n" 36 | "\tcmpw %2,%0\n" 37 | "\tbne 0b\n" 38 | : "=r" (hi), "=r" (lo), "=r" (t) 39 | ); 40 | return (uint64_t) hi << 32 | lo; 41 | } 42 | #endif 43 | #endif 44 | 45 | 46 | #endif /*CPUCOUNTER_H*/ 47 | -------------------------------------------------------------------------------- /support/linenoise.h: -------------------------------------------------------------------------------- 1 | /* linenoise.h -- guerrilla line editing library against the idea that a 2 | * line editing lib needs to be 20,000 lines of C code. 3 | * 4 | * See linenoise.c for more information. 5 | * 6 | * ------------------------------------------------------------------------ 7 | * 8 | * Copyright (c) 2010, Salvatore Sanfilippo 9 | * Copyright (c) 2010, Pieter Noordhuis 10 | * 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef __LINENOISE_H 38 | #define __LINENOISE_H 39 | 40 | #define NO_COMPLETION 41 | #ifndef NO_COMPLETION 42 | typedef struct linenoiseCompletions { 43 | size_t len; 44 | char **cvec; 45 | } linenoiseCompletions; 46 | 47 | typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); 48 | void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); 49 | void linenoiseAddCompletion(linenoiseCompletions *, const char *); 50 | #endif 51 | 52 | char *linenoise(const char *prompt); 53 | int linenoiseHistoryAdd(const char *line); 54 | int linenoiseHistorySetMaxLen(int len); 55 | int linenoiseHistorySave(const char *filename); 56 | int linenoiseHistoryLoad(const char *filename); 57 | void linenoiseHistoryFree(void); 58 | char **linenoiseHistory(int *len); 59 | 60 | #endif /* __LINENOISE_H */ 61 | -------------------------------------------------------------------------------- /support/mem_util.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2009 Karl Robillard 3 | 4 | This file is part of the Boron programming language. 5 | 6 | Boron is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Boron is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Boron. If not, see . 18 | */ 19 | 20 | 21 | #include 22 | 23 | 24 | /* 25 | Returns pointer to val or zero if val not found. 26 | */ 27 | #define FIND(T) \ 28 | const T* find_ ## T( const T* it, const T* end, T val ) { \ 29 | while( it != end ) { \ 30 | if( *it == val ) \ 31 | return it; \ 32 | ++it; \ 33 | } \ 34 | return 0; \ 35 | } 36 | 37 | FIND(uint8_t) 38 | FIND(uint16_t) 39 | FIND(uint32_t) 40 | 41 | 42 | /* 43 | Returns pointer to val or zero if val not found. 44 | */ 45 | #define FIND_LAST(T) \ 46 | const T* find_last_ ## T( const T* it, const T* end, T val ) { \ 47 | while( it != end ) { \ 48 | --end; \ 49 | if( *end == val ) \ 50 | return end; \ 51 | } \ 52 | return 0; \ 53 | } 54 | 55 | FIND_LAST(uint8_t) 56 | FIND_LAST(uint16_t) 57 | FIND_LAST(uint32_t) 58 | 59 | 60 | /* 61 | Returns first occurance of any character in cset or 0 if none are found. 62 | csetLen is the number of bytes in cset. 63 | */ 64 | #define FIND_CHARSET(T) \ 65 | const T* find_charset_ ## T( const T* it, const T* end, \ 66 | const uint8_t* cset, int csetLen ) { \ 67 | T n; \ 68 | int index; \ 69 | while( it != end ) { \ 70 | n = *it; \ 71 | index = n >> 3; \ 72 | if( (index < csetLen) && (cset[index] & (1 << (n & 7))) ) \ 73 | return it; \ 74 | ++it; \ 75 | } \ 76 | return 0; \ 77 | } 78 | 79 | FIND_CHARSET(uint8_t) 80 | FIND_CHARSET(uint16_t) 81 | 82 | 83 | /* 84 | Returns last occurance of any character in cset or 0 if none are found. 85 | csetLen is the number of bytes in cset. 86 | */ 87 | #define FIND_LAST_CHARSET(T) \ 88 | const T* find_last_charset_ ## T( const T* it, const T* end, \ 89 | const uint8_t* cset, int csetLen ) { \ 90 | T n; \ 91 | int index; \ 92 | while( it != end ) { \ 93 | --end; \ 94 | n = *end; \ 95 | index = n >> 3; \ 96 | if( (index < csetLen) && (cset[index] & (1 << (n & 7))) ) \ 97 | return end; \ 98 | } \ 99 | return 0; \ 100 | } 101 | 102 | FIND_LAST_CHARSET(uint8_t) 103 | FIND_LAST_CHARSET(uint16_t) 104 | 105 | 106 | /* 107 | Returns first occurance of pattern or 0 if it is not found. 108 | 109 | TODO: Look at using a faster search algorithm such as Boyer-Moore or grep 110 | source. 111 | */ 112 | #define FIND_PATTERN(N,T,P) \ 113 | const T* find_pattern_ ## N( const T* it, const T* end, \ 114 | const P* pit, const P* pend ) { \ 115 | int pfirst = *pit++; \ 116 | while( it != end ) { \ 117 | if( *it == pfirst ) { \ 118 | const T* in = it + 1; \ 119 | const P* p = pit; \ 120 | while( p != pend && in != end ) { \ 121 | if( *in != *p ) \ 122 | break; \ 123 | ++in; \ 124 | ++p; \ 125 | } \ 126 | if( p == pend ) \ 127 | return it; \ 128 | } \ 129 | ++it; \ 130 | } \ 131 | return 0; \ 132 | } 133 | 134 | FIND_PATTERN(8,uint8_t,uint8_t) 135 | FIND_PATTERN(16,uint16_t,uint16_t) 136 | FIND_PATTERN(8_16,uint8_t,uint16_t) 137 | FIND_PATTERN(16_8,uint16_t,uint8_t) 138 | 139 | 140 | /* 141 | Returns pointer in pattern at the end of the matching elements. 142 | */ 143 | #define MATCH_PATTERN(N,T,P) \ 144 | const P* match_pattern_ ## N( const T* it, const T* end, \ 145 | const P* pit, const P* pend ) { \ 146 | while( pit != pend ) { \ 147 | if( it == end ) \ 148 | return pit; \ 149 | if( *it != *pit ) \ 150 | return pit; \ 151 | ++it; \ 152 | ++pit; \ 153 | } \ 154 | return pit; \ 155 | } 156 | 157 | MATCH_PATTERN(8,uint8_t,uint8_t) 158 | MATCH_PATTERN(16,uint16_t,uint16_t) 159 | MATCH_PATTERN(8_16,uint8_t,uint16_t) 160 | MATCH_PATTERN(16_8,uint16_t,uint8_t) 161 | 162 | 163 | #define REVERSE(T) \ 164 | void reverse_ ## T( T* it, T* end ) { \ 165 | T tmp; \ 166 | while( it < end ) { \ 167 | tmp = *it; \ 168 | --end; \ 169 | *it++ = *end; \ 170 | *end = tmp; \ 171 | } \ 172 | } 173 | 174 | REVERSE(uint8_t) 175 | REVERSE(uint16_t) 176 | REVERSE(uint32_t) 177 | 178 | 179 | #define COMPARE(T) \ 180 | int compare_ ## T( const T* it, const T* end, const T* itB, const T* endB ) { \ 181 | int lenA = end - it; \ 182 | int lenB = endB - itB; \ 183 | while( it < end && itB < endB ) { \ 184 | if( *it > *itB ) \ 185 | return 1; \ 186 | if( *it < *itB ) \ 187 | return -1; \ 188 | ++it; \ 189 | ++itB; \ 190 | } \ 191 | if( lenA > lenB ) \ 192 | return 1; \ 193 | if( lenA < lenB ) \ 194 | return -1; \ 195 | return 0; \ 196 | } 197 | 198 | COMPARE(uint8_t) 199 | COMPARE(uint16_t) 200 | 201 | 202 | /*EOF*/ 203 | -------------------------------------------------------------------------------- /support/mem_util.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_UTIL_H 2 | #define MEM_UTIL_H 3 | 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | const uint8_t* find_uint8_t( const uint8_t* it, const uint8_t* end, 10 | uint8_t val ); 11 | const uint16_t* find_uint16_t( const uint16_t* it, const uint16_t* end, 12 | uint16_t val ); 13 | const uint32_t* find_uint32_t( const uint32_t* it, const uint32_t* end, 14 | uint32_t val ); 15 | 16 | const uint8_t* find_last_uint8_t( const uint8_t* it, const uint8_t* end, 17 | uint8_t val ); 18 | const uint16_t* find_last_uint16_t( const uint16_t* it, const uint16_t* end, 19 | uint16_t val ); 20 | const uint32_t* find_last_uint32_t( const uint32_t* it, const uint32_t* end, 21 | uint32_t val ); 22 | 23 | const uint8_t* find_charset_uint8_t( const uint8_t* it, const uint8_t* end, 24 | const uint8_t* cset, int csetLen ); 25 | const uint16_t* find_charset_uint16_t( const uint16_t* it, const uint16_t* end, 26 | const uint8_t* cset, int csetLen ); 27 | 28 | const uint8_t* find_last_charset_uint8_t( const uint8_t* it, const uint8_t* end, 29 | const uint8_t* cset, int csetLen ); 30 | const uint16_t* find_last_charset_uint16_t( const uint16_t* it, 31 | const uint16_t* end, 32 | const uint8_t* cset, int csetLen ); 33 | 34 | const uint8_t* find_pattern_8( const uint8_t* it, const uint8_t* end, 35 | const uint8_t* pit, const uint8_t* pend ); 36 | const uint16_t* find_pattern_16( const uint16_t* it, const uint16_t* end, 37 | const uint16_t* pit, const uint16_t* pend ); 38 | const uint8_t* find_pattern_8_16( const uint8_t* it, const uint8_t* end, 39 | const uint16_t* pit, const uint16_t* pend ); 40 | const uint16_t* find_pattern_16_8( const uint16_t* it, const uint16_t* end, 41 | const uint8_t* pit, const uint8_t* pend ); 42 | 43 | const uint8_t* match_pattern_8( const uint8_t* it, const uint8_t* end, 44 | const uint8_t* pit, const uint8_t* pend ); 45 | const uint16_t* match_pattern_16( const uint16_t* it, const uint16_t* end, 46 | const uint16_t* pit, const uint16_t* pend ); 47 | const uint16_t* match_pattern_8_16( const uint8_t* it, const uint8_t* end, 48 | const uint16_t* pit, const uint16_t* pend ); 49 | const uint8_t* match_pattern_16_8( const uint16_t* it, const uint16_t* end, 50 | const uint8_t* pit, const uint8_t* pend ); 51 | 52 | void reverse_uint8_t( uint8_t* it, uint8_t* end ); 53 | void reverse_uint16_t( uint16_t* it, uint16_t* end ); 54 | void reverse_uint32_t( uint32_t* it, uint32_t* end ); 55 | 56 | int compare_uint8_t( const uint8_t* it, const uint8_t* end, 57 | const uint8_t* itB, const uint8_t* endB ); 58 | int compare_uint16_t( const uint16_t* it, const uint16_t* end, 59 | const uint16_t* itB, const uint16_t* endB ); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /support/quickSortIndex.c: -------------------------------------------------------------------------------- 1 | /* Quick Sort of Index */ 2 | 3 | 4 | //#include 5 | #include "quickSortIndex.h" 6 | 7 | 8 | //#define DEBUG_SORT 1 9 | 10 | #define INSERT_SIZE 10 11 | #define isGT(a,b) (qs->compare(qs->user, a, b) > 0) 12 | #define isLT(a,b) (qs->compare(qs->user, a, b) < 0) 13 | #define VALUE(n) (data + (index[n] * qs->elemSize)) 14 | 15 | #define swap(a,b) \ 16 | tmp = index[a]; \ 17 | index[a] = index[b]; \ 18 | index[b] = tmp 19 | 20 | 21 | static void qsortIndex( const QuickSortIndex* qs, uint32_t l, uint32_t r ) 22 | { 23 | uint8_t* pivot; 24 | uint8_t* data = qs->data; 25 | uint32_t* index = qs->index; 26 | uint32_t i, j; 27 | uint32_t p; 28 | uint32_t tmp; 29 | 30 | #ifdef DEBUG_SORT 31 | printf( "qsortIndex [" ); 32 | for( i = l; i <= r; ++i ) 33 | printf( " %d", index[i] ); 34 | printf( "]\n" ); 35 | #endif 36 | 37 | if( (l + INSERT_SIZE) > r ) 38 | { 39 | #ifdef DEBUG_SORT 40 | printf( "insertion\n" ); 41 | #endif 42 | // Insertion sorting on small series. 43 | for( p = l + 1; p <= r; p++ ) 44 | { 45 | tmp = index[p]; 46 | pivot = data + (tmp * qs->elemSize); 47 | for( j = p; j > l; j-- ) 48 | { 49 | if( isGT( pivot, VALUE(j - 1) ) ) 50 | break; 51 | index[j] = index[j - 1]; 52 | } 53 | index[j] = tmp; 54 | } 55 | } 56 | else 57 | { 58 | // Select pivot using median-of-three. 59 | p = (l + r) / 2; 60 | #ifdef DEBUG_SORT 61 | printf( "median %d %d %d\n", l, p, r ); 62 | #endif 63 | if( isGT( VALUE(l), VALUE(p) ) ) 64 | { 65 | swap( l, p ); 66 | } 67 | if( isGT( VALUE(l), VALUE(r) ) ) 68 | { 69 | swap( l, r ); 70 | } 71 | if( isGT( VALUE(p), VALUE(r) ) ) 72 | { 73 | swap( p, r ); 74 | } 75 | 76 | // Move pivot to end. 77 | swap( p, r ); 78 | pivot = VALUE(r); 79 | 80 | i = l; 81 | j = r - 1; 82 | while( 1 ) 83 | { 84 | while( i < j && isLT( VALUE(i), pivot ) ) 85 | ++i; 86 | while( i < j && isGT( VALUE(j), pivot ) ) 87 | --j; 88 | if( i >= j ) 89 | break; 90 | swap( i, j ); 91 | ++i; 92 | } 93 | 94 | // Restore pivot. 95 | if( isGT( VALUE(i), pivot ) ) 96 | { 97 | swap( i, r ); 98 | } 99 | 100 | if( l < i ) 101 | qsortIndex( qs, l, i - 1 ); 102 | if( r > i ) 103 | qsortIndex( qs, i + 1, r ); 104 | } 105 | } 106 | 107 | 108 | /* 109 | Sort an index of elements (rather than the elements themselves). 110 | 111 | The QuickSortIndex struct must be filled by the caller. 112 | 113 | The index must point to an array of which is large enough to hold 114 | ((end - begin) / stride) uint32_t values. 115 | 116 | The compare callback must return 1, 0, or -1 if the first argument is 117 | greater than, equal to, or less than the second argument. 118 | 119 | \param begin First index. 120 | \param end Ending index (not included in the sort). 121 | \param stride Index increment. 122 | 123 | \return Number of indicies set and sorted in qs->index. 124 | */ 125 | int quickSortIndex( const QuickSortIndex* qs, uint32_t begin, uint32_t end, 126 | uint32_t stride ) 127 | { 128 | uint32_t icount; 129 | uint32_t* ip = qs->index; 130 | 131 | icount = (end - begin) / stride; 132 | if( icount < 2 ) 133 | { 134 | if( icount == 1 ) 135 | *ip = begin; 136 | else 137 | icount = 0; 138 | } 139 | else 140 | { 141 | for( ; begin < end; begin += stride ) 142 | *ip++ = begin; 143 | qsortIndex( qs, 0, icount - 1 ); 144 | } 145 | return icount; 146 | } 147 | 148 | 149 | /*EOF*/ 150 | -------------------------------------------------------------------------------- /support/quickSortIndex.h: -------------------------------------------------------------------------------- 1 | #ifndef QUICKSORTINDEX_H 2 | #define QUICKSORTINDEX_H 3 | 4 | 5 | #include 6 | 7 | 8 | typedef struct QuickSortIndex QuickSortIndex; 9 | typedef int (*QuickSortFunc)( void* user, void* a, void* b ); 10 | 11 | struct QuickSortIndex 12 | { 13 | uint32_t* index; 14 | uint8_t* user; 15 | uint8_t* data; 16 | uint32_t elemSize; 17 | QuickSortFunc compare; 18 | }; 19 | 20 | 21 | extern int quickSortIndex( const QuickSortIndex*, 22 | uint32_t first, uint32_t last, uint32_t stride ); 23 | 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /support/str.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | Returns pointer in 'to' buffer at end of copy. 5 | */ 6 | char* str_copy( char* to, const char* from ) 7 | { 8 | while( *from ) 9 | *to++ = *from++; 10 | return to; 11 | } 12 | 13 | 14 | /* 15 | Returns pointer in 'cp' buffer at end of whitespace. 16 | */ 17 | const char* str_skipWhite( const char* cp ) 18 | { 19 | int c; 20 | while( (c = *cp) ) 21 | { 22 | if( c == ' ' || c == '\t' || c == '\n' || c == '\r' ) 23 | ++cp; 24 | else 25 | break; 26 | } 27 | return cp; 28 | } 29 | 30 | 31 | /* 32 | Returns pointer in 'cp' buffer at start of whitespace. 33 | */ 34 | const char* str_toWhite( const char* cp ) 35 | { 36 | int c; 37 | while( (c = *cp) ) 38 | { 39 | if( c == ' ' || c == '\t' || c == '\n' || c == '\r' ) 40 | break; 41 | ++cp; 42 | } 43 | return cp; 44 | } 45 | 46 | 47 | /*EOF*/ 48 | -------------------------------------------------------------------------------- /support/str.h: -------------------------------------------------------------------------------- 1 | #ifndef STR_H 2 | #define STR_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | extern char* str_copy( char* to, const char* from ); 9 | extern const char* str_skipWhite( const char* cp ); 10 | extern const char* str_toWhite( const char* cp ); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /support/trim_string.c: -------------------------------------------------------------------------------- 1 | /* Trim string template */ 2 | /* 3 | Copyright 2009 Karl Robillard 4 | 5 | This file is part of the Boron programming language. 6 | 7 | Boron is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU Lesser General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Boron is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with Boron. If not, see . 19 | */ 20 | 21 | 22 | /* 23 | Returns number of characters skipped from start. 24 | */ 25 | static int TRIM_FUNC_HEAD( TRIM_T* it, TRIM_T* end ) 26 | { 27 | TRIM_T* origIt = it; 28 | while( it != end ) 29 | { 30 | if( *it > ' ' ) 31 | break; 32 | ++it; 33 | } 34 | return it - origIt; 35 | } 36 | 37 | 38 | /* 39 | Returns number of characters removed. 40 | */ 41 | static int TRIM_FUNC_TAIL( TRIM_T* it, TRIM_T* end ) 42 | { 43 | TRIM_T* origEnd = end; 44 | while( end != it ) 45 | { 46 | if( end[-1] > ' ' ) 47 | break; 48 | --end; 49 | } 50 | return origEnd - end; 51 | } 52 | 53 | 54 | /* 55 | Returns number of characters removed. 56 | */ 57 | static int TRIM_FUNC_LINES( TRIM_T* it, TRIM_T* end ) 58 | { 59 | TRIM_T* out; 60 | int prev = 0; 61 | 62 | while( it != end ) 63 | { 64 | if( (*it == ' ' || *it == '\t') && (*it == prev) ) 65 | goto copy; 66 | else if( *it == '\n' ) 67 | goto copy; 68 | prev = *it++; 69 | } 70 | return 0; 71 | 72 | copy: 73 | 74 | out = it++; 75 | while( it != end ) 76 | { 77 | if( (*it == ' ' || *it == '\t') && (*it == prev) ) 78 | prev = *it++; 79 | else if( *it == '\n' ) 80 | ++it; 81 | else 82 | *out++ = prev = *it++; 83 | } 84 | return it - out; 85 | } 86 | 87 | 88 | /* 89 | Returns number of characters removed. 90 | */ 91 | int TRIM_FUNC_INDENT( TRIM_T* it, TRIM_T* end ) 92 | { 93 | TRIM_T* cp = it; 94 | int margin = 0; 95 | 96 | // Set margin to number of spaces on first line with text. 97 | while( cp != end ) 98 | { 99 | if( *cp > ' ' ) 100 | break; 101 | if( *cp == '\n' ) 102 | margin = 0; 103 | else 104 | ++margin; 105 | ++cp; 106 | } 107 | 108 | if( margin ) 109 | { 110 | int removed; 111 | TRIM_T* out = it; 112 | 113 | copy_line: 114 | 115 | while( (cp != end) ) 116 | { 117 | if( *cp == '\n' ) 118 | { 119 | *out++ = *cp++; 120 | break; 121 | } 122 | *out++ = *cp++; 123 | } 124 | 125 | // Skip margin 126 | removed = 0; 127 | while( cp != end ) 128 | { 129 | if( *cp > ' ' ) 130 | goto copy_line; 131 | 132 | if( *cp == '\n' ) 133 | { 134 | *out++ = *cp++; 135 | removed = 0; 136 | } 137 | else 138 | { 139 | ++cp; 140 | ++removed; 141 | if( removed == margin ) 142 | goto copy_line; 143 | } 144 | } 145 | return end - out; 146 | } 147 | return 0; 148 | } 149 | 150 | 151 | #undef TRIM_FUNC_HEAD 152 | #undef TRIM_FUNC_TAIL 153 | #undef TRIM_FUNC_LINES 154 | #undef TRIM_FUNC_INDENT 155 | #undef TRIM_T 156 | 157 | 158 | /* EOF */ 159 | -------------------------------------------------------------------------------- /support/url_encoding.c: -------------------------------------------------------------------------------- 1 | /* URL encoder template */ 2 | 3 | 4 | #ifdef URLENC_COMMON 5 | #ifdef URLENC_FUNC_ENCODE 6 | static char urlenc_hex[] = "0123456789ABCDEF"; 7 | 8 | /* "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.~" */ 9 | static unsigned char urlenc_bitset[ 16 ] = 10 | { 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFF, 0x03, 12 | 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x47 13 | }; 14 | #endif 15 | 16 | #ifdef URLENC_FUNC_DECODE 17 | /* 18 | Convert hex character to integer value. 19 | */ 20 | static int urlenc_fromHex( int ch ) 21 | { 22 | if( ch >= '0' && ch <= '9' ) 23 | return ch - '0'; 24 | if( ch >= 'a' && ch <= 'f' ) 25 | return ch - ('a' - 10); 26 | if( ch >= 'A' && ch <= 'F' ) 27 | return ch - ('A' - 10); 28 | return 0; 29 | } 30 | #endif 31 | 32 | #undef URLENC_COMMON 33 | #endif 34 | 35 | 36 | #ifdef URLENC_FUNC_ENCODE 37 | /* 38 | Dest must have room for ((end - it) * 3) elements. 39 | */ 40 | URLENC_T* URLENC_FUNC_ENCODE( const URLENC_T* it, const URLENC_T* end, 41 | URLENC_T* dest ) 42 | { 43 | URLENC_T ch; 44 | while( it != end ) 45 | { 46 | ch = *it++; 47 | if( ch < (8 * sizeof(urlenc_bitset)) && 48 | (urlenc_bitset[ ch>>3 ] & 1<<(ch & 7)) ) 49 | *dest++ = ch; 50 | else if( ch == ' ' ) 51 | *dest++ = '+'; 52 | else 53 | { 54 | *dest++ = '%'; 55 | *dest++ = urlenc_hex[ (ch >> 4) & 15 ]; 56 | *dest++ = urlenc_hex[ ch & 15 ]; 57 | } 58 | } 59 | return dest; 60 | } 61 | #undef URLENC_FUNC_ENCODE 62 | #endif 63 | 64 | 65 | #ifdef URLENC_FUNC_DECODE 66 | /* 67 | Dest must have room for (end - it) elements. 68 | */ 69 | URLENC_T* URLENC_FUNC_DECODE( const URLENC_T* it, const URLENC_T* end, 70 | URLENC_T* dest ) 71 | { 72 | URLENC_T ch; 73 | while( it != end ) 74 | { 75 | ch = *it++; 76 | if( ch == '%' ) 77 | { 78 | if( it == end ) 79 | { 80 | *dest++ = '%'; 81 | break; 82 | } 83 | ch = urlenc_fromHex( *it++ ); 84 | if( it == end ) 85 | { 86 | *dest++ = '%'; 87 | *dest++ = it[ -1 ]; 88 | break; 89 | } 90 | *dest++ = (ch << 4) | urlenc_fromHex( *it++ ); 91 | } 92 | else if( ch == '+' ) 93 | *dest++ = ' '; 94 | else 95 | *dest++ = ch; 96 | } 97 | return dest; 98 | } 99 | #undef URLENC_FUNC_DECODE 100 | #endif 101 | 102 | 103 | #undef URLENC_T 104 | 105 | 106 | /* EOF */ 107 | -------------------------------------------------------------------------------- /support/well512.c: -------------------------------------------------------------------------------- 1 | /* 2 | * WELL 512 Random number generator 3 | * See http://www.iro.umontreal.ca/~panneton/WELLRNG.html 4 | */ 5 | 6 | 7 | #include "well512.h" 8 | 9 | 10 | void well512_init( Well512* ws, uint32_t seed ) 11 | { 12 | int i; 13 | uint32_t prev; 14 | uint32_t* wstate = ws->wstate; 15 | 16 | ws->wi = 0; 17 | wstate[0] = seed; 18 | for( i = 1; i < WELL512_STATE_SIZE; ++i ) 19 | { 20 | prev = wstate[i-1]; 21 | wstate[i] = (1812433253 * (prev ^ (prev >> 30)) + i); 22 | } 23 | } 24 | 25 | 26 | /* 27 | Generates a random number on [0,0xffffffff]-interval 28 | */ 29 | uint32_t well512_genU32( Well512* ws ) 30 | { 31 | uint32_t a, b, c, z0; 32 | uint32_t* wstate = ws->wstate; 33 | uint32_t wi = ws->wi; 34 | 35 | #define MAT0(v,t) (v^(v<>11); 43 | 44 | wstate[wi] = a = b ^ c; 45 | ws->wi = wi = (wi + 15) & 15; 46 | z0 = wstate[wi]; 47 | wstate[wi] = MAT0(z0,2) ^ MAT0(b,18) ^ (c<<28) ^ 48 | (a ^ ((a << 5) & 0xDA442D24)); 49 | 50 | return wstate[wi]; 51 | } 52 | -------------------------------------------------------------------------------- /support/well512.h: -------------------------------------------------------------------------------- 1 | #ifndef WELL512_H 2 | #define WELL512_H 3 | 4 | #ifdef __sun__ 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | #define WELL512_STATE_SIZE 16 11 | 12 | typedef struct 13 | { 14 | uint32_t wi; 15 | uint32_t wstate[ WELL512_STATE_SIZE ]; 16 | } 17 | Well512; 18 | 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | void well512_init( Well512* ws, uint32_t seed ); 25 | uint32_t well512_genU32( Well512* ws ); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | 32 | /* 33 | Generate a random number on [0,1)-real-interval. 34 | (uint32_t divided by 2^32) 35 | */ 36 | #define well512_genReal(ws) (well512_genU32(ws) * (1.0 / 4294967296.0)) 37 | 38 | 39 | #endif /* WELL512_H */ 40 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | 3 | .PHONY: test grind clean 4 | 5 | test: 6 | @./run_test *.b 7 | 8 | grind: 9 | @./grind *.b 10 | 11 | clean: 12 | @rm -f *.out 13 | -------------------------------------------------------------------------------- /test/binary.b: -------------------------------------------------------------------------------- 1 | print "---- compare" 2 | a: #{010203} 3 | b: #{0a0b0c010203} 4 | print same? a a 5 | print same? a b 6 | print equal? a a 7 | print equal? a b 8 | ;print equal? #{414243} "ABC" 9 | 10 | 11 | print "---- append" 12 | probe append copy a "end" 13 | probe append copy a #{F00BAD} 14 | probe append copy a 'A' 15 | probe append copy a 255 16 | 17 | 18 | print "---- insert" 19 | probe insert copy a "end" 20 | probe insert copy a #{F00BAD} 21 | probe insert copy a 'A' 22 | probe insert copy a 255 23 | 24 | 25 | print "---- insert part" 26 | in-a: does [skip c: copy a 2] 27 | probe insert/part in-a "end" 0 28 | probe insert/part in-a #{F00BAD} 2 29 | probe c 30 | 31 | 32 | print "---- reverse" 33 | probe reverse #{01020304} 34 | probe reverse/part #{0102030405} 3 35 | 36 | 37 | print "---- find" 38 | probe find b 1 39 | probe find b #{0c01} 40 | probe find/part b #{0203} 4 41 | probe find/part b #{0203} 90 42 | s: charset "^0^D" 43 | probe find #{ffff0d11 11002222} s 44 | probe find/last #{ffff0d11 11002222} s 45 | 46 | 47 | print "---- change" 48 | w: #{0a0b0c0d0e} 49 | b: #{0102030405} 50 | a: copy w 51 | probe change next a b 52 | probe a 53 | 54 | a: copy w 55 | probe change/part next a b 2 56 | probe a 57 | 58 | a: copy w 59 | probe change/part a b 8 60 | probe a 61 | 62 | 63 | print "---- swap" 64 | probe swap #{FFFE680065006C006C006F00} 65 | probe swap/group #{00112233} 4 66 | probe swap/group #{0011223344556677} 3 67 | 68 | 69 | print "---- rejoin" 70 | a: #{ABCD} 71 | probe rejoin [#{0001} 2 a a] 72 | 73 | 74 | print "---- encoding" 75 | probe b: #{abcd012345} 76 | probe b2: 2#{10101011 11001101 00000001 00100011 01000101} 77 | probe b64: 64#{q80BI0U=} 78 | 79 | probe eq? b b2 80 | probe encode 16 b2 81 | 82 | probe eq? b b64 83 | probe encode 16 b64 84 | 85 | probe encode 64 b 86 | probe reduce [slice b 1 slice b 2 slice b 3] 87 | probe [64#{qw==} 64#{q80=} 64#{q80B}] 88 | -------------------------------------------------------------------------------- /test/binary.good: -------------------------------------------------------------------------------- 1 | ---- compare 2 | true 3 | false 4 | true 5 | false 6 | ---- append 7 | #{010203656E64} 8 | #{010203F00BAD} 9 | #{01020341} 10 | #{010203FF} 11 | ---- insert 12 | #{656E64010203} 13 | #{F00BAD010203} 14 | #{41010203} 15 | #{FF010203} 16 | ---- insert part 17 | #{03} 18 | #{F00B03} 19 | #{0102F00B03} 20 | ---- reverse 21 | #{04030201} 22 | #{0302010405} 23 | ---- find 24 | #{010203} 25 | #{0C010203} 26 | none 27 | #{0203} 28 | #{0D1111002222} 29 | #{002222} 30 | ---- change 31 | #{} 32 | #{0A0102030405} 33 | #{0D0E} 34 | #{0A01020304050D0E} 35 | #{} 36 | #{0102030405} 37 | ---- swap 38 | #{FEFF00680065006C006C006F} 39 | #{33221100} 40 | #{2211005544336677} 41 | ---- rejoin 42 | #{000102ABCDABCD} 43 | ---- encoding 44 | #{ABCD012345} 45 | 2#{10101011 11001101 00000001 00100011 01000101} 46 | 64#{q80BI0U=} 47 | true 48 | #{ABCD012345} 49 | true 50 | #{ABCD012345} 51 | 64#{q80BI0U=} 52 | [64#{qw==} 64#{q80=} 64#{q80B}] 53 | [64#{qw==} 64#{q80=} 64#{q80B}] 54 | -------------------------------------------------------------------------------- /test/bind.b: -------------------------------------------------------------------------------- 1 | pref: context [ 2 | size: 0,0 3 | path: none 4 | auto-save: false 5 | ] 6 | 7 | print "---- bind/secure" 8 | foreach blk [ 9 | [size: 100,200 path: %/tmp/save auto-save: true] 10 | [size: quit] 11 | [new-word: 0] 12 | ][ 13 | probe v: try [ 14 | do bind/secure blk pref 15 | ] 16 | ifn error? v [probe pref] 17 | ] 18 | -------------------------------------------------------------------------------- /test/bind.good: -------------------------------------------------------------------------------- 1 | ---- bind/secure 2 | true 3 | context [ 4 | size: 100,200 5 | path: %/tmp/save 6 | auto-save: true 7 | ] 8 | Script Error: unbound word 'quit 9 | Trace: 10 | -> size: quit 11 | -> do bind/secure blk pref 12 | Script Error: unbound word 'new-word 13 | Trace: 14 | -> new-word: 0 15 | -> do bind/secure blk pref 16 | -------------------------------------------------------------------------------- /test/bitset.b: -------------------------------------------------------------------------------- 1 | print "---- Make Bitset" 2 | print make bitset! 61 3 | print make bitset! "abc" 4 | print make bitset! "01234567890" 5 | probe charset ' ' 6 | 7 | 8 | print "---- Bitset pick" 9 | c: charset "^0abc" 10 | probe c 11 | foreach i [0 1 2 97 98 '`' 'a' 'b' 'c' 'd'] [prin rejoin [' ' i ':' pick c i]] 12 | prin '^/' 13 | 14 | 15 | print "---- Bitset poke" 16 | foreach [i v] [2 true 'A' 1 'b' false] [poke c i do v] 17 | probe c 18 | b: make bitset! 32 19 | poke b 12 2 20 | poke b 13 0.02 21 | probe b 22 | poke b 12 0 23 | poke b 13 0.0 24 | probe b 25 | 26 | 27 | print "---- Bitset operators" 28 | a: charset "abc" 29 | b: charset "123b" 30 | probe and a b 31 | probe or a b 32 | probe xor a b 33 | 34 | 35 | print "---- Bitset compare" 36 | c: make bitset! #{01000000000000000600} 37 | d: charset "^0AB" 38 | probe c 39 | probe d 40 | probe same? c c 41 | probe same? c d 42 | probe eq? c d 43 | probe eq? c a 44 | 45 | 46 | print "---- Charset range" 47 | probe n: make bitset! s: "_0-9A-F" 48 | probe a: make bitset! "_0123456789ABCDEF" 49 | probe b: charset s 50 | print [eq? n b eq? a b] 51 | -------------------------------------------------------------------------------- /test/bitset.good: -------------------------------------------------------------------------------- 1 | ---- Make Bitset 2 | make bitset! #{0000000000000000} 3 | make bitset! #{0000000000000000000000000E00000000000000000000000000000000000000} 4 | make bitset! #{000000000000FF03000000000000000000000000000000000000000000000000} 5 | make bitset! #{0000000001} 6 | ---- Bitset pick 7 | make bitset! #{0100000000000000000000000E00000000000000000000000000000000000000} 8 | 0:none 1:true 2:false 97:false 98:true `:false a:true b:true c:true d:false 9 | ---- Bitset poke 10 | make bitset! #{0300000000000000020000000A00000000000000000000000000000000000000} 11 | make bitset! #{00180000} 12 | make bitset! #{00000000} 13 | ---- Bitset operators 14 | make bitset! #{0000000000000000000000000400000000000000000000000000000000000000} 15 | make bitset! #{0000000000000E00000000000E00000000000000000000000000000000000000} 16 | make bitset! #{0000000000000E00000000000A00000000000000000000000000000000000000} 17 | ---- Bitset compare 18 | make bitset! #{01000000000000000600} 19 | make bitset! #{0100000000000000060000000000000000000000000000000000000000000000} 20 | true 21 | false 22 | true 23 | false 24 | ---- Charset range 25 | make bitset! #{0000000000200102420000800000000000000000000000000000000000000000} 26 | make bitset! #{000000000000FF037E0000800000000000000000000000000000000000000000} 27 | make bitset! #{000000000000FF037E0000800000000000000000000000000000000000000000} 28 | false true 29 | -------------------------------------------------------------------------------- /test/block.b: -------------------------------------------------------------------------------- 1 | print "---- block newline formatting" 2 | probe [ 3 | stuff: [ 4 | 1 2 3 some [] ( ; This paren becomes () 5 | ) 6 | ] 7 | ] 8 | probe [ stuff2: [ 9 | 1 2 3 some [] (a 10 | b 11 | ) 12 | ] 13 | ] 14 | 15 | 16 | print "---- make" 17 | probe make block! 'a/b/c 18 | probe make block! first [(1 2)] 19 | probe to-block 'a/b/c 20 | probe to-block first [(1 2)] 21 | 22 | 23 | print "---- paren eval" 24 | print [[mul 3 4]] 25 | print [(mul 3 4)] 26 | 27 | 28 | print "---- compare" 29 | a: [1 2 3] 30 | b: [a b c 1 2 3] 31 | print same? a a 32 | print same? a b 33 | print equal? a a 34 | print equal? a b 35 | 36 | 37 | print "---- append" 38 | probe append [1 2 3] "end" 39 | probe append [1 2 3] [x y z] 40 | probe append/block [1 2 3] [x y z] 41 | probe append a: [1 2 3 4 five] a ; Append to self 42 | 43 | 44 | print "---- insert" 45 | probe insert [1 2 3] "end" 46 | probe insert [1 2 3] [x y z] 47 | probe insert/block [1 2 3] [x y z] 48 | probe insert a: [1 2 3 4 five] a ; Insert into self 49 | probe head insert/part next [1 2 3] [x y z] 2 50 | 51 | 52 | print "---- select" 53 | opt: ["eh" 1 b 2 b 4 c 3] 54 | probe select opt "eh" 55 | probe select opt 'b 56 | probe select opt 3 57 | probe select opt 22 58 | probe select/last opt 'b 59 | 60 | 61 | print "---- set relation" 62 | probe intersect [a b c d] [c 1 'a] 63 | probe intersect b: ["h" 45 new 45] b 64 | probe difference [a b c d] [c 1 'a] 65 | probe difference b: ["h" 45 new 45] b 66 | probe difference [3 2 2 0] [1 3 4] 67 | probe union [3 2 2 0] [1 3 4] 68 | a: ["-a" "-A"] 69 | probe intersect a a 70 | probe intersect/case a a 71 | 72 | 73 | print "---- change" 74 | w: [a b c d e] 75 | b: [1 2 3 4 5] 76 | a: copy w 77 | probe change next a b 78 | probe a 79 | 80 | ;probe change/only a [x y] 81 | ;probe a 82 | 83 | a: copy w 84 | probe change/part next a b 2 85 | probe a 86 | 87 | a: copy w 88 | probe change/part a b 8 89 | probe a 90 | 91 | a: copy w 92 | probe change/part a b -33 93 | probe a 94 | 95 | a: copy w 96 | probe change next a "new" 97 | probe a 98 | probe change tail a "new" 99 | probe a 100 | 101 | 102 | print "---- reverse" 103 | probe reverse [1 2 3 4] 104 | probe reverse/part [1 2 3 4 5] 3 105 | -------------------------------------------------------------------------------- /test/block.good: -------------------------------------------------------------------------------- 1 | ---- block newline formatting 2 | [ 3 | stuff: [ 4 | 1 2 3 some [] () 5 | ] 6 | ] 7 | [stuff2: [ 8 | 1 2 3 some [] (a 9 | b) 10 | ]] 11 | ---- make 12 | [a b c] 13 | [1 2] 14 | [a b c] 15 | [1 2] 16 | ---- paren eval 17 | mul 3 4 18 | 12 19 | ---- compare 20 | true 21 | false 22 | true 23 | false 24 | ---- append 25 | [1 2 3 "end"] 26 | [1 2 3 x y z] 27 | [1 2 3 [x y z]] 28 | [1 2 3 4 five 1 2 3 4 five] 29 | ---- insert 30 | ["end" 1 2 3] 31 | [x y z 1 2 3] 32 | [[x y z] 1 2 3] 33 | [1 2 3 4 five 1 2 3 4 five] 34 | [1 x y 2 3] 35 | ---- select 36 | 1 37 | 2 38 | none 39 | none 40 | 4 41 | ---- set relation 42 | [a c] 43 | ["h" 45 new] 44 | [b d] 45 | [] 46 | [2 2 0] 47 | [3 2 0 1 4] 48 | ["-a"] 49 | ["-a" "-A"] 50 | ---- change 51 | [] 52 | [a 1 2 3 4 5] 53 | [d e] 54 | [a 1 2 3 4 5 d e] 55 | [] 56 | [1 2 3 4 5] 57 | [] 58 | [1 2 3 4 5] 59 | [c d e] 60 | [a "new" c d e] 61 | [] 62 | [a "new" c d e "new"] 63 | ---- reverse 64 | [4 3 2 1] 65 | [3 2 1 4 5] 66 | -------------------------------------------------------------------------------- /test/char.b: -------------------------------------------------------------------------------- 1 | print "---- basic" 2 | c: 'a' 3 | print [type? c c] 4 | probe c 5 | 6 | print "---- escape seq" 7 | b: ['^0' '^D' '^-' '^/' '^^' '^''] 8 | probe b 9 | print ["size? b:" size? b] 10 | print ["first line" '^/' '^-' "second line"] 11 | 12 | print "---- escape hex" 13 | eh: ['^(a9)' '^(0B6)' '^(0439)' '^(220b)'] 14 | probe eh 15 | print eh 16 | foreach c eh [prin c] prin '^/' 17 | print to-string eh 18 | -------------------------------------------------------------------------------- /test/char.good: -------------------------------------------------------------------------------- 1 | ---- basic 2 | char! a 3 | 'a' 4 | ---- escape seq 5 | ['^0' '^D' '^-' '^/' '^^' '^''] 6 | size? b: 6 7 | first line 8 | second line 9 | ---- escape hex 10 | ['©' '¶' 'й' '∋'] 11 | © ¶ й ∋ 12 | ©¶й∋ 13 | ['^(A9)' '^(B6)' '^(0439)' '^(220B)'] 14 | -------------------------------------------------------------------------------- /test/compare.b: -------------------------------------------------------------------------------- 1 | tf: func [blk] [ 2 | map it blk [pick ['T' '.'] it] 3 | ] 4 | comp-id: func [a b] [ 5 | msg: [ 6 | a '^-' b '^-' 7 | '(' tf reduce [same? a b equal? a b gt? a b lt? a b ge? a b le? a b] ')' 8 | type? a type? b 9 | ] 10 | print msg 11 | b: to-double b 12 | print msg 13 | a: to-double a 14 | print msg 15 | ] 16 | 17 | print "---- numbers <" 18 | comp-id -1 0 19 | 20 | print "---- numbers =" 21 | comp-id 0 0 22 | 23 | print "---- numbers >" 24 | comp-id 1 0 25 | -------------------------------------------------------------------------------- /test/compare.good: -------------------------------------------------------------------------------- 1 | ---- numbers < 2 | -1 0 ( . . . T . T ) int! int! 3 | -1 0.0 ( . . . T . T ) int! double! 4 | -1.0 0.0 ( . . . T . T ) double! double! 5 | ---- numbers = 6 | 0 0 ( T T . . T T ) int! int! 7 | 0 0.0 ( . T . . T T ) int! double! 8 | 0.0 0.0 ( T T . . T T ) double! double! 9 | ---- numbers > 10 | 1 0 ( . . T . T . ) int! int! 11 | 1 0.0 ( . . T . T . ) int! double! 12 | 1.0 0.0 ( . . T . T . ) double! double! 13 | -------------------------------------------------------------------------------- /test/conditional.b: -------------------------------------------------------------------------------- 1 | print "---- if" 2 | print if same? 2 add 1 1 ["same"] 3 | print if same? 2 3 ["same"] 4 | 5 | print if equal? 2 add 1 1 ["equal"] 6 | print if equal? 2 1 ["equal"] 7 | 8 | probe if lt? 2 3 "2 < 3" 9 | probe if lt? 4 2 "4 < 2" 10 | 11 | probe if gt? 4 2 "4 > 2" 12 | probe if gt? 2 3 "2 > 3" 13 | 14 | 15 | print "---- either" 16 | print either true ['yes]['no] 17 | print either false ['yes]['no] 18 | a: ['eval-yes] 19 | b: ['eval-no] 20 | print either equal? 2 add 1 1 a b 21 | print either true 'e-yes 'e-no 22 | print either none 'e-yes 'e-no 23 | 24 | 25 | print "---- all" 26 | print all [true] 27 | print all [false] 28 | print all [equal? 2 add 1 1 gt? 4 2] 29 | print all [equal? 2 add 1 1 gt? 2 4] 30 | 31 | 32 | print "---- any" 33 | print any [true] 34 | print any [false] 35 | print any [equal? 2 add 2 1 gt? 4 2] 36 | print any [equal? 2 add 2 1 gt? 2 4] 37 | 38 | 39 | print "---- switch" 40 | cases: [ 41 | 0 ['zero] 42 | 1 ['one] 43 | 2 ['two] 44 | ['default] 45 | ] 46 | print switch 1 cases 47 | print switch 4 cases 48 | 49 | 50 | print "---- while" 51 | a: 3 52 | print while [gt? a 0] [print a -- a] 53 | a: 3 54 | print while [gt? a 0] [ 55 | print a 56 | ++ a 57 | if gt? a 5 [print "Done" break] 58 | ] 59 | 60 | 61 | print "---- case" 62 | foreach x [3 ^ 0 box] [ 63 | case [ 64 | find [^ & |] x [print ['operator x]] 65 | word? x [print ['word x]] 66 | all [int? x gt? x 2] [print "integer > 2"] 67 | ] 68 | ] 69 | -------------------------------------------------------------------------------- /test/conditional.good: -------------------------------------------------------------------------------- 1 | ---- if 2 | same 3 | none 4 | equal 5 | none 6 | "2 < 3" 7 | none 8 | "4 > 2" 9 | none 10 | ---- either 11 | yes 12 | no 13 | eval-yes 14 | e-yes 15 | e-no 16 | ---- all 17 | true 18 | false 19 | true 20 | false 21 | ---- any 22 | true 23 | false 24 | true 25 | false 26 | ---- switch 27 | one 28 | default 29 | ---- while 30 | 3 31 | 2 32 | 1 33 | false 34 | 3 35 | 4 36 | 5 37 | Done 38 | ~unset!~ 39 | ---- case 40 | integer > 2 41 | operator ^ 42 | word box 43 | -------------------------------------------------------------------------------- /test/construct.b: -------------------------------------------------------------------------------- 1 | print "---- make binary" 2 | probe construct binary! [big-endian 1 2 3 4] 3 | probe construct binary! [little-endian 1 2 3 4] 4 | probe construct binary! [big-endian u16 1 2 3 4] 5 | probe construct binary! [#{DA7A0000} u16 1000,2000,3000 u8 1,2,3,4] 6 | probe construct binary! [big-endian u16 1000,2000,3000 u32 1,2] 7 | 8 | 9 | print "---- append binary" 10 | blk: [23 43 43 2309 84 823] 11 | bin: #{FAFB} 12 | probe construct bin [big-endian u16 blk] 13 | 14 | 15 | print "---- copy string and edit" 16 | inp: {This is some ... type-of "text"} 17 | format: 'HTML 18 | probe construct inp [ 19 | ;replace 20 | '<' "<" 21 | '>' ">" 22 | '&' "&" 23 | '^'' "'" 24 | '"' """ 25 | " ..." none 26 | "type-of" format 27 | ] 28 | -------------------------------------------------------------------------------- /test/construct.good: -------------------------------------------------------------------------------- 1 | ---- make binary 2 | #{00000001000000020000000300000004} 3 | #{01000000020000000300000004000000} 4 | #{0001000200030004} 5 | #{DA7A0000E803D007B80B01020304} 6 | #{03E807D00BB80000000100000002} 7 | ---- append binary 8 | #{FAFB0017002B002B090500540337} 9 | ---- copy string and edit 10 | "This is some HTML "text"" 11 | -------------------------------------------------------------------------------- /test/context.b: -------------------------------------------------------------------------------- 1 | print "---- bind" 2 | a: 1 3 | c: context [ 4 | a: 2 5 | b: "two" 6 | bind-me: func [a] [bind a 'b] ; local a 7 | ] 8 | print bind [a b] c 9 | print c/bind-me [a b] 10 | 11 | 12 | print "---- get" 13 | probe get 'a 14 | probe get in c 'b 15 | probe get c 16 | 17 | 18 | print "---- proto" 19 | a: context [first: 1 second: 2] 20 | b: make a [third: 3] 21 | probe a 22 | probe b 23 | probe words-of b 24 | probe values-of b 25 | 26 | 27 | print "---- infuse" 28 | probe infuse [nest (a b c d)] c 29 | 30 | ia: copy a 31 | blk: words-of ia 32 | set blk infuse copy blk context [x: none first: "one" second: "two"] 33 | probe ia 34 | 35 | 36 | print "---- append" 37 | c: context [a: 1 b: 2] 38 | set append c 'extra 3.0 39 | probe c 40 | 41 | 42 | print "---- print recursion" 43 | c1: context [a: 1 b: none] 44 | c2: make c1 [a: 2 b: c1] 45 | c1/b: c2 46 | probe c1 47 | 48 | 49 | print "---- self" 50 | c1: context [ 51 | f: does [self/v] 52 | v: 1 53 | ] 54 | c2: make c1 [v: 2] 55 | print [c1/f c2/f] 56 | probe c1/self 57 | 58 | 59 | print "---- self override" 60 | co: context [ 61 | self: 'override 62 | f: does [probe self] 63 | ] 64 | co/f 65 | probe co/self 66 | 67 | 68 | print "---- bind/secure" 69 | sc: context [ 70 | high: low: none 71 | ] 72 | probe try [ 73 | do bind/secure [low: 2 high: read %/tmp/config] sc 74 | ] 75 | probe sc 76 | -------------------------------------------------------------------------------- /test/context.good: -------------------------------------------------------------------------------- 1 | ---- bind 2 | 2 two 3 | 2 two 4 | ---- get 5 | 1 6 | "two" 7 | [2 "two" func [a][bind a 'b]] 8 | ---- proto 9 | context [ 10 | first: 1 11 | second: 2 12 | ] 13 | context [ 14 | first: 1 15 | second: 2 16 | third: 3 17 | ] 18 | [first second third] 19 | [1 2 3] 20 | ---- infuse 21 | [nest (2 "two" c d)] 22 | context [ 23 | first: "one" 24 | second: "two" 25 | ] 26 | ---- append 27 | context [ 28 | a: 1 29 | b: 2 30 | extra: 3.0 31 | ] 32 | ---- print recursion 33 | context [ 34 | a: 1 35 | b: context [ 36 | a: 2 37 | b: ~context!~ 38 | ] 39 | ] 40 | ---- self 41 | 1 2 42 | context [ 43 | f: does [self/v] 44 | v: 1 45 | ] 46 | ---- self override 47 | override 48 | override 49 | ---- bind/secure 50 | Script Error: unbound word 'read 51 | Trace: 52 | -> low: 2 high: read %/tmp/config 53 | -> do bind/secure [low: 2 high: read %/tmp/config] sc 54 | context [ 55 | high: none 56 | low: 2 57 | ] 58 | -------------------------------------------------------------------------------- /test/coord.b: -------------------------------------------------------------------------------- 1 | print "---- make" 2 | probe d: -44, 6, 9888 3 | print [size? d d/1 d/4] 4 | 5 | probe c: make coord! [1 2 10 -66 5] 6 | print [size? c c/3 c/0] 7 | 8 | print "---- tokenize" 9 | probe to-block {1,2} ; coord! at end of input. 10 | 11 | print "---- math" 12 | probe add 1,2 3,4,5 13 | probe sub 1,2 3,4,5 14 | probe mul 1,2 3,4,5 15 | probe div 5,2 2,1 16 | probe and 5,2 2,2 17 | 18 | print "---- math int!" 19 | probe add 1,2 3 20 | probe sub 1,2,3,4 3 21 | probe mul 1,2,3,4,5,6 3 22 | probe div 5,2 2 23 | probe and 5,2 2 24 | 25 | print "---- slice" 26 | x: 0,1,2,3,4 27 | probe slice x 2 28 | probe slice x -2 29 | probe slice x 2,2 30 | probe slice 10,11 4 ; increase length 31 | probe slice 10,11,2 1,4 32 | -------------------------------------------------------------------------------- /test/coord.good: -------------------------------------------------------------------------------- 1 | ---- make 2 | -44,6,9888 3 | 3 -44 none 4 | 1,2,10,-66,5 5 | 5 10 none 6 | ---- tokenize 7 | [1,2] 8 | ---- math 9 | 4,6,5 10 | -2,-2,5 11 | 3,8,5 12 | 2,2 13 | 0,2 14 | ---- math int! 15 | 4,5 16 | -2,-1,0,1 17 | 3,6,9,12,15,18 18 | 2,1 19 | 0,2 20 | ---- slice 21 | 0,1 22 | 0,1,2 23 | 2,3 24 | 10,11,0,0 25 | 11,2,0,0 26 | -------------------------------------------------------------------------------- /test/data-104: -------------------------------------------------------------------------------- 1 | This test file contains 104 bytes of data. 2 | 3 | Vidit numquam ad quo, eos antiopam electram consulatu in. 4 | -------------------------------------------------------------------------------- /test/datatype.b: -------------------------------------------------------------------------------- 1 | print "---- tokenize" 2 | a: int!/double!/word! 3 | print [type? a a] 4 | 5 | 6 | print "---- type test" 7 | print same? a int!/double! 8 | print equal? a 4 9 | print equal? a type? 4 10 | print equal? a type? "str" 11 | 12 | 13 | print "---- compare to word" 14 | ; Handled by word_compare(). 15 | print eq? int! 'int! 16 | print eq? int! first ['int!] 17 | print switch type? "abc" [string! "Is string" none] 18 | print switch type? "abc" [string!/file! "Is string or file" none] 19 | 20 | 21 | print "---- make" 22 | probe make datatype! logic! 23 | probe make datatype! 'logic! 24 | -------------------------------------------------------------------------------- /test/datatype.good: -------------------------------------------------------------------------------- 1 | ---- tokenize 2 | datatype! int!/double!/word! 3 | ---- type test 4 | false 5 | false 6 | true 7 | false 8 | ---- compare to word 9 | true 10 | true 11 | Is string 12 | Is string or file 13 | ---- make 14 | datatype! 15 | word! 16 | -------------------------------------------------------------------------------- /test/date.b_: -------------------------------------------------------------------------------- 1 | print "---- tokenize" 2 | probe a: 2012-03-15 3 | probe b: 2012-03-15T23:57:22-07:00 4 | 5 | 6 | print "---- math" 7 | probe add a 1 8 | probe sub b 74 9 | probe sub b 365 10 | -------------------------------------------------------------------------------- /test/date.good: -------------------------------------------------------------------------------- 1 | ---- tokenize 2 | 2012-03-15-07:00 3 | 2012-03-15T23:57:22-07:00 4 | ---- math 5 | 2012-03-16-07:00 6 | 2012-01-01T22:57:22-08:00 7 | 2011-03-16T23:57:22-07:00 8 | -------------------------------------------------------------------------------- /test/error.b: -------------------------------------------------------------------------------- 1 | print "---- trace format" 2 | print try [ 3 | top: does [f 3] 4 | f: func [a] [ 5 | add b a "ok" ; <- This string tests that report is data, not text. 6 | ] 7 | top 8 | ] 9 | 10 | 11 | print "---- error func" 12 | print try [error "Test error"] 13 | fe: func [a] [ 14 | if gt? a 5 [ 15 | error rejoin ["number (" a ") is bigger than 5"] 16 | ] 17 | ] 18 | print try [fe 22] 19 | 20 | 21 | print "---- error compare" 22 | a: try [div 1 0] 23 | b: try [div 1 0] 24 | print eq? a a 25 | print eq? a b 26 | 27 | 28 | print "---- stack overflow" 29 | factorial: func [x | pad1 pad2 pad3 pad4 pad5 pad6 pad7] [ 30 | if lt? x 2 [return 1] 31 | mul x factorial sub x 1 32 | ] 33 | msg: to-string try [print factorial 1000] 34 | parse msg [thru "factorial" thru '^/' :msg] 35 | print [msg "..."] 36 | -------------------------------------------------------------------------------- /test/error.good: -------------------------------------------------------------------------------- 1 | ---- trace format 2 | Script Error: Unset word 'b 3 | Trace: 4 | -> add b a "ok" 5 | -> f 3 6 | -> top 7 | ---- error func 8 | Script Error: Test error 9 | Script Error: number (22) is bigger than 5 10 | Trace: 11 | -> fe 22 12 | ---- error compare 13 | true 14 | false 15 | ---- stack overflow 16 | Script Error: Stack overflow 17 | Trace: 18 | -> if lt? x 2 [return 1] 19 | -> mul x factorial sub x 1 20 | ... 21 | -------------------------------------------------------------------------------- /test/eval.b: -------------------------------------------------------------------------------- 1 | print "---- Do various types" 2 | probe do [1 2 3] 3 | probe type? do 'hi 4 | 5 | print "---- Do get-word!" 6 | probe do :gwval 7 | gwval: 2 8 | probe do :gwval 9 | parse [10.0 :gwval] [double! tok: get-word! (probe do first tok)] 10 | 11 | print "---- Do functions" 12 | addf: func [a b] [add a b] 13 | probe do reduce [:add 2 3] 14 | probe do reduce [:addf 2 3] 15 | -------------------------------------------------------------------------------- /test/eval.good: -------------------------------------------------------------------------------- 1 | ---- Do various types 2 | 3 3 | unset! 4 | ---- Do get-word! 5 | ~unset!~ 6 | 2 7 | 2 8 | ---- Do functions 9 | 5 10 | 5 11 | -------------------------------------------------------------------------------- /test/exception.b: -------------------------------------------------------------------------------- 1 | print "---- throw/catch" 2 | a: func [x] [if lt? x 4 [throw 'low] x] 3 | print catch [a 3] 4 | print catch [a 4] 5 | 6 | 7 | print "---- throw/catch name" 8 | a: func [x] [if lt? x 4 [throw/name 8 'signal] x] 9 | print catch/name [a 3] 'signal 10 | print catch/name [a 4] 'signal 11 | y: 0 12 | x: catch/name [y: catch/name [a 3] 'sig1] [sig2 signal] 13 | print [x y] 14 | -------------------------------------------------------------------------------- /test/exception.good: -------------------------------------------------------------------------------- 1 | ---- throw/catch 2 | low 3 | 4 4 | ---- throw/catch name 5 | 8 6 | 4 7 | 8 0 8 | -------------------------------------------------------------------------------- /test/execute.b: -------------------------------------------------------------------------------- 1 | cmd-args: "" 2 | c: to-int 'a' 3 | n: 1 4 | loop 20 [ 5 | append cmd-args rejoin [" -" to-char ++ c ++ n] 6 | ] 7 | 8 | out: "" 9 | err: "" 10 | execute/out/err join "../boron execute_child " cmd-args out err 11 | probe out 12 | probe err 13 | -------------------------------------------------------------------------------- /test/execute.good: -------------------------------------------------------------------------------- 1 | {["-a1" "-b2" "-c3" "-d4" "-e5" "-f6" "-g7" "-h8" "-i9" "-j10" "-k11" "-l12" "-m13" "-n14" "-o15" "-p16" "-q17" "-r18" "-s19" "-t20"] 2 | output 1 3 | output 2 4 | output 3 5 | } 6 | "ERR 1^/ERR 2^/ERR 3^/" 7 | -------------------------------------------------------------------------------- /test/execute_child: -------------------------------------------------------------------------------- 1 | out: open 1 2 | err: open 2 3 | 4 | write out mold args 5 | write out "^/" 6 | write out "output 1^/" 7 | 8 | write err "ERR 1^/" 9 | 10 | write out "output 2^/" 11 | write out "output 3^/" 12 | 13 | write err "ERR 2^/" 14 | write err "ERR 3^/" 15 | -------------------------------------------------------------------------------- /test/file.b: -------------------------------------------------------------------------------- 1 | print "---- make file" 2 | probe make file! "Some File" 3 | probe make file! 'my-file 4 | probe f: %filename-v12.ext 5 | print f 6 | probe f: %"file before block"[] 7 | print f 8 | 9 | 10 | print "---- to-file" 11 | probe to-file "Some File" 12 | probe to-file 'my-file 13 | probe join to-file "../" %src 14 | 15 | 16 | print "---- special characters" 17 | probe %"$(QTDIR)/lib" 18 | 19 | 20 | print "---- file as series" 21 | f: %my-file.ext 22 | probe next f 23 | probe find f "file" 24 | probe find f %file 25 | probe append %my-file- 23 26 | probe rejoin [%file- 10 %.ext] 27 | -------------------------------------------------------------------------------- /test/file.good: -------------------------------------------------------------------------------- 1 | ---- make file 2 | %"Some File" 3 | %my-file 4 | %filename-v12.ext 5 | filename-v12.ext 6 | %"file before block" 7 | file before block 8 | ---- to-file 9 | %"Some File" 10 | %my-file 11 | %../src 12 | ---- special characters 13 | %"$(QTDIR)/lib" 14 | ---- file as series 15 | %y-file.ext 16 | %file.ext 17 | %file.ext 18 | %my-file-23 19 | %file-10.ext 20 | -------------------------------------------------------------------------------- /test/format.b: -------------------------------------------------------------------------------- 1 | print "---- int! & string!" 2 | foreach [item n name][ 3 | cookies 30 "Joe Smith" 4 | cake 102 "Sally M. Longshanks" 5 | tea 5 "Fred" 6 | ][ 7 | print format [" | " 11 6 12 " |"] [item n name] 8 | ] 9 | 10 | print "---- pad" 11 | foreach [file h m s][ 12 | %some/file 1 22 3 13 | %some/other/file 0 4 45 14 | ][ 15 | print format [pad '.' 20 pad 0 -2 ':' -2 ':' -2] [file h m s] 16 | ] 17 | 18 | print "---- coord! & non-block values" 19 | foreach [v][ 20 | 'a' 0xfedc 'more-than-four 21 | ][ 22 | print format [" value(" 2,4 ");"] v 23 | ] 24 | -------------------------------------------------------------------------------- /test/format.good: -------------------------------------------------------------------------------- 1 | ---- int! & string! 2 | | cookies 30 Joe Smith | 3 | | cake 102 Sally M. Longshanks | 4 | | tea 5 Fred | 5 | ---- pad 6 | some/file...........01:22:03 7 | some/other/file.....00:04:45 8 | ---- coord! & non-block values 9 | value(a ); 10 | value(0xFE); 11 | value(more); 12 | -------------------------------------------------------------------------------- /test/func.b: -------------------------------------------------------------------------------- 1 | print "---- does" 2 | hello: does [print 'hello] 3 | hello 4 | 5 | print "---- func" 6 | add1: func [a b] [add add a b 1] 7 | print add1 4 5 8 | 9 | 10 | print "---- nested" 11 | r1: func [a b c] [hello mul c add1 a b] 12 | print r1 4 5 2 13 | 14 | 15 | print "---- locals" 16 | a: 2 17 | fl: func [x | a] [print [a x] a: 3 print a] 18 | fl 8 19 | print a 20 | 21 | f2: func [v] [reduce v] 22 | f1: func [v /local local-f1] [local-f1: 44 f2 [v local-f1]] 23 | probe f1 "str" 24 | 25 | 26 | print "---- signature comments" 27 | cf: func [s "series" i "index" | n] [n: add 1 i print pick s n] 28 | cf [123 abc true] 1 29 | 30 | 31 | print "---- return" 32 | f: func [x] [if gt? x 4 [return "x > 4"] "x < 4"] 33 | print f 1 34 | print f 5 35 | 36 | 37 | print "---- recursion" 38 | factorial: func [x] [ 39 | if lt? x 2 [return 1] 40 | mul x factorial sub x 1 41 | ] 42 | print factorial 30 43 | 44 | fibonacci: func [x] [ 45 | if lt? x 3 [return 1] 46 | add fibonacci sub x 1 fibonacci sub x 2 47 | ] 48 | print fibonacci 25 ;1000000 49 | 50 | 51 | print "---- argument validation" 52 | af: func [n int!][add n 1] 53 | print af 2 54 | print try [af 2.0] 55 | 56 | 57 | print "---- literal arguments" 58 | num: 0 59 | lf: func [n int! 'arg word!] [set arg add n 1] 60 | lf 44 num 61 | print num 62 | 63 | 64 | print "---- options" 65 | ; Test option alone and that result is logic!. 66 | optf: func [/opt] [print pick ["option set" "no option"] opt] 67 | optf 68 | optf/opt 69 | 70 | optf: func [n int! /two] [add n either two [2][1]] 71 | print optf 6 num 72 | print optf/two 6 num 73 | 74 | 75 | print "---- optional arguments" 76 | oaf: func [a /op 'f b] [ 77 | either op [ 78 | print do f a b 79 | ][ 80 | print [a f b] 81 | ] 82 | ] 83 | oaf 1 84 | oaf/op 10 add 3 85 | oaf/op 10 sub 3 86 | 87 | 88 | print "---- multiple options" 89 | mo: func [/opt /some n /any] [print [opt some n any]] 90 | mo 91 | mo/opt 92 | mo/some 66 93 | mo/any 94 | mo/opt/any 95 | 96 | 97 | print "---- option ordering" 98 | mof: func [/a arg1 /b arg2] [print [a arg1 b arg2]] 99 | mof 100 | mof/a 1 101 | mof/b 2 102 | mof/a/b 1 2 103 | mof/b/a 2 1 104 | 105 | 106 | print "---- empty body" 107 | ef: func [blk block!] [] 108 | ef [1 2] 109 | ef: does [] 110 | ef 111 | 112 | 113 | print "---- compare" 114 | print equal? :ef :oaf 115 | print same? :ef :oaf 116 | print equal? :ef :ef 117 | print same? :ef :ef 118 | 119 | 120 | print "---- bugs fixed" 121 | ; Found problem in makeVerifyFuncBlock(). 122 | sources_from: func [path files block!] [verify_slash path] 123 | 124 | ; Optional argument type checking 125 | oat: func [a int! /opt b string!] [ 126 | if opt [return b] 127 | a 128 | ] 129 | print oat 4 130 | print oat/opt 4 "opt-b" 131 | 132 | ; Check that set-word! doesn't duplicate argument in automatic locals. 133 | auto-local-arg: func [spec] [ 134 | probe spec ; Should be arg 1, not none. 135 | spec: 0 out: 1 136 | ] 137 | auto-local-arg [a b c] 138 | auto-local-arg 'blk 139 | 140 | 141 | print "---- generator" 142 | fgen: func[x] [ 143 | get in context [ 144 | v: x 145 | f: does [print v] 146 | ] 'f 147 | ] 148 | a: fgen 2 149 | b: fgen 3 150 | a 151 | b 152 | 153 | fc: context [v: 1 f: does [print v]] 154 | a: make fc [v: 2] 155 | b: make fc [v: 3] 156 | a/f 157 | b/f 158 | 159 | -------------------------------------------------------------------------------- /test/func.good: -------------------------------------------------------------------------------- 1 | ---- does 2 | hello 3 | ---- func 4 | 10 5 | ---- nested 6 | hello 7 | 20 8 | ---- locals 9 | none 8 10 | 3 11 | 2 12 | ["str" 44] 13 | ---- signature comments 14 | abc 15 | ---- return 16 | x < 4 17 | x > 4 18 | ---- recursion 19 | -8764578968847253504 20 | 75025 21 | ---- argument validation 22 | 3 23 | Datatype Error: Unexpected double! for argument 1 24 | Trace: 25 | -> af 2.0 26 | ---- literal arguments 27 | 45 28 | ---- options 29 | no option 30 | option set 31 | 7 32 | 8 33 | ---- optional arguments 34 | 1 none none 35 | 13 36 | 7 37 | ---- multiple options 38 | false false none false 39 | true false none false 40 | false true 66 false 41 | false false none true 42 | true false none true 43 | ---- option ordering 44 | false none false none 45 | true 1 false none 46 | false none true 2 47 | true 1 true 2 48 | true 1 true 2 49 | ---- empty body 50 | ---- compare 51 | false 52 | false 53 | true 54 | true 55 | ---- bugs fixed 56 | 4 57 | opt-b 58 | [a b c] 59 | blk 60 | ---- generator 61 | 2 62 | 3 63 | 2 64 | 3 65 | -------------------------------------------------------------------------------- /test/grind: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | INTERPRETER=../boron 4 | OUT=grind.out 5 | 6 | rm -f $OUT 7 | 8 | for FILE in $* 9 | do 10 | echo Grinding $FILE 11 | echo Test: $FILE >$OUT 12 | valgrind $INTERPRETER -s $FILE >>$OUT 2>>$OUT 13 | grep ERROR $OUT 14 | done 15 | 16 | -------------------------------------------------------------------------------- /test/hash-map.b: -------------------------------------------------------------------------------- 1 | m: make hash-map! [hi [willy wonka] 5 "five" 0:10:0 some-time "key" value] 2 | 3 | print "---- print" 4 | probe m 5 | print m 6 | 7 | print "---- path" 8 | probe m/hi 9 | probe m/5 10 | ;probe m/0:10:0 ; Not a valid path. 11 | 12 | print "---- pick" 13 | probe pick m 0:10:0 14 | probe pick m "five" 15 | probe pick m "key" 16 | 17 | print "---- poke" 18 | poke m "new-key" 77 19 | poke m "key" 88 20 | print [pick m "new-key" pick m "key"] 21 | 22 | print "---- remove" 23 | remove/key m "new-key" 24 | remove/key m "key" 25 | print [pick m "new-key" pick m "key"] 26 | probe values-of m 27 | 28 | print "---- similar keys" 29 | s: make hash-map! [ 30 | "game" 0 31 | "GAME" 1 32 | %game 2 33 | game 3 34 | 'game 4 35 | ] 36 | print [ 37 | pick s "game" 38 | pick s "GAME" 39 | pick s %game 40 | pick s 'game 41 | pick s to-lit-word 'game 42 | pick s to-get-word 'game 43 | ] 44 | -------------------------------------------------------------------------------- /test/hash-map.good: -------------------------------------------------------------------------------- 1 | ---- print 2 | make hash-map! [ 3 | hi [willy wonka] 4 | 5 "five" 5 | 0:10:00.0 some-time 6 | "key" value 7 | ] 8 | hi [willy wonka] 9 | 5 "five" 10 | 0:10:00.0 some-time 11 | "key" value 12 | 13 | ---- path 14 | [willy wonka] 15 | "five" 16 | ---- pick 17 | some-time 18 | none 19 | value 20 | ---- poke 21 | 77 88 22 | ---- remove 23 | none none 24 | [[willy wonka] "five" some-time] 25 | ---- similar keys 26 | 0 1 2 3 4 none 27 | -------------------------------------------------------------------------------- /test/helpers.b: -------------------------------------------------------------------------------- 1 | print "---- split-path" 2 | probe split-path %path/to/file 3 | probe split-path %some-file 4 | probe split-path %C:/windows/file 5 | ;probe split-path %C:\windows\file 6 | 7 | 8 | print "---- replace" 9 | s: "comma,separated,words," 10 | probe replace copy s ',' ' ' 11 | probe replace/all copy s ',' ' ' 12 | probe replace/all copy s ',' "-->" 13 | s2: {include: ""} 14 | probe replace/all copy s2 '"' {\"} 15 | 16 | 17 | print "---- funct" 18 | sum: func [a] [ 19 | lsum: 0 20 | forall a [ 21 | lsum: add lsum lval: first a 22 | if eq? lval 2 [print "Found lval 2."] 23 | ] 24 | lsum 25 | ] 26 | probe sum [1 2 3] 27 | print [value? 'lsum value? 'lval] 28 | -------------------------------------------------------------------------------- /test/helpers.good: -------------------------------------------------------------------------------- 1 | ---- split-path 2 | [%path/to/ %file] 3 | [none %some-file] 4 | [%C:/windows/ %file] 5 | ---- replace 6 | "comma separated,words," 7 | "comma separated words " 8 | "comma-->separated-->words-->" 9 | {include: \"\"} 10 | ---- funct 11 | Found lval 2. 12 | 6 13 | false false 14 | -------------------------------------------------------------------------------- /test/int.b: -------------------------------------------------------------------------------- 1 | print "---- tokenize" 2 | probe [0 +0 -0 +1 -1] 3 | print try [do {32word}] 4 | 5 | print "---- hex" 6 | probe [0x0 0x10 0xffffffff] 7 | print type? 0xffffffff 8 | print try [do {0x}] 9 | 10 | print "---- format" 11 | print [to-dec 0x10 to-dec 0xffffffff to-dec 0xffffffffffffffff] 12 | print [to-hex 16 to-hex 4294967295 to-hex -1] 13 | 14 | print "---- convert" 15 | print to-int "-34 j" ; Conversion stops at non-digit 16 | print to-int "0xFF08f201" 17 | -------------------------------------------------------------------------------- /test/int.good: -------------------------------------------------------------------------------- 1 | ---- tokenize 2 | [0 0 0 1 -1] 3 | Script Error: Unset word 'word 4 | Trace: 5 | -> 32 word 6 | -> do "32word" 7 | ---- hex 8 | [0x0 0x10 0xFFFFFFFF] 9 | int! 10 | 0x0 11 | ---- format 12 | 16 4294967295 -1 13 | 0x10 0xFFFFFFFF 0xFFFFFFFFFFFFFFFF 14 | ---- convert 15 | -34 16 | 0xFF08F201 17 | -------------------------------------------------------------------------------- /test/iterate.b: -------------------------------------------------------------------------------- 1 | print "---- binary foreach" 2 | foreach [a b] #{00010203} [ 3 | print [a b] 4 | ] 5 | foreach [a b] #{0001020304} [ 6 | print [a b] 7 | ] 8 | 9 | 10 | print "---- string foreach" 11 | foreach [a b] "four" [ 12 | print [a b] 13 | ] 14 | foreach [a b] "hello" [ 15 | print [a b] 16 | ] 17 | 18 | 19 | print "---- block foreach" 20 | foreach [a b] [four words to iterate] [ 21 | print [a b] 22 | ] 23 | foreach [a b] [five words to iterate extra] [ 24 | print [a b] 25 | ] 26 | 27 | 28 | print "---- block forall" 29 | a: [1 2 3] 30 | forall a [probe a] 31 | probe a 32 | a: head a 33 | forall a [probe a/1] 34 | 35 | 36 | print "---- forall tweaking" 37 | a: [1 2 3] 38 | forall a [ 39 | if equal? first a 2 [ 40 | poke a 1 'two 41 | a: head a 42 | ] 43 | print first a 44 | ] 45 | 46 | 47 | print "---- forall series change" 48 | d: [1 2 3] 49 | foreach x d [if eq? 2 x [append d [4 5]] print x] 50 | 51 | 52 | print "---- map" 53 | probe map x [1 2 3] [add x 2] 54 | probe map x {a-b-c;d-e} [ 55 | switch x [ 56 | '-' ' ' 57 | ';' [break] 58 | x 59 | ] 60 | ] 61 | 62 | 63 | print "---- remove-each" 64 | arr2: copy arr: [1 1 a 0 2 2 b 0 3 3 c 0] 65 | remove-each a arr [and int? a lt? a 2] 66 | probe arr 67 | remove-each [a b] arr2 [word? a] 68 | probe arr2 69 | -------------------------------------------------------------------------------- /test/iterate.good: -------------------------------------------------------------------------------- 1 | ---- binary foreach 2 | 0 1 3 | 2 3 4 | 0 1 5 | 2 3 6 | 4 none 7 | ---- string foreach 8 | f o 9 | u r 10 | h e 11 | l l 12 | o none 13 | ---- block foreach 14 | four words 15 | to iterate 16 | five words 17 | to iterate 18 | extra none 19 | ---- block forall 20 | [1 2 3] 21 | [2 3] 22 | [3] 23 | [] 24 | 1 25 | 2 26 | 3 27 | ---- forall tweaking 28 | 1 29 | 1 30 | two 31 | 3 32 | ---- forall series change 33 | 1 34 | 2 35 | 3 36 | 4 37 | 5 38 | ---- map 39 | [3 4 5] 40 | "a b c;d-e" 41 | ---- remove-each 42 | [a 2 2 b 3 3 c] 43 | [1 1 2 2 3 3] 44 | -------------------------------------------------------------------------------- /test/logic.b: -------------------------------------------------------------------------------- 1 | print "---- compare" 2 | probe equal? true true 3 | probe equal? false false 4 | probe equal? true false 5 | probe ne? true true 6 | probe ne? false false 7 | probe ne? true false 8 | a: true 9 | b: true 10 | probe eq? a b 11 | probe eq? not a not b 12 | -------------------------------------------------------------------------------- /test/logic.good: -------------------------------------------------------------------------------- 1 | ---- compare 2 | true 3 | true 4 | false 5 | false 6 | false 7 | true 8 | true 9 | true 10 | -------------------------------------------------------------------------------- /test/loop.b: -------------------------------------------------------------------------------- 1 | print "---- loop" 2 | loop 0 [print 'zero] 3 | loop -1 [print 'negative] 4 | loop 5 [print 'five] 5 | 6 | 7 | print "---- range" 8 | loop [a 3] [print a] 9 | loop [a 5 7] [print ['loopB a]] 10 | loop [a -18 0 5] [print a] 11 | 12 | 13 | print "---- forever" 14 | i: 0 15 | forever [ 16 | if eq? 10 ++ i [break] 17 | ] 18 | print i 19 | 20 | 21 | print "---- continue" 22 | loop [a 3] [ 23 | if eq? a 2 [continue] 24 | print ['loop-continue a] 25 | ] 26 | foreach a [1 2 3 2] [ 27 | if eq? a 2 [continue] 28 | print ['foreach-continue a] 29 | ] 30 | a: [1 2 3 2] 31 | forall a [ 32 | if eq? first a 2 [continue] 33 | print ['forall-continue first a] 34 | ] 35 | a: 1 36 | while [lt? a 4] [ 37 | x: ++ a 38 | if eq? x 2 [continue] 39 | print ['while-continue x] 40 | ] 41 | -------------------------------------------------------------------------------- /test/loop.good: -------------------------------------------------------------------------------- 1 | ---- loop 2 | five 3 | five 4 | five 5 | five 6 | five 7 | ---- range 8 | 1 9 | 2 10 | 3 11 | loopB 5 12 | loopB 6 13 | loopB 7 14 | -18 15 | -13 16 | -8 17 | -3 18 | ---- forever 19 | 11 20 | ---- continue 21 | loop-continue 1 22 | loop-continue 3 23 | foreach-continue 1 24 | foreach-continue 3 25 | forall-continue 1 26 | forall-continue 3 27 | while-continue 1 28 | while-continue 3 29 | -------------------------------------------------------------------------------- /test/math.b: -------------------------------------------------------------------------------- 1 | print "---- print decimal" 2 | print [0.0 -0.0 1.0 -1.0 9.2 -9.2] 3 | print [0.0005 5e-4 0.000005 5e-6 0.0000005 5e-7 0.0000000005 5e-10] 4 | print [343043.003432 222111.00343201 2221190.0034320109] 5 | print [-9.45e-06 9.0e+200 -9e-200 1e+308 1e+309 1e-311 /*1e-312*/] 6 | 7 | print "---- rounding" 8 | print div add 5 4 2 ; Rounded. 9 | print div add 5 4 2.0 ; Not rounded. 10 | print div add 5.0 1 2 11 | 12 | print "---- char" 13 | probe add '0' 3 14 | probe add 0 '3' 15 | 16 | print "---- vec3" 17 | print add 0.0,1.1,0.5 1.8,3,-5.5 18 | print mul 4.3,8,11.34 2.5 19 | 20 | print "---- block" 21 | print add 0 [1 2 3 4 5] 22 | print add 0.0 [1.0 20.0 3] 23 | print or 0 [0x10 0x03 0x8000] 24 | -------------------------------------------------------------------------------- /test/math.good: -------------------------------------------------------------------------------- 1 | ---- print decimal 2 | 0.0 -0.0 1.0 -1.0 9.2 -9.2 3 | 0.0005 0.0005 0.000005 0.000005 5e-7 5e-7 5e-10 5e-10 4 | 343043.003432 2.2211100343201e+5 2.2211900034320108e+6 5 | -9.45e-6 9e+200 -9e-200 1e+308 inf 1e-311 6 | ---- rounding 7 | 4 8 | 4.5 9 | 3.0 10 | ---- char 11 | '3' 12 | 51 13 | ---- vec3 14 | 1.79999995,4.0999999,-5.0 15 | 10.75,20.0,28.3500004 16 | ---- block 17 | 15 18 | 24.0 19 | 32787 20 | -------------------------------------------------------------------------------- /test/none.b: -------------------------------------------------------------------------------- 1 | if none [ 2 | probe 'none-is-true 3 | ] 4 | probe either none ['none-is-true] ['none-is-false] 5 | probe empty? none 6 | -------------------------------------------------------------------------------- /test/none.good: -------------------------------------------------------------------------------- 1 | none-is-false 2 | true 3 | -------------------------------------------------------------------------------- /test/parse.b: -------------------------------------------------------------------------------- 1 | print "---- string parse" 2 | white: make bitset! " ." 3 | word: make bitset! "abcdefghijklmnopqrstuvwxyz" 4 | 5 | print parse { token...} [ 6 | any white a: some word :a any white (print "eval OK") 7 | ] 8 | print a 9 | 10 | 11 | print "---- basic tokenizer" 12 | white: charset " ^-^/" 13 | non-white: complement copy white 14 | words: [] 15 | print parse {some words ...} [some[ 16 | any white a: some non-white :a (append words a) 17 | ]] 18 | probe words 19 | 20 | 21 | print "---- block parse" 22 | print parse [1 2 token ...] [ 23 | any int! a: word! :a any word! 24 | ] 25 | probe a 26 | 27 | 28 | print "---- parse into" 29 | name: age: x: none 30 | print parse [person ["Janet" 38] "-x" 20.2 ] [some[ 31 | 'person into [set name skip set age skip] 32 | | "-x" set x skip 33 | ]] 34 | probe reduce [name age x] 35 | 36 | 37 | print "---- sanity checks" 38 | ogs: "frog clog dog smog bog woggle toggle" 39 | print parse copy ogs [ 40 | some [a: "smog" (clear a) | skip] 41 | ] 42 | 43 | 44 | print "---- string case" 45 | in: {Mixed case from FROM From} 46 | rules: [some[ "From" (++ count) | skip ]] 47 | count: 0 parse in rules print count 48 | count: 0 parse/case in rules print count 49 | rules: [some[ thru "From" (++ count) ]] 50 | count: 0 parse in rules print count 51 | count: 0 parse/case in rules print count 52 | 53 | 54 | print "---- string UCS2" 55 | str: {Рабочий стол Plasma, Чувар екрана} 56 | a: b: none 57 | parse str [thru "стол" some white a: to ',' :a] 58 | probe a 59 | parse str [to "Plasma" b: to #{2C20} :b] 60 | probe b 61 | 62 | 63 | print "---- bits" 64 | gz: #{1f8b 0808 f21c 3743 0003 6f63 6f72 6500} 65 | parse gz [ 66 | '^(1f)' '^(8b)' bits [ 67 | method: u8 68 | 3 fcomment:1 fname:1 fextra:1 fcrc:1 ftext:1 69 | timestamp: u32 70 | cflags: u8 71 | os: u8 72 | ] 73 | ] 74 | foreach it [ 75 | method fcomment fname fextra fcrc ftext timestamp cflags os 76 | ][ 77 | prin rejoin [' ' it ':' get it] 78 | ] 79 | prin '^/' 80 | -------------------------------------------------------------------------------- /test/parse.good: -------------------------------------------------------------------------------- 1 | ---- string parse 2 | eval OK 3 | true 4 | token 5 | ---- basic tokenizer 6 | true 7 | ["some" "words" "..."] 8 | ---- block parse 9 | true 10 | [token] 11 | ---- parse into 12 | true 13 | ["Janet" 38 20.2] 14 | ---- sanity checks 15 | true 16 | ---- string case 17 | 3 18 | 1 19 | 3 20 | 1 21 | ---- string UCS2 22 | "Plasma" 23 | "Plasma" 24 | ---- bits 25 | method:8 fcomment:0 fname:1 fextra:0 fcrc:0 ftext:0 timestamp:1127685362 cflags:0 os:3 26 | -------------------------------------------------------------------------------- /test/path.b: -------------------------------------------------------------------------------- 1 | print "---- make" 2 | p: make path! blk: [a 2] 3 | print [type? p p] 4 | p: make lit-path! blk 5 | print [type? p p] 6 | p: make set-path! blk 7 | print [type? p p] 8 | 9 | 10 | a: ["abc" "hij" "xyz"] 11 | print reduce [make path! [a 2]] 12 | probe a/1 13 | probe a/4 14 | 15 | 16 | print "---- lit-path" 17 | p: 'some/path 18 | print [type? p p] 19 | lp: 'a/'b 20 | print [type? lp lp type? first lp type? second lp] 21 | 22 | 23 | print "---- set-path" 24 | blk: [a [0 (0)]] 25 | blk/2/1: 5 26 | blk/2/2/1: 'pword 27 | probe blk 28 | n: skip p: [1 2 3] 2 29 | n/1: 'new 30 | probe p 31 | 32 | 33 | print "---- block" 34 | a: [x 33 y: 44] 35 | print [a/x a/y] 36 | blk: [a 1 b [x 11 y (aa bb cc)]] 37 | probe blk/b/y/3 38 | blk/b/y/3: 44 39 | probe blk 40 | probe blk/nod 41 | 42 | 43 | print "---- integer" 44 | a: first [foo/-900/48] 45 | foreach elem a [ 46 | print [:elem type? elem] 47 | ] 48 | 49 | 50 | print "---- get-word" 51 | ctx: context [a: 1 b: 2] 52 | val: 'b 53 | probe ctx/:val 54 | blk: [foo [bar sol] b cog] 55 | probe blk/:val 56 | val: 2 57 | probe blk/:val/2 58 | 59 | 60 | print "---- get-path" 61 | obj: context [f: does [1]] 62 | blk: infuse [what f] obj 63 | probe obj/f 64 | probe blk/what 65 | probe :obj/f 66 | probe :blk/what 67 | 68 | 69 | print "---- do path" 70 | dpc: context [ 71 | f: does [print 'hi] 72 | f1: func [a] [print a] 73 | ] 74 | do first [dpc/f] 75 | do 'dpc/f 76 | do first [dpc/f1] 'done-with-arg 77 | do 'dpc/f1 'done-with-arg 78 | -------------------------------------------------------------------------------- /test/path.good: -------------------------------------------------------------------------------- 1 | ---- make 2 | path! a/2 3 | lit-path! 'a/2 4 | set-path! a/2: 5 | hij 6 | "abc" 7 | none 8 | ---- lit-path 9 | path! some/path 10 | path! a/'b word! lit-word! 11 | ---- set-path 12 | [a [5 (pword)]] 13 | [1 2 new] 14 | ---- block 15 | 33 44 16 | cc 17 | [a 1 b [x 11 y (aa bb 44)]] 18 | none 19 | ---- integer 20 | foo word! 21 | -900 int! 22 | 48 int! 23 | ---- get-word 24 | 2 25 | cog 26 | sol 27 | ---- get-path 28 | 1 29 | 1 30 | does [1] 31 | does [1] 32 | ---- do path 33 | hi 34 | hi 35 | done-with-arg 36 | done-with-arg 37 | -------------------------------------------------------------------------------- /test/random.b: -------------------------------------------------------------------------------- 1 | random/seed 0xf045aa21 2 | vals: [r g b a] 3 | loop 4 [ 4 | probe random vals 5 | probe random 1.0 6 | probe random 100 7 | ] 8 | 9 | -------------------------------------------------------------------------------- /test/random.good: -------------------------------------------------------------------------------- 1 | [g b a] 2 | 0.13211317313835025 3 | 87 4 | [b a] 5 | 0.5539955506101251 6 | 18 7 | [b a] 8 | 0.42643637442961335 9 | 23 10 | [r g b a] 11 | 0.21736370818689466 12 | 6 13 | -------------------------------------------------------------------------------- /test/read.b: -------------------------------------------------------------------------------- 1 | print "---- file read" 2 | f: %data-104 3 | buf: "init^/" 4 | probe read/append f buf 5 | probe read/into f buf 6 | probe read/append/part f buf 4 7 | 8 | print "---- eof returns none" 9 | fp: open f 10 | str: "" 11 | len: [] 12 | while [read/part/into fp 20 str] [ 13 | probe str 14 | append len size? str 15 | ] 16 | probe len 17 | close fp 18 | -------------------------------------------------------------------------------- /test/read.good: -------------------------------------------------------------------------------- 1 | ---- file read 2 | {init 3 | This test file contains 104 bytes of data. 4 | 5 | Vidit numquam ad quo, eos antiopam electram consulatu in. 6 | } 7 | {This test file contains 104 bytes of data. 8 | 9 | Vidit numquam ad quo, eos antiopam electram consulatu in. 10 | } 11 | {This test file contains 104 bytes of data. 12 | 13 | Vidit numquam ad quo, eos antiopam electram consulatu in. 14 | This} 15 | ---- eof returns none 16 | "This test file conta" 17 | "ins 104 bytes of dat" 18 | "a.^/^/ Vidit numquam " 19 | "ad quo, eos antiopam" 20 | " electram consulatu " 21 | "in.^/" 22 | [20 20 20 20 20 4] 23 | -------------------------------------------------------------------------------- /test/reduce.b: -------------------------------------------------------------------------------- 1 | print reduce [add 1 3 make logic! 1] 2 | -------------------------------------------------------------------------------- /test/reduce.good: -------------------------------------------------------------------------------- 1 | 4 true 2 | -------------------------------------------------------------------------------- /test/run_test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LD_LIBRARY_PATH=.. 4 | INTERPRETER=../boron 5 | 6 | #DIFF='diff -w --ignore-blank-lines' 7 | 8 | case `uname` in 9 | "CYGWIN"*) 10 | INTERPRETER=../boron.exe 11 | DIFF='diff -w' 12 | ;; 13 | "SunOS") DIFF='diff';; 14 | *) DIFF='diff -a';; 15 | esac 16 | 17 | RC=0 18 | for FILE in $* 19 | do 20 | echo Test: $FILE 21 | GOOD=${FILE%.*}.good 22 | OUT=${FILE%.*}.out 23 | $INTERPRETER -s $FILE >$OUT 24 | ${DIFF} $OUT $GOOD || RC=1 25 | done 26 | exit $RC 27 | -------------------------------------------------------------------------------- /test/serialize.b: -------------------------------------------------------------------------------- 1 | 2 | input: [ 3 | none!/int!/double! 0 -1 2147483647 -2147483648 0xffff0011 4 | 0.0 1.0 -654321.123456 4:59:20.56 5 | -99.0,0.0,1028.9432 32767,-32768 -1,2,-3,4,-5,6 6 | ; 01:02:03:45D 7 | some words set: words:'lit 'words :get :words 8 | [1 (2 "two") [3 "three" words]] 9 | "Tasty treats." #{00112233AABBCCDD} 10 | #[65495810 -3243 0 1 -1] #[67434.403 -1.0 0.0] ; .403 -> .40625 11 | 12 | ctx1 ctx2 iter slic bset ; Bound to values 13 | ] 14 | 15 | values: context [ 16 | ctxP: context [name: speed: child: none] 17 | ctx1: make ctxP [name: "Bob" speed: 2] 18 | ctx2: make ctxP [name: "Tom" speed: 1 child: ctx1] 19 | iter: next next "**text**" 20 | slic: slice iter -2 21 | bset: make bitset! "^-^/ ()[]{}" 22 | ] 23 | bind input values 24 | append input reduce skip tail input -4 25 | 26 | 27 | bin: serialize input 28 | probe size? bin 29 | probe bin 30 | 31 | out: unserialize bin 32 | 33 | input-str: mold input 34 | out-str: mold out 35 | if eq? input-str out-str [ 36 | print size? input-str 37 | print input-str 38 | print out-str 39 | ] 40 | 41 | ;print size? compress bin 42 | ;print size? compress out-str 43 | -------------------------------------------------------------------------------- /test/serialize.good: -------------------------------------------------------------------------------- 1 | 474 2 | #{424F523200000194000000121723816300000064000500050105C0FFFFFFFE05C0FFFFFFFF45C1C0FFFE002286000000000000000006000000000000F03F06F59F353FE2F723C108713D0AD7238AD1408BC0C2C6000000C044809E2F0A0280FFFE80FFFF0A0601040508090C8D00000D00010F00020F00010E00030E00011000041000019701009402001203009604001605008D010601050D010602060D010603070D010604080D010605091C07140801021408020206130917030502180A00170B0014000D5461737479207472656174732E120800112233AABBCCDD1644050263E70355F3FFFF0000000001000000FFFFFFFF16460334B58347000080BF000000001C060A05060708091C0C1C0D1C0714080102140802020613091C030B0C0D140E0005021C0D1400082A2A746578742A2A130020000600000103000000000028000000280000000000000000000000000000000017020504140F00170305061410000D00011C030B0C0D0202021C030B0C0D141100050402140003546F6D14000374776F1400057468726565140003426F62736F6D6520776F72647320736574206C69742067657420637478312063747832206974657220736C696320627365742063747850206E616D65207370656564206368696C6400} 3 | 618 4 | [ 5 | none!/int!/double! 0 -1 2147483647 -2147483648 0xFFFF0011 6 | 0.0 1.0 -654321.123456 4:59:20.56 7 | -99.0,0.0,1028.94324 32767,-32768 -1,2,-3,4,-5,6 8 | some words set: words: 'lit 'words :get :words 9 | [1 (2 "two") [3 "three" words]] 10 | "Tasty treats." #{00112233AABBCCDD} 11 | #[65495810 -3243 0 1 -1] #[67434.4063 -1.0 0.0] 12 | ctx1 ctx2 iter slic bset context [ 13 | name: "Tom" 14 | speed: 1 15 | child: context [ 16 | name: "Bob" 17 | speed: 2 18 | child: none 19 | ] 20 | ] "text**" "text" make bitset! #{0006000001030000000000280000002800000000000000000000000000000000} 21 | ] 22 | [ 23 | none!/int!/double! 0 -1 2147483647 -2147483648 0xFFFF0011 24 | 0.0 1.0 -654321.123456 4:59:20.56 25 | -99.0,0.0,1028.94324 32767,-32768 -1,2,-3,4,-5,6 26 | some words set: words: 'lit 'words :get :words 27 | [1 (2 "two") [3 "three" words]] 28 | "Tasty treats." #{00112233AABBCCDD} 29 | #[65495810 -3243 0 1 -1] #[67434.4063 -1.0 0.0] 30 | ctx1 ctx2 iter slic bset context [ 31 | name: "Tom" 32 | speed: 1 33 | child: context [ 34 | name: "Bob" 35 | speed: 2 36 | child: none 37 | ] 38 | ] "text**" "text" make bitset! #{0006000001030000000000280000002800000000000000000000000000000000} 39 | ] 40 | -------------------------------------------------------------------------------- /test/series.b: -------------------------------------------------------------------------------- 1 | print "---- ordinal" 2 | v: "hello" 3 | print first v 4 | print second v 5 | 6 | 7 | print "---- query" 8 | print series? 2 9 | foreach s [ 10 | "123" 11 | "" 12 | #{010203} 13 | #{} 14 | [1 2 3] 15 | [] 16 | ][ 17 | print [type? s series? s empty? s] 18 | ] 19 | 20 | 21 | print "---- next" 22 | probe prev v 23 | probe n: next next v 24 | probe prev n 25 | 26 | 27 | print "---- ++/--" 28 | it: [1 2 3 4] 29 | print ++ it 30 | print it 31 | print -- it 32 | print -- it 33 | 34 | 35 | print "---- clear" 36 | clear it 37 | probe it 38 | 39 | 40 | print "---- pick" 41 | b: [word1 word2 word3] 42 | print [pick b -1 pick b 0 pick b 2 pick b 4] 43 | print [pick tail b -2 pick tail b 0] 44 | 45 | 46 | print "---- append" 47 | probe append b 5 48 | probe append "abc" 'd' 49 | probe append #{0102} 3 50 | probe append #{0102} #{beef} 51 | 52 | 53 | print "---- join" 54 | probe join 'x' "abc" 55 | probe join 23 "abc" 56 | v: "Good" 57 | probe join v " job" 58 | probe v ; v unchanged. 59 | 60 | 61 | print "---- pop" 62 | b: [1 2 3 4] 63 | print [pop b pop b b] 64 | s: {smog} 65 | print [pop s pop s s] 66 | probe pop [] 67 | 68 | 69 | print "---- terminate" 70 | p: "path" 71 | probe terminate p '/' 72 | probe terminate p '/' 73 | probe terminate p 'b' 74 | probe terminate p '\' 75 | probe terminate/dir p '/' 76 | 77 | 78 | print "---- slice" 79 | t: "" 80 | probe s: slice t 1,-1 81 | probe slice s 2 82 | probe t 83 | probe slice s none 84 | probe slice "some tiny example" 5,4 85 | 86 | 87 | print "---- slice to tail" 88 | t: "" 89 | s: slice t size? t 90 | append t "" 91 | probe s 92 | 93 | 94 | print "---- skip" 95 | b: [1 2] 96 | probe skip b 4 97 | probe skip b -4 98 | b: [1 2 3] 99 | probe skip b 2 100 | probe skip b false 101 | probe skip b true 102 | 103 | 104 | print "---- skip/wrap" 105 | b: [1 2 3] 106 | probe skip/wrap b 7 107 | probe skip/wrap b 0 108 | probe skip/wrap b -1 109 | b: [] 110 | probe skip/wrap b 2 111 | -------------------------------------------------------------------------------- /test/series.good: -------------------------------------------------------------------------------- 1 | ---- ordinal 2 | h 3 | e 4 | ---- query 5 | false 6 | string! true false 7 | string! true true 8 | binary! true false 9 | binary! true true 10 | block! true false 11 | block! true true 12 | ---- next 13 | "hello" 14 | "llo" 15 | "ello" 16 | ---- ++/-- 17 | 1 2 3 4 18 | 2 3 4 19 | 2 3 4 20 | 1 2 3 4 21 | ---- clear 22 | [] 23 | ---- pick 24 | none none word2 none 25 | word2 none 26 | ---- append 27 | [word1 word2 word3 5] 28 | "abcd" 29 | #{010203} 30 | #{0102BEEF} 31 | ---- join 32 | "xabc" 33 | "23abc" 34 | "Good job" 35 | "Good" 36 | ---- pop 37 | 4 3 1 2 38 | g o sm 39 | none 40 | ---- terminate 41 | "path/" 42 | "path/" 43 | "path/b" 44 | "path/b\" 45 | "path/b\" 46 | ---- slice 47 | "test" 48 | "te" 49 | "" 50 | "" 51 | "tiny" 52 | ---- slice to tail 53 | "" 54 | ---- skip 55 | [] 56 | [1 2] 57 | [3] 58 | [1 2 3] 59 | [2 3] 60 | ---- skip/wrap 61 | [2 3] 62 | [1 2 3] 63 | [3] 64 | [] 65 | -------------------------------------------------------------------------------- /test/sort.b: -------------------------------------------------------------------------------- 1 | print "---- sort block!" 2 | probe sort [1 50.0 20.0 5] 3 | probe sort b: ["then" "hello" "goodbye" "NOW" "now"] 4 | probe sort/case b 5 | probe sort [zulu alpha gamma beta] 6 | probe sort/group [0 Apple 3 Dog 1 Box 2 Cat] 2 7 | 8 | ; Caught bug in qsortIndex. 9 | probe sort [6 2 1 9 3 7 5 8 15 4 0 16 14 10 12 11 13 17] 10 | 11 | 12 | print "---- sort field" 13 | ctxb: reduce [ 14 | context [part: 'head size: 2 regen: false] 15 | context [part: 'wing size: 4 regen: false] 16 | context [part: 'head size: 1 regen: true] 17 | context [other: none part: 'wing size: 3 regen: false] 18 | ] 19 | probe sort/field copy ctxb [part size] 20 | probe sort/field copy ctxb [part size /desc] 21 | 22 | blkb: [ 23 | [2 false head] 24 | [4 false wing] 25 | [1 true head] 26 | [3 false wing] 27 | ] 28 | probe sort/field copy blkb [3 1] 29 | probe sort/field copy blkb [3 1 /desc] 30 | 31 | /* 32 | strb: [ 33 | "a-8" 34 | "X-2" 35 | "x-3" 36 | "j-9" 37 | "b-3" 38 | "m-0" 39 | ] 40 | probe sort/field strb [3 1] 41 | */ 42 | -------------------------------------------------------------------------------- /test/sort.good: -------------------------------------------------------------------------------- 1 | ---- sort block! 2 | [1 5 20.0 50.0] 3 | ["goodbye" "hello" "now" "NOW" "then"] 4 | ["NOW" "goodbye" "hello" "now" "then"] 5 | [alpha beta gamma zulu] 6 | [0 Apple 1 Box 2 Cat 3 Dog] 7 | [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17] 8 | ---- sort field 9 | [context [ 10 | part: head 11 | size: 1 12 | regen: true 13 | ] context [ 14 | part: head 15 | size: 2 16 | regen: false 17 | ] context [ 18 | other: none 19 | part: wing 20 | size: 3 21 | regen: false 22 | ] context [ 23 | part: wing 24 | size: 4 25 | regen: false 26 | ]] 27 | [context [ 28 | part: head 29 | size: 2 30 | regen: false 31 | ] context [ 32 | part: head 33 | size: 1 34 | regen: true 35 | ] context [ 36 | part: wing 37 | size: 4 38 | regen: false 39 | ] context [ 40 | other: none 41 | part: wing 42 | size: 3 43 | regen: false 44 | ]] 45 | [ 46 | [1 true head] 47 | [2 false head] 48 | [3 false wing] 49 | [4 false wing] 50 | ] 51 | [ 52 | [2 false head] 53 | [1 true head] 54 | [4 false wing] 55 | [3 false wing] 56 | ] 57 | -------------------------------------------------------------------------------- /test/speed: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SPATH=scripts 4 | INTERPRETER=./boron 5 | RESULTS=test/speed.results 6 | 7 | echo "; " >>$RESULTS 8 | 9 | valgrind --tool=massif --massif-out-file=massif.out $INTERPRETER -e "quit" >out 10 | $SPATH/vm-summary.b massif.out >>$RESULTS 11 | 12 | valgrind --tool=massif --massif-out-file=massif.out $INTERPRETER test/func.b >out 13 | $SPATH/vm-summary.b massif.out >>$RESULTS 14 | 15 | valgrind --tool=massif --massif-out-file=massif.out $INTERPRETER -s $SPATH/m2/m2 -o /tmp/Makefile >out 16 | $SPATH/vm-summary.b massif.out >>$RESULTS 17 | 18 | valgrind --tool=massif --massif-out-file=massif.out $INTERPRETER -e "loop 10 [load %scripts/m2/m2]" 19 | $SPATH/vm-summary.b massif.out >>$RESULTS 20 | 21 | cat $RESULTS 22 | -------------------------------------------------------------------------------- /test/speed.results: -------------------------------------------------------------------------------- 1 | ; v0.3.2 2 | 1391385 102480 boron -e quit 3 | 233260406 127336 boron test/func.b 4 | 53878733 581312 boron -s scripts/m2/m2 -o /tmp/Makefile 5 | 16308125 253880 boron -e loop 10 [load %scripts/m2/m2] 6 | ; master b0f8a735 7 | 1286224 100632 ./boron -e quit 8 | 234262470 124280 ./boron test/func.b 9 | 53718258 568672 ./boron -s scripts/m2/m2 -o /tmp/Makefile 10 | 16150986 251560 ./boron -e loop 10 [load %scripts/m2/m2] 11 | ; b2-eval f15654fa4 12 | 1308259 103016 ./boron -e quit 13 | 195412578 121104 ./boron test/func.b 14 | 51248605 554816 ./boron -s scripts/m2/m2 -o /tmp/Makefile 15 | 16180834 247032 ./boron -e loop 10 [load %scripts/m2/m2] 16 | ; signature type checking 17 | 1340445 111208 ./boron -e quit 18 | 195445039 121104 ./boron test/func.b 19 | 51180209 554800 ./boron -s scripts/m2/m2 -o /tmp/Makefile 20 | 16213017 247000 ./boron -e loop 10 [load %scripts/m2/m2] 21 | ; Remove deprecated functions 964a010 22 | 1351876 111192 ./boron -e quit 23 | 195906508 121088 ./boron test/func.b 24 | 50562257 559632 ./boron -s scripts/m2/m2 -o /tmp/Makefile 25 | 16223222 246984 ./boron -e loop 10 [load %scripts/m2/m2] 26 | ; ur_atomsSort() insertion sort 27 | 1171630 111192 ./boron -e quit 28 | 195725474 121088 ./boron test/func.b 29 | 50116616 559632 ./boron -s scripts/m2/m2 -o /tmp/Makefile 30 | 16043855 246984 ./boron -e loop 10 [load %scripts/m2/m2] 31 | ; serialized boot 32 | 1139118 108280 ./boron -e quit 33 | 195693097 119024 ./boron test/func.b 34 | 50320636 561864 ./boron -s scripts/m2/m2 -o /tmp/Makefile 35 | 16010025 244936 ./boron -e loop 10 [load %scripts/m2/m2] 36 | ; format function 37 | 1142614 108280 ./boron -e quit 38 | 195696593 119024 ./boron test/func.b 39 | 50580636 556976 ./boron -s scripts/m2/m2 -o /tmp/Makefile 40 | 16013627 244936 ./boron -e loop 10 [load %scripts/m2/m2] 41 | ; stack overlow 42 | 1142400 108296 ./boron -e quit 43 | 198248171 119040 ./boron test/func.b 44 | 50687416 556976 ./boron -s scripts/m2/m2 -o /tmp/Makefile 45 | 16013437 244952 ./boron -e loop 10 [load %scripts/m2/m2] 46 | ; boron_doBlock returns UStatus 52b319148 47 | 1142402 108296 ./boron -e quit 48 | 197947926 119040 ./boron test/func.b 49 | 50684728 556976 ./boron -s scripts/m2/m2 -o /tmp/Makefile 50 | 16013438 244952 ./boron -e loop 10 [load %scripts/m2/m2] 51 | ; UBlockIt pointers const cb89c13b0 52 | 1143323 108296 ./boron -e quit 53 | 198924893 119040 ./boron test/func.b 54 | 50691868 556976 ./boron -s scripts/m2/m2 -o /tmp/Makefile 55 | 16014224 244952 ./boron -e loop 10 [load %scripts/m2/m2] 56 | ; sharedStoreBuf pointer 57 | 1143327 108296 ./boron -e quit 58 | 197723875 119040 ./boron test/func.b 59 | 50634093 556976 ./boron -s scripts/m2/m2 -o /tmp/Makefile 60 | 16014208 244952 ./boron -e loop 10 [load %scripts/m2/m2] 61 | ; eval1 INLINE_WORDVAL 62 | 1143243 108296 ./boron -e quit 63 | 196372949 119040 ./boron test/func.b 64 | 50631349 556976 ./boron -s scripts/m2/m2 -o /tmp/Makefile 65 | 16014082 244952 ./boron -e loop 10 [load %scripts/m2/m2] 66 | ; tokenize: Accept 16#[] 128590596 67 | 1154305 108040 ./boron -e quit 68 | 196620898 117488 ./boron test/func.b 69 | 50675370 553912 ./boron -s scripts/m2/m2 -o /tmp/Makefile 70 | 15882917 242576 ./boron -e loop 10 [load %scripts/m2/m2] 71 | ; ur_tokenizeB 72 | 1167836 108040 ./boron -e quit 73 | 196639169 117424 ./boron test/func.b 74 | 50459629 553752 ./boron -s scripts/m2/m2 -o /tmp/Makefile 75 | 16158836 242416 ./boron -e loop 10 [load %scripts/m2/m2] 76 | -------------------------------------------------------------------------------- /test/split.b: -------------------------------------------------------------------------------- 1 | white: charset " ^-^/" 2 | 3 | print "---- not found" 4 | probe split "a bit of time" ':' 5 | probe split "heel-on-shoe" white 6 | probe split #{CC00DEAD00BEEF} 0x01 7 | probe split [blk | of time | blah] 'x 8 | 9 | print "---- normal" 10 | probe split "a bit of time" ' ' 11 | probe split "heel on^/shoe" white 12 | probe split #{CC00DEAD00BEEF} 0x00 13 | probe split [blk | of time | blah] '| 14 | 15 | print "---- subsequent delim" 16 | probe split " a bit of time " ' ' 17 | probe split "^/^-heel^/^-on shoe^/^- " white 18 | probe split #{0000CC0000DEAD000000BEEF0000} 0x00 19 | probe split [+ + blk + + of time + + + blah + +] '+ 20 | -------------------------------------------------------------------------------- /test/split.good: -------------------------------------------------------------------------------- 1 | ---- not found 2 | ["a bit of time"] 3 | ["heel-on-shoe"] 4 | [#{CC00DEAD00BEEF}] 5 | [[blk | of time | blah]] 6 | ---- normal 7 | ["a" "bit" "of" "time"] 8 | ["heel" "on" "shoe"] 9 | [#{CC} #{DEAD} #{BEEF}] 10 | [[blk] [of time] [blah]] 11 | ---- subsequent delim 12 | ["a" "bit" "of" "time"] 13 | ["heel" "on" "shoe"] 14 | [#{CC} #{DEAD} #{BEEF}] 15 | [[blk] [of time] [blah]] 16 | -------------------------------------------------------------------------------- /test/string.b: -------------------------------------------------------------------------------- 1 | print "---- encoding" 2 | print encoding? "abc" 3 | u: "Sîne klâwen" 4 | print [encoding? u encoding? encode 'ucs2 u] 5 | probe encode/bom 'utf8 u 6 | probe to-block {"Copyright © 1930"} 7 | probe to-block mold "^(100)" 8 | 9 | 10 | print "---- append" 11 | probe append "x" [a b c] 12 | 13 | 14 | print "---- insert" 15 | probe insert "string" '0' 16 | probe insert "string" {_abc_} 17 | probe insert/part skip orig: "string" 4 {_abc_} 3 18 | probe orig 19 | 20 | 21 | print "---- trim" 22 | probe trim " trim1 " 23 | probe trim/lines "aa bb" 24 | probe trim/lines " aa^/ bb " 25 | probe trim/indent { 26 | Line One. 27 | Line Two. 28 | Line Three. 29 | } 30 | 31 | 32 | print "---- caret escape" 33 | probe "^"" 34 | print "^"" 35 | probe {^}^"} 36 | print {^}^"} 37 | probe "^}^"" 38 | print "^}^"" 39 | probe "}" 40 | print "}" 41 | probe to-block mold "a^/b" 42 | 43 | 44 | print "---- caret hex" 45 | a: "hash: ^(23) AE: ^(1E2) xai: ^(03e6)" 46 | print [encoding? a size? a] 47 | probe a 48 | print a 49 | b: encode 'latin1 a 50 | probe b 51 | 52 | 53 | print "---- compare" 54 | probe equal? "str" "STR" 55 | 56 | 57 | print "---- do" 58 | print do "add 3 4" 59 | 60 | 61 | print "---- change" 62 | b: "12345" 63 | a: "abcde" 64 | probe change next a b 65 | probe a 66 | 67 | a: "abcde" 68 | probe change next a "^/^/gg^/" 69 | probe a 70 | 71 | a: change "abc" 'z' 72 | probe a 73 | probe head a 74 | 75 | a: change tail "abc" 'z' 76 | probe a 77 | probe head a 78 | 79 | a: "abcde" 80 | probe p: change/slice slice a 1,2 b 81 | print index? p 82 | probe a 83 | 84 | a: "abcdefg" 85 | probe p: change/slice slice a 5 "UU" 86 | probe a 87 | 88 | 89 | print "---- change/part" 90 | a: change/part "abcde" "12" 4 91 | probe a 92 | probe head a 93 | 94 | a: change/part "abcde" "12" 8 95 | probe a 96 | probe head a 97 | 98 | /* 99 | a: "abcde" 100 | probe change/part a b -33 101 | probe a 102 | */ 103 | 104 | 105 | print "---- remove" 106 | a: "remove stuff" 107 | probe remove a 108 | probe remove/part next a 3 109 | probe a 110 | 111 | 112 | print "---- reverse" 113 | probe reverse "vwxy" 114 | probe reverse/part "vwxyz" 3 115 | 116 | 117 | print "---- find" 118 | sq: "A squirrel in winter rests" 119 | u2: "Rests ЃԐ" 120 | probe find sq "WINTER" 121 | probe find/case sq "WINTER" 122 | probe find/case sq lowercase "WINTER" 123 | probe encoding? u2 124 | probe find sq slice u2 5 125 | probe find sq "re" 126 | probe find/last sq "re" 127 | probe find/last/case sq "RE" 128 | 129 | ; Find does't work with utf8 series & latin1 value. 130 | ;probe find encode 'utf8 "Some Random Bits" "Random" 131 | 132 | 133 | print "---- find bitset!" 134 | sep: charset "/\" 135 | probe find a: "/tmp/path/file" sep 136 | probe find b: "c:\Temp\path\file" sep 137 | probe find c: "Not a path" sep 138 | probe find/last a sep 139 | probe find/last b sep 140 | probe find/last c sep 141 | 142 | 143 | print "---- Invalid" 144 | probe to-string #{496E76616C69642031 A0} 145 | 146 | 147 | print "---- nested brackets" 148 | probe { {}} 149 | probe try [do "{ {}"] 150 | 151 | 152 | print "---- Auto-unindent" 153 | probe {{ 154 | }} 155 | probe {{ 156 | int main() { 157 | return 0; 158 | } 159 | }} 160 | probe 161 | {{ 162 | 163 | Item 1 164 | * Sub-time A 165 | * Sub-time B 166 | 167 | }} 168 | probe {{{ 169 | example {{ 170 | Text 171 | }} 172 | }}} 173 | -------------------------------------------------------------------------------- /test/string.good: -------------------------------------------------------------------------------- 1 | ---- encoding 2 | latin1 3 | latin1 ucs2 4 | #{EFBBBF53C3AE6E65206B6CC3A277656E} 5 | ["Copyright © 1930"] 6 | ["Ā"] 7 | ---- append 8 | "xabc" 9 | ---- insert 10 | "0string" 11 | "_abc_string" 12 | "_abng" 13 | "stri_abng" 14 | ---- trim 15 | "trim1" 16 | "aa bb" 17 | "aa bb" 18 | "Line One.^/ Line Two.^/Line Three.^/" 19 | ---- caret escape 20 | {"} 21 | " 22 | {^}"} 23 | }" 24 | {^}"} 25 | }" 26 | "}" 27 | } 28 | ["a^/b"] 29 | ---- caret hex 30 | ucs2 20 31 | "hash: # AE: Ǣ xai: Ϧ" 32 | hash: # AE: Ǣ xai: Ϧ 33 | "hash: # AE: ¿ xai: ¿" 34 | ---- compare 35 | true 36 | ---- do 37 | 7 38 | ---- change 39 | "" 40 | "a12345" 41 | "" 42 | "a^/^/gg^/" 43 | "bc" 44 | "zbc" 45 | "" 46 | "abcz" 47 | "" 48 | 7 49 | "a12345de" 50 | "fg" 51 | "UUfg" 52 | ---- change/part 53 | "e" 54 | "12e" 55 | "" 56 | "12" 57 | ---- remove 58 | "emove stuff" 59 | "e stuff" 60 | "ee stuff" 61 | ---- reverse 62 | "yxwv" 63 | "xwvyz" 64 | ---- find 65 | "winter rests" 66 | none 67 | "winter rests" 68 | ucs2 69 | "rests" 70 | "rel in winter rests" 71 | "rests" 72 | none 73 | ---- find bitset! 74 | "/tmp/path/file" 75 | "\Temp\path\file" 76 | none 77 | "/file" 78 | "\file" 79 | none 80 | ---- Invalid 81 | "Invalid 1" 82 | ---- nested brackets 83 | " {}" 84 | Syntax Error: String not terminated (line 1) 85 | Trace: 86 | -> do "{ {}" 87 | ---- Auto-unindent 88 | "" 89 | "int main() {^/ return 0;^/}^/" 90 | {Item 1 91 | * Sub-time A 92 | * Sub-time B 93 | 94 | } 95 | "example {{^/ Text^/}}^/" 96 | -------------------------------------------------------------------------------- /test/thread.b: -------------------------------------------------------------------------------- 1 | print "---- basic" 2 | tp: thread/port [ 3 | while [true] [ 4 | val: read thread-port 5 | prin "read: " probe val 6 | if block? val [print do val] 7 | if eq? val 'bye [break] 8 | ] 9 | print "Thread exit" 10 | ] 11 | 12 | send: func [val] [ 13 | write tp val 14 | sleep 0.1 15 | ] 16 | 17 | str: "Here is some text." 18 | 19 | send 1 20 | send true 21 | send str 22 | send str ; Will be cleared by previous send. 23 | send [1 2 3] 24 | send [add 4 5] 25 | send 'bye 26 | 27 | 28 | print "---- join on close" 29 | tp: thread/port {{ 30 | while [string? val: read thread-port] [ 31 | print join "Echo " val 32 | ] 33 | print "Thread auto-exit" 34 | }} 35 | send "apple" 36 | send "ball" 37 | close tp 38 | -------------------------------------------------------------------------------- /test/thread.good: -------------------------------------------------------------------------------- 1 | ---- basic 2 | read: 1 3 | read: true 4 | read: "Here is some text." 5 | read: "" 6 | read: [1 2 3] 7 | 3 8 | read: [add 4 5] 9 | 9 10 | read: bye 11 | Thread exit 12 | ---- join on close 13 | Echo apple 14 | Echo ball 15 | Thread auto-exit 16 | -------------------------------------------------------------------------------- /test/time.b: -------------------------------------------------------------------------------- 1 | print "---- make" 2 | print [make time! 300.0 to-time 300] 3 | 4 | 5 | print "---- math" 6 | print add 00:37:12 40.5 7 | print sub 0:37:12 0:35:48 8 | 9 | 10 | print "---- seconds" 11 | a: 1:30:4.7 12 | print [to-double a to-int a] 13 | -------------------------------------------------------------------------------- /test/time.good: -------------------------------------------------------------------------------- 1 | ---- make 2 | 0:05:00.0 0:05:00.0 3 | ---- math 4 | 0:37:52.5 5 | 0:01:24.0 6 | ---- seconds 7 | 5404.7 5404 8 | -------------------------------------------------------------------------------- /test/utf8.b: -------------------------------------------------------------------------------- 1 | ; Some UTF-8 text from http://www.columbia.edu/kermit/utf8.html 2 | 3 | strings: 4 | [ 5 | French {Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus et de voir leurs drôles d'œufs abîmés.} 6 | 7 | German {Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.} 8 | 9 | Greek-monotonic {ξεσκεπάζω την ψυχοφθόρα βδελυγμία} 10 | 11 | Icelandic {Sævör grét áðan því úlpan var ónýt.} 12 | 13 | Russian {В чащах юга жил-был цитрус? Да, но фальшивый экземпляр! ёъ.} 14 | 15 | Emoticons "^(1f600) ^(1f635) ^(1f64c) ^(1f927)" 16 | ] 17 | 18 | probe strings 19 | 20 | foreach [l s] strings [ 21 | print [" --" l encoding? s "--"] 22 | probe s 23 | probe uppercase s 24 | probe lowercase s 25 | ] 26 | -------------------------------------------------------------------------------- /test/utf8.good: -------------------------------------------------------------------------------- 1 | [ 2 | French {Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus et de voir leurs drôles d'œufs abîmés.} 3 | German {Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.} 4 | Greek-monotonic "ξεσκεπάζω την ψυχοφθόρα βδελυγμία" 5 | Icelandic "Sævör grét áðan því úlpan var ónýt." 6 | Russian {В чащах юга жил-был цитрус? Да, но фальшивый экземпляр! ёъ.} 7 | Emoticons "😀 😵 🙌 🤧" 8 | ] 9 | -- French ucs2 -- 10 | {Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus et de voir leurs drôles d'œufs abîmés.} 11 | {LES NAÏFS ÆGITHALES HÂTIFS PONDANT À NOËL OÙ IL GÈLE SONT SÛRS D'ÊTRE DÉÇUS ET DE VOIR LEURS DRÔLES D'ŒUFS ABÎMÉS.} 12 | {les naïfs ægithales hâtifs pondant à noël où il gèle sont sûrs d'être déçus et de voir leurs drôles d'œufs abîmés.} 13 | -- German latin1 -- 14 | {Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.} 15 | {FALSCHES ÜBEN VON XYLOPHONMUSIK QUÄLT JEDEN GRÖßEREN ZWERG.} 16 | {falsches üben von xylophonmusik quält jeden größeren zwerg.} 17 | -- Greek-monotonic ucs2 -- 18 | "ξεσκεπάζω την ψυχοφθόρα βδελυγμία" 19 | "ΞΕΣΚΕΠΆΖΩ ΤΗΝ ΨΥΧΟΦΘΌΡΑ ΒΔΕΛΥΓΜΊΑ" 20 | "ξεσκεπάζω την ψυχοφθόρα βδελυγμία" 21 | -- Icelandic latin1 -- 22 | "Sævör grét áðan því úlpan var ónýt." 23 | "SÆVÖR GRÉT ÁÐAN ÞVÍ ÚLPAN VAR ÓNÝT." 24 | "sævör grét áðan því úlpan var ónýt." 25 | -- Russian ucs2 -- 26 | {В чащах юга жил-был цитрус? Да, но фальшивый экземпляр! ёъ.} 27 | {В ЧАЩАХ ЮГА ЖИЛ-БЫЛ ЦИТРУС? ДА, НО ФАЛЬШИВЫЙ ЭКЗЕМПЛЯР! ЁЪ.} 28 | {в чащах юга жил-был цитрус? да, но фальшивый экземпляр! ёъ.} 29 | -- Emoticons utf8 -- 30 | "😀 😵 🙌 🤧" 31 | "😀 😵 🙌 🤧" 32 | "😀 😵 🙌 🤧" 33 | -------------------------------------------------------------------------------- /test/vec3.b: -------------------------------------------------------------------------------- 1 | print "---- make" 2 | probe 1.2,5.8891 3 | probe d: -44.0, 6, 9888 4 | print [d/1 d/4] 5 | 6 | probe c: make vec3! [1 2.2 10] 7 | print [c/3 c/0] 8 | probe to-vec3 next #[1.0 2 3 4.1] 9 | 10 | 11 | print "---- tokenize" 12 | print [1.1,2.51,-45 1.0,4] 13 | 14 | 15 | print "---- ordinal" 16 | v: 1.1,2.51,-45 17 | print [v first v second v third v] 18 | print [v/1 v/2 v/3] 19 | print [pick v 1 pick v 2 pick v 3] 20 | 21 | 22 | print "---- set element" 23 | a: 0.0,1,2 24 | a/1: 9.0 25 | a/2: 10.0 26 | a/3: 11.0 27 | probe a 28 | a: 0.0,1,2 29 | b: poke a 1 4.4 30 | b: poke b 2 5.5 31 | b: poke b 3 6.6 32 | probe a 33 | probe b 34 | 35 | 36 | print "---- compare" 37 | foreach [n v] [ 38 | 1.1 1.1,0 39 | 2.51 2.51,0 40 | -45.0 -45.0,0 41 | 2.15 2.15,0 42 | ][ 43 | print [n eq? n first v same? n first v] 44 | ] 45 | -------------------------------------------------------------------------------- /test/vec3.good: -------------------------------------------------------------------------------- 1 | ---- make 2 | 1.20000005,5.88910007,0.0 3 | -44.0,6.0,9888.0 4 | -44.0 none 5 | 1.0,2.20000005,10.0 6 | 10.0 none 7 | 2.0,3.0,4.0999999 8 | ---- tokenize 9 | 1.10000002,2.50999999,-45.0 1.0,4.0,0.0 10 | ---- ordinal 11 | 1.10000002,2.50999999,-45.0 1.100000023841858 2.509999990463257 -45.0 12 | 1.100000023841858 2.509999990463257 -45.0 13 | 1.100000023841858 2.509999990463257 -45.0 14 | ---- set element 15 | 9.0,10.0,11.0 16 | 0.0,1.0,2.0 17 | 4.4000001,5.5,6.5999999 18 | ---- compare 19 | 1.1 true false 20 | 2.51 true false 21 | -45.0 true true 22 | 2.15 true false 23 | -------------------------------------------------------------------------------- /test/vector.b: -------------------------------------------------------------------------------- 1 | print "---- tokenize" 2 | probe #[1 -22 3.55] ; i32 3 | probe #[1.0 -22 3.55] ; f32 4 | probe #[ 4 88/*89*/5 /*6*/] 5 | probe #[ 6 | 1 1 1 7 | ;2 2 2 8 | 3 3 3 9 | ] 10 | probe #[9e+6 -9.45e-06 1e+38 1e+39 1e-42] ; exponential notation 11 | 12 | 13 | print "---- form i16" 14 | probe a: i16#[1 -22 3.55] 15 | print size? to-binary a 16 | probe b: i16#[1.0 -22 3.55] 17 | print size? to-binary b 18 | 19 | 20 | print "---- form f64" 21 | probe a: f64#[1 -22 3.55] 22 | print size? to-binary a 23 | probe b: f64#[1.0 -22 3.55] 24 | print size? to-binary b 25 | 26 | 27 | print "---- append" 28 | a: #[1 2 3] 29 | probe append copy a 4 30 | probe append copy a #[70 80 90] 31 | probe append copy a 9.0,-8.7,7.0 32 | probe append copy a [9 8.6 'C'] 33 | 34 | 35 | ;print "---- find" 36 | ;probe find a 2 37 | 38 | 39 | print "---- poke" 40 | a: #[1.0 2 3 4 5 6] 41 | probe poke a 3 8.0,9.2,10 42 | 43 | 44 | print "---- reverse" 45 | probe reverse #[1 2 3 4] 46 | probe reverse/part #[1 2 3 4 5] 3 47 | 48 | 49 | print "---- insert" 50 | a: #[0] 51 | probe insert a 9 52 | probe insert a 3.0,2.0,1.0 53 | probe insert/part skip a 4 #[-1 -2 -3] 1 54 | probe a 55 | 56 | 57 | print "---- change" 58 | a: #[1.0 2 3] 59 | b: #[-1.5 -2.5 -3.5] 60 | probe change next a b 61 | probe a 62 | 63 | a: #[1.0 2 3] 64 | probe change a 7.0,6,5 65 | probe a 66 | 67 | 68 | print "---- to-text" 69 | print to-text #[-1.0 2.0] 70 | print to-text a: i16#[4 -32] 71 | print mold/contents a 72 | -------------------------------------------------------------------------------- /test/vector.good: -------------------------------------------------------------------------------- 1 | ---- tokenize 2 | #[1 -22 3] 3 | #[1.0 -22.0 3.54999995] 4 | #[4 88 5] 5 | #[1 1 1 3 3 3] 6 | #[9000000.0 -9.45000011e-6 9.99999968e+37 inf 1.0005271e-42] 7 | ---- form i16 8 | i16#[1 -22 3] 9 | 6 10 | i16#[1 -22 3] 11 | 6 12 | ---- form f64 13 | f64#[1.0 -22.0 3.55] 14 | 24 15 | f64#[1.0 -22.0 3.55] 16 | 24 17 | ---- append 18 | #[1 2 3 4] 19 | #[1 2 3 70 80 90] 20 | #[1 2 3 9 -8 7] 21 | #[1 2 3 9 8 67] 22 | ---- poke 23 | #[1.0 2.0 8.0 9.19999981 10.0 6.0] 24 | ---- reverse 25 | #[4 3 2 1] 26 | #[3 2 1 4 5] 27 | ---- insert 28 | #[9 0] 29 | #[3 2 1 9 0] 30 | #[-1 0] 31 | #[3 2 1 9 -1 0] 32 | ---- change 33 | #[] 34 | #[1.0 -1.5 -2.5 -3.5] 35 | #[] 36 | #[7.0 6.0 5.0] 37 | ---- to-text 38 | -1.0 2.0 39 | 4 -32 40 | 4 -32 41 | -------------------------------------------------------------------------------- /test/word.b: -------------------------------------------------------------------------------- 1 | print "---- Multiple set" 2 | a: b: c: true 3 | print [a b c] 4 | set [e f g] [1 2] 5 | print [e f g] 6 | 7 | 8 | print "---- Mixed Case" 9 | probe ['MixedCase A_very_long_word_of_40_characters-yes_40] 10 | 11 | 12 | print "---- set func" 13 | set 'wx none 14 | print wx 15 | 16 | words: [x y] 17 | set words 21 18 | print words 19 | 20 | 21 | print "---- make" 22 | probe to-word int! 23 | ;probe to-word int!/decimal! 24 | 25 | 26 | print "---- toText" 27 | words: [a 'b c: :d] 28 | foreach w words [prin w prin ' ' probe w] 29 | 30 | 31 | print "---- tokenize" 32 | words: [+ +1 +a+ - -1 -a- * & / /a] ; '/ /: 33 | foreach w words [print [w type? w]] 34 | 35 | 36 | print "---- lit-words" 37 | probe ['= '== '!= '> '< '<= '>=] 38 | -------------------------------------------------------------------------------- /test/word.good: -------------------------------------------------------------------------------- 1 | ---- Multiple set 2 | true true true 3 | 1 2 none 4 | ---- Mixed Case 5 | ['MixedCase A_very_long_word_of_40_characters-yes_40] 6 | ---- set func 7 | none 8 | 21 21 9 | ---- make 10 | int! 11 | ---- toText 12 | a a 13 | b 'b 14 | c c: 15 | d :d 16 | ---- tokenize 17 | + word! 18 | 1 int! 19 | +a+ word! 20 | - word! 21 | -1 int! 22 | -a- word! 23 | * word! 24 | & word! 25 | / word! 26 | /a option! 27 | ---- lit-words 28 | ['= '== '!= '> '< '<= '>=] 29 | -------------------------------------------------------------------------------- /urlan/array.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2009,2010 Karl Robillard 3 | 4 | This file is part of the Urlan datatype system. 5 | 6 | Urlan is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Urlan is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Urlan. If not, see . 18 | */ 19 | /* 20 | UBuffer members: 21 | type Set by user, defaults to UT_UNSET 22 | elemSize Element byte size 23 | form Unused 24 | flags Unused 25 | used Number of elements used 26 | ptr.v Elements 27 | ptr.i[-1] Number of elements available 28 | */ 29 | 30 | 31 | #include "urlan.h" 32 | #include "os.h" 33 | 34 | 35 | // Align for 64-bit pointers or doubles if size > 4. 36 | #define FORWARD(s) ((s > 4) ? 8 : 4) 37 | 38 | 39 | /** 40 | Initialize array buffer. 41 | The buf type, form, flags, and used members are set to zero. 42 | 43 | \param buf Uninitialized buffer. 44 | \param size Element byte size. Must be less than 256. 45 | \param count Number of elements to allocate. 46 | */ 47 | void ur_arrInit( UBuffer* buf, int size, int count ) 48 | { 49 | assert( size ); 50 | assert( size < 256 ); 51 | 52 | *((uint32_t*) buf) = 0; 53 | buf->elemSize = size; 54 | buf->used = 0; 55 | 56 | if( count > 0 ) 57 | { 58 | int fwd = FORWARD(size); 59 | 60 | buf->ptr.b = (uint8_t*) memAlloc( (size * count) + fwd ); 61 | if( buf->ptr.b ) 62 | { 63 | buf->ptr.b += fwd; 64 | ur_avail(buf) = count; 65 | } 66 | } 67 | else 68 | { 69 | buf->ptr.b = 0; 70 | } 71 | } 72 | 73 | 74 | /** 75 | Free array data. 76 | 77 | buf->ptr and buf->used are set to zero. 78 | */ 79 | void ur_arrFree( UBuffer* buf ) 80 | { 81 | if( buf->ptr.b ) 82 | { 83 | memFree( buf->ptr.b - FORWARD(buf->elemSize) ); 84 | buf->ptr.b = 0; 85 | } 86 | buf->used = 0; 87 | } 88 | 89 | 90 | /** 91 | Allocates enough memory to hold count elements. 92 | buf->used is not changed. 93 | 94 | \param buf Initialized array buffer. 95 | \param count Total number of elements. 96 | */ 97 | void ur_arrReserve( UBuffer* buf, int count ) 98 | { 99 | uint8_t* mem; 100 | int avail; 101 | int fwd; 102 | 103 | avail = ur_testAvail( buf ); 104 | if( count <= avail ) 105 | return; 106 | 107 | /* Double the buffer size (unless that is not big enough). */ 108 | avail *= 2; 109 | if( avail < count ) 110 | avail = (count < 8) ? 8 : count; 111 | 112 | fwd = FORWARD(buf->elemSize); 113 | 114 | if( buf->ptr.b ) 115 | mem = (uint8_t*) memRealloc( buf->ptr.b - fwd, 116 | (buf->elemSize * avail) + fwd ); 117 | else 118 | mem = (uint8_t*) memAlloc( (buf->elemSize * avail) + fwd ); 119 | assert( mem ); 120 | //printf( "realloc %d\n", mem == (buf->ptr.b - fsize) ); 121 | 122 | buf->ptr.b = mem + fwd; 123 | ur_avail(buf) = avail; 124 | } 125 | 126 | 127 | /** 128 | Remove elements from the array. 129 | 130 | \param buf Initialized array buffer. 131 | \param start Start index of erase. 132 | \param count Number of elements to remove. 133 | */ 134 | void ur_arrErase( UBuffer* buf, int start, int count ) 135 | { 136 | if( start >= buf->used ) 137 | return; 138 | if( (start + count) < buf->used ) 139 | { 140 | int size = buf->elemSize; 141 | uint8_t* mem = buf->ptr.b + (size * start); 142 | memMove(mem, mem + (size * count), size * (buf->used - start - count)); 143 | buf->used -= count; 144 | } 145 | else 146 | buf->used = start; 147 | } 148 | 149 | 150 | /** 151 | Create space in the array for count elements starting at index. 152 | The memory in the new space is uninitialized. 153 | 154 | \param buf Initialized array buffer. 155 | \param index Position to expand at. 156 | \param count Number of elements to expand. 157 | */ 158 | void ur_arrExpand( UBuffer* buf, int index, int count ) 159 | { 160 | ur_arrReserve( buf, buf->used + count ); 161 | if( index < buf->used ) 162 | { 163 | int size = buf->elemSize; 164 | uint8_t* mem = buf->ptr.b + (size * index); 165 | memMove( mem + (size * count), mem, size * (buf->used - index) ); 166 | } 167 | buf->used += count; 168 | } 169 | 170 | 171 | /** 172 | Append int32_t to array. 173 | 174 | \param buf Array buffer with elemSize of 4. 175 | \param n Number to append. 176 | */ 177 | void ur_arrAppendInt32( UBuffer* buf, int32_t n ) 178 | { 179 | ur_arrReserve( buf, buf->used + 1 ); 180 | buf->ptr.i32[ buf->used++ ] = n; 181 | } 182 | 183 | 184 | /** 185 | Append float to array. 186 | 187 | \param buf Array buffer with elemSize of 4. 188 | \param n Number to append. 189 | */ 190 | void ur_arrAppendFloat( UBuffer* buf, float n ) 191 | { 192 | ur_arrReserve( buf, buf->used + 1 ); 193 | buf->ptr.f[ buf->used++ ] = n; 194 | } 195 | 196 | 197 | /*EOF*/ 198 | -------------------------------------------------------------------------------- /urlan/env.h: -------------------------------------------------------------------------------- 1 | #ifndef ENV_H 2 | #define ENV_H 3 | /* 4 | Copyright 2009,2010 Karl Robillard 5 | 6 | This file is part of the Urlan datatype system. 7 | 8 | Urlan is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | Urlan is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with Urlan. If not, see . 20 | */ 21 | 22 | 23 | #include "urlan.h" 24 | #include "os.h" 25 | 26 | 27 | #define LOCK_GLOBAL mutexLock( env->mutex ); 28 | #define UNLOCK_GLOBAL mutexUnlock( env->mutex ); 29 | 30 | 31 | struct UEnv 32 | { 33 | OSMutex mutex; 34 | UBuffer sharedStore; 35 | UBuffer atomNames; // Protected by mutex. 36 | UBuffer atomTable; // Protected by mutex. 37 | uint16_t typeCount; 38 | uint16_t threadCount; // Protected by mutex. 39 | uint32_t threadSize; 40 | void (*threadFunc)( UThread*, enum UThreadMethod ); 41 | UThread* initialThread; 42 | const UDatatype* types[ UT_MAX ]; 43 | }; 44 | 45 | 46 | #endif /*EOF*/ 47 | -------------------------------------------------------------------------------- /urlan/hashmap.h: -------------------------------------------------------------------------------- 1 | #ifndef HASHMAP_H 2 | #define HASHMAP_H 3 | 4 | 5 | extern void hashmap_values( UThread*, const UCell* mapC, UBuffer* blk ); 6 | extern void hashmap_clear( UThread*, UCell* mapC ); 7 | extern UStatus hashmap_insert( UThread*, const UCell* mapC, const UCell* keyC, 8 | const UCell* valueC ); 9 | extern UStatus hashmap_remove( UThread*, const UCell* mapC, const UCell* keyC ); 10 | extern const UCell* hashmap_select( UThread*, const UCell* cell, 11 | const UCell* sel, UCell* tmp ); 12 | 13 | 14 | #endif //HASHMAP_H 15 | -------------------------------------------------------------------------------- /urlan/i_parse_blk.h: -------------------------------------------------------------------------------- 1 | #ifndef I_PARSE_BLK_H 2 | #define I_PARSE_BLK_H 3 | /* 4 | Bytecode interpreter for parsing blocks 5 | Copyright 2016, 2019 Karl Robillard 6 | */ 7 | 8 | 9 | #include "urlan.h" 10 | 11 | 12 | enum ParseBlockInstruction 13 | { 14 | PB_End, 15 | PB_Flag, // rflag bitmask (limit 8 bits) 16 | PB_Report, // report id 17 | PB_ReportEnd, // report id 18 | PB_Next, // Number of bytes to skip to next alternate rule 19 | //PB_Repeat, 20 | //PB_RepeatV, 21 | PB_Skip, 22 | PB_LitWord, // atoms index 23 | PB_Rule, // rules offset to instructions 24 | PB_Type, // Datatype 25 | PB_Typeset, // rules offset of 64-bit mask 26 | PB_OptR, // rules offset to instructions 27 | PB_OptT, // Datatype 28 | PB_OptTs, // rules offset of 64-bit mask 29 | PB_AnyR, // rules offset to instructions 30 | PB_AnyT, // Datatype 31 | PB_AnyTs, // rules offset of 64-bit mask 32 | PB_SomeR, // rules offset to instructions 33 | PB_SomeT, // Datatype 34 | PB_SomeTs, // rules offset of 64-bit mask 35 | PB_ToT, // Datatype 36 | PB_ToTs, // rules offset of 64-bit mask 37 | PB_ToLitWord, // atoms index 38 | PB_ThruT, // Datatype 39 | PB_ThruTs // rules offset of 64-bit mask 40 | }; 41 | 42 | 43 | typedef struct UBlockParser UBlockParser; 44 | 45 | struct UBlockParser 46 | { 47 | UThread* ut; 48 | const UAtom* atoms; 49 | const uint8_t* rules; 50 | const UCell* it; 51 | const UCell* end; 52 | void (*report)(UBlockParser*, int, const UCell*, const UCell*); 53 | int rflag; 54 | }; 55 | 56 | 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | 61 | int ur_parseBlockI( UBlockParser* par, const uint8_t* pc, const UCell* it ); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | 68 | #endif /* I_PARSE_BLK_H */ 69 | -------------------------------------------------------------------------------- /urlan/memtrack.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2009 Karl Robillard 3 | 4 | This file is part of the Urlan datatype system. 5 | 6 | Urlan is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Urlan is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Urlan. If not, see . 18 | */ 19 | 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | #ifdef TRACK_MALLOC 27 | typedef struct OListNode OListNode; 28 | 29 | struct OListNode 30 | { 31 | OListNode* prev; 32 | OListNode* next; 33 | }; 34 | 35 | typedef struct 36 | { 37 | OListNode head; 38 | OListNode tail; 39 | } 40 | OList; 41 | 42 | static void _listAppend( OListNode* node, OListNode* after ) 43 | { 44 | node->prev = after; 45 | node->next = after->next; 46 | after->next->prev = node; 47 | after->next = node; 48 | } 49 | 50 | static void _listRemove( OListNode* node ) 51 | { 52 | node->prev->next = node->next; 53 | node->next->prev = node->prev; 54 | node->prev = node->next = 0; 55 | } 56 | 57 | 58 | typedef struct 59 | { 60 | OListNode link; 61 | void* ptr; 62 | size_t size; 63 | } 64 | MallocRecord; 65 | 66 | 67 | static OList _list = { {0,&_list.tail}, {&_list.head,0} }; 68 | 69 | 70 | void* memAlloc( size_t size ) 71 | { 72 | MallocRecord* rec; 73 | void* ptr = malloc( size ); 74 | 75 | if( ptr ) 76 | { 77 | // Add ptr to list. 78 | 79 | rec = (MallocRecord*) malloc( sizeof(MallocRecord) ); 80 | assert( rec ); 81 | rec->ptr = ptr; 82 | rec->size = size; 83 | _listAppend( &rec->link, &_list.head ); 84 | } 85 | 86 | return ptr; 87 | } 88 | 89 | 90 | static MallocRecord* memFindRecord( void* ptr ) 91 | { 92 | OListNode* it = _list.head.next; 93 | while( it->next ) 94 | { 95 | if( ((MallocRecord*) it)->ptr == ptr ) 96 | return (MallocRecord*) it; 97 | it = it->next; 98 | } 99 | return 0; 100 | } 101 | 102 | 103 | void* memRealloc( void* ptr, size_t size ) 104 | { 105 | MallocRecord* rec = memFindRecord( ptr ); 106 | if( rec ) 107 | { 108 | rec->ptr = realloc( ptr, size ); 109 | assert( rec->ptr ); 110 | rec->size = size; 111 | return rec->ptr; 112 | } 113 | else 114 | { 115 | printf( "memRealloc - %p was not allocted with memAlloc!\n", ptr ); 116 | return realloc( ptr, size ); 117 | } 118 | } 119 | 120 | 121 | void memFree( void* ptr ) 122 | { 123 | MallocRecord* rec = memFindRecord( ptr ); 124 | if( rec ) 125 | { 126 | // Remove ptr from list. 127 | free( rec->ptr ); 128 | _listRemove( &rec->link ); 129 | free( rec ); 130 | } 131 | else 132 | { 133 | printf( "memFree - %p was not allocted with memAlloc!\n", ptr ); 134 | } 135 | } 136 | 137 | 138 | void memReport( int verbose ) 139 | { 140 | size_t total; 141 | int count; 142 | OListNode* it; 143 | MallocRecord* rec; 144 | 145 | printf( "memReport:\n" ); 146 | 147 | count = total = 0; 148 | it = _list.head.next; 149 | while( it->next ) 150 | { 151 | rec = (MallocRecord*) it; 152 | 153 | total += rec->size; 154 | ++count; 155 | 156 | if( verbose ) 157 | printf( " %d bytes at %p\n", (int) rec->size, rec->ptr ); 158 | 159 | it = it->next; 160 | } 161 | 162 | printf( " %d allocations\n %d bytes\n", count, (int) total ); 163 | } 164 | #endif 165 | 166 | 167 | //EOF 168 | -------------------------------------------------------------------------------- /urlan/os.h: -------------------------------------------------------------------------------- 1 | #ifndef OS_H 2 | #define OS_H 3 | /* 4 | Boron operating system interface. 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #ifdef __sun__ 15 | #include 16 | #else 17 | #include 18 | #endif 19 | 20 | 21 | #ifdef _WIN32 22 | 23 | // Must define _WIN32_WINNT to use InitializeCriticalSectionAndSpinCount 24 | #ifndef _WIN32_WINNT 25 | #define _WIN32_WINNT 0x0403 26 | #endif 27 | #include 28 | #include // _chdir, _getcwd 29 | 30 | #undef small // Defined in RpcNdr.h (SDK v6.0A) 31 | 32 | #ifdef _MSC_VER 33 | #define inline __inline 34 | #endif 35 | 36 | #define vaStrPrint _vsnprintf 37 | 38 | typedef HANDLE OSThread; 39 | typedef CRITICAL_SECTION OSMutex; 40 | typedef CONDITION_VARIABLE OSCond; 41 | 42 | #define mutexInitF(mh) \ 43 | (InitializeCriticalSectionAndSpinCount(&mh,0x80000400) == 0) 44 | #define mutexFree(mh) DeleteCriticalSection(&mh) 45 | #define mutexLock(mh) EnterCriticalSection(&mh) 46 | #define mutexUnlock(mh) LeaveCriticalSection(&mh) 47 | #define condInit(cond) InitializeConditionVariable(&cond) 48 | #define condFree(cond) 49 | #define condWaitF(cond,mh) (! SleepConditionVariableCS(&cond,&mh,INFINITE)) 50 | #define condSignal(cond) WakeConditionVariable(&cond) 51 | 52 | #else 53 | 54 | #include 55 | #include 56 | 57 | #define vaStrPrint vsnprintf 58 | 59 | typedef pthread_t OSThread; 60 | typedef pthread_mutex_t OSMutex; 61 | typedef pthread_cond_t OSCond; 62 | 63 | #define mutexInitF(mh) (pthread_mutex_init(&mh,0) == -1) 64 | #define mutexFree(mh) pthread_mutex_destroy(&mh) 65 | #define mutexLock(mh) pthread_mutex_lock(&mh) 66 | #define mutexUnlock(mh) pthread_mutex_unlock(&mh) 67 | #define condInit(cond) pthread_cond_init(&cond,0) 68 | #define condFree(cond) pthread_cond_destroy(&cond) 69 | #define condWaitF(cond,mh) pthread_cond_wait(&cond,&mh) 70 | #define condSignal(cond) pthread_cond_signal(&cond) 71 | 72 | #endif 73 | 74 | 75 | #define strPrint sprintf 76 | #define strNCpy strncpy 77 | #define strLen strlen 78 | 79 | #define memCpy memcpy 80 | #define memSet memset 81 | #define memMove memmove 82 | 83 | 84 | #ifdef __cplusplus 85 | extern "C" { 86 | #endif 87 | 88 | #ifdef TRACK_MALLOC 89 | void* memAlloc( size_t ); 90 | void* memRealloc( void*, size_t ); 91 | void memFree( void* ); 92 | void memReport( int verbose ); 93 | #else 94 | #define memAlloc malloc 95 | #define memRealloc realloc 96 | #define memFree free 97 | #endif 98 | 99 | #ifdef UR_CONFIG_EMH 100 | extern void ur_dprint( const char*, ... ); 101 | #define dprint ur_dprint 102 | #else 103 | #define dprint printf 104 | #endif 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | 111 | #endif /* OS_H */ 112 | -------------------------------------------------------------------------------- /urlan/project.b: -------------------------------------------------------------------------------- 1 | project: "urlan" 2 | 3 | timecode: false 4 | 5 | do-any %project.config 6 | 7 | default [ 8 | ;debug 9 | release 10 | 11 | objdir %obj 12 | include_from [%. %../support] 13 | 14 | macx [ 15 | cflags {-std=c99} 16 | cflags {-pedantic} 17 | universal 18 | ] 19 | unix [ 20 | ;cflags {-std=c99} 21 | cflags {-std=gnu99} ; Try this if c99 fails. 22 | cflags {-pedantic} 23 | ] 24 | win32 [ 25 | include_from %../win32 26 | ] 27 | ] 28 | 29 | shlib %urlan [ 30 | if timecode [ 31 | cflags {-DCONFIG_TIMECODE} 32 | ] 33 | ;cflags {-DTRACK_MALLOC} sources [%memtrack.c] 34 | 35 | sources_from %../support [ 36 | %str.c 37 | %mem_util.c 38 | ] 39 | 40 | sources [ 41 | %env.c 42 | %array.c 43 | %binary.c 44 | %block.c 45 | %coord.c 46 | %date.c 47 | %path.c 48 | %string.c 49 | %context.c 50 | %gc.c 51 | %serialize.c 52 | %tokenize.c 53 | %bignum.c 54 | %vector.c 55 | 56 | %parse_binary.c 57 | %parse_block.c 58 | %parse_string.c 59 | ] 60 | 61 | macx [libs %m] 62 | unix [libs %m] 63 | win32 [ 64 | lflags "/def:win32\urlan.def" 65 | ] 66 | ] 67 | 68 | exe %calc [ 69 | linux [lflags {-Wl,-z,origin,-rpath,'$$ORIGIN/'}] 70 | win32 [console] 71 | libs_from %. %urlan 72 | sources [ %../examples/calculator.c] 73 | ] 74 | -------------------------------------------------------------------------------- /urlan/unset.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2009 Karl Robillard 3 | 4 | This file is part of the Urlan datatype system. 5 | 6 | Urlan is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Urlan is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Urlan. If not, see . 18 | */ 19 | 20 | 21 | extern int unset_make( UThread*, const UCell* from, UCell* res ); 22 | extern void unset_copy( UThread*, const UCell* from, UCell* res ); 23 | extern int unset_compare( UThread*, const UCell* a, const UCell* b, int mode ); 24 | extern int unset_operate( UThread*, const UCell*, const UCell*, UCell*, int ); 25 | extern const UCell* 26 | unset_select( UThread*, const UCell* cell, const UCell* sel, 27 | UCell* tmp ); 28 | extern int unset_fromString( UThread*, const UBuffer* str, UCell* res ); 29 | extern void unset_toString( UThread*, const UCell* cell, UBuffer* str, 30 | int depth ); 31 | extern void unset_mark( UThread*, UCell* cell ); 32 | extern void unset_destroy( UBuffer* buf ); 33 | extern void unset_toShared( UCell* cell ); 34 | extern void unset_bind( UThread*, UCell* cell, const UBindTarget* bt ); 35 | 36 | #define unset_toText unset_toString 37 | #define unset_recycle 0 38 | #define unset_markBuf 0 39 | 40 | 41 | //EOF 42 | -------------------------------------------------------------------------------- /util/CBParser.c: -------------------------------------------------------------------------------- 1 | /* 2 | CBParser.c 3 | 4 | C Block Parser is a simple pattern matcher. 5 | 6 | Here is an example pattern rule set with three patterns for describing 7 | a cylinder: 8 | 9 | 'radius int!/decimal! | 'length int!/decimal! | 'close-ends 10 | */ 11 | 12 | 13 | #include 14 | #include "urlan.h" 15 | #include "urlan_atoms.h" 16 | #include "CBParser.h" 17 | 18 | 19 | /** 20 | Initialize CBParser given a range of input cells and a block of rules. 21 | 22 | ruleSet is a block of patterns to match, separated by '|'. 23 | Note that the order of rules is important. Earlier rules will match before 24 | later ones. 25 | */ 26 | void cbp_beginParse( UThread* ut, CBParser* cbp, 27 | const UCell* it, const UCell* end, UIndex ruleBlkN ) 28 | { 29 | const UBuffer* buf = ur_bufferE( ruleBlkN ); 30 | 31 | if( buf->used ) 32 | { 33 | cbp->_rules = buf->ptr.cell; 34 | cbp->_rulesEnd = buf->ptr.cell + buf->used; 35 | } 36 | else 37 | cbp->_rules = cbp->_rulesEnd = 0; 38 | 39 | cbp->_inputPos = it; 40 | cbp->_inputEnd = end; 41 | } 42 | 43 | 44 | /** 45 | Initialize CBParser given an input block and a set of rules in a C string. 46 | Returns index of rule block. 47 | */ 48 | UIndex cbp_beginParseStr( UThread* ut, CBParser* cbp, const UBuffer* input, 49 | const char* rules, int rulesLen ) 50 | { 51 | UCell tmp; 52 | UIndex ruleN = ur_tokenize( ut, rules, rules + rulesLen, &tmp ); 53 | assert( ruleN ); 54 | cbp_beginParse( ut, cbp, input->ptr.cell, input->ptr.cell + input->used, 55 | ruleN ); 56 | return ruleN; 57 | } 58 | 59 | 60 | /** 61 | Returns rule number of matched rule or -1 if no match was found. 62 | cbp->values points to the current position in the input block, or is set 63 | to zero when the end of input is reached. 64 | */ 65 | int cbp_matchRule( CBParser* cbp ) 66 | { 67 | const UCell* rit; 68 | const UCell* rend; 69 | const UCell* sit = cbp->_inputPos; 70 | const UCell* send = cbp->_inputEnd; 71 | int ruleN = 0; 72 | 73 | if( sit == send ) 74 | { 75 | cbp->values = 0; 76 | return -1; 77 | } 78 | 79 | cbp->values = sit; 80 | 81 | if( ! cbp->_rules ) 82 | return -1; 83 | 84 | rit = cbp->_rules; 85 | rend = cbp->_rulesEnd; 86 | 87 | next: 88 | 89 | if( ur_is(rit, UT_LITWORD) ) 90 | { 91 | if( ur_is(sit, UT_WORD) && (ur_atom(rit) == ur_atom(sit)) ) 92 | goto value_matched; 93 | } 94 | else if( ur_is(rit, UT_WORD) ) 95 | { 96 | UAtom atom = ur_atom(rit); 97 | if( atom < UT_BI_COUNT ) 98 | { 99 | if( atom == ur_type(sit) ) 100 | goto value_matched; 101 | } 102 | else if( atom == UR_ATOM_BAR ) 103 | goto rule_matched; 104 | } 105 | else if( ur_is(rit, UT_DATATYPE) ) 106 | { 107 | if( ur_isDatatype( sit, rit ) ) 108 | goto value_matched; 109 | } 110 | 111 | next_rule: 112 | 113 | sit = cbp->_inputPos; 114 | do 115 | { 116 | if( ur_is(rit, UT_WORD) && (ur_atom(rit) == UR_ATOM_BAR) ) 117 | { 118 | ++ruleN; 119 | if( ++rit == rend ) 120 | goto fail; 121 | goto next; 122 | } 123 | ++rit; 124 | } 125 | while( rit != rend ); 126 | 127 | fail: 128 | 129 | cbp->_inputPos = send; 130 | return -1; 131 | 132 | value_matched: 133 | 134 | ++rit; 135 | ++sit; 136 | if( rit == rend ) 137 | goto rule_matched; 138 | if( sit == send ) 139 | { 140 | if( ur_is(rit, UT_WORD) && (ur_atom(rit) == UR_ATOM_BAR) ) 141 | goto rule_matched; 142 | goto next_rule; 143 | } 144 | goto next; 145 | 146 | rule_matched: 147 | 148 | cbp->_inputPos = sit; 149 | return ruleN; 150 | } 151 | 152 | 153 | /*EOF*/ 154 | -------------------------------------------------------------------------------- /util/CBParser.h: -------------------------------------------------------------------------------- 1 | #ifndef CBPARSER_H 2 | #define CBPARSER_H 3 | 4 | 5 | typedef struct 6 | { 7 | const UCell* values; 8 | 9 | // Private 10 | const UCell* _rules; 11 | const UCell* _rulesEnd; 12 | const UCell* _inputPos; 13 | const UCell* _inputEnd; 14 | } 15 | CBParser; 16 | 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | extern void cbp_beginParse( UThread*, CBParser*, const UCell*, const UCell*, 23 | UIndex ruleBlkN ); 24 | extern UIndex cbp_beginParseStr( UThread*, CBParser*, const UBuffer* input, 25 | const char* rules, int rulesLen ); 26 | extern int cbp_matchRule( CBParser* ); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | 33 | #endif /* CBPARSER_H */ 34 | -------------------------------------------------------------------------------- /win32/redef.b: -------------------------------------------------------------------------------- 1 | n: 1 2 | parse read/text %boron.def [some [ 3 | tok: thru '@' :tok thru '^/' (prin tok print ++ n) 4 | ]] 5 | -------------------------------------------------------------------------------- /win32/win32console.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | #include 8 | #include 9 | using namespace std; 10 | #endif 11 | 12 | 13 | // maximum mumber of lines the output console should have 14 | #define MAX_CONSOLE_LINES 500 15 | 16 | 17 | void redirectIOToConsole() 18 | { 19 | int hConHandle; 20 | intptr_t stdHandle; 21 | CONSOLE_SCREEN_BUFFER_INFO coninfo; 22 | FILE* fp; 23 | 24 | // allocate a console for this app 25 | AllocConsole(); 26 | 27 | // set the screen buffer to be big enough to let us scroll text 28 | GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &coninfo ); 29 | 30 | coninfo.dwSize.Y = MAX_CONSOLE_LINES; 31 | SetConsoleScreenBufferSize( GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize ); 32 | 33 | // redirect unbuffered STDOUT to the console 34 | stdHandle = (intptr_t) GetStdHandle(STD_OUTPUT_HANDLE); 35 | hConHandle = _open_osfhandle(stdHandle, _O_TEXT); 36 | fp = _fdopen( hConHandle, "w" ); 37 | *stdout = *fp; 38 | setvbuf( stdout, NULL, _IONBF, 0 ); 39 | 40 | // redirect unbuffered STDIN to the console 41 | stdHandle = (intptr_t) GetStdHandle(STD_INPUT_HANDLE); 42 | hConHandle = _open_osfhandle(stdHandle, _O_TEXT); 43 | fp = _fdopen( hConHandle, "r" ); 44 | *stdin = *fp; 45 | setvbuf( stdin, NULL, _IONBF, 0 ); 46 | 47 | // redirect unbuffered STDERR to the console 48 | stdHandle = (intptr_t) GetStdHandle(STD_ERROR_HANDLE); 49 | hConHandle = _open_osfhandle(stdHandle, _O_TEXT); 50 | fp = _fdopen( hConHandle, "w" ); 51 | *stderr = *fp; 52 | setvbuf( stderr, NULL, _IONBF, 0 ); 53 | 54 | #ifdef __cplusplus 55 | // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog 56 | // point to console as well 57 | ios::sync_with_stdio(); 58 | #endif 59 | } 60 | 61 | 62 | /*EOF*/ 63 | --------------------------------------------------------------------------------