├── .gitmodules ├── .travis.yml ├── AUTHORS ├── COPYING ├── Dockerfile ├── README.md ├── ci_build.sh ├── codecov.yml ├── doc ├── b6b.1 └── meson.build ├── docs ├── code.css ├── dict.md ├── eval.md ├── evloop.md ├── exc.md ├── flow.md ├── fs.md ├── index.md ├── interp.md ├── linenoise.md ├── list.md ├── loop.md ├── meson.build ├── objects.md ├── proc.md ├── str.md ├── streams.md ├── thread.md ├── tutorial.md └── zlib.md ├── examples ├── httpd.b6b ├── install.sh └── meson.build ├── include ├── b6b.h ├── b6b │ ├── core.h │ ├── dict.h │ ├── ext.h │ ├── fdops.h │ ├── float.h │ ├── frame.h │ ├── hash.h │ ├── int.h │ ├── interp.h │ ├── list.h │ ├── obj.h │ ├── offload.h │ ├── proc.h │ ├── stdio.h │ ├── str.h │ ├── strm.h │ ├── syscall.h │ └── thread.h └── meson.build ├── meson.build ├── meson_options.txt ├── mkdocs.yml ├── src ├── b6b.c ├── b6b_co.c ├── b6b_core.c ├── b6b_dict.c ├── b6b_evloop.c ├── b6b_exc.c ├── b6b_fdops.c ├── b6b_ffi.c ├── b6b_file.c ├── b6b_float.c ├── b6b_frame.c ├── b6b_hash.c ├── b6b_int.c ├── b6b_interp.c ├── b6b_linenoise.c ├── b6b_list.c ├── b6b_logic.c ├── b6b_loop.c ├── b6b_math.c ├── b6b_obj.c ├── b6b_offload.c ├── b6b_path.c ├── b6b_poll.c ├── b6b_proc.c ├── b6b_rand.c ├── b6b_sem.c ├── b6b_sh.c ├── b6b_signal.c ├── b6b_socket.c ├── b6b_stdio.c ├── b6b_str.c ├── b6b_strm.c ├── b6b_syscall.c ├── b6b_thread.c ├── b6b_time.c ├── b6b_timer.c ├── b6b_zlib.c └── meson.build └── tests ├── b6b_test_add.c ├── b6b_test_and.c ├── b6b_test_b6b.c ├── b6b_test_bit_and.c ├── b6b_test_bit_or.c ├── b6b_test_bit_xor.c ├── b6b_test_break.c ├── b6b_test_call.c ├── b6b_test_cast.c ├── b6b_test_choice.c ├── b6b_test_co.c ├── b6b_test_compress.c ├── b6b_test_continue.c ├── b6b_test_decompress.c ├── b6b_test_deflate.c ├── b6b_test_dict_get.c ├── b6b_test_dict_set.c ├── b6b_test_dict_unset.c ├── b6b_test_div.c ├── b6b_test_echo.c ├── b6b_test_eq.c ├── b6b_test_eval.c ├── b6b_test_evloop_after.c ├── b6b_test_exit.c ├── b6b_test_export.c ├── b6b_test_ffi_buf.c ├── b6b_test_ffi_call.c ├── b6b_test_ffi_dlopen.c ├── b6b_test_ffi_func.c ├── b6b_test_ffi_memcpy.c ├── b6b_test_ffi_pack.c ├── b6b_test_ffi_unpack.c ├── b6b_test_ge.c ├── b6b_test_global.c ├── b6b_test_gt.c ├── b6b_test_gunzip.c ├── b6b_test_gzip.c ├── b6b_test_hash.c ├── b6b_test_if.c ├── b6b_test_inet_client.c ├── b6b_test_inet_server.c ├── b6b_test_inflate.c ├── b6b_test_istrue.c ├── b6b_test_le.c ├── b6b_test_list_append.c ├── b6b_test_list_extend.c ├── b6b_test_list_in.c ├── b6b_test_list_index.c ├── b6b_test_list_len.c ├── b6b_test_list_new.c ├── b6b_test_list_parse.c ├── b6b_test_list_pop.c ├── b6b_test_list_range.c ├── b6b_test_local.c ├── b6b_test_lt.c ├── b6b_test_map.c ├── b6b_test_mod.c ├── b6b_test_mul.c ├── b6b_test_ne.c ├── b6b_test_nop.c ├── b6b_test_not.c ├── b6b_test_nslookup.c ├── b6b_test_obj_decode.c ├── b6b_test_offload.c ├── b6b_test_open.c ├── b6b_test_or.c ├── b6b_test_poll.c ├── b6b_test_proc.c ├── b6b_test_randint.c ├── b6b_test_range.c ├── b6b_test_repr.c ├── b6b_test_return.c ├── b6b_test_sem.c ├── b6b_test_sh.c ├── b6b_test_signal.c ├── b6b_test_sleep.c ├── b6b_test_socket_endian.c ├── b6b_test_source.c ├── b6b_test_spawn.c ├── b6b_test_str_chr.c ├── b6b_test_str_expand.c ├── b6b_test_str_in.c ├── b6b_test_str_index.c ├── b6b_test_str_join.c ├── b6b_test_str_len.c ├── b6b_test_str_ltrim.c ├── b6b_test_str_ord.c ├── b6b_test_str_range.c ├── b6b_test_str_rtrim.c ├── b6b_test_str_split.c ├── b6b_test_strm.c ├── b6b_test_sub.c ├── b6b_test_throw.c ├── b6b_test_timer.c ├── b6b_test_try.c ├── b6b_test_un_client.c ├── b6b_test_un_pair.c ├── b6b_test_un_server.c ├── b6b_test_xor.c ├── data ├── empty.b6b ├── exit.b6b ├── multi.b6b └── shebang.b6b └── meson.build /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "subprojects/miniz"] 2 | path = subprojects/miniz 3 | url = https://github.com/richgel999/miniz 4 | [submodule "src/linenoise"] 5 | path = src/linenoise 6 | url = https://github.com/antirez/linenoise 7 | [submodule "subprojects/lolibc"] 8 | path = subprojects/lolibc 9 | url = http://github.com/dimkr/lolibc 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017, 2018, 2020 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | language: c 18 | dist: bionic 19 | 20 | env: 21 | global: 22 | # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created 23 | # via the "travis encrypt" command using the project repo's public key 24 | - secure: "aPMOOUYbnK4PpLnV/iKyct8eSsYVFgIiAXZywHITD1KB43K+qXW6YBofOSTIv7qLiWBnckO7K3QviZkUprWoY+OasZO8QEMCb2MKSod1njRManXZKsirMcQtzHsnxtnbECK3ArJpw048ItyxRRTe7NxP+swoC4wxO5ThItw6QFrpaH4BAqMAG4qp88vpUrui/pMj1KKVkwoZhUv4J6aRWHzPcp5nHcaGbnn9LAEBX89MgsgGtRKPizulAkdMp9iHbpd+bfKddgxLH/IBfOlt+bR3XbWYAmpyZSVF/ThABatQZKt7yngO45zUAUwoLbfY4AxUEXLBL1bYjA/97itpxy6ar0EDlogM8hOzGoIRAf/59pMfnmzVwmp5mHcUgCgNXMj3xMEjbZT8MypRpyxWpcjYrlu+EWpBKneh3MQo68R0EnZHF2bFpsN/+BHUqvLXLkRciEFa1hlD9EiB9TeJ6w9eLM6Fq3sERND7eRhl677ZV06Nt2uBugtvm7tSIJpHHbDauSeojUSHefTYBJgfn+/1QgZzyqp0zWmn5UTTawnuIM4ZRIehMPSsQXBFgBr1NFgdNcv/J2srBULoAt+YFcVJ9tEav8Bc/C08QpxC7bZ9MYOeB5RLcbj6wPXxsoE4q9Rbyo90yymFJFbg7v697648ldsjFG3Y/lyYAhkbBHo=" 25 | 26 | services: 27 | - docker 28 | 29 | before_install: 30 | - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt 31 | 32 | before_script: 33 | - pip3 install meson 34 | - 'echo {\"ipv6\": true, \"fixed-cidr-v6\": \"2001:db8:1::/64\"} | sudo tee /etc/docker/daemon.json' 35 | - sudo systemctl restart docker 36 | 37 | script: 38 | - docker run --rm --cap-add SYS_PTRACE -u `id -u`:`id -g` -w /b6b -v `pwd`:/b6b -v ~/.ccache:/tmp/.ccache -e CCACHE_DIR=/tmp/.ccache dimkr/b6b ./ci_build.sh 39 | 40 | after_success: 41 | - meson -Db_coverage=true -Doptimistic_alloc=false build-coverage 42 | - meson test -C build-coverage 43 | - bash <(curl -s https://codecov.io/bash) 44 | - meson build-coverity 45 | 46 | addons: 47 | apt: 48 | packages: 49 | - python3-pip 50 | - python3-setuptools 51 | - python3-wheel 52 | - ninja-build 53 | coverity_scan: 54 | project: 55 | name: "dimkr/b6b" 56 | description: "Build submitted via Travis CI" 57 | notification_email: dima@dimakrasner.com 58 | build_command_prepend: "meson build-coverity" 59 | build_command: "ninja -C build-coverity" 60 | branch_pattern: master 61 | 62 | cache: ccache 63 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Dima Krasner (dima@dimakrasner.com) -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2020 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | FROM dimkr/c-dev:clang 18 | 19 | RUN apt-get -qq update && apt-get -y --no-install-recommends install libffi-dev -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | _ __ _ 3 | | |__ / /_ | |__ 4 | | '_ \| '_ \| '_ \ 5 | | |_) | (_) | |_) | 6 | |_.__/ \___/|_.__/ 7 | ``` 8 | 9 | [![Build Status](https://travis-ci.org/dimkr/b6b.svg?branch=master)](https://travis-ci.org/dimkr/b6b) [![codecov](https://codecov.io/gh/dimkr/b6b/branch/master/graph/badge.svg)](https://codecov.io/gh/dimkr/b6b) [![Coverity](https://scan.coverity.com/projects/13321/badge.svg)](https://scan.coverity.com/projects/dimkr-b6b) [![Documentation Status](https://readthedocs.org/projects/b6b/badge/?version=latest)](http://b6b.readthedocs.io/en/latest/?badge=latest) 10 | 11 | ## Overview 12 | 13 | b6b is a simple, dynamic, procedural and reflective scripting language inspired by [Tcl](http://www.tcl.tk/), [Python](http://www.python.org/), Lisp and shell scripting. 14 | 15 | b6b wraps operating system mechanisms and interfaces such as sockets, files, shell commands and even signals with *a unified interface: the stream*. I/O events generated by streams of any kind can be managed through a **single** event loop. This way, b6b enables rapid development of lightweight, asynchronous and scalable, event-driven applications. 16 | 17 | b6b is **easy** and safe to embed into other projects: it provides a simple API which allows the creation of multiple, *independent* interpreter instances. In addition, b6b's garbage collection is **deterministic and predictable**, which contributes to easy debugging of memory issues and high reliability in use cases such as long-running daemons. Moreover, b6b uses only *one* OS thread: b6b threads are implemented on top of userspace fibers. Therefore, b6b is safe for inclusion in existing, complex, multi-threaded applications. 18 | 19 | b6b is named so in admiration of the *excellent* [Vincent Bach](http://www.bachbrass.com/) 6B trumpet mouthpiece, which produces compact, yet lively and expressive tone with a **strong, solid core**, that makes it a good choice for many playing situations. The name was chosen with hope that these qualities will also be attributed to the language and its implementation. 20 | 21 | ## Building 22 | 23 | b6b is built using [Meson](http://mesonbuild.com/). 24 | 25 | ```bash 26 | meson build 27 | ninja -C build install 28 | ``` 29 | 30 | ## Credits and Legal Information 31 | 32 | b6b is free and unencumbered software released under the terms of the [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0); see COPYING for the license text. For a list of its authors and contributors, see AUTHORS. 33 | 34 | The ASCII art logo at the top was made using [FIGlet](http://www.figlet.org/). 35 | -------------------------------------------------------------------------------- /ci_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | # This file is part of b6b. 4 | # 5 | # Copyright 2017, 2018, 2019, 2020 Dima Krasner 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | meson --default-library=static -Dwith_valgrind=true build-gcc 20 | CC="ccache clang" meson --unity=on --unity-size=100 -Dwith_valgrind=true build-clang 21 | meson --unity=on --unity-size=100 -Dwith_threads=false -Dwith_valgrind=true build-no-threads 22 | meson --unity=on --unity-size=100 -Dwith_threads=false -Dwith_miniz=false -Dwith_linenoise=false build-small 23 | meson --unity=on --unity-size=100 --optimization=3 -Db_sanitize=address build-asan 24 | 25 | ninja -C build-gcc 26 | meson configure --default-library=shared --unity=on --unity-size=100 build-gcc 27 | 28 | # build with GCC, clang, with GCC while thread support is disabled and a small build with all optional features off 29 | for i in build-gcc build-clang build-no-threads 30 | do 31 | ninja -C $i 32 | meson configure --optimization=3 -Dwith_miniz=false -Db_lto=true $i 33 | DESTDIR=dest ninja -C $i install 34 | done 35 | 36 | DESTDIR=dest ninja -C build-small install 37 | meson test -C build-small --no-rebuild --print-errorlogs 38 | 39 | # rebuild the small build with a static library 40 | meson configure -Ddefault_library=static build-small 41 | DESTDIR=dest-static ninja -C build-small install 42 | 43 | for i in build-gcc build-clang 44 | do 45 | # run all single-threaded tests 46 | meson test -C $i --no-rebuild --print-errorlogs --no-suite b6b:threaded 47 | 48 | # run multi-threaded tests on a single CPU and 5 additional times, to increase the chance of triggering race conditions 49 | meson test -C $i --no-rebuild --print-errorlogs --suite b6b:threaded --wrapper "taskset -c 0" 50 | meson test -C $i --no-rebuild --print-errorlogs --suite b6b:threaded --repeat 5 51 | done 52 | 53 | # run all tests except extremely slow ones with AddressSanitizer 54 | meson test -C build-asan --print-errorlogs --no-suite b6b:intensive -t 2 55 | 56 | # this is required to work around missing suppressions in glibc's symbol lookup 57 | export LD_BIND_NOW=1 58 | 59 | for i in build-gcc build-clang 60 | do 61 | # run all tests except extremely slow ones with Valgrind 62 | meson test -C $i --no-rebuild --print-errorlogs --no-suite b6b:slow --num-processes 1 -t 3 --wrapper "valgrind --leak-check=full --error-exitcode=1 --malloc-fill=1 --free-fill=1 --track-fds=yes" 63 | 64 | # run multi-threaded tests with Helgrind 65 | meson test -C $i --no-rebuild --print-errorlogs --suite b6b:threaded --no-suite b6b:intensive --num-processes 1 -t 3 --wrapper "valgrind --tool=helgrind --error-exitcode=1" 66 | meson test -C $i --no-rebuild --print-errorlogs --suite b6b:threaded --no-suite b6b:intensive --num-processes 1 -t 3 --wrapper "valgrind --tool=helgrind --error-exitcode=1 --fair-sched=yes" 67 | done 68 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017, 2018 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | coverage: 18 | range: 60..75 19 | 20 | ignore: 21 | - "tests/*" 22 | -------------------------------------------------------------------------------- /doc/b6b.1: -------------------------------------------------------------------------------- 1 | .TH b6b 1 2 | .SH NAME 3 | .B b6b 4 | \- b6b script interpreter 5 | .SH SYNOPSIS 6 | .B b6b 7 | [\fIoption\fR]... [\fIscript\fR] [\fIarg\fR]... 8 | .SH DESCRIPTION 9 | Runs \fIscript\fR or an interactive scripting shell. 10 | .SH OPTIONS 11 | .TP 12 | .B -c 13 | Run \fIscript\fR instead of running statements in the file at \fIscript\fR. 14 | .TP 15 | .B -e 16 | Propagate errors caught by \fBtry\fR blocks. 17 | .TP 18 | .B -u 19 | Disable buffering of input and output through standard input pipes. 20 | .TP 21 | .B -x 22 | Write each statement before it is executed. 23 | .SH AUTHOR 24 | Dima Krasner (dima@dimakrasner.com) 25 | -------------------------------------------------------------------------------- /doc/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | install_man('b6b.1') 18 | -------------------------------------------------------------------------------- /docs/code.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | .hljs-keyword, .hljs-literal, .hljs-built_in, .hljs-variable, .hljs-type { 20 | color: #333; 21 | font-weight: normal; 22 | } 23 | -------------------------------------------------------------------------------- /docs/dict.md: -------------------------------------------------------------------------------- 1 | {$dict.get {human 2 dog 4} snake 0} 2 | 3 | *dict.get* returns the value associated with a dictionary key. If the key is not found and a fallback value was specified, that value is returned. Otherwise, an error condition is triggered. 4 | 5 | {$dict.set $legs snake 0} 6 | 7 | *dict.set* associates a value with a dictionary key. If the key already exists, the value associated with it is replaced. 8 | 9 | {$dict.unset $legs snake} 10 | 11 | *dict.unset* removes a key from a dictionary. 12 | -------------------------------------------------------------------------------- /docs/eval.md: -------------------------------------------------------------------------------- 1 | {$eval {[$+ 4 5]}} 2 | 3 | *eval* evaluates an expression. 4 | 5 | {$repr {hello world}} 6 | 7 | *repr* returns a human-readable, printable representation of an object. 8 | 9 | {$call { 10 | {$stdout writeln a} 11 | {$stdout writeln b} 12 | }} 13 | 14 | *call* executes a list of statements. 15 | -------------------------------------------------------------------------------- /docs/evloop.md: -------------------------------------------------------------------------------- 1 | {$evloop} 2 | 3 | *evloop* creates a new event loop. 4 | -------------------------------------------------------------------------------- /docs/exc.md: -------------------------------------------------------------------------------- 1 | {$try { 2 | {$/ 4 0} 3 | } { 4 | {$stdout writeln $_} 5 | } { 6 | {$stdout writeln {}} 7 | }} 8 | 9 | *try* receives a list of statements and runs it. 10 | 11 | If an error condition is triggered, a second list of statements is executed. 12 | 13 | Finally, a third list of statements is executed. 14 | 15 | **If only one lists of statements has been specified**, error conditions triggered by the first list of statements are silenced. 16 | -------------------------------------------------------------------------------- /docs/flow.md: -------------------------------------------------------------------------------- 1 | {$if [$== 4 3] { 2 | {$stdout writeln a} 3 | } { 4 | {$stdout writeln b} 5 | }} 6 | 7 | *if* executes a list of statements if a condition is true. Otherwise, if the condition is false and a second list of statements was specified, it is executed instead. 8 | 9 | {$return} 10 | {$return 5} 11 | 12 | *return* stops the execution of the currently running procedure and sets its return value. If no return value is specified, the procedure returns an empty string. 13 | 14 | {$continue} 15 | 16 | *continue* stops the current iteration of a loop. 17 | 18 | {$break} 19 | 20 | *break* stops the execution of a loop. 21 | 22 | {$throw} 23 | {$throw {error message}} 24 | 25 | *throw* triggers an error condition. Error conditions are propagated until caught by a *try* block, or until they reach the global scope. In the latter case, the script exits immediately with a non-zero exit code. 26 | 27 | {$exit} 28 | {$exit 1} 29 | 30 | *exit* stops the execution of the script. 31 | 32 | {$yield} 33 | 34 | *yield* switches to another thread, if there is one. 35 | 36 | *yield* should be called only by threads that repeatedly check for a certain condition, which is guaranteed to be false unless another thread performs some action. For example, a thread that runs a loop which removes an item from a list and performs a certain action on it, should call *yield* every time the list is empty, since no item will be added to the list until another thread has a chance to do so. The *yield* call improves efficiency because it allows the polling thread to postpone the next iteration of its polling loop, when the polled condition is guaranteed to be false if polled again immediately. 37 | -------------------------------------------------------------------------------- /docs/fs.md: -------------------------------------------------------------------------------- 1 | {$realpath .} 2 | 3 | *realpath* returns the absolute path of a file. 4 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | **b6b** is a simple, dynamic, procedural and reflective scripting language inspired by [Tcl](http://www.tcl.tk/), [CPython](http://www.python.org/), Lisp, shell scripting and various ideas or views in western philosophy. 4 | 5 | **b6b** follows five design principles: 6 | 7 | 1. Everything is an object 8 | 2. Every object is a string 9 | 3. Every object is a procedure 10 | 4. Every statement is a procedure call 11 | 5. Transparent parallelism 12 | 13 | # Use Cases 14 | 15 | **b6b** is especially useful as: 16 | 17 | 1. A more powerful, yet simple alternative to shell scripting 18 | 2. A thin layer above C and system calls, which provides exceptions, garbage collection, easy parallelism and a dynamic type system 19 | 3. An embedded interpreter in a big software project 20 | 4. An extremely lightweight scripting language, for rapid development of fault-tolerant embedded software 21 | 22 | # Design 23 | 24 | **b6b** is implemented as a library, *libb6b*. This library exposes a rich API that allows applications to embed **b6b**. For example, **b6b** also includes an interactive interpreter application built on top of *libb6b*. 25 | 26 | Each **b6b** interpreter uses two kinds of threads: 27 | 28 | 1. The "interpreter thread", the thread which calls the *libb6b* API to create an interpreter instance and run a script through it 29 | 2. A pool of "offloading threads", spawned during the initialization of the interpreter 30 | 31 | **b6b** implements multi-threading using fibers (or, green threads) while a simple, round-robin scheduler relies on voluntary preemption to prevent starvation. **All these threads run on a single native thread: the interpreter thread.** 32 | 33 | Therefore, **b6b**'s implementation of multi-threading does not benefit from SMP, but it is lock-free, lightweight, safe (for example, safe for embedding in heavily multi-threaded applications) and simple, which are far more important design considerations for the uses cases **b6b** shines at. 34 | 35 | As many system calls are non-blocking by nature, most operations in **b6b** are non-blocking as well. However, under multi-threaded scenarios, the interpreter thread **delegates blocking or slow operations** (such as compression or file creation) to an offloading thread, while the interpreter thread continues to run other fibers. 36 | 37 | Since multiple script threads may perform blocking operations **at the same time** and the number of offloading threads is smal, this offloading mechanism is mostly useful in situations such as an event-based server, where the only blocking operation is waiting for more events, while previous events are dealt with in coroutines. 38 | 39 | # License 40 | 41 | **b6b** is free and unencumbered software released under the terms of the [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0); see *COPYING* for the license text. 42 | 43 | For a list of its authors and contributors, see *AUTHORS*. 44 | -------------------------------------------------------------------------------- /docs/interp.md: -------------------------------------------------------------------------------- 1 | {[$b6b {a b}] call {{$stdout writeln $@}}} 2 | 3 | **b6b** creates a new interpreter with given global scope parameters. The interpreter object provides a 'call' method, which runs a list of statements. 4 | -------------------------------------------------------------------------------- /docs/linenoise.md: -------------------------------------------------------------------------------- 1 | {$linenoise.read {> }} 2 | 3 | *linenoise.read* displays a prompt and reads a line of user input. 4 | 5 | {$linenoise.add $line} 6 | 7 | *linenoise.add* adds a line to the history of *linenoise.read*. 8 | 9 | {$linenoise.save history.txt} 10 | 11 | *linenoise.save* saves the history of *linenoise.read* to a file. 12 | 13 | {$linenoise.load history.txt} 14 | 15 | *linenoise.load* loads the history of *linenoise.read* from a file. 16 | -------------------------------------------------------------------------------- /docs/list.md: -------------------------------------------------------------------------------- 1 | {$list.new a b c {d e}} 2 | 3 | *list.new* creates a new list containing its arguments. 4 | 5 | {$list.len {a b c}} 6 | 7 | *list.len* returns the length of a list. 8 | 9 | {$list.append $list f} 10 | 11 | *list.copy* copies a list. 12 | 13 | {$list.copy $list} 14 | 15 | *list.append* appends an item to a list. 16 | 17 | {$list.extend $list {f g}} 18 | 19 | *list.extend* adds all items of a list to an existing list. 20 | 21 | {$list.index {a b c} 0} 22 | 23 | *list.index* returns the list item at a given index. 24 | 25 | {$list.range {a b c d e f} 2 4} 26 | 27 | *list.range* returns the items of a list, between two indices. 28 | 29 | {$list.in a {a b c}} 30 | 31 | *list.in* determines whether an item belongs to a list. 32 | 33 | {$list.pop $list 1} 34 | 35 | *list.pop* removes the item at a given index from a list. 36 | 37 | {$choice {a b c}} 38 | 39 | *choice* returns a pseudo-random list item. 40 | -------------------------------------------------------------------------------- /docs/loop.md: -------------------------------------------------------------------------------- 1 | {$map {a b} [$range 0 9] { 2 | {$+ $a $b} 3 | }} 4 | 5 | *map* receives a list of object names and a list, then repeatedly runs a list of statements with local named objects that specify the next items of the list. The return value of *map* is a list of values returned by all iterations of the loop. 6 | 7 | If an iteration of the loop calls *continue*, its return value is ignored. 8 | 9 | {$loop { 10 | {$stdout writeln a} 11 | }} 12 | 13 | *loop* repeatedly runs a list of statements. 14 | 15 | {$range 1 5} 16 | 17 | *range* returns a list of all whole numbers in a given range. 18 | -------------------------------------------------------------------------------- /docs/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | foreach md: ['dict.md', 'eval.md', 'evloop.md', 'exc.md', 'flow.md', 'fs.md', 'index.md', 'interp.md', 'linenoise.md', 'list.md', 'loop.md', 'objects.md', 'proc.md', 'str.md', 'streams.md', 'thread.md', 'tutorial.md', 'zlib.md'] 18 | install_data(md, install_dir: docdir) 19 | endforeach 20 | -------------------------------------------------------------------------------- /docs/objects.md: -------------------------------------------------------------------------------- 1 | {$local number 5} 2 | 3 | *local* assigns a name to object, in the local scope. 4 | 5 | {$global number 5} 6 | 7 | *global* assigns a name to object, in the global scope. 8 | 9 | {$export number} 10 | {$export number 5} 11 | 12 | *export* assigns a name to object, in the calling scope. If no object is specified, *export* uses the object with the same name in the local scope. 13 | -------------------------------------------------------------------------------- /docs/proc.md: -------------------------------------------------------------------------------- 1 | {$proc append_stuff { 2 | {$list.append $. c} 3 | {$return $.} 4 | } {a b}} 5 | 6 | *proc* creates a new procedure. If optional private data is specified, it is named *.* and preserved across procedure calls. 7 | -------------------------------------------------------------------------------- /docs/str.md: -------------------------------------------------------------------------------- 1 | {$str.len abcd} 2 | 3 | *str.len* returns the length of a string. 4 | 5 | {$str.index abcd 2} 6 | 7 | *str.index* returns the character at a given index within a string. 8 | 9 | {$str.range abcd 0 2} 10 | 11 | *str.range* returns a substring, identified by two indexes within a string. 12 | 13 | {$str.join , {a b c}} 14 | 15 | *str.join* joins a list of strings, with a delimiter. 16 | 17 | {$str.split a,b,c ,} 18 | 19 | *str.split* splits a string, by a delimiter. 20 | 21 | {$str.ord a} 22 | 23 | *str.ord* returns the numeric value of a character. 24 | 25 | {$str.chr 0x61} 26 | 27 | *str.chr* returns the character associated with a given numeric value. 28 | 29 | {$str.expand {a\tb}} 30 | 31 | *str.expand* expands escape sequences in a string. 32 | 33 | {$str.in bc abcd} 34 | 35 | *str.in* determines whether a string is a subset of another string. 36 | 37 | {$rtrim {a b }} 38 | 39 | *rtrim* removes trailing whitespace from a string. 40 | 41 | {$ltrim {a b }} 42 | 43 | *ltrim* removes leading whitespace from a string. 44 | -------------------------------------------------------------------------------- /docs/streams.md: -------------------------------------------------------------------------------- 1 | {$open file.txt rb} 2 | 3 | *open* creates a file stream. The second argument may be *r* (read), *w* (create and write) or *a* (create or append), but can be suffixed with *+* (read and write), *b* (to enable full buffering) or *u* (to disable buffering). 4 | 5 | **If no access mode is specified**, the default is *r* (line-buffered, read-only access). 6 | 7 | {$sem 5} 8 | 9 | *sem* creates a semaphore stream. 10 | 11 | {$sh {ls -la}} 12 | 13 | *sh* creates pipe streams, attached to the standard I/O pipes of a shell command. 14 | 15 | {$signal $SIGTERM} 16 | 17 | *signal* creates a signal stream. 18 | 19 | {$timer 5.3} 20 | 21 | *timer* creates a timer stream. 22 | 23 | {$inet.client tcp 10.0.0.138 80} 24 | 25 | *inet.client* creates a TCP or UDP client stream. 26 | 27 | {$inet.server tcp 0.0.0.0 8000 5} 28 | 29 | *inet.server* creates a TCP or UDP server stream. 30 | 31 | {$un.client dgram /tmp/server} 32 | 33 | *un.client* creates a Unix socket client stream. 34 | 35 | {$un.server dgram /tmp/server 5} 36 | 37 | *un.server* creates a Unix socket server stream. 38 | 39 | {$un.pair stream} 40 | 41 | *un.pair* creates a pair of connected Unix socket streams. 42 | -------------------------------------------------------------------------------- /docs/thread.md: -------------------------------------------------------------------------------- 1 | {$spawn { 2 | {$loop { 3 | {$stdout writeln a} 4 | }} 5 | }} 6 | 7 | *spawn* executes a list of statements in a new thread. 8 | 9 | {$co { 10 | {$map i [$range 1 20] { 11 | {$stdout writeln $i} 12 | }} 13 | }} 14 | 15 | *co* puts a list of statements in a queue. If the queue is empty, *co* starts a thread that calls each item in the queue, then exits. 16 | 17 | **The statements must not block.** 18 | -------------------------------------------------------------------------------- /docs/zlib.md: -------------------------------------------------------------------------------- 1 | {$deflate [[$open file.txt ru] read] 9} 2 | 3 | *deflate* compresses a string. 4 | 5 | {$inflate [$deflate [[$open file.txt ru] read]]} 6 | 7 | *inflate* decompresses a string compressed using *deflate*. 8 | -------------------------------------------------------------------------------- /examples/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of b6b. 4 | # 5 | # Copyright 2017 Dima Krasner 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | install -m 755 "$MESON_SOURCE_ROOT/examples/httpd.b6b" \ 20 | "$DESTDIR/$MESON_INSTALL_PREFIX/bin/b6b-httpd" 21 | -------------------------------------------------------------------------------- /examples/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | if get_option('with_linenoise') 18 | meson.add_install_script('install.sh') 19 | endif 20 | -------------------------------------------------------------------------------- /include/b6b.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifndef _B6B_H_INCLUDED 20 | # define _B6B_H_INCLUDED 21 | 22 | # include 23 | # include 24 | # include 25 | # include 26 | # include 27 | # include 28 | # include 29 | # include 30 | # include 31 | # include 32 | # ifdef B6B_HAVE_OFFLOAD_THREAD 33 | # include 34 | # endif 35 | # include 36 | # include 37 | # include 38 | # include 39 | # include 40 | # include 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/b6b/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #define b6b_likely(cond) __builtin_expect(!!(cond), 1) 20 | #define b6b_unlikely(cond) __builtin_expect(!!(cond), 0) 21 | 22 | /* if malloc() can return a non-NULL pointer when out of memory and writing to 23 | * that address will crash the process, checking the return value of malloc() is 24 | * useless; if malloc() gets to return NULL, we let the process crash due to 25 | * dereference of NULL */ 26 | #ifdef B6B_OPTIMISTIC_ALLOC 27 | # define b6b_allocated(cond) 1 28 | #else 29 | # define b6b_allocated(cond) b6b_likely(cond) 30 | #endif 31 | 32 | /** 33 | * @enum b6b_res 34 | * Procedure status codes, which control the flow of execution 35 | */ 36 | enum b6b_res { 37 | B6B_OK, /**< Success */ 38 | B6B_ERR, /**< Error: the next statement shall not be executed */ 39 | B6B_YIELD, /**< Switch to another thread of execution */ 40 | B6B_BREAK, /**< Success, but the next statement shall not be executed */ 41 | B6B_CONT, /**< Jump back to the first statement in the loop body */ 42 | B6B_RET, /**< Stop execution of statements in the current block and 43 | stop the caller with B6B_BREAK */ 44 | B6B_EXIT /**< Exit the script */ 45 | }; 46 | -------------------------------------------------------------------------------- /include/b6b/dict.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #define b6b_dict_new b6b_list_new 20 | int b6b_dict_get(struct b6b_obj *d, struct b6b_obj *k, struct b6b_obj **v); 21 | int b6b_dict_set(struct b6b_obj *d, struct b6b_obj *k, struct b6b_obj *v); 22 | int b6b_dict_unset(struct b6b_obj *d, struct b6b_obj *k); 23 | -------------------------------------------------------------------------------- /include/b6b/ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /* 20 | * these two structs are not packed, because we want them natively aligned - 21 | * otherwise, on some architectures, the linker adds padding between structs and 22 | * we cannot scan the sections containing them as arrays 23 | */ 24 | 25 | struct b6b_ext_obj { 26 | const char *name; 27 | b6b_procf proc; 28 | b6b_delf del; 29 | union { 30 | const char *s; 31 | b6b_int i; 32 | } val; 33 | uint8_t type; 34 | }; 35 | 36 | struct b6b_ext { 37 | const struct b6b_ext_obj *os; 38 | uint8_t n; 39 | }; 40 | 41 | #define __b6b_ext_name(os) b6b_ext_ ##os 42 | #define __b6b_ext(_os) \ 43 | struct b6b_ext __attribute__((section("_b6b_ext"), used)) \ 44 | __b6b_ext_name(_os) = { \ 45 | .os = _os, \ 46 | .n = sizeof(_os) / sizeof(_os[0]) \ 47 | } 48 | 49 | extern const struct b6b_ext __start__b6b_ext[]; 50 | #define b6b_ext_first __start__b6b_ext 51 | extern const struct b6b_ext __stop__b6b_ext[]; 52 | #define b6b_ext_last __stop__b6b_ext 53 | 54 | typedef int (*b6b_initf)(struct b6b_interp *); 55 | 56 | #define __b6b_initp_name(_init) __ ##_init 57 | #define __b6b_init(_func) \ 58 | __attribute__((section("_b6b_init"), used)) b6b_initf __b6b_initp_name(_func) = _func 59 | 60 | extern b6b_initf __start__b6b_init[]; 61 | #define b6b_init_first __start__b6b_init 62 | extern b6b_initf __stop__b6b_init[]; 63 | #define b6b_init_last __stop__b6b_init 64 | -------------------------------------------------------------------------------- /include/b6b/fdops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | ssize_t b6b_fd_peeksz(struct b6b_interp *interp, void *priv); 20 | ssize_t b6b_fd_on_read(struct b6b_interp *interp, 21 | const ssize_t out, 22 | int *eof); 23 | ssize_t b6b_fd_read(struct b6b_interp *interp, 24 | void *priv, 25 | unsigned char *buf, 26 | const size_t len, 27 | int *eof, 28 | int *again); 29 | ssize_t b6b_fd_recv(struct b6b_interp *interp, 30 | void *priv, 31 | unsigned char *buf, 32 | const size_t len, 33 | int *eof, 34 | int *again); 35 | 36 | ssize_t b6b_fd_write(struct b6b_interp *interp, 37 | void *priv, 38 | const unsigned char *buf, 39 | const size_t len); 40 | ssize_t b6b_fd_send(struct b6b_interp *interp, 41 | void *priv, 42 | const unsigned char *buf, 43 | const size_t len); 44 | 45 | int b6b_fd_fd(void *priv); 46 | void b6b_fd_close(void *priv); 47 | 48 | ssize_t b6b_fd_peeksz_u64(struct b6b_interp *interp, void *priv); 49 | ssize_t b6b_fd_read_u64(struct b6b_interp *interp, 50 | void *priv, 51 | unsigned char *buf, 52 | const size_t len, 53 | int *eof, 54 | int *again); 55 | ssize_t b6b_fd_write_u64(struct b6b_interp *interp, 56 | void *priv, 57 | const unsigned char *buf, 58 | const size_t len); 59 | -------------------------------------------------------------------------------- /include/b6b/float.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | struct b6b_obj *b6b_float_new(const b6b_float f); 20 | int b6b_as_float(struct b6b_obj *o); 21 | -------------------------------------------------------------------------------- /include/b6b/frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #define B6B_MAX_NESTING 64 20 | 21 | struct b6b_frame { 22 | struct b6b_obj *locals; 23 | struct b6b_obj *args; 24 | struct b6b_frame *prev; 25 | }; 26 | 27 | struct b6b_frame *b6b_frame_new(struct b6b_frame *prev); 28 | int b6b_frame_set_args(struct b6b_interp *interp, 29 | struct b6b_frame *f, 30 | struct b6b_obj *args); 31 | void b6b_frame_destroy(struct b6b_frame *f); 32 | 33 | struct b6b_frame *b6b_frame_push(struct b6b_interp *interp); 34 | void b6b_frame_pop(struct b6b_interp *interp); 35 | -------------------------------------------------------------------------------- /include/b6b/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | static inline uint32_t b6b_hash_init(void) 22 | { 23 | return 0; 24 | } 25 | 26 | static inline void b6b_hash_update(uint32_t *hash, 27 | const unsigned char *buf, 28 | const size_t len) 29 | { 30 | size_t i; 31 | 32 | for (i = 0; i < len; ++i) { 33 | *hash += buf[i] + (*hash << 10); 34 | *hash ^= (*hash >> 6); 35 | } 36 | } 37 | 38 | static inline void b6b_hash_finish(uint32_t *hash) 39 | { 40 | *hash += (*hash << 3); 41 | *hash ^= (*hash >> 11); 42 | *hash += (*hash << 15); 43 | } 44 | 45 | __attribute__((nonnull(1))) 46 | uint32_t b6b_hash(const unsigned char *buf, const size_t len); 47 | -------------------------------------------------------------------------------- /include/b6b/int.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | struct b6b_obj *b6b_int_new(const b6b_int i); 20 | int b6b_as_int(struct b6b_obj *o); 21 | -------------------------------------------------------------------------------- /include/b6b/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | struct b6b_obj *b6b_list_new(void); 22 | struct b6b_obj *b6b_list_build(struct b6b_obj *o, ...); 23 | struct b6b_obj *b6b_list_from(const char *s, const size_t len); 24 | int b6b_as_list(struct b6b_obj *o); 25 | 26 | void b6b_list_flush(struct b6b_obj *l); 27 | int b6b_list_add(struct b6b_obj *l, struct b6b_obj *o); 28 | int b6b_list_extend(struct b6b_obj *l, struct b6b_obj *o); 29 | struct b6b_obj *b6b_list_pop(struct b6b_obj *l, struct b6b_litem *li); 30 | struct b6b_obj *b6b_list_pop(struct b6b_obj *l, struct b6b_litem *li); 31 | unsigned int b6b_list_parse(struct b6b_obj *l, const char *fmt, ...); 32 | unsigned int b6b_list_vparse(struct b6b_obj *l, const char *fmt, va_list ap); 33 | -------------------------------------------------------------------------------- /include/b6b/offload.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017, 2020 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #ifdef B6B_HAVE_VALGRIND 23 | # include 24 | #endif 25 | 26 | /* simple state machine: b6b_offload_thread.state is B6B_OFFLOAD_IDLE when no 27 | * offload is running, transitions to B6B_OFFLOAD_RUNNING before preparations 28 | * for execution and to B6B_OFFLOAD_DONE when the offload returns */ 29 | enum b6b_offload_state { 30 | B6B_OFFLOAD_INIT, 31 | B6B_OFFLOAD_UP, 32 | B6B_OFFLOAD_IDLE, 33 | B6B_OFFLOAD_RUNNING, 34 | B6B_OFFLOAD_DONE 35 | }; 36 | 37 | struct b6b_offload_thread { 38 | sigset_t mask; 39 | sigset_t wmask; 40 | pthread_t tid; 41 | pthread_t main; 42 | void (*fn)(void *); 43 | void *arg; 44 | atomic_int state; 45 | int sig; 46 | }; 47 | 48 | static inline void b6b_offload_thread_init(struct b6b_offload_thread *t) 49 | { 50 | atomic_store(&t->state, B6B_OFFLOAD_INIT); 51 | 52 | #ifdef B6B_HAVE_VALGRIND 53 | /* all operations on t->state are atomic */ 54 | VALGRIND_HG_DISABLE_CHECKING(&t->state, sizeof(t->state)); 55 | 56 | /* stores are guarded by t->state and loads happen only after delivery of 57 | * t->sig */ 58 | VALGRIND_HG_DISABLE_CHECKING(&t->fn, sizeof(t->fn)); 59 | VALGRIND_HG_DISABLE_CHECKING(&t->arg, sizeof(t->arg)); 60 | #endif 61 | } 62 | 63 | int b6b_offload_thread_start(struct b6b_offload_thread *t, const int id); 64 | void b6b_offload_thread_stop(struct b6b_offload_thread *t); 65 | 66 | /* these two macros are used to poll the state machine */ 67 | #define b6b_offload_ready(t) (atomic_load(&(t)->state) == B6B_OFFLOAD_IDLE) 68 | #define b6b_offload_done(t) (atomic_load(&(t)->state) == B6B_OFFLOAD_DONE) 69 | 70 | int b6b_offload_start(struct b6b_offload_thread *t, 71 | void (*fn)(void *), 72 | void *arg); 73 | 74 | int b6b_offload_finish(struct b6b_offload_thread *t); 75 | -------------------------------------------------------------------------------- /include/b6b/proc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | unsigned int b6b_proc_get_args(struct b6b_interp *interp, 20 | struct b6b_obj *l, 21 | const char *fmt, 22 | ...); 23 | -------------------------------------------------------------------------------- /include/b6b/stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | struct b6b_stdio_strm { 22 | FILE *fp; 23 | struct b6b_interp *interp; 24 | void *buf; 25 | int fd; 26 | }; 27 | 28 | void b6b_stdio_do_fclose(void *arg); 29 | 30 | ssize_t b6b_stdio_peeksz(struct b6b_interp *interp, void *priv); 31 | ssize_t b6b_stdio_read(struct b6b_interp *interp, 32 | void *priv, 33 | unsigned char *buf, 34 | const size_t len, 35 | int *eof, 36 | int *again); 37 | ssize_t b6b_stdio_write(struct b6b_interp *interp, 38 | void *priv, 39 | const unsigned char *buf, 40 | const size_t len); 41 | int b6b_stdio_fd(void *priv); 42 | void b6b_stdio_close(void *priv); 43 | -------------------------------------------------------------------------------- /include/b6b/str.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | char *b6b_strndup(const char *s, const size_t len); 23 | 24 | __attribute__((nonnull(1))) 25 | struct b6b_obj *b6b_str_new(char *s, const size_t len); 26 | 27 | static inline struct b6b_obj *b6b_str_init(struct b6b_obj *o, 28 | char *s, 29 | const size_t len) 30 | { 31 | o->s = s; 32 | o->slen = len; 33 | o->flags = B6B_TYPE_STR; 34 | o->refc = 1; 35 | return o; 36 | } 37 | 38 | __attribute__((nonnull(1))) 39 | struct b6b_obj *b6b_str_copy(const char *s, const size_t len); 40 | struct b6b_obj *b6b_str_vfmt(const char *fmt, va_list ap); 41 | 42 | __attribute__((format(printf, 1, 2))) 43 | struct b6b_obj *b6b_str_fmt(const char *fmt, ...); 44 | 45 | int b6b_as_str(struct b6b_obj *o); 46 | 47 | struct b6b_obj *b6b_str_decode(const char *s, size_t len); 48 | 49 | static inline int b6b_isspace(const char c) 50 | { 51 | return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')); 52 | } 53 | -------------------------------------------------------------------------------- /include/b6b/strm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #define B6B_STRM_BUFSIZ (64 * 1024) 20 | 21 | struct b6b_strm; 22 | 23 | struct b6b_strm_ops { 24 | ssize_t (*peeksz)(struct b6b_interp *, void *); 25 | ssize_t (*read)(struct b6b_interp *, 26 | void *, 27 | unsigned char *, 28 | const size_t, 29 | int *, 30 | int *); 31 | ssize_t (*write)(struct b6b_interp *, 32 | void *, 33 | const unsigned char *, 34 | const size_t); 35 | struct b6b_obj *(*peer)(struct b6b_interp *, void *); 36 | int (*accept)(struct b6b_interp *, void *, struct b6b_obj **); 37 | int (*fd)(void *); 38 | void (*close)(void *); 39 | }; 40 | 41 | enum b6b_strm_flags { 42 | B6B_STRM_CLOSED = 1, 43 | B6B_STRM_EOF = 1 << 1 44 | }; 45 | 46 | struct b6b_strm { 47 | const struct b6b_strm_ops *ops; 48 | void *priv; 49 | uint8_t flags; 50 | }; 51 | 52 | struct b6b_obj *b6b_strm_copy(struct b6b_interp *interp, 53 | const struct b6b_strm_ops *ops, 54 | void *priv, 55 | const char *s, 56 | const size_t len); 57 | struct b6b_obj *b6b_strm_fmt(struct b6b_interp *interp, 58 | const struct b6b_strm_ops *ops, 59 | void *priv, 60 | const char *type); 61 | -------------------------------------------------------------------------------- /include/b6b/syscall.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | int b6b_syscall(struct b6b_interp *interp, 20 | int *ret, 21 | const long nr, 22 | ...); 23 | -------------------------------------------------------------------------------- /include/b6b/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #ifdef B6B_HAVE_THREADS 20 | 21 | # include 22 | 23 | # include 24 | 25 | enum b6b_thread_flags { 26 | B6B_THREAD_BG = 1, 27 | B6B_THREAD_FG = 1 << 1, 28 | B6B_THREAD_DONE = 1 << 2, 29 | B6B_THREAD_BLOCKED = 1 << 3 30 | }; 31 | 32 | TAILQ_HEAD(b6b_threads, b6b_thread); 33 | struct b6b_thread { 34 | ucontext_t ucp; 35 | void *stack; 36 | struct b6b_frame *curr; 37 | struct b6b_obj *fn; 38 | struct b6b_obj *_; 39 | TAILQ_ENTRY(b6b_thread) ents; 40 | # ifdef B6B_HAVE_VALGRIND 41 | int sid; 42 | # endif 43 | unsigned int depth; 44 | uint8_t flags; 45 | }; 46 | 47 | # define b6b_thread_init(h) TAILQ_INIT(h) 48 | # define b6b_thread_first(h) TAILQ_FIRST(h) 49 | # define b6b_thread_next(t) TAILQ_NEXT(t, ents) 50 | # define b6b_thread_foreach(h, t) TAILQ_FOREACH(t, h, ents) 51 | # define b6b_thread_foreach_safe(h, t, tt) TAILQ_FOREACH_SAFE(t, h, ents, tt) 52 | 53 | struct b6b_thread *b6b_thread_new(struct b6b_threads *threads, 54 | struct b6b_obj *fn, 55 | struct b6b_frame *global, 56 | struct b6b_obj *null, 57 | void (*routine)(int, int, int, int), 58 | void *priv, 59 | const size_t stksiz); 60 | 61 | static inline void b6b_thread_push(struct b6b_threads *threads, 62 | struct b6b_thread *t, 63 | struct b6b_thread *fg) 64 | { 65 | /* if this isn't the first thread, we want to let it run immediately */ 66 | if (fg) 67 | TAILQ_INSERT_AFTER(threads, fg, t, ents); 68 | else 69 | TAILQ_INSERT_TAIL(threads, t, ents); 70 | } 71 | 72 | void b6b_thread_pop(struct b6b_threads *ts, struct b6b_thread *t); 73 | void b6b_thread_swap(struct b6b_thread *bg, struct b6b_thread *fg); 74 | 75 | # define b6b_thread_block(t) \ 76 | (t)->flags |= B6B_THREAD_BLOCKED 77 | # define b6b_thread_unblock(t) \ 78 | (t)->flags &= ~B6B_THREAD_BLOCKED 79 | # define b6b_thread_blocked(t) \ 80 | ((t)->flags & B6B_THREAD_BLOCKED) 81 | 82 | #else 83 | 84 | struct b6b_thread { 85 | struct b6b_obj *_; 86 | struct b6b_frame *curr; 87 | unsigned int depth; 88 | }; 89 | 90 | #endif 91 | 92 | struct b6b_thread *b6b_thread_self(struct b6b_frame *global, 93 | struct b6b_obj *null); 94 | void b6b_thread_destroy(struct b6b_thread *t); 95 | -------------------------------------------------------------------------------- /include/meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017, 2020 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | b6b_includes = [lolibc.get_variable('lolibc_includes'), include_directories('.')] 18 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017, 2020 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | project('b6b', 'c', version: '0.0.1', license: 'Apache-2.0') 18 | 19 | docdir = join_paths(get_option('datadir'), 'doc', 'b6b') 20 | add_project_arguments('-Wno-overlength-strings', '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', 21 | language: 'c') 22 | 23 | lolibc = subproject('lolibc') 24 | 25 | subdir('include') 26 | subdir('src') 27 | subdir('tests') 28 | subdir('doc') 29 | subdir('docs') 30 | subdir('examples') 31 | 32 | install_data('README.md', 'AUTHORS', 'COPYING', 33 | install_dir: join_paths(get_option('datadir'), 'doc', 'b6b')) 34 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | # This file is part of b6b. 2 | # 3 | # Copyright 2017 Dima Krasner 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | option('with_threads', type: 'boolean') 18 | option('with_miniz', type: 'boolean') 19 | option('with_linenoise', type: 'boolean') 20 | option('with_valgrind', type: 'boolean', value: false) 21 | option('optimistic_alloc', type: 'boolean') 22 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: b6b 2 | repo_url: https://github.com/dimkr/b6b 3 | pages: 4 | - Home: index.md 5 | - Tutorial: tutorial.md 6 | - Standard Library: 7 | - Interpreters: interp.md 8 | - Objects: objects.md 9 | - Flow Control: flow.md 10 | - Strings: str.md 11 | - Lists: list.md 12 | - Dictionaries: dict.md 13 | - Loops: loop.md 14 | - Procedures: proc.md 15 | - Exceptions: exc.md 16 | - Evaluation: eval.md 17 | - Threads: thread.md 18 | - I/O: 19 | - Streams: streams.md 20 | - Event Loops: evloop.md 21 | - File System: fs.md 22 | - Bindings: 23 | - zlib: zlib.md 24 | - linenoise: linenoise.md 25 | theme: readthedocs 26 | extra_css: [code.css] 27 | -------------------------------------------------------------------------------- /src/b6b_co.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | #define B6B_CO_BODY \ 22 | "{$global _fco 1}\n" \ 23 | "{$global _cos {}}\n" \ 24 | "{$proc co {" \ 25 | "{$list.append $_cos $1}\n" \ 26 | "{$if $_fco {" \ 27 | "{$spawn {" \ 28 | "{$loop {" \ 29 | "{$if $_cos {" \ 30 | "{$try {" \ 31 | "{$call [$list.pop $_cos 0]}" \ 32 | "}}" \ 33 | "} {" \ 34 | "{$global _fco 1}\n" \ 35 | "{$return}" \ 36 | "}}" \ 37 | "}}" \ 38 | "}}\n" \ 39 | "{$global _fco 0}" \ 40 | "}}" \ 41 | "}}" \ 42 | 43 | static int b6b_co_init(struct b6b_interp *interp) 44 | { 45 | return b6b_call_copy(interp, 46 | B6B_CO_BODY, 47 | sizeof(B6B_CO_BODY) - 1) == B6B_OK; 48 | } 49 | __b6b_init(b6b_co_init); 50 | -------------------------------------------------------------------------------- /src/b6b_exc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | static enum b6b_res b6b_exc_proc_try(struct b6b_interp *interp, 22 | struct b6b_obj *args) 23 | { 24 | struct b6b_obj *t, *e, *f, *o; 25 | unsigned int argc; 26 | #ifdef B6B_HAVE_THREADS 27 | int exit; 28 | #endif 29 | enum b6b_res res, eres = B6B_ERR, fres; 30 | 31 | argc = b6b_proc_get_args(interp, args, "oo|oo", NULL, &t, &e, &f); 32 | if (!argc) 33 | return B6B_ERR; 34 | 35 | res = b6b_call(interp, t); 36 | if (res == B6B_ERR) { 37 | if (interp->opts & B6B_OPT_RAISE) { 38 | if (argc == 2) 39 | return res; 40 | 41 | eres = b6b_call(interp, e); 42 | 43 | if (eres != B6B_EXIT) 44 | eres = B6B_ERR; 45 | } 46 | else { 47 | /* silence the error thrown by the try block if there's no except 48 | * block */ 49 | if (argc == 2) 50 | return B6B_OK; 51 | 52 | eres = b6b_call(interp, e); 53 | } 54 | } 55 | 56 | if (argc == 4) { 57 | #ifdef B6B_HAVE_THREADS 58 | exit = interp->exit; 59 | /* if the try block triggered exit, postpone it and let the finally 60 | * block run */ 61 | interp->exit = 0; 62 | #endif 63 | o = b6b_ref(interp->fg->_); 64 | fres = b6b_call(interp, f); 65 | b6b_unref(interp->fg->_); 66 | interp->fg->_ = o; 67 | #ifdef B6B_HAVE_THREADS 68 | interp->exit = exit; 69 | #endif 70 | 71 | if ((res == B6B_RET) || (res == B6B_EXIT)) 72 | return res; 73 | 74 | if ((res == B6B_ERR) && (eres != B6B_OK)) 75 | return eres; 76 | 77 | return fres; 78 | } 79 | 80 | if (res == B6B_ERR) 81 | return eres; 82 | 83 | return res; 84 | } 85 | 86 | static const struct b6b_ext_obj b6b_exc[] = { 87 | { 88 | .name = "try", 89 | .type = B6B_TYPE_STR, 90 | .val.s = "try", 91 | .proc = b6b_exc_proc_try 92 | } 93 | }; 94 | __b6b_ext(b6b_exc); 95 | -------------------------------------------------------------------------------- /src/b6b_float.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | struct b6b_obj *b6b_float_new(const b6b_float f) 24 | { 25 | struct b6b_obj *o; 26 | 27 | o = b6b_new(); 28 | if (o) { 29 | o->f = f; 30 | o->flags = B6B_TYPE_FLOAT; 31 | } 32 | 33 | return o; 34 | } 35 | 36 | int b6b_as_float(struct b6b_obj *o) 37 | { 38 | char *p = NULL; 39 | 40 | if (o->flags & B6B_TYPE_FLOAT) 41 | return 1; 42 | 43 | /* always prefer the string representation over the integer one, since it's 44 | * more accurate */ 45 | if (o->flags & B6B_TYPE_STR) { 46 | if (!o->slen) 47 | return 0; 48 | 49 | o->f = strtod(o->s, &p); 50 | 51 | /* make sure the entire string was converted - for example, 127\0abc is 52 | * an invalid integer */ 53 | if (p != o->s + o->slen) 54 | return 0; 55 | } else if (o->flags & B6B_TYPE_LIST) { 56 | if (!b6b_as_str(o) || !o->slen) 57 | return 0; 58 | 59 | o->f = strtod(o->s, &p); 60 | if (p != o->s + o->slen) 61 | return 0; 62 | } 63 | else 64 | o->f = (b6b_float)o->i; 65 | 66 | o->flags |= B6B_TYPE_FLOAT; 67 | return 1; 68 | } 69 | -------------------------------------------------------------------------------- /src/b6b_frame.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | struct b6b_frame *b6b_frame_new(struct b6b_frame *prev) 24 | { 25 | struct b6b_frame *f = (struct b6b_frame *)malloc(sizeof(*f)); 26 | 27 | if (b6b_allocated(f)) { 28 | f->locals = b6b_dict_new(); 29 | if (b6b_unlikely(!f->locals)) { 30 | free(f); 31 | return NULL; 32 | } 33 | 34 | f->args = b6b_list_new(); 35 | if (b6b_unlikely(!f->args)) { 36 | b6b_destroy(f->locals); 37 | free(f); 38 | return NULL; 39 | } 40 | 41 | f->prev = prev; 42 | } 43 | 44 | return f; 45 | } 46 | 47 | void b6b_frame_destroy(struct b6b_frame *f) 48 | { 49 | b6b_unref(f->args); 50 | b6b_unref(f->locals); 51 | free(f); 52 | } 53 | 54 | struct b6b_frame *b6b_frame_push(struct b6b_interp *interp) 55 | { 56 | struct b6b_frame *f; 57 | 58 | if (b6b_unlikely(interp->fg->depth >= B6B_MAX_NESTING)) { 59 | b6b_return_str(interp, 60 | "call stack overflow", 61 | sizeof("call stack overflow") - 1); 62 | return NULL; 63 | } 64 | 65 | f = b6b_frame_new(interp->fg->curr); 66 | if (b6b_likely(f)) { 67 | interp->fg->curr = f; 68 | ++interp->fg->depth; 69 | } 70 | 71 | return f; 72 | } 73 | 74 | int b6b_frame_set_args(struct b6b_interp *interp, 75 | struct b6b_frame *f, 76 | struct b6b_obj *args) 77 | { 78 | struct b6b_litem *li; 79 | struct b6b_obj *io; 80 | b6b_int i = 0; 81 | 82 | if (!b6b_as_list(args) || !b6b_dict_set(f->locals, interp->at, args)) 83 | return 0; 84 | 85 | b6b_list_foreach(args, li) { 86 | io = b6b_int_new(i); 87 | if (b6b_unlikely(!io)) 88 | return 0; 89 | 90 | if (b6b_unlikely(!b6b_dict_set(f->locals, io, li->o))) { 91 | b6b_destroy(io); 92 | return 0; 93 | } 94 | b6b_unref(io); 95 | 96 | ++i; 97 | } 98 | 99 | return 1; 100 | } 101 | 102 | void b6b_frame_pop(struct b6b_interp *interp) 103 | { 104 | struct b6b_frame *prev = interp->fg->curr->prev; 105 | 106 | b6b_frame_destroy(interp->fg->curr); 107 | 108 | interp->fg->curr = prev; 109 | --interp->fg->depth; 110 | } 111 | -------------------------------------------------------------------------------- /src/b6b_hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | uint32_t b6b_hash(const unsigned char *buf, const size_t len) 24 | { 25 | uint32_t h; 26 | 27 | h = b6b_hash_init(); 28 | b6b_hash_update(&h, buf, len); 29 | b6b_hash_finish(&h); 30 | 31 | return h; 32 | } 33 | -------------------------------------------------------------------------------- /src/b6b_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #ifdef B6B_HAVE_FENV 22 | # include 23 | #endif 24 | 25 | #include 26 | 27 | struct b6b_obj *b6b_int_new(const b6b_int i) 28 | { 29 | struct b6b_obj *o; 30 | 31 | o = b6b_new(); 32 | if (o) { 33 | o->i = i; 34 | o->flags = B6B_TYPE_INT; 35 | } 36 | 37 | return o; 38 | } 39 | 40 | int b6b_as_int(struct b6b_obj *o) 41 | { 42 | if (o->flags & B6B_TYPE_INT) 43 | return 1; 44 | 45 | if (!b6b_as_float(o)) 46 | return 0; 47 | 48 | #ifdef B6B_HAVE_FENV 49 | feclearexcept(FE_ALL_EXCEPT); 50 | #endif 51 | o->i = (b6b_int)floor(o->f); 52 | #ifdef B6B_HAVE_FENV 53 | if (fetestexcept(FE_INVALID)) 54 | return 0; 55 | #endif 56 | 57 | o->flags |= B6B_TYPE_INT; 58 | return 1; 59 | } 60 | -------------------------------------------------------------------------------- /src/b6b_obj.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #ifdef B6B_HAVE_VALGRIND 22 | # include 23 | #endif 24 | 25 | #include 26 | 27 | static enum b6b_res b6b_obj_proc(struct b6b_interp *interp, 28 | struct b6b_obj *args) 29 | { 30 | struct b6b_obj *s, *op, *o; 31 | 32 | if (!b6b_proc_get_args(interp, args, "ss", &s, &op)) 33 | return B6B_ERR; 34 | 35 | if (strcmp(op->s, "decode")) 36 | return B6B_ERR; 37 | 38 | o = b6b_str_decode(s->s, s->slen); 39 | if (!o) 40 | return B6B_ERR; 41 | 42 | return b6b_return(interp, o); 43 | } 44 | 45 | struct b6b_obj *b6b_new(void) 46 | { 47 | struct b6b_obj *o = (struct b6b_obj *)malloc(sizeof(*o)); 48 | 49 | if (b6b_allocated(o)) { 50 | o->refc = 1; 51 | o->proc = b6b_obj_proc; 52 | o->del = NULL; 53 | } 54 | 55 | return o; 56 | } 57 | 58 | void b6b_destroy_l(struct b6b_obj *o) 59 | { 60 | struct b6b_litem *li, *tli; 61 | 62 | b6b_list_foreach_safe(o, li, tli) { 63 | b6b_unref(li->o); 64 | free(li); 65 | } 66 | 67 | #ifdef B6B_HAVE_VALGRIND 68 | VALGRIND_MAKE_MEM_UNDEFINED(&o->l, sizeof(o->l)); 69 | #endif 70 | } 71 | 72 | void b6b_destroy(struct b6b_obj *o) 73 | { 74 | if (o->flags & B6B_TYPE_LIST) 75 | b6b_destroy_l(o); 76 | 77 | if (o->flags & B6B_TYPE_STR) 78 | free(o->s); 79 | 80 | if (o->del) 81 | o->del(o->priv); 82 | 83 | free(o); 84 | } 85 | 86 | int b6b_obj_hash(struct b6b_obj *o) 87 | { 88 | if (!(o->flags & B6B_OBJ_HASHED)) { 89 | if (!b6b_as_str(o)) 90 | return 0; 91 | 92 | o->hash = b6b_hash((const unsigned char *)o->s, o->slen); 93 | o->flags |= B6B_OBJ_HASHED; 94 | } 95 | 96 | return 1; 97 | } 98 | -------------------------------------------------------------------------------- /src/b6b_path.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | static enum b6b_res b6b_path_proc_realpath(struct b6b_interp *interp, 26 | struct b6b_obj *args) 27 | { 28 | struct b6b_obj *s, *o; 29 | char *abs; 30 | 31 | if (!b6b_proc_get_args(interp, args, "os", NULL, &s)) 32 | return B6B_ERR; 33 | 34 | abs = realpath(s->s, NULL); 35 | if (!abs) 36 | return b6b_return_strerror(interp, errno); 37 | 38 | o = b6b_str_new(abs, strlen(abs)); 39 | if (b6b_unlikely(!o)) { 40 | free(abs); 41 | return B6B_ERR; 42 | } 43 | 44 | return b6b_return(interp, o); 45 | } 46 | 47 | static const struct b6b_ext_obj b6b_path[] = { 48 | { 49 | .name = "realpath", 50 | .type = B6B_TYPE_STR, 51 | .val.s = "realpath", 52 | .proc = b6b_path_proc_realpath 53 | } 54 | }; 55 | __b6b_ext(b6b_path); 56 | -------------------------------------------------------------------------------- /src/b6b_rand.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | static enum b6b_res b6b_rand_proc_choice(struct b6b_interp *interp, 25 | struct b6b_obj *args) 26 | { 27 | struct b6b_obj *l; 28 | struct b6b_litem *li; 29 | unsigned int i, c; 30 | 31 | if (!b6b_proc_get_args(interp, args, "ol", NULL, &l)) 32 | return B6B_ERR; 33 | 34 | li = b6b_list_first(l); 35 | if (!li) 36 | return B6B_ERR; 37 | 38 | c = (unsigned int)(rand_r(&interp->seed) & UINT_MAX); 39 | 40 | for (i = 1; i < c; ++i) { 41 | li = b6b_list_next(li); 42 | if (!li) { 43 | /* if the list length is smaller than the random number, divide the 44 | * latter by the former */ 45 | c %= i; 46 | 47 | li = b6b_list_first(l); 48 | for (i = 1; i <= c; ++i) 49 | li = b6b_list_next(li); 50 | 51 | break; 52 | } 53 | } 54 | 55 | return b6b_return(interp, b6b_ref(li->o)); 56 | } 57 | 58 | static enum b6b_res b6b_rand_proc_randint(struct b6b_interp *interp, 59 | struct b6b_obj *args) 60 | { 61 | struct b6b_obj *start, *end; 62 | unsigned int delta; 63 | 64 | if (!b6b_proc_get_args(interp, args, "oii", NULL, &start, &end) || 65 | (start->i < INT_MIN) || 66 | (start->i >= INT_MAX) || 67 | (end->i <= start->i) || 68 | (end->i > INT_MAX)) 69 | return B6B_ERR; 70 | 71 | delta = (unsigned int)(end->i - start->i); 72 | if (delta == UINT_MAX) 73 | return B6B_ERR; 74 | 75 | return b6b_return_int( 76 | interp, 77 | (b6b_int)(start->i + 78 | ((unsigned int)(rand_r(&interp->seed) & UINT_MAX) % 79 | (delta + 1)))); 80 | } 81 | 82 | static const struct b6b_ext_obj b6b_rand[] = { 83 | { 84 | .name = "choice", 85 | .type = B6B_TYPE_STR, 86 | .val.s = "choice", 87 | .proc = b6b_rand_proc_choice 88 | }, 89 | { 90 | .name = "randint", 91 | .type = B6B_TYPE_STR, 92 | .val.s = "randint", 93 | .proc = b6b_rand_proc_randint 94 | } 95 | }; 96 | __b6b_ext(b6b_rand); 97 | -------------------------------------------------------------------------------- /src/b6b_sem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | static const struct b6b_strm_ops b6b_sem_ops = { 27 | .peeksz = b6b_fd_peeksz_u64, 28 | .read = b6b_fd_read_u64, 29 | .write = b6b_fd_write_u64, 30 | .fd = b6b_fd_fd, 31 | .close = b6b_fd_close 32 | }; 33 | 34 | static enum b6b_res b6b_sem_proc_sem(struct b6b_interp *interp, 35 | struct b6b_obj *args) 36 | { 37 | struct b6b_obj *n, *o; 38 | int fd; 39 | 40 | if (!b6b_proc_get_args(interp, args, "oi", NULL, &n) || 41 | (n->i > UINT_MAX)) 42 | return B6B_ERR; 43 | 44 | fd = eventfd((unsigned int)n->i, 45 | EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE); 46 | if (fd < 0) 47 | return b6b_return_strerror(interp, errno); 48 | 49 | o = b6b_strm_fmt(interp, &b6b_sem_ops, (void *)(intptr_t)fd, "sem"); 50 | if (b6b_unlikely(!o)) { 51 | close(fd); 52 | return B6B_ERR; 53 | } 54 | 55 | return b6b_return(interp, o); 56 | } 57 | 58 | static const struct b6b_ext_obj b6b_sem[] = { 59 | { 60 | .name = "sem", 61 | .type = B6B_TYPE_STR, 62 | .val.s = "sem", 63 | .proc = b6b_sem_proc_sem 64 | } 65 | }; 66 | __b6b_ext(b6b_sem); 67 | -------------------------------------------------------------------------------- /src/b6b_syscall.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #ifdef B6B_HAVE_VALGRIND 24 | # include 25 | #endif 26 | 27 | #include 28 | 29 | static void b6b_do_syscall(void *arg) 30 | { 31 | struct b6b_syscall_data *data = (struct b6b_syscall_data *)arg; 32 | 33 | data->rval = syscall(data->args[0], 34 | data->args[1], 35 | data->args[2], 36 | data->args[3], 37 | data->args[4], 38 | data->args[5]); 39 | if (data->rval < 0) 40 | data->rerrno = errno; 41 | } 42 | 43 | int b6b_syscall(struct b6b_interp *interp, 44 | int *ret, 45 | const long nr, 46 | ...) 47 | { 48 | struct b6b_syscall_data data; 49 | va_list ap; 50 | int i; 51 | 52 | va_start(ap, nr); 53 | 54 | data.args[0] = nr; 55 | for (i = 1; i < sizeof(data.args) / sizeof(data.args[0]); ++i) 56 | data.args[i] = va_arg(ap, long); 57 | 58 | va_end(ap); 59 | 60 | #ifdef B6B_HAVE_VALGRIND 61 | VALGRIND_HG_DISABLE_CHECKING(&data, sizeof(data)); 62 | #endif 63 | if (!b6b_offload(interp, b6b_do_syscall, &data)) 64 | return 0; 65 | 66 | *ret = data.rval; 67 | if (data.rval < 0) 68 | errno = data.rerrno; 69 | 70 | return 1; 71 | } 72 | -------------------------------------------------------------------------------- /src/b6b_time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #ifdef B6B_HAVE_VALGRIND 26 | # include 27 | #endif 28 | 29 | #include 30 | 31 | static enum b6b_res b6b_time_proc_sleep(struct b6b_interp *interp, 32 | struct b6b_obj *args) 33 | { 34 | struct timespec req, rem; 35 | struct b6b_obj *f; 36 | int ret; 37 | 38 | if (!b6b_proc_get_args(interp, args, "of", NULL, &f)) 39 | return B6B_ERR; 40 | 41 | /* we assume sizeof(time_t) == 4 */ 42 | if ((f->f < 0) || (f->f > UINT_MAX)) 43 | return B6B_ERR; 44 | 45 | /* we want to avoid costly offloading the nanosleep() call, if the interval 46 | * is zero */ 47 | if (!f->f) 48 | return B6B_OK; 49 | 50 | req.tv_sec = (time_t)floor(f->f); 51 | req.tv_nsec = labs((long)(1000000000 * (f->f - (b6b_float)req.tv_sec))); 52 | 53 | #ifdef B6B_HAVE_VALGRIND 54 | VALGRIND_HG_DISABLE_CHECKING(&rem, sizeof(rem)); 55 | #endif 56 | 57 | do { 58 | if (!b6b_syscall(interp, &ret, __NR_nanosleep, &req, &rem)) 59 | return B6B_ERR; 60 | 61 | if (ret == 0) 62 | break; 63 | 64 | if (errno != EINTR) 65 | return b6b_return_strerror(interp, errno); 66 | 67 | req.tv_sec = rem.tv_sec; 68 | req.tv_nsec = rem.tv_nsec; 69 | } while (1); 70 | 71 | return B6B_OK; 72 | } 73 | 74 | static const struct b6b_ext_obj b6b_time[] = { 75 | { 76 | .name = "sleep", 77 | .type = B6B_TYPE_STR, 78 | .val.s = "sleep", 79 | .proc = b6b_time_proc_sleep 80 | } 81 | }; 82 | __b6b_ext(b6b_time); 83 | -------------------------------------------------------------------------------- /src/b6b_timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | static const struct b6b_strm_ops b6b_timer_ops = { 28 | .peeksz = b6b_fd_peeksz_u64, 29 | .read = b6b_fd_read_u64, 30 | .fd = b6b_fd_fd, 31 | .close = b6b_fd_close 32 | }; 33 | 34 | static enum b6b_res b6b_timer_proc_timer(struct b6b_interp *interp, 35 | struct b6b_obj *args) 36 | { 37 | struct itimerspec its; 38 | struct b6b_obj *f, *o; 39 | int fd, err; 40 | 41 | if (!b6b_proc_get_args(interp, args, "of", NULL, &f) || !f->f) 42 | return B6B_ERR; 43 | 44 | fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); 45 | if (fd < 0) 46 | return b6b_return_strerror(interp, errno); 47 | 48 | its.it_value.tv_sec = (time_t)floor(f->f); 49 | its.it_value.tv_nsec = labs( 50 | (long)(1000000000 * (f->f - (b6b_float)its.it_value.tv_sec))); 51 | its.it_interval.tv_sec = its.it_value.tv_sec; 52 | its.it_interval.tv_nsec = its.it_value.tv_nsec; 53 | if (timerfd_settime(fd, 0, &its, NULL) < 0) { 54 | err = errno; 55 | close(fd); 56 | return b6b_return_strerror(interp, err); 57 | } 58 | 59 | o = b6b_strm_fmt(interp, &b6b_timer_ops, (void *)(intptr_t)fd, "timer"); 60 | if (b6b_unlikely(!o)) { 61 | close(fd); 62 | return B6B_ERR; 63 | } 64 | 65 | return b6b_return(interp, o); 66 | } 67 | 68 | static const struct b6b_ext_obj b6b_timer[] = { 69 | { 70 | .name = "timer", 71 | .type = B6B_TYPE_STR, 72 | .val.s = "timer", 73 | .proc = b6b_timer_proc_timer 74 | } 75 | }; 76 | __b6b_ext(b6b_timer); 77 | -------------------------------------------------------------------------------- /tests/b6b_test_and.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$&&}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$&& 0 0}", 9) == B6B_OK); 34 | assert(!b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$&& 1 0}", 9) == B6B_OK); 39 | assert(!b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$&& 0 1}", 9) == B6B_OK); 44 | assert(!b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$&& 1 1}", 9) == B6B_OK); 49 | assert(b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$&& {} {}}", 11) == B6B_OK); 54 | assert(!b6b_obj_istrue(interp.fg->_)); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$&& a a}", 9) == B6B_OK); 59 | assert(b6b_obj_istrue(interp.fg->_)); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_b6b.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$b6b}", 6) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{[$b6b {}] call {{$echo 5}}}", 28) == B6B_OK); 35 | assert(b6b_as_float(interp.fg->_)); 36 | assert(interp.fg->_->f == 5); 37 | b6b_interp_destroy(&interp); 38 | 39 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 40 | assert(b6b_call_copy(&interp, "{[$b6b {a b}] call {{$echo $@}}}", 32) == B6B_OK); 41 | assert(b6b_as_list(interp.fg->_)); 42 | assert(!b6b_list_empty(interp.fg->_)); 43 | assert(b6b_as_str(b6b_list_first(interp.fg->_)->o)); 44 | assert(b6b_list_first(interp.fg->_)->o->slen == 1); 45 | assert(strcmp(b6b_list_first(interp.fg->_)->o->s, "a") == 0); 46 | assert(b6b_list_next(b6b_list_first(interp.fg->_))); 47 | assert(b6b_as_str(b6b_list_next(b6b_list_first(interp.fg->_))->o)); 48 | assert(b6b_list_next(b6b_list_first(interp.fg->_))->o->slen == 1); 49 | assert(strcmp(b6b_list_next(b6b_list_first(interp.fg->_))->o->s, "b") == 0); 50 | assert(!b6b_list_next(b6b_list_next(b6b_list_first(interp.fg->_)))); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 54 | assert(b6b_call_copy(&interp, "{[$b6b {}] a {{$echo 5}}}", 25) == B6B_ERR); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, 59 | "{[$b6b {}] call {{$exit 5}}}", 60 | 28) == B6B_EXIT); 61 | b6b_interp_destroy(&interp); 62 | 63 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 64 | assert(b6b_call_copy(&interp, 65 | "{$local a 1337} {[$b6b {}] call {{$global a 1338}}} {$echo $a}", 66 | 62) == B6B_OK); 67 | assert(b6b_as_float(interp.fg->_)); 68 | assert(interp.fg->_->f == 1337); 69 | b6b_interp_destroy(&interp); 70 | 71 | return EXIT_SUCCESS; 72 | } 73 | -------------------------------------------------------------------------------- /tests/b6b_test_bit_and.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$&}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$& 0 2}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$& 4 6}", 8) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 4); 42 | b6b_interp_destroy(&interp); 43 | 44 | return EXIT_SUCCESS; 45 | } 46 | -------------------------------------------------------------------------------- /tests/b6b_test_bit_or.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$|}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$| 0 2}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 2); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$| 4 2}", 8) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 6); 42 | b6b_interp_destroy(&interp); 43 | 44 | return EXIT_SUCCESS; 45 | } 46 | -------------------------------------------------------------------------------- /tests/b6b_test_bit_xor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$^}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$^ 4 6}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 2); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$^ 2 4}", 8) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 6); 42 | b6b_interp_destroy(&interp); 43 | 44 | return EXIT_SUCCESS; 45 | } 46 | -------------------------------------------------------------------------------- /tests/b6b_test_break.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, 30 | "{$echo 1} {$break} {$echo 2}", 31 | 28) == B6B_BREAK); 32 | assert(b6b_as_str(interp.fg->_)); 33 | assert(interp.fg->_->slen == 0); 34 | b6b_interp_destroy(&interp); 35 | 36 | return EXIT_SUCCESS; 37 | } 38 | -------------------------------------------------------------------------------- /tests/b6b_test_call.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$call}", 7) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$echo 1} {$call {}}", 20) == B6B_OK); 34 | assert(b6b_as_str(interp.fg->_)); 35 | assert(interp.fg->_->slen == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, 40 | "{$echo 1} {$call {{$echo 2} {$echo 3}}}", 41 | 39) == B6B_OK); 42 | assert(b6b_as_float(interp.fg->_)); 43 | assert(interp.fg->_->f == 3); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, 48 | "{$echo 1} {$call {{$echo 2} {$throw 3} {$echo 4}}}", 49 | 50) == B6B_ERR); 50 | assert(b6b_as_float(interp.fg->_)); 51 | assert(interp.fg->_->f == 3); 52 | b6b_interp_destroy(&interp); 53 | 54 | return EXIT_SUCCESS; 55 | } 56 | -------------------------------------------------------------------------------- /tests/b6b_test_choice.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | int occ[5] = {0, 0, 0, 0, 0}; 29 | 30 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 31 | assert(b6b_call_copy(&interp, "{$choice}", 9) == B6B_ERR); 32 | b6b_interp_destroy(&interp); 33 | 34 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 35 | assert(b6b_call_copy(&interp, "{$choice {}}", 12) == B6B_ERR); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$choice a}", 11) == B6B_OK); 40 | assert(b6b_as_str(interp.fg->_)); 41 | assert(interp.fg->_->slen == 1); 42 | assert(strcmp(interp.fg->_->s, "a") == 0); 43 | b6b_interp_destroy(&interp); 44 | 45 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 46 | assert(b6b_call_copy(&interp, "{$choice {a b}}", 15) == B6B_OK); 47 | assert(b6b_as_str(interp.fg->_)); 48 | assert(interp.fg->_->slen == 1); 49 | assert((strcmp(interp.fg->_->s, "a") == 0) || 50 | (strcmp(interp.fg->_->s, "b") == 0)); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 54 | do { 55 | assert(b6b_call_copy(&interp, "{$choice {0 1 2 3 4}}", 21) == B6B_OK); 56 | assert(b6b_as_int(interp.fg->_)); 57 | assert(interp.fg->_->i >= 0); 58 | assert(interp.fg->_->i <= 4); 59 | ++occ[interp.fg->_->i]; 60 | } while (!occ[0] || !occ[1] || !occ[2] || !occ[3] || !occ[4]); 61 | b6b_interp_destroy(&interp); 62 | 63 | return EXIT_SUCCESS; 64 | } 65 | -------------------------------------------------------------------------------- /tests/b6b_test_compress.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$compress}", 11) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$compress {}}", 14) == B6B_OK); 34 | assert(b6b_as_str(interp.fg->_)); 35 | assert(interp.fg->_->slen == 8); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, 40 | "{$compress [$str.join {} [$range 0 1000]]}", 41 | 42) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen > 0); 44 | assert(interp.fg->_->slen < 2894); 45 | b6b_interp_destroy(&interp); 46 | 47 | return EXIT_SUCCESS; 48 | } 49 | -------------------------------------------------------------------------------- /tests/b6b_test_continue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, 30 | "{$echo 1} {$continue} {$echo 2}", 31 | 31) == B6B_CONT); 32 | assert(b6b_as_str(interp.fg->_)); 33 | assert(interp.fg->_->slen == 0); 34 | b6b_interp_destroy(&interp); 35 | 36 | return EXIT_SUCCESS; 37 | } 38 | -------------------------------------------------------------------------------- /tests/b6b_test_decompress.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$decompress}", 13) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$decompress {}}", 16) == B6B_ERR); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 37 | assert(b6b_call_copy( 38 | &interp, 39 | "{$decompress [$compress [$str.join {} [$range 0 1000]]]}", 40 | 56) == B6B_OK); 41 | assert(b6b_as_str(interp.fg->_)); 42 | assert(interp.fg->_->slen == 2894); 43 | b6b_interp_destroy(&interp); 44 | 45 | return EXIT_SUCCESS; 46 | } 47 | -------------------------------------------------------------------------------- /tests/b6b_test_deflate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$deflate}", 10) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$deflate {}}", 13) == B6B_OK); 34 | assert(b6b_as_str(interp.fg->_)); 35 | assert(interp.fg->_->slen == 2); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$deflate a}", 12) == B6B_OK); 40 | assert(b6b_as_str(interp.fg->_)); 41 | assert(interp.fg->_->slen > 1); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, 46 | "{$deflate [$str.join {} [$range 0 1000]]}", 47 | 41) == B6B_OK); 48 | assert(b6b_as_str(interp.fg->_)); 49 | assert(interp.fg->_->slen > 0); 50 | assert(interp.fg->_->slen < 2894); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 54 | assert(b6b_call_copy( 55 | &interp, 56 | "{$deflate [$deflate [$str.join {} [$range 0 1000]] 10] 10}", 57 | 58) == B6B_OK); 58 | assert(b6b_as_str(interp.fg->_)); 59 | assert(interp.fg->_->slen > 0); 60 | assert(interp.fg->_->slen < 2894); 61 | b6b_interp_destroy(&interp); 62 | 63 | return EXIT_SUCCESS; 64 | } 65 | -------------------------------------------------------------------------------- /tests/b6b_test_dict_get.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$dict.get}", 11) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$dict.get {a b c d}}", 21) == B6B_ERR); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$dict.get {a b c d} c}", 23) == B6B_OK); 39 | assert(b6b_as_str(interp.fg->_)); 40 | assert(strcmp(interp.fg->_->s, "d") == 0); 41 | b6b_interp_destroy(&interp); 42 | 43 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 44 | assert(b6b_call_copy(&interp, "{$dict.get {a b c d} e}", 23) == B6B_ERR); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$dict.get {a b c d} e f}", 25) == B6B_OK); 49 | assert(b6b_as_str(interp.fg->_)); 50 | assert(strcmp(interp.fg->_->s, "f") == 0); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 54 | assert(b6b_call_copy(&interp, "{$dict.get {a b c} c}", 21) == B6B_ERR); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$dict.get {a b c} c d}", 23) == B6B_ERR); 59 | b6b_interp_destroy(&interp); 60 | 61 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 62 | assert(b6b_call_copy(&interp, "{$dict.get {} a}", 16) == B6B_ERR); 63 | b6b_interp_destroy(&interp); 64 | 65 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 66 | assert(b6b_call_copy(&interp, "{$dict.get {} a b}", 18) == B6B_OK); 67 | assert(b6b_as_str(interp.fg->_)); 68 | assert(strcmp(interp.fg->_->s, "b") == 0); 69 | b6b_interp_destroy(&interp); 70 | 71 | return EXIT_SUCCESS; 72 | } 73 | -------------------------------------------------------------------------------- /tests/b6b_test_dict_set.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$dict.set}", 11) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$dict.set {} a b}", 18) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 3); 37 | assert(strcmp(interp.fg->_->s, "a b") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$dict.set {a b} c d}", 21) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen == 7); 44 | assert(strcmp(interp.fg->_->s, "a b c d") == 0); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$dict.set {a} c d}", 19) == B6B_ERR); 49 | b6b_interp_destroy(&interp); 50 | 51 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 52 | assert(b6b_call_copy(&interp, "{$dict.set {a b} a c}", 21) == B6B_OK); 53 | assert(b6b_as_str(interp.fg->_)); 54 | assert(interp.fg->_->slen == 3); 55 | assert(strcmp(interp.fg->_->s, "a c") == 0); 56 | b6b_interp_destroy(&interp); 57 | 58 | return EXIT_SUCCESS; 59 | } 60 | -------------------------------------------------------------------------------- /tests/b6b_test_dict_unset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$dict.unset}", 13) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$dict.unset {} a}", 18) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 0); 37 | b6b_interp_destroy(&interp); 38 | 39 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 40 | assert(b6b_call_copy(&interp, "{$dict.unset {a b c d} c}", 25) == B6B_OK); 41 | assert(b6b_as_str(interp.fg->_)); 42 | assert(interp.fg->_->slen == 3); 43 | assert(strcmp(interp.fg->_->s, "a b") == 0); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, "{$dict.unset {a b c d} e}", 25) == B6B_OK); 48 | assert(b6b_as_str(interp.fg->_)); 49 | assert(interp.fg->_->slen == 7); 50 | assert(strcmp(interp.fg->_->s, "a b c d") == 0); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 54 | assert(b6b_call_copy(&interp, "{$dict.unset {a b c} e}", 23) == B6B_ERR); 55 | b6b_interp_destroy(&interp); 56 | 57 | return EXIT_SUCCESS; 58 | } 59 | -------------------------------------------------------------------------------- /tests/b6b_test_div.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$/}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$/ 0 2}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$/ 4 0}", 8) == B6B_ERR); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$/ 4 2}", 8) == B6B_OK); 44 | assert(b6b_as_float(interp.fg->_)); 45 | assert(interp.fg->_->f == 2); 46 | b6b_interp_destroy(&interp); 47 | 48 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 49 | assert(b6b_call_copy(&interp, "{$/ 4 2.5}", 10) == B6B_OK); 50 | assert(b6b_as_float(interp.fg->_)); 51 | assert(interp.fg->_->f == 1.6); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$/ 4 0.5}", 10) == B6B_OK); 56 | assert(b6b_as_float(interp.fg->_)); 57 | assert(interp.fg->_->f == 8); 58 | b6b_interp_destroy(&interp); 59 | 60 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 61 | assert(b6b_call_copy(&interp, "{$/ 4 -2.5}", 11) == B6B_OK); 62 | assert(b6b_as_float(interp.fg->_)); 63 | assert(interp.fg->_->f == -1.6); 64 | b6b_interp_destroy(&interp); 65 | 66 | return EXIT_SUCCESS; 67 | } 68 | -------------------------------------------------------------------------------- /tests/b6b_test_echo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$echo}", 7) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$echo abc}", 11) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 3); 37 | assert(strcmp(interp.fg->_->s, "abc") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | return EXIT_SUCCESS; 41 | } 42 | -------------------------------------------------------------------------------- /tests/b6b_test_eq.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$==}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$== abc abc}", 13) == B6B_OK); 34 | assert(b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$== abc abd}", 13) == B6B_OK); 39 | assert(!b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$== {} {}}", 11) == B6B_OK); 44 | assert(b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | return EXIT_SUCCESS; 48 | } 49 | -------------------------------------------------------------------------------- /tests/b6b_test_eval.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$eval}", 7) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$eval abc}", 11) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 3); 37 | assert(strcmp(interp.fg->_->s, "abc") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$eval {}}", 10) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen == 0); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, "{$eval {[$echo 5]}}", 19) == B6B_OK); 48 | assert(b6b_as_float(interp.fg->_)); 49 | assert(interp.fg->_->f == 5); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$eval {[$echo 5}}", 18) == B6B_ERR); 54 | b6b_interp_destroy(&interp); 55 | 56 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 57 | assert(b6b_call_copy(&interp, "{$eval {[}}", 11) == B6B_ERR); 58 | b6b_interp_destroy(&interp); 59 | 60 | return EXIT_SUCCESS; 61 | } 62 | -------------------------------------------------------------------------------- /tests/b6b_test_evloop_after.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2018 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | /* regression test: this used to leak the event loop */ 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{[$evloop] after 1 {}}", 22) == B6B_OK); 31 | b6b_interp_destroy(&interp); 32 | 33 | return EXIT_SUCCESS; 34 | } 35 | -------------------------------------------------------------------------------- /tests/b6b_test_exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, 30 | "{$echo 1} {$exit} {$echo 2}", 31 | 27) == B6B_EXIT); 32 | assert(b6b_as_str(interp.fg->_)); 33 | assert(interp.fg->_->slen == 0); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, 38 | "{$echo 1} {$exit 2} {$echo 3}", 39 | 29) == B6B_EXIT); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 2); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, 46 | "{$echo 1} {$exit 2 3} {$echo 4}", 47 | 31) == B6B_ERR); 48 | b6b_interp_destroy(&interp); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /tests/b6b_test_export.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$export}", 9) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, 34 | "{$export a 1337} {$echo 2} {$echo $a}", 35 | 37) == B6B_OK); 36 | assert(b6b_as_float(interp.fg->_)); 37 | assert(interp.fg->_->f == 1337); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, 42 | "{$local a 1337} {$call {{$export a 1338}}} {$echo $a}", 43 | 53) == B6B_OK); 44 | assert(b6b_as_float(interp.fg->_)); 45 | assert(interp.fg->_->f == 1338); 46 | b6b_interp_destroy(&interp); 47 | 48 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 49 | assert(b6b_call_copy(&interp, 50 | "{$local a 1337} {$call {{$export b}}} {$echo $a}", 51 | 48) == B6B_ERR); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, 56 | "{$local a 1337} {$call {{$local a 1338} {$export a}}} {$echo $a}", 57 | 64) == B6B_OK); 58 | assert(b6b_as_float(interp.fg->_)); 59 | assert(interp.fg->_->f == 1338); 60 | b6b_interp_destroy(&interp); 61 | 62 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 63 | assert(b6b_call_copy(&interp, 64 | "{$local a 1337} {$call {{$local a 1338} {$export b}}} {$echo $a}", 65 | 64) == B6B_ERR); 66 | b6b_interp_destroy(&interp); 67 | 68 | return EXIT_SUCCESS; 69 | } 70 | -------------------------------------------------------------------------------- /tests/b6b_test_ffi_buf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017, 2018 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$ffi.buf}", 10) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$ffi.buf abcd}", 15) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 4); 37 | assert(strcmp(interp.fg->_->s, "abcd") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$ffi.buf abc\0d}", 16) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen == 5); 44 | assert(memcmp(interp.fg->_->s, "abc\0d", 5) == 0); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{[$ffi.buf abc]}", 16) == B6B_ERR); 49 | b6b_interp_destroy(&interp); 50 | 51 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 52 | assert(b6b_call_copy(&interp, 53 | "{$ffi.memcpy [[$ffi.buf abcd] address] 3}", 54 | 41) == B6B_OK); 55 | assert(b6b_as_str(interp.fg->_)); 56 | assert(interp.fg->_->slen == 3); 57 | assert(strcmp(interp.fg->_->s, "abc") == 0); 58 | b6b_interp_destroy(&interp); 59 | 60 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 61 | assert(b6b_call_copy(&interp, "{[$ffi.buf abc] addres}", 23) == B6B_ERR); 62 | b6b_interp_destroy(&interp); 63 | 64 | return EXIT_SUCCESS; 65 | } 66 | -------------------------------------------------------------------------------- /tests/b6b_test_ffi_call.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017, 2018 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 29 | assert(b6b_call_copy(&interp, 30 | "{$local a [$ffi.buf abcde]} {$ffi.call [$ffi.func [[$ffi.dlopen {}] dlsym puts] i p] [$ffi.pack p [$a address]]}", 31 | 112) == B6B_OK); 32 | assert(b6b_as_int(interp.fg->_)); 33 | assert(interp.fg->_->i == 6); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 37 | assert(b6b_call_copy(&interp, 38 | "{$local a [$ffi.buf 00ff00ff]} {$ffi.call [$ffi.func [[$ffi.dlopen {}] dlsym strtol] l ppi] [$ffi.pack p [$a address]] [$ffi.pack p 0] [$ffi.pack i 16]}", 39 | 152) == B6B_OK); 40 | assert(b6b_as_int(interp.fg->_)); 41 | assert(interp.fg->_->i == 16711935); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 45 | assert(b6b_call_copy(&interp, 46 | "{$local a [$ffi.buf b6b_interp_new_argv]} {$ffi.call [$ffi.func [[$ffi.dlopen {}] dlsym dlsym] p pp] [$ffi.pack p [[$ffi.dlopen {}] handle]] [$ffi.pack p [$a address]]}", 47 | 168) == B6B_OK); 48 | b6b_interp_destroy(&interp); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /tests/b6b_test_ffi_func.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017, 2018 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$ffi.func}", 11) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, 34 | "{$ffi.func [[$ffi.dlopen {}] dlsym fopen] p pp}", 35 | 47) == B6B_OK); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, 40 | "{$ffi.func 0 p pp}", 41 | 18) == B6B_ERR); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, 46 | "{$ffi.func [[$ffi.dlopen {}] dlsym fopen] pp pp}", 47 | 48) == B6B_ERR); 48 | b6b_interp_destroy(&interp); 49 | 50 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 51 | assert(b6b_call_copy(&interp, 52 | "{$ffi.func [[$ffi.dlopen {}] dlsym fopen] p px}", 53 | 47) == B6B_ERR); 54 | b6b_interp_destroy(&interp); 55 | 56 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 57 | assert(b6b_call_copy(&interp, 58 | "{$ffi.func [[$ffi.dlopen {}] dlsym sync] i {}}", 59 | 46) == B6B_OK); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_ffi_memcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017, 2018 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | int main() 31 | { 32 | static char stmt[128]; 33 | struct b6b_interp interp; 34 | const char *s; 35 | size_t len; 36 | int out; 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$ffi.memcpy}", 13) == B6B_ERR); 40 | b6b_interp_destroy(&interp); 41 | 42 | s = gai_strerror(EAI_SERVICE); 43 | assert(s); 44 | 45 | len = strlen(s); 46 | assert(len > 0); 47 | 48 | /* reading a string should succeed */ 49 | out = sprintf(stmt, "{$ffi.memcpy %"PRIuPTR" %zu}", (uintptr_t)s, len); 50 | assert(out > 0); 51 | assert(out < sizeof(stmt)); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 54 | assert(b6b_call_copy(&interp, stmt, (size_t)out) == B6B_OK); 55 | assert(b6b_as_str(interp.fg->_)); 56 | assert(interp.fg->_->slen == len); 57 | assert(strcmp(interp.fg->_->s, s) == 0); 58 | b6b_interp_destroy(&interp); 59 | 60 | /* reading a substring should succeed */ 61 | out = sprintf(stmt, "{$ffi.memcpy %"PRIuPTR" 5}", (uintptr_t)s); 62 | assert(out > 0); 63 | assert(out < sizeof(stmt)); 64 | 65 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 66 | assert(b6b_call_copy(&interp, stmt, (size_t)out) == B6B_OK); 67 | assert(b6b_as_str(interp.fg->_)); 68 | assert(interp.fg->_->slen == 5); 69 | assert(memcmp(interp.fg->_->s, s, 5) == 0); 70 | b6b_interp_destroy(&interp); 71 | 72 | /* reading 0 bytes should fail */ 73 | out = sprintf(stmt, "{$ffi.memcpy %"PRIuPTR" 0}", (uintptr_t)s); 74 | assert(out > 0); 75 | assert(out < sizeof(stmt)); 76 | 77 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 78 | assert(b6b_call_copy(&interp, stmt, (size_t)out) == B6B_ERR); 79 | b6b_interp_destroy(&interp); 80 | 81 | /* attempts to read from NULL should be detected */ 82 | out = sprintf(stmt, "{$ffi.memcpy %"PRIuPTR" 5}", (uintptr_t)NULL); 83 | assert(out > 0); 84 | assert(out < sizeof(stmt)); 85 | 86 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 87 | assert(b6b_call_copy(&interp, stmt, (size_t)out) == B6B_ERR); 88 | b6b_interp_destroy(&interp); 89 | 90 | return EXIT_SUCCESS; 91 | } 92 | -------------------------------------------------------------------------------- /tests/b6b_test_ge.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$>=}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$>= 4 1}", 9) == B6B_OK); 34 | assert(b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$>= 4 4}", 9) == B6B_OK); 39 | assert(b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$>= 4 8}", 9) == B6B_OK); 44 | assert(!b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$>= -4 1}", 10) == B6B_OK); 49 | assert(!b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$>= -1 4}", 10) == B6B_OK); 54 | assert(!b6b_obj_istrue(interp.fg->_)); 55 | b6b_interp_destroy(&interp); 56 | 57 | return EXIT_SUCCESS; 58 | } 59 | -------------------------------------------------------------------------------- /tests/b6b_test_global.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$global}", 9) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, 34 | "{$global a 1337} {$echo 2} {$echo $a}", 35 | 37) == B6B_OK); 36 | assert(b6b_as_float(interp.fg->_)); 37 | assert(interp.fg->_->f == 1337); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, 42 | "{$global a 1337} {$echo 2} {$global a 1338} {$echo 3} {$echo $a}", 43 | 64) == B6B_OK); 44 | assert(b6b_as_float(interp.fg->_)); 45 | assert(interp.fg->_->f == 1338); 46 | b6b_interp_destroy(&interp); 47 | 48 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 49 | assert(b6b_call_copy(&interp, 50 | "{$global a 1337} {$echo 2} {$global b $a} {$global a 1338} {$echo 3} {$echo $b}", 51 | 79) == B6B_OK); 52 | assert(b6b_as_float(interp.fg->_)); 53 | assert(interp.fg->_->f == 1337); 54 | b6b_interp_destroy(&interp); 55 | 56 | return EXIT_SUCCESS; 57 | } 58 | -------------------------------------------------------------------------------- /tests/b6b_test_gt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$>}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$> 4 1}", 8) == B6B_OK); 34 | assert(b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$> 4 4}", 8) == B6B_OK); 39 | assert(!b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$> 4 8}", 8) == B6B_OK); 44 | assert(!b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$> -4 1}", 9) == B6B_OK); 49 | assert(!b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$> -1 4}", 9) == B6B_OK); 54 | assert(!b6b_obj_istrue(interp.fg->_)); 55 | b6b_interp_destroy(&interp); 56 | 57 | return EXIT_SUCCESS; 58 | } 59 | -------------------------------------------------------------------------------- /tests/b6b_test_gzip.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2018 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$gzip}", 7) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$gzip {}}", 10) == B6B_OK); 34 | assert(b6b_as_str(interp.fg->_)); 35 | assert(interp.fg->_->slen > 18); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$gzip a}", 9) == B6B_OK); 40 | assert(b6b_as_str(interp.fg->_)); 41 | assert(interp.fg->_->slen > 18); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, 46 | "{$gzip [$str.join {} [$range 0 1000]]}", 47 | 38) == B6B_OK); 48 | assert(b6b_as_str(interp.fg->_)); 49 | assert(interp.fg->_->slen > 18); 50 | assert(interp.fg->_->slen < 2894); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 54 | assert(b6b_call_copy( 55 | &interp, 56 | "{$gzip [$deflate [$str.join {} [$range 0 1000]] 10] 10}", 57 | 55) == B6B_OK); 58 | assert(b6b_as_str(interp.fg->_)); 59 | assert(interp.fg->_->slen > 18); 60 | assert(interp.fg->_->slen < 2894); 61 | b6b_interp_destroy(&interp); 62 | 63 | return EXIT_SUCCESS; 64 | } 65 | -------------------------------------------------------------------------------- /tests/b6b_test_hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #define NHASHES 4 * 1024 27 | 28 | static int hash_cmp(const void *a, const void *b) 29 | { 30 | uint32_t m = *(uint32_t *)a, n = *(uint32_t *)b; 31 | 32 | if (m > n) 33 | return 1; 34 | 35 | if (m < n) 36 | return -1; 37 | 38 | return 0; 39 | } 40 | 41 | int main() 42 | { 43 | unsigned int seed, i; 44 | uint32_t *hashes; 45 | unsigned char c; 46 | 47 | seed = (unsigned int)time(NULL); 48 | hashes = (uint32_t *)malloc(sizeof(uint32_t) * NHASHES); 49 | assert(hashes); 50 | 51 | c = (unsigned char)(rand_r(&seed) & 0xFF); 52 | hashes[0] = b6b_hash_init(); 53 | b6b_hash_update(&hashes[0], &c, 1); 54 | b6b_hash_finish(&hashes[0]); 55 | 56 | for (i = 1; i < NHASHES; ++i) { 57 | c = (unsigned char)(rand_r(&seed) & 0xFF); 58 | hashes[i] = hashes[i - 1]; 59 | b6b_hash_update(&hashes[i], &c, 1); 60 | b6b_hash_finish(&hashes[i]); 61 | assert(hashes[i] != hashes[i - 1]); 62 | } 63 | 64 | qsort(hashes, NHASHES, sizeof(hashes[0]), hash_cmp); 65 | 66 | for (i = 0; i < NHASHES; ++i) { 67 | assert(!bsearch(&hashes[i], 68 | &hashes[i + 1], 69 | NHASHES - i - 1, 70 | sizeof(hashes[0]), 71 | hash_cmp)); 72 | } 73 | 74 | free(hashes); 75 | return EXIT_SUCCESS; 76 | } 77 | -------------------------------------------------------------------------------- /tests/b6b_test_if.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$if}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$if 1 {{$exit 2}}}", 19) == B6B_EXIT); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 2); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, 40 | "{$if 1 {{$exit 2}} {{$throw}}}", 41 | 30) == B6B_EXIT); 42 | assert(b6b_as_float(interp.fg->_)); 43 | assert(interp.fg->_->f == 2); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, "{$if 0 {{$exit 2}}}", 19) == B6B_OK); 48 | assert(b6b_as_str(interp.fg->_)); 49 | assert(interp.fg->_->slen == 0); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, 54 | "{$if 0 {{$throw}} {{$exit 2}}}", 55 | 30) == B6B_EXIT); 56 | assert(b6b_as_float(interp.fg->_)); 57 | assert(interp.fg->_->f == 2); 58 | b6b_interp_destroy(&interp); 59 | 60 | return EXIT_SUCCESS; 61 | } 62 | -------------------------------------------------------------------------------- /tests/b6b_test_inflate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$inflate}", 10) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$inflate {}}", 13) == B6B_ERR); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 37 | assert(b6b_call_copy(&interp, 38 | "{$inflate [$deflate [$str.join {} [$range 0 1000]]]}", 39 | 52) == B6B_OK); 40 | assert(b6b_as_str(interp.fg->_)); 41 | assert(interp.fg->_->slen == 2894); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 45 | assert(b6b_call_copy( 46 | &interp, 47 | "{$inflate [$deflate [[$open /dev/zero ru] read 524288]]}", 48 | 56) == B6B_OK); 49 | assert(b6b_as_str(interp.fg->_)); 50 | assert(interp.fg->_->slen == 524288); 51 | b6b_interp_destroy(&interp); 52 | 53 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 54 | assert(b6b_call_copy( 55 | &interp, 56 | "{$inflate [$deflate [[$open /dev/urandom ru] read 131072]]}", 57 | 59) == B6B_OK); 58 | assert(b6b_as_str(interp.fg->_)); 59 | assert(interp.fg->_->slen == 131072); 60 | b6b_interp_destroy(&interp); 61 | 62 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 63 | assert(b6b_call_copy(&interp, 64 | "{$inflate [$str.join {} [$range 0 1000]]}", 65 | 41) == B6B_ERR); 66 | b6b_interp_destroy(&interp); 67 | 68 | return EXIT_SUCCESS; 69 | } 70 | -------------------------------------------------------------------------------- /tests/b6b_test_istrue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_obj *o, *s; 27 | 28 | o = b6b_int_new(0); 29 | assert(o); 30 | assert(!b6b_obj_istrue(o)); 31 | b6b_unref(o); 32 | 33 | o = b6b_int_new(2); 34 | assert(o); 35 | assert(b6b_obj_istrue(o)); 36 | b6b_unref(o); 37 | 38 | o = b6b_float_new(0); 39 | assert(o); 40 | assert(!b6b_obj_istrue(o)); 41 | b6b_unref(o); 42 | 43 | o = b6b_float_new(2); 44 | assert(o); 45 | assert(b6b_obj_istrue(o)); 46 | b6b_unref(o); 47 | 48 | o = b6b_list_new(); 49 | assert(o); 50 | assert(!b6b_obj_istrue(o)); 51 | b6b_unref(o); 52 | 53 | s = b6b_str_copy("1", 0); 54 | assert(s); 55 | o = b6b_list_build(s, NULL); 56 | b6b_unref(s); 57 | assert(o); 58 | assert(b6b_obj_istrue(o)); 59 | assert(b6b_as_str(o)); 60 | assert(b6b_obj_istrue(o)); 61 | b6b_unref(b6b_list_pop(o, b6b_list_first(o))); 62 | assert(b6b_list_empty(o)); 63 | assert(!b6b_obj_istrue(o)); 64 | b6b_unref(o); 65 | 66 | o = b6b_str_copy("", 0); 67 | assert(o); 68 | assert(!b6b_obj_istrue(o)); 69 | b6b_unref(o); 70 | 71 | o = b6b_str_copy("a", 1); 72 | assert(o); 73 | assert(b6b_obj_istrue(o)); 74 | b6b_unref(o); 75 | 76 | o = b6b_str_copy("0", 1); 77 | assert(o); 78 | assert(!b6b_obj_istrue(o)); 79 | b6b_unref(o); 80 | 81 | o = b6b_str_copy("1", 1); 82 | assert(o); 83 | assert(b6b_obj_istrue(o)); 84 | b6b_unref(o); 85 | 86 | o = b6b_str_copy("00", 2); 87 | assert(o); 88 | assert(!b6b_obj_istrue(o)); 89 | b6b_unref(o); 90 | 91 | o = b6b_str_copy("0.0", 3); 92 | assert(o); 93 | assert(!b6b_obj_istrue(o)); 94 | b6b_unref(o); 95 | 96 | o = b6b_str_copy("001", 3); 97 | assert(o); 98 | assert(b6b_obj_istrue(o)); 99 | b6b_unref(o); 100 | 101 | o = b6b_str_copy("0.000000001", 11); 102 | assert(o); 103 | assert(b6b_obj_istrue(o)); 104 | b6b_unref(o); 105 | 106 | o = b6b_str_copy(".0", 2); 107 | assert(o); 108 | assert(!b6b_obj_istrue(o)); 109 | b6b_unref(o); 110 | 111 | o = b6b_str_copy(".1", 2); 112 | assert(o); 113 | assert(b6b_obj_istrue(o)); 114 | b6b_unref(o); 115 | 116 | o = b6b_str_copy("1.0", 3); 117 | assert(o); 118 | assert(b6b_obj_istrue(o)); 119 | b6b_unref(o); 120 | 121 | return EXIT_SUCCESS; 122 | } 123 | -------------------------------------------------------------------------------- /tests/b6b_test_le.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$<=}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$<= 1 4}", 9) == B6B_OK); 34 | assert(b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$<= 4 4}", 9) == B6B_OK); 39 | assert(b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$<= 4 -1}", 10) == B6B_OK); 44 | assert(!b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | return EXIT_SUCCESS; 48 | } 49 | -------------------------------------------------------------------------------- /tests/b6b_test_list_in.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$list.in}", 10) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$list.in a {}}", 15) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(!interp.fg->_->f); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$list.in a a}", 14) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, "{$list.in a b}", 14) == B6B_OK); 46 | assert(b6b_as_float(interp.fg->_)); 47 | assert(!interp.fg->_->f); 48 | b6b_interp_destroy(&interp); 49 | 50 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 51 | assert(b6b_call_copy(&interp, "{$list.in a {a b}}", 18) == B6B_OK); 52 | assert(b6b_as_float(interp.fg->_)); 53 | assert(interp.fg->_->f); 54 | b6b_interp_destroy(&interp); 55 | 56 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 57 | assert(b6b_call_copy(&interp, "{$list.in a {b a}}", 18) == B6B_OK); 58 | assert(b6b_as_float(interp.fg->_)); 59 | assert(interp.fg->_->f); 60 | b6b_interp_destroy(&interp); 61 | 62 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 63 | assert(b6b_call_copy(&interp, "{$list.in a {b c}}", 18) == B6B_OK); 64 | assert(b6b_as_float(interp.fg->_)); 65 | assert(!interp.fg->_->f); 66 | b6b_interp_destroy(&interp); 67 | 68 | return EXIT_SUCCESS; 69 | } 70 | -------------------------------------------------------------------------------- /tests/b6b_test_list_index.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$list.index}", 13) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$list.index {a b c} 0}", 23) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 1); 37 | assert(strcmp(interp.fg->_->s, "a") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$list.index {a b c} 1}", 23) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen == 1); 44 | assert(strcmp(interp.fg->_->s, "b") == 0); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$list.index {a b c} 2}", 23) == B6B_OK); 49 | assert(b6b_as_str(interp.fg->_)); 50 | assert(interp.fg->_->slen == 1); 51 | assert(strcmp(interp.fg->_->s, "c") == 0); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$list.index {a b c} 3}", 23) == B6B_ERR); 56 | b6b_interp_destroy(&interp); 57 | 58 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 59 | assert(b6b_call_copy(&interp, "{$list.index {a b c} -1}", 24) == B6B_ERR); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_list_len.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$list.len}", 11) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$list.len {}}", 14) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$list.len a}", 13) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 1); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, "{$list.len {a b}}", 17) == B6B_OK); 46 | assert(b6b_as_float(interp.fg->_)); 47 | assert(interp.fg->_->f == 2); 48 | b6b_interp_destroy(&interp); 49 | 50 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 51 | assert(b6b_call_copy(&interp, "{$list.len {a b c}}", 19) == B6B_OK); 52 | assert(b6b_as_float(interp.fg->_)); 53 | assert(interp.fg->_->f == 3); 54 | b6b_interp_destroy(&interp); 55 | 56 | return EXIT_SUCCESS; 57 | } 58 | -------------------------------------------------------------------------------- /tests/b6b_test_list_pop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$list.pop}", 11) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$list.pop {}}", 14) == B6B_ERR); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, "{$list.pop {} 0}", 16) == B6B_ERR); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$list.pop 4 0}", 15) == B6B_OK); 42 | assert(b6b_as_float(interp.fg->_)); 43 | assert(interp.fg->_->f == 4); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, "{$list.pop {4 5 6} 2}", 21) == B6B_OK); 48 | assert(b6b_as_float(interp.fg->_)); 49 | assert(interp.fg->_->f == 6); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$list.pop {4 5 6} 3}", 21) == B6B_ERR); 54 | b6b_interp_destroy(&interp); 55 | 56 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 57 | assert(b6b_call_copy(&interp, "{$list.pop {4 5 6} -1}", 22) == B6B_ERR); 58 | b6b_interp_destroy(&interp); 59 | 60 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 61 | assert(b6b_call_copy(&interp, "{$local a {4 5 6}} {$list.new [$list.pop $a 2] [$list.pop $a 1]}", 64) == B6B_OK); 62 | assert(b6b_as_list(interp.fg->_)); 63 | assert(!b6b_list_empty(interp.fg->_)); 64 | assert(b6b_as_float(b6b_list_first(interp.fg->_)->o)); 65 | assert(b6b_list_first(interp.fg->_)->o->f == 6); 66 | assert(b6b_list_next(b6b_list_first(interp.fg->_))); 67 | assert(b6b_as_float(b6b_list_next(b6b_list_first(interp.fg->_))->o)); 68 | assert(b6b_list_next(b6b_list_first(interp.fg->_))->o->f == 5); 69 | assert(!b6b_list_next(b6b_list_next(b6b_list_first(interp.fg->_)))); 70 | b6b_interp_destroy(&interp); 71 | 72 | return EXIT_SUCCESS; 73 | } 74 | -------------------------------------------------------------------------------- /tests/b6b_test_lt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$<}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$< 1 4}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 1); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$< 4 4}", 8) == B6B_OK); 40 | assert(!b6b_obj_istrue(interp.fg->_)); 41 | b6b_interp_destroy(&interp); 42 | 43 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 44 | assert(b6b_call_copy(&interp, "{$< 4 -1}", 9) == B6B_OK); 45 | assert(b6b_as_float(interp.fg->_)); 46 | assert(interp.fg->_->f == 0); 47 | b6b_interp_destroy(&interp); 48 | 49 | return EXIT_SUCCESS; 50 | } 51 | -------------------------------------------------------------------------------- /tests/b6b_test_mod.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$%}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$% 0 2}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$% 4 0}", 8) == B6B_ERR); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$% 4 2}", 8) == B6B_OK); 44 | assert(b6b_as_float(interp.fg->_)); 45 | assert(interp.fg->_->f == 0); 46 | b6b_interp_destroy(&interp); 47 | 48 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 49 | assert(b6b_call_copy(&interp, "{$% 4 3}", 8) == B6B_OK); 50 | assert(b6b_as_float(interp.fg->_)); 51 | assert(interp.fg->_->f == 1); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$% 6 -4}", 9) == B6B_OK); 56 | assert(b6b_as_float(interp.fg->_)); 57 | assert(interp.fg->_->f == -2); 58 | b6b_interp_destroy(&interp); 59 | 60 | /* regression test: $% 3 4 used to return -1 */ 61 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 62 | assert(b6b_call_copy(&interp, "{$% 3 4}", 8) == B6B_OK); 63 | assert(b6b_as_float(interp.fg->_)); 64 | assert(interp.fg->_->f == 3); 65 | b6b_interp_destroy(&interp); 66 | 67 | return EXIT_SUCCESS; 68 | } 69 | -------------------------------------------------------------------------------- /tests/b6b_test_mul.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$*}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$* 0 2}", 8) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$* 4 0}", 8) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 0); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, "{$* 4 2}", 8) == B6B_OK); 46 | assert(b6b_as_float(interp.fg->_)); 47 | assert(interp.fg->_->f == 8); 48 | b6b_interp_destroy(&interp); 49 | 50 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 51 | assert(b6b_call_copy(&interp, "{$* 4 2.5}", 10) == B6B_OK); 52 | assert(b6b_as_float(interp.fg->_)); 53 | assert(interp.fg->_->f == 10); 54 | b6b_interp_destroy(&interp); 55 | 56 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 57 | assert(b6b_call_copy(&interp, "{$* 4 0.5}", 10) == B6B_OK); 58 | assert(b6b_as_float(interp.fg->_)); 59 | assert(interp.fg->_->f == 2); 60 | b6b_interp_destroy(&interp); 61 | 62 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 63 | assert(b6b_call_copy(&interp, "{$* 4 -2.5}", 11) == B6B_OK); 64 | assert(b6b_as_float(interp.fg->_)); 65 | assert(interp.fg->_->f == -10); 66 | b6b_interp_destroy(&interp); 67 | 68 | return EXIT_SUCCESS; 69 | } 70 | -------------------------------------------------------------------------------- /tests/b6b_test_ne.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$!=}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$!= abc abc}", 13) == B6B_OK); 34 | assert(!b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$!= abc abd}", 13) == B6B_OK); 39 | assert(b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$!= {} {}}", 11) == B6B_OK); 44 | assert(!b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | return EXIT_SUCCESS; 48 | } 49 | -------------------------------------------------------------------------------- /tests/b6b_test_nop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$nop}", 6) == B6B_OK); 30 | assert(b6b_as_str(interp.fg->_)); 31 | assert(interp.fg->_->slen == 0); 32 | b6b_interp_destroy(&interp); 33 | 34 | return EXIT_SUCCESS; 35 | } 36 | -------------------------------------------------------------------------------- /tests/b6b_test_not.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$!}", 4) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$! 1}", 6) == B6B_OK); 34 | assert(!b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$! a}", 6) == B6B_OK); 39 | assert(!b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$! 0}", 6) == B6B_OK); 44 | assert(b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$! {}}", 7) == B6B_OK); 49 | assert(b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | return EXIT_SUCCESS; 53 | } 54 | -------------------------------------------------------------------------------- /tests/b6b_test_or.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$||}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$|| 0 0}", 9) == B6B_OK); 34 | assert(!b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$|| 1 0}", 9) == B6B_OK); 39 | assert(b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$|| 0 1}", 9) == B6B_OK); 44 | assert(b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$|| 1 1}", 9) == B6B_OK); 49 | assert(b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$|| {} {}}", 11) == B6B_OK); 54 | assert(!b6b_obj_istrue(interp.fg->_)); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$|| a 0}", 9) == B6B_OK); 59 | assert(b6b_obj_istrue(interp.fg->_)); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_repr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$repr}", 7) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$repr {}}", 10) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 2); 37 | assert(strcmp(interp.fg->_->s, "{}") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$repr a}", 9) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen == 1); 44 | assert(strcmp(interp.fg->_->s, "a") == 0); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$repr { }}", 11) == B6B_OK); 49 | assert(b6b_as_str(interp.fg->_)); 50 | assert(interp.fg->_->slen == 3); 51 | assert(strcmp(interp.fg->_->s, "{ }") == 0); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$repr abc}", 11) == B6B_OK); 56 | assert(b6b_as_str(interp.fg->_)); 57 | assert(interp.fg->_->slen == 3); 58 | assert(strcmp(interp.fg->_->s, "abc") == 0); 59 | b6b_interp_destroy(&interp); 60 | 61 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 62 | assert(b6b_call_copy(&interp, "{$repr {a\tb\tc}}", 15) == B6B_OK); 63 | assert(b6b_as_str(interp.fg->_)); 64 | assert(interp.fg->_->slen == 7); 65 | assert(strcmp(interp.fg->_->s, "{a\tb\tc}") == 0); 66 | b6b_interp_destroy(&interp); 67 | 68 | return EXIT_SUCCESS; 69 | } 70 | -------------------------------------------------------------------------------- /tests/b6b_test_return.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, 30 | "{$echo 1} {$return} {$echo 2}", 31 | 29) == B6B_RET); 32 | assert(b6b_as_str(interp.fg->_)); 33 | assert(interp.fg->_->slen == 0); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, 38 | "{$echo 1} {$return 2} {$echo 3}", 39 | 31) == B6B_RET); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 2); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, 46 | "{$echo 1} {$return 2 3} {$echo 4}", 47 | 33) == B6B_ERR); 48 | b6b_interp_destroy(&interp); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /tests/b6b_test_signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | int main() 28 | { 29 | struct b6b_interp interp; 30 | pid_t pid = getpid(); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$signal}", 9) == B6B_ERR); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, "{$signal {}}", 12) == B6B_ERR); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$signal -1}", 12) == B6B_ERR); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, "{$signal $SIGINT}", 17) == B6B_OK); 46 | b6b_interp_destroy(&interp); 47 | 48 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 49 | assert(b6b_call_copy(&interp, 50 | "{$signal $SIGINT $SIGTERM}", 51 | 26) == B6B_OK); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, 56 | "{$global a [$signal $SIGINT $SIGTERM]}", 57 | 38) == B6B_OK); 58 | assert(b6b_call_copy(&interp, "{$a read}", 9) == B6B_OK); 59 | assert(b6b_as_str(interp.fg->_)); 60 | assert(!interp.fg->_->slen); 61 | assert(kill(pid, SIGINT) == 0); 62 | assert(kill(pid, SIGTERM) == 0); 63 | assert(b6b_call_copy(&interp, "{$a read}", 9) == B6B_OK); 64 | assert(b6b_as_float(interp.fg->_)); 65 | assert(interp.fg->_->f == SIGINT); 66 | assert(b6b_call_copy(&interp, "{$a read}", 9) == B6B_OK); 67 | assert(b6b_as_float(interp.fg->_)); 68 | assert(interp.fg->_->f == SIGTERM); 69 | assert(b6b_call_copy(&interp, "{$a read}", 9) == B6B_OK); 70 | assert(b6b_as_str(interp.fg->_)); 71 | assert(!interp.fg->_->slen); 72 | b6b_interp_destroy(&interp); 73 | 74 | return EXIT_SUCCESS; 75 | } 76 | -------------------------------------------------------------------------------- /tests/b6b_test_source.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$source}", 9) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$source {}}", 12) == B6B_ERR); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, "{$source data/empty.b6b}", 24) == B6B_ERR); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$source data/exit.b6b}", 23) == B6B_EXIT); 42 | assert(b6b_as_float(interp.fg->_)); 43 | assert(interp.fg->_->f == 7); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, 48 | "{$source data/shebang.b6b}", 49 | 26) == B6B_EXIT); 50 | assert(b6b_as_float(interp.fg->_)); 51 | assert(interp.fg->_->f == 7); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, 56 | "{$source data/multi.b6b}", 57 | 24) == B6B_EXIT); 58 | assert(b6b_as_float(interp.fg->_)); 59 | assert(interp.fg->_->f == 7); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_spawn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy( &interp, "{$spawn}", 8) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy( 35 | &interp, 36 | "{$global x {}} " \ 37 | "{$spawn {{$map y [$range 1 20] {{$list.append $x a}}}}} " \ 38 | "{$map y [$range 1 20] {{$list.append $x b}}} " \ 39 | "{$return $x} " , 40 | 15 + 56 + 45 + 13) == B6B_RET); 41 | assert(b6b_as_str(interp.fg->_)); 42 | assert(strstr(interp.fg->_->s, "a b")); 43 | assert(strstr(interp.fg->_->s, "b a")); 44 | b6b_interp_destroy(&interp); 45 | 46 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 47 | assert(b6b_call_copy(&interp, 48 | "{$global x {}} " \ 49 | "{$spawn {{$map y [$range 1 20] {{$list.append $x a}}}}} " \ 50 | "{$spawn {{$map y [$range 1 20] {{$list.append $x b}}}}} " \ 51 | "{$map y [$range 1 20] {{$list.append $x c}}} " \ 52 | "{$return $x} " , 53 | 15 + 56 + 56 + 45 + 13) == B6B_RET); 54 | assert(b6b_as_str(interp.fg->_)); 55 | assert(strstr(interp.fg->_->s, "a b") || 56 | strstr(interp.fg->_->s, "a c")); 57 | assert(strstr(interp.fg->_->s, "b a") || 58 | strstr(interp.fg->_->s, "b c")); 59 | assert(strstr(interp.fg->_->s, "c a") || 60 | strstr(interp.fg->_->s, "c b")); 61 | b6b_interp_destroy(&interp); 62 | 63 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 64 | assert(b6b_call_copy(&interp, 65 | "{$global x {}} " \ 66 | "{$spawn {{$map y [$range 1 3] {{$list.append $x a} {$yield}}}}} " \ 67 | "{$map y [$range 1 3] {{$list.append $x b} {$yield}}} " \ 68 | "{$return $x} " , 69 | 15 + 64 + 53 + 13) == B6B_RET); 70 | assert(b6b_as_str(interp.fg->_)); 71 | assert(strcmp(interp.fg->_->s, "b a b a b a") == 0); 72 | b6b_interp_destroy(&interp); 73 | 74 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 75 | assert(b6b_call_copy(&interp, 76 | "{$global x {}} " \ 77 | "{$spawn {{$yield} {$exit 7}}} " \ 78 | "{$loop {{$yield}}}", 79 | 15 + 30 + 18) == B6B_EXIT); 80 | b6b_interp_destroy(&interp); 81 | 82 | return EXIT_SUCCESS; 83 | } 84 | -------------------------------------------------------------------------------- /tests/b6b_test_str_chr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$str.chr [$str.ord a]}", 23) == B6B_OK); 31 | assert(b6b_as_str(interp.fg->_)); 32 | assert(interp.fg->_->slen == 1); 33 | assert(strcmp(interp.fg->_->s, "a") == 0); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, "{$str.chr 0xFF}", 15) == B6B_OK); 38 | assert(b6b_as_str(interp.fg->_)); 39 | assert(interp.fg->_->slen == 1); 40 | assert(strcmp(interp.fg->_->s, "\xFF") == 0); 41 | b6b_interp_destroy(&interp); 42 | 43 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 44 | assert(b6b_call_copy(&interp, "{$str.chr [$str.ord [$str.expand \\0]]}", 38) == B6B_OK); 45 | assert(b6b_as_str(interp.fg->_)); 46 | assert(interp.fg->_->slen == 1); 47 | assert(interp.fg->_->s[0] == '\0'); 48 | b6b_interp_destroy(&interp); 49 | 50 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 51 | assert(b6b_call_copy(&interp, "{$str.chr {}}", 13) == B6B_ERR); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$str.chr 256}", 14) == B6B_ERR); 56 | b6b_interp_destroy(&interp); 57 | 58 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 59 | assert(b6b_call_copy(&interp, "{$str.chr -1}", 13) == B6B_ERR); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_str_in.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$str.in {} abcd}", 17) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$str.in ef abcd}", 17) == B6B_OK); 34 | assert(!b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$str.in ab abcd}", 17) == B6B_OK); 39 | assert(b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$str.in bc abcd}", 17) == B6B_OK); 44 | assert(b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$str.in cd abcd}", 17) == B6B_OK); 49 | assert(b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$str.in bc bc}", 15) == B6B_OK); 54 | assert(b6b_obj_istrue(interp.fg->_)); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$str.in bc bb}", 15) == B6B_OK); 59 | assert(!b6b_obj_istrue(interp.fg->_)); 60 | b6b_interp_destroy(&interp); 61 | 62 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 63 | assert(b6b_call_copy(&interp, "{$str.in bc b}", 14) == B6B_OK); 64 | assert(!b6b_obj_istrue(interp.fg->_)); 65 | b6b_interp_destroy(&interp); 66 | 67 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 68 | assert(b6b_call_copy(&interp, "{$str.in bc {}}", 15) == B6B_OK); 69 | assert(!b6b_obj_istrue(interp.fg->_)); 70 | b6b_interp_destroy(&interp); 71 | 72 | return EXIT_SUCCESS; 73 | } 74 | -------------------------------------------------------------------------------- /tests/b6b_test_str_index.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$str.index}", 12) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$str.index abc 0}", 18) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 1); 37 | assert(strcmp(interp.fg->_->s, "a") == 0); 38 | b6b_interp_destroy(&interp); 39 | 40 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 41 | assert(b6b_call_copy(&interp, "{$str.index abc 1}", 18) == B6B_OK); 42 | assert(b6b_as_str(interp.fg->_)); 43 | assert(interp.fg->_->slen == 1); 44 | assert(strcmp(interp.fg->_->s, "b") == 0); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$str.index abc 2}", 18) == B6B_OK); 49 | assert(b6b_as_str(interp.fg->_)); 50 | assert(interp.fg->_->slen == 1); 51 | assert(strcmp(interp.fg->_->s, "c") == 0); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$str.index abc 3}", 18) == B6B_ERR); 56 | b6b_interp_destroy(&interp); 57 | 58 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 59 | assert(b6b_call_copy(&interp, "{$str.index abc -1}", 19) == B6B_ERR); 60 | b6b_interp_destroy(&interp); 61 | 62 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 63 | assert(b6b_call_copy(&interp, "{$str.index a 0}", 16) == B6B_OK); 64 | assert(b6b_as_str(interp.fg->_)); 65 | assert(interp.fg->_->slen == 1); 66 | assert(strcmp(interp.fg->_->s, "a") == 0); 67 | b6b_interp_destroy(&interp); 68 | 69 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 70 | assert(b6b_call_copy(&interp, "{$str.index {} 0}", 17) == B6B_ERR); 71 | b6b_interp_destroy(&interp); 72 | 73 | return EXIT_SUCCESS; 74 | } 75 | -------------------------------------------------------------------------------- /tests/b6b_test_str_len.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$str.len}", 10) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$str.len {}}", 13) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 0); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$str.len abc}", 14) == B6B_OK); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 3); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, "{$str.len ab\0c}", 15) == B6B_OK); 46 | assert(b6b_as_float(interp.fg->_)); 47 | assert(interp.fg->_->f == 4); 48 | b6b_interp_destroy(&interp); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /tests/b6b_test_str_ltrim.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$ltrim}", 8) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$ltrim {}}", 11) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 0); 37 | b6b_interp_destroy(&interp); 38 | 39 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 40 | assert(b6b_call_copy(&interp, "{$ltrim {abc }}", 16) == B6B_OK); 41 | assert(b6b_as_str(interp.fg->_)); 42 | assert(strcmp(interp.fg->_->s, "abc ") == 0); 43 | b6b_interp_destroy(&interp); 44 | 45 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 46 | assert(b6b_call_copy(&interp, "{$ltrim abc}", 12) == B6B_OK); 47 | assert(b6b_as_str(interp.fg->_)); 48 | assert(strcmp(interp.fg->_->s, "abc") == 0); 49 | b6b_interp_destroy(&interp); 50 | 51 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 52 | assert(b6b_call_copy(&interp, "{$ltrim { abc}}", 15) == B6B_OK); 53 | assert(b6b_as_str(interp.fg->_)); 54 | assert(strcmp(interp.fg->_->s, "abc") == 0); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$ltrim { abc}}", 16) == B6B_OK); 59 | assert(b6b_as_str(interp.fg->_)); 60 | assert(strcmp(interp.fg->_->s, "abc") == 0); 61 | b6b_interp_destroy(&interp); 62 | 63 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 64 | assert(b6b_call_copy(&interp, "{$ltrim { abc }}", 18) == B6B_OK); 65 | assert(b6b_as_str(interp.fg->_)); 66 | assert(strcmp(interp.fg->_->s, "abc ") == 0); 67 | b6b_interp_destroy(&interp); 68 | 69 | return EXIT_SUCCESS; 70 | } 71 | -------------------------------------------------------------------------------- /tests/b6b_test_str_ord.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$str.ord}", 10) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$str.ord a}", 12) == B6B_OK); 34 | assert(b6b_as_float(interp.fg->_)); 35 | assert(interp.fg->_->f == 'a'); 36 | b6b_interp_destroy(&interp); 37 | 38 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 39 | assert(b6b_call_copy(&interp, "{$str.ord aa}", 13) == B6B_ERR); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, 0)); 43 | assert(b6b_call_copy(&interp, "{$str.ord [$str.expand \\xff]}", 29) == B6B_OK); 44 | assert(b6b_as_float(interp.fg->_)); 45 | assert(interp.fg->_->f == 0xFF); 46 | b6b_interp_destroy(&interp); 47 | 48 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 49 | assert(b6b_call_copy(&interp, "{$str.ord [$str.expand \\0]}", 27) == B6B_OK); 50 | assert(b6b_as_float(interp.fg->_)); 51 | assert(interp.fg->_->f == 0); 52 | b6b_interp_destroy(&interp); 53 | 54 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 55 | assert(b6b_call_copy(&interp, "{$str.ord {}}", 13) == B6B_ERR); 56 | b6b_interp_destroy(&interp); 57 | 58 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 59 | assert(b6b_call_copy(&interp, "{$str.ord aa}", 13) == B6B_ERR); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/b6b_test_str_rtrim.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | int main() 26 | { 27 | struct b6b_interp interp; 28 | 29 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 30 | assert(b6b_call_copy(&interp, "{$rtrim}", 8) == B6B_ERR); 31 | b6b_interp_destroy(&interp); 32 | 33 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 34 | assert(b6b_call_copy(&interp, "{$rtrim {}}", 11) == B6B_OK); 35 | assert(b6b_as_str(interp.fg->_)); 36 | assert(interp.fg->_->slen == 0); 37 | b6b_interp_destroy(&interp); 38 | 39 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 40 | assert(b6b_call_copy(&interp, "{$rtrim { abc}}", 16) == B6B_OK); 41 | assert(b6b_as_str(interp.fg->_)); 42 | assert(strcmp(interp.fg->_->s, " abc") == 0); 43 | b6b_interp_destroy(&interp); 44 | 45 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 46 | assert(b6b_call_copy(&interp, "{$rtrim abc}", 12) == B6B_OK); 47 | assert(b6b_as_str(interp.fg->_)); 48 | assert(strcmp(interp.fg->_->s, "abc") == 0); 49 | b6b_interp_destroy(&interp); 50 | 51 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 52 | assert(b6b_call_copy(&interp, "{$rtrim {abc }}", 15) == B6B_OK); 53 | assert(b6b_as_str(interp.fg->_)); 54 | assert(strcmp(interp.fg->_->s, "abc") == 0); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$rtrim {abc }}", 16) == B6B_OK); 59 | assert(b6b_as_str(interp.fg->_)); 60 | assert(strcmp(interp.fg->_->s, "abc") == 0); 61 | b6b_interp_destroy(&interp); 62 | 63 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 64 | assert(b6b_call_copy(&interp, "{$rtrim { abc }}", 18) == B6B_OK); 65 | assert(b6b_as_str(interp.fg->_)); 66 | assert(strcmp(interp.fg->_->s, " abc") == 0); 67 | b6b_interp_destroy(&interp); 68 | 69 | return EXIT_SUCCESS; 70 | } 71 | -------------------------------------------------------------------------------- /tests/b6b_test_throw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, 30 | "{$echo 1} {$throw} {$echo 2}", 31 | 28) == B6B_ERR); 32 | assert(b6b_as_str(interp.fg->_)); 33 | assert(interp.fg->_->slen == 0); 34 | b6b_interp_destroy(&interp); 35 | 36 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 37 | assert(b6b_call_copy(&interp, 38 | "{$echo 1} {$throw 2} {$echo 3}", 39 | 30) == B6B_ERR); 40 | assert(b6b_as_float(interp.fg->_)); 41 | assert(interp.fg->_->f == 2); 42 | b6b_interp_destroy(&interp); 43 | 44 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 45 | assert(b6b_call_copy(&interp, 46 | "{$echo 1} {$throw 2 3} {$echo 4}", 47 | 32) == B6B_ERR); 48 | b6b_interp_destroy(&interp); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /tests/b6b_test_xor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of b6b. 3 | * 4 | * Copyright 2017 Dima Krasner 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | int main() 25 | { 26 | struct b6b_interp interp; 27 | 28 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 29 | assert(b6b_call_copy(&interp, "{$^^}", 5) == B6B_ERR); 30 | b6b_interp_destroy(&interp); 31 | 32 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 33 | assert(b6b_call_copy(&interp, "{$^^ 0 0}", 9) == B6B_OK); 34 | assert(!b6b_obj_istrue(interp.fg->_)); 35 | b6b_interp_destroy(&interp); 36 | 37 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 38 | assert(b6b_call_copy(&interp, "{$^^ 1 0}", 9) == B6B_OK); 39 | assert(b6b_obj_istrue(interp.fg->_)); 40 | b6b_interp_destroy(&interp); 41 | 42 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 43 | assert(b6b_call_copy(&interp, "{$^^ 0 1}", 9) == B6B_OK); 44 | assert(b6b_obj_istrue(interp.fg->_)); 45 | b6b_interp_destroy(&interp); 46 | 47 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 48 | assert(b6b_call_copy(&interp, "{$^^ 1 1}", 9) == B6B_OK); 49 | assert(!b6b_obj_istrue(interp.fg->_)); 50 | b6b_interp_destroy(&interp); 51 | 52 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 53 | assert(b6b_call_copy(&interp, "{$^^ {} {}}", 11) == B6B_OK); 54 | assert(!b6b_obj_istrue(interp.fg->_)); 55 | b6b_interp_destroy(&interp); 56 | 57 | assert(b6b_interp_new_argv(&interp, 0, NULL, B6B_OPT_TRACE)); 58 | assert(b6b_call_copy(&interp, "{$^^ a 0}", 9) == B6B_OK); 59 | assert(b6b_obj_istrue(interp.fg->_)); 60 | b6b_interp_destroy(&interp); 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | -------------------------------------------------------------------------------- /tests/data/empty.b6b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimkr/b6b/f8972059d3146e61572b55090ba4a9cadedf606d/tests/data/empty.b6b -------------------------------------------------------------------------------- /tests/data/exit.b6b: -------------------------------------------------------------------------------- 1 | {# 2 | This file is part of b6b. 3 | 4 | Copyright 2017 Dima Krasner 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | } 18 | 19 | {$exit 7} 20 | -------------------------------------------------------------------------------- /tests/data/multi.b6b: -------------------------------------------------------------------------------- 1 | {# 2 | This file is part of b6b. 3 | 4 | Copyright 2017 Dima Krasner 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | } 18 | 19 | {$echo 5} 20 | {$echo 6} 21 | {$exit 7} 22 | -------------------------------------------------------------------------------- /tests/data/shebang.b6b: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | {# 4 | This file is part of b6b. 5 | 6 | Copyright 2017 Dima Krasner 7 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | } 20 | 21 | {$exit 7} 22 | --------------------------------------------------------------------------------